credible 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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