credible 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96162f717345b6f2e21358b34a5b51f86a305c92a3c98a39453596619d88317d
4
- data.tar.gz: 67852dc6fda7440f1a00e6e9e0613c39eb9df826079388d0034d013135011a7a
3
+ metadata.gz: 26e8296ed1bf8eccded84ae3f9d856942475bd0a9f4599b5b7a396932e280fce
4
+ data.tar.gz: 61f7119a19a8295f1ea82aa62074417a04cc2ba7fd64d5b81147fdfe931507c1
5
5
  SHA512:
6
- metadata.gz: 17f04e7f1a9826489e3182ddb060c7522b835a2f4e009b7bcebd8a38154cd0b22b8d09a23c83b7fce758a4c2b8a0431bd42120c2e3b5c57c04a05685414f0e93
7
- data.tar.gz: d76edd44b640d760af1329449dd35ee52db0f332056a20856acf2432589012ed86d63d8ac2b5af26def7ea2c3dc41fc995ec64501bd127aa8cf0e489538ad822
6
+ metadata.gz: f33e0db40e889814c25dbefd88efe0ea6f39fa67d3eb966054b07064b5268e89cdcb58a056ded8c79b54d7df7c7f87da6e2eaf22b6d1298966c4820998795d50
7
+ data.tar.gz: 1e260353acc82654382167391a2cd8ba3d4f69eb0ef1ce37edcb25bfd72cceaa8f87ceb30176e490ac2e90358892588aefadade526b1f383d132e5307882c36a
data/README.md CHANGED
@@ -29,6 +29,14 @@ Rails.application.routes.draw do
29
29
  end
30
30
  ```
31
31
 
32
+ And in your Application Controller, inherit from `Credible::ApplicationController`:
33
+
34
+ ```ruby
35
+ class ApplicationController < ActionController::Base
36
+ include Credible::ApplicationController
37
+ end
38
+ ```
39
+
32
40
  Credible is a work in progress and requires a complicated setup for now. It was extracted from [thombruce/helvellyn](https://github.com/thombruce/helvellyn). You'll need to add models and configure them manually. In future, I'll had helpers to handle this for you.
33
41
 
34
42
  ## Add Models
@@ -43,43 +51,7 @@ rails g model User email:string:uniq password_digest:string confirmation_token:t
43
51
 
44
52
  ```ruby
45
53
  class User < ApplicationRecord
46
- has_secure_password validations: false
47
- has_secure_token :confirmation_token
48
-
49
- has_many :sessions, dependent: :destroy
50
-
51
- validates :email, presence: true
52
- validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
53
-
54
- # Custom password validation
55
- validate do |record|
56
- record.errors.add(:password, :blank) unless record.password_digest.present? || record.confirmation_token.present?
57
- end
58
-
59
- validates_length_of :password, maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED
60
- validates_confirmation_of :password, allow_blank: true
61
- # End custom password validation
62
-
63
- def self.authenticate(params)
64
- user = find_by_login(params[:login])
65
- user&.authenticate(params[:password])
66
- end
67
-
68
- def confirm
69
- self.confirmation_token = nil
70
- self.password = SecureRandom.hex(8) unless password_digest.present?
71
- self.confirmed_at = Time.now.utc
72
- end
73
-
74
- def confirmed?
75
- confirmed_at.present?
76
- end
77
-
78
- def reset_password
79
- self.password_digest = nil
80
- self.confirmed_at = nil
81
- regenerate_confirmation_token
82
- end
54
+ include Credible::User
83
55
  end
84
56
  ```
85
57
 
@@ -91,35 +63,7 @@ rails g model Session user:references token:token
91
63
 
92
64
  ```ruby
93
65
  class Session < ApplicationRecord
94
- belongs_to :user
95
-
96
- has_secure_token
97
-
98
- def self.authenticate(params)
99
- user = User.authenticate(params)
100
- new(user: user)
101
- end
102
-
103
- def jwt
104
- payload = {
105
- data: jwt_data,
106
- iss: 'Helvellyn'
107
- }
108
- JWT.encode payload, Rails.application.secrets.secret_key_base, 'HS256' # [1]
109
- end
110
-
111
- private
112
-
113
- def jwt_data
114
- {
115
- session_id: id,
116
- user_id: user.id,
117
- user: {
118
- id: user.id,
119
- email: user.email
120
- }
121
- }
122
- end
66
+ include Credible::Session
123
67
  end
