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 +4 -4
- data/README.md +10 -66
- data/app/controllers/credible/authentication/sessions_controller.rb +2 -2
- data/app/controllers/credible/authentication/users_controller.rb +6 -6
- data/app/controllers/credible/authentication_controller.rb +1 -1
- data/config/initializers/warden.rb +2 -2
- data/lib/credible/application_controller.rb +50 -0
- data/lib/credible/session.rb +43 -0
- data/lib/credible/user.rb +51 -0
- data/lib/credible/version.rb +1 -1
- data/lib/credible.rb +7 -0
- metadata +7 -5
- data/app/controllers/credible/application_controller.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26e8296ed1bf8eccded84ae3f9d856942475bd0a9f4599b5b7a396932e280fce
|
4
|
+
data.tar.gz: 61f7119a19a8295f1ea82aa62074417a04cc2ba7fd64d5b81147fdfe931507c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
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
|
@@ -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
|
data/lib/credible/version.rb
CHANGED
data/lib/credible.rb
CHANGED
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.
|
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:
|
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:
|
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
|