124
68
  ```
125
69
 
@@ -15,14 +15,14 @@ class Credible::Authentication::SessionsController < Credible::AuthenticationCon
15
15
 
16
16
  # GET /sessions/new
17
17
  def new
18
- @session = Session.new
18
+ @session = ::Session.new
19
19
  authorize @session
20
20
  end
21
21
 
22
22
  # POST /sessions
23
23
  # POST /sessions.json
24
24
  def create
25
- @session = Session.authenticate(permitted_attributes(Session))
25
+ @session = ::Session.authenticate(permitted_attributes(Session))
26
26
  authorize @session
27
27
 
28
28
  if @session.save
@@ -10,19 +10,19 @@ class Credible::Authentication::UsersController < Credible::AuthenticationContro
10
10
 
11
11
  # GET /users/new
12
12
  def new
13
- @user = User.new
13
+ @user = ::User.new
14
14
  authorize @user
15
15
  end
16
16
 
17
17
  # POST /users
18
18
  # POST /users.json
19
19
  def create
20
- @user = User.new(permitted_attributes(User))
20
+ @user = ::User.new(permitted_attributes(User))
21
21
  authorize @user
22
22
 
23
23
  if @user.save
24
24
  Credible::UserMailer.with(user: @user).confirmation_email.deliver_later
25
- @session = Session.create(user: @user)
25
+ @session = ::Session.create(user: @user)
26
26
  render :show, status: :created, location: @user
27
27
  else
28
28
  render json: @user.errors, status: :unprocessable_entity
@@ -32,13 +32,13 @@ class Credible::Authentication::UsersController < Credible::AuthenticationContro
32
32
  # GET /users/confirm/:confirmation_token
33
33
  # GET /users/confirm/:confirmation_token.json
34
34
  def confirm
35
- @user = User.find_by(confirmation_token: params[:confirmation_token])
35
+ @user = ::User.find_by(confirmation_token: params[:confirmation_token])
36
36
  authorize @user
37
37
 
38
38
  @user.confirm
39
39
 
40
40
  if @user.save
41
- @session = current_user ? current_session : Session.create(user: @user)
41
+ @session = current_user ? current_session : ::Session.create(user: @user)
42
42
  render :show, status: :created, location: @user
43
43
  else
44
44
  render json: @user.errors, status: :unprocessable_entity
@@ -48,7 +48,7 @@ class Credible::Authentication::UsersController < Credible::AuthenticationContro
48
48
  # POST /users/reset_password
49
49
  # POST /users/reset_password.json
50
50
  def reset_password
51
- @user = User.find_by(email: permitted_attributes(User)[:email])
51
+ @user = ::User.find_by(email: permitted_attributes(User)[:email])
52
52
  authorize @user
53
53
 
54
54
  @user.reset_password
@@ -1,4 +1,4 @@
1
- class Credible::AuthenticationController < Credible::ApplicationController
1
+ class Credible::AuthenticationController < ApplicationController
2
2
  # TODO: Authentication module is now redundant inside Credible Engine.
3
3
  # Migrate out of namespace.
4
4
 
@@ -30,7 +30,7 @@ Warden::Strategies.add(:jwt) do
30
30
  fail!('Could not authenticate')
31
31
  end
32
32
 
33
- session = Session.find(token[0]['data']['session_id'])
33
+ session = ::Session.find(token[0]['data']['session_id'])
34
34
 
35
35
  session ? success!(session) : fail!('Could not authenticate')
36
36
  end
@@ -50,7 +50,7 @@ Warden::Strategies.add(:api_token) do
50
50
  end
51
51
 
52
52
  def authenticate!
53
- session = Session.find_by(token: env['HTTP_API_TOKEN'])
53
+ session = ::Session.find_by(token: env['HTTP_API_TOKEN'])
54
54
  session ? success!(session) : fail!('Could not authenticate')
55
55
  end
56
56
 
@@ -0,0 +1,50 @@
1
+ module Credible
2
+ module ApplicationController
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ skip_before_action :verify_authenticity_token
7
+
8
+ include Pundit
9
+ after_action :verify_authorized
10
+ after_action :verify_policy_scoped, only: :index
11
+
12
+ rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
13
+ rescue_from Pundit::NotDefinedError, with: :user_not_authorized
14
+
15
+ before_action :authenticate!, if: proc { request.env['HTTP_AUTHORIZATION'] || request.env['HTTP_API_TOKEN'] }
16
+
17
+ helper_method :current_user
18
+ helper_method :current_session
19
+
20
+ def pundit_user
21
+ current_session
22
+ end
23
+
24
+ def current_user
25
+ current_session.user
26
+ end
27
+
28
+ def current_session
29
+ warden.user(:session) || ::Session.new(user: nil)
30
+ end
31
+
32
+ def warden
33
+ request.env['warden']
34
+ end
35
+
36
+ def authenticate!
37
+ warden.authenticate!
38
+ end
39
+ end
40
+
41
+ class_methods do
42
+ end
43
+
44
+ private
45
+
46
+ def user_not_authorized
47
+ render json: {}.to_json, status: :forbidden
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,43 @@
1
+ module Credible
2
+ module Session
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attr_accessor :login
7
+
8
+ belongs_to :user, optional: true
9
+
10
+ has_secure_token
11
+
12
+ def jwt
13
+ payload = {
14
+ data: jwt_data,
15
+ iss: 'Helvellyn'
16
+ }
17
+ JWT.encode payload, Rails.application.secrets.secret_key_base, 'HS256' # [1]
18
+ end
19
+ end
20
+
21
+ class_methods do
22
+ def authenticate(params)
23
+ user = ::User.authenticate(params)
24
+ new(user: user)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def jwt_data
31
+ {
32
+ session_id: id,
33
+ user_id: user.id,
34
+ user: {
35
+ id: user.id,
36
+ email: user.email
37
+ }
38
+ }
39
+ end
40
+ end
41
+ end
42
+
43
+ # [1] Use of `secrets` instead of `credentials` makes for a container-ready deploy on Heroku (easier setup for open source)
@@ -0,0 +1,51 @@
1
+ module Credible
2
+ module User
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ has_secure_password validations: false
7
+ has_secure_token :confirmation_token
8
+
9
+ has_many :sessions, dependent: :destroy
10
+
11
+ validates :email, presence: true
12
+ validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
13
+
14
+ # Custom password validation
15
+ validate do |record|
16
+ record.errors.add(:password, :blank) unless record.password_digest.present? || record.confirmation_token.present?
17
+ end
18
+
19
+ validates_length_of :password, maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED
20
+ validates_confirmation_of :password, allow_blank: true
21
+ # End custom password validation
22
+
23
+ def confirm
24
+ self.confirmation_token = nil
25
+ self.password = SecureRandom.hex(8) unless password_digest.present?
26
+ self.confirmed_at = Time.now.utc
27
+ end
28
+
29
+ def confirmed?
30
+ confirmed_at.present?
31
+ end
32
+
33
+ def reset_password
34
+ self.password_digest = nil
35
+ self.confirmed_at = nil
36
+ regenerate_confirmation_token
37
+ end
38
+ end
39
+
40
+ class_methods do
41
+ def find_by_login(login)
42
+ find_by(email: login)
43
+ end
44
+
45
+ def authenticate(params)
46
+ user = find_by_login(params[:login])
47
+ user&.authenticate(params[:password])
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,3 +1,3 @@
1
1
  module Credible
2
- VERSION = '0.1.3'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/credible.rb CHANGED
@@ -1,5 +1,12 @@
1
+ require "active_support"
2
+
1
3
  require "credible/engine"
2
4
 
5
+ require "credible/application_controller"
6
+
7
+ require "credible/user"
8
+ require "credible/session"
9
+
3
10
  module Credible
4
11
  # Your code goes here...
5
12
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: credible
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thom Bruce
@@ -73,19 +73,19 @@ dependencies:
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
75
  - !ruby/object:Gem::Dependency
76
- name: rspec
76
+ name: rspec-rails
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: 3.9.0
81
+ version: 4.0.0.beta3
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: 3.9.0
88
+ version: 4.0.0.beta3
89
89
  description: Provides token-based authentication for Rails API apps.
90
90
  email:
91
91
  - thom@thombruce.com
@@ -95,7 +95,6 @@ extra_rdoc_files: []
95
95
  files:
96
96
  - README.md
97
97
  - Rakefile
98
- - app/controllers/credible/application_controller.rb
99
98
  - app/controllers/credible/authentication/sessions_controller.rb
100
99
  - app/controllers/credible/authentication/users_controller.rb
101
100
  - app/controllers/credible/authentication_controller.rb
@@ -119,7 +118,10 @@ files:
119
118
  - config/initializers/warden.rb
120
119
  - config/routes.rb
121
120
  - lib/credible.rb
121
+ - lib/credible/application_controller.rb
122
122
  - lib/credible/engine.rb
123
+ - lib/credible/session.rb
124
+ - lib/credible/user.rb
123
125
  - lib/credible/version.rb
124
126
  - lib/tasks/credible_tasks.rake
125
127
  homepage: https://github.com/thombruce/credible
@@ -1,43 +0,0 @@
1
- module Credible
2
- class ApplicationController < ActionController::Base
3
- skip_before_action :verify_authenticity_token
4
-
5
- include Pundit
6
- after_action :verify_authorized
7
- after_action :verify_policy_scoped, only: :index
8
-
9
- rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
10
- rescue_from Pundit::NotDefinedError, with: :user_not_authorized
11
-
12
- before_action :authenticate!, if: proc { request.env['HTTP_AUTHORIZATION'] || request.env['HTTP_API_TOKEN'] }
13
-
14
- helper_method :current_user
15
- helper_method :current_session
16
-
17
- def pundit_user
18
- current_session
19
- end
20
-
21
- def current_user
22
- current_session.user
23
- end
24
-
25
- def current_session
26
- warden.user(:session) || Session.new(user: nil)
27
- end
28
-
29
- def warden
30
- request.env['warden']
31
- end
32
-
33
- def authenticate!
34
- warden.authenticate!
35
- end
36
-
37
- private
38
-
39
- def user_not_authorized
40
- render json: {}.to_json, status: :forbidden
41
- end
42
- end
43
- end