wor-authentication 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -1
- data/.travis.yml +3 -8
- data/CHANGELOG.md +23 -0
- data/LICENSE.md +1 -1
- data/README.md +29 -31
- data/Rakefile +3 -3
- data/lib/generators/templates/wor_authentication.rb +4 -0
- data/lib/generators/wor/authentication/install_generator.rb +14 -0
- data/lib/wor/authentication.rb +34 -1
- data/lib/wor/authentication/controller.rb +29 -17
- data/lib/wor/authentication/decoded_token.rb +6 -4
- data/lib/wor/authentication/exceptions.rb +7 -5
- data/lib/wor/authentication/sessions_controller.rb +11 -6
- data/lib/wor/authentication/version.rb +1 -1
- data/wor-authentication.gemspec +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 787ae1d673913fc47b4ab942d4fca187c13a0e33
|
4
|
+
data.tar.gz: c4d4697f041f984c6fc37e3f36f7cbca3c10e1c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f52f09a7d4068a8bab032f5d6705d785be43afc08aafa5e5eb7ef90c35e779c487448e69940b54ec7bb34ac543987eecbeb7af7639eef85597443af73617dac
|
7
|
+
data.tar.gz: 8b87dddd1e8cb02d02e86e5eb32194f0c9123a72b9bfeac00cc2e250579a7326e592825559f4462e3c8372d5590209d136d32be9af815318731f87d643c064af
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.
|
4
|
-
- 2.1
|
5
|
-
- 2.2
|
3
|
+
- 2.2.2
|
6
4
|
- 2.3.3
|
7
5
|
- 2.4.0
|
8
6
|
|
@@ -11,9 +9,6 @@ install:
|
|
11
9
|
- bundle install --retry=3
|
12
10
|
|
13
11
|
script:
|
14
|
-
- bundle exec rspec
|
15
12
|
- bundle exec rubocop -R --format simple
|
16
|
-
|
17
|
-
|
18
|
-
code_climate:
|
19
|
-
repo_token:
|
13
|
+
- bundle exec rspec
|
14
|
+
- bundle exec codeclimate-test-reporter
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
## Change log
|
3
|
+
|
4
|
+
### [0.2.0]
|
5
|
+
|
6
|
+
#### Added
|
7
|
+
|
8
|
+
- Initializer with its generator.
|
9
|
+
- Specs for initializer and generator.
|
10
|
+
|
11
|
+
#### Changed
|
12
|
+
|
13
|
+
- Instead of overriding methods, it is now possible to configure `expiration_days` and `maximum_useful_days` with the initializer.
|
14
|
+
|
15
|
+
#### Removed
|
16
|
+
|
17
|
+
- Removed restriction for authentication parameters.
|
18
|
+
|
19
|
+
### [0.1.0]
|
20
|
+
|
21
|
+
#### Added
|
22
|
+
|
23
|
+
- `wor-authentication` gem first release.
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# Wolox on Rails - Authentication
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/wor-authentication.svg)](https://badge.fury.io/rb/wor-authentication)
|
3
|
+
[![Dependency Status](https://gemnasium.com/badges/github.com/Wolox/wor-authentication.svg)](https://gemnasium.com/github.com/Wolox/wor-authentication)
|
2
4
|
[![Build Status](https://travis-ci.org/Wolox/wor-authentication.svg)](https://travis-ci.org/Wolox/wor-authentication)
|
3
5
|
[![Code Climate](https://codeclimate.com/github/Wolox/wor-authentication/badges/gpa.svg)](https://codeclimate.com/github/Wolox/wor-authentication)
|
4
6
|
[![Test Coverage](https://codeclimate.com/github/Wolox/wor-authentication/badges/coverage.svg)](https://codeclimate.com/github/Wolox/wor-authentication/coverage)
|
5
|
-
[![Issue Count](https://codeclimate.com/github/Wolox/wor-authentication/badges/issue_count.svg)](https://codeclimate.com/github/Wolox/wor-authentication)
|
6
7
|
|
7
8
|
Gem to add authentication to your application using JWT, with expirable, renewable and customizable tokens!
|
8
9
|
|
@@ -53,75 +54,72 @@ end
|
|
53
54
|
```
|
54
55
|
> Note that our controller extends from ApplicationController.
|
55
56
|
|
56
|
-
### <a name='custom-validations'>
|
57
|
+
### <a name='custom-validations'> Entity tracking and custom validations
|
57
58
|
|
58
59
|
#### Validations before giving out a token? Override `authenticate_entity`:
|
59
60
|
|
60
61
|
```ruby
|
61
|
-
#
|
62
|
+
# application_controller.rb
|
62
63
|
def authenticate_entity(params)
|
63
|
-
|
64
|
-
return nil unless
|
64
|
+
entity = Entity.find_by(some_unique_id: params[:some_unique_id])
|
65
|
+
return nil unless entity.present? && entity.valid_password?(params[:password])
|
66
|
+
entity
|
65
67
|
end
|
66
68
|
```
|
67
69
|
> Returning no value or false won't create the authentication token.
|
68
70
|
|
69
|
-
#### Keeping track of
|
71
|
+
#### Keeping track of entities? Override: `entity_payload`:
|
70
72
|
|
71
73
|
```ruby
|
72
|
-
#
|
73
|
-
ENTITY_KEY = :
|
74
|
+
# application_controller.rb
|
75
|
+
ENTITY_KEY = :entity_id
|
74
76
|
|
75
|
-
def entity_payload(
|
76
|
-
{ ENTITY_KEY =>
|
77
|
+
def entity_payload(entity)
|
78
|
+
{ ENTITY_KEY => entity.id }
|
77
79
|
end
|
78
80
|
|
79
81
|
def find_authenticable_entity(entity_payload_returned_object)
|
80
|
-
|
82
|
+
Entity.find_by(id: entity_payload_returned_object.fetch(ENTITY_KEY))
|
81
83
|
end
|
82
84
|
```
|
83
85
|
|
84
86
|
#### Validations in every request? Override `entity_custom_validation_value` to get it verified as the following:
|
85
87
|
|
86
88
|
```ruby
|
87
|
-
#
|
88
|
-
def entity_custom_validation_value(
|
89
|
-
|
89
|
+
# application_controller.rb
|
90
|
+
def entity_custom_validation_value(entity)
|
91
|
+
entity.some_value_that_shouldnt_change
|
90
92
|
end
|
91
93
|
```
|
92
94
|
This method will be called before creating the token and in every request to compare if the returned values are the same. If values mismatch, the token won't be valid anymore. If values are the same, expiration validations will be checked.
|
93
95
|
> If it is desired to update this value when renewing the token, override: `entity_custom_validation_renew_value`.
|
94
96
|
|
95
|
-
#### Invalidating all tokens for
|
97
|
+
#### Invalidating all tokens for an entity? Override `entity_custom_validation_invalidate_all_value` as the following:
|
96
98
|
|
97
99
|
```ruby
|
98
|
-
#
|
99
|
-
def entity_custom_validation_invalidate_all_value(
|
100
|
-
|
101
|
-
|
100
|
+
# application_controller.rb
|
101
|
+
def entity_custom_validation_invalidate_all_value(entity)
|
102
|
+
entity.some_value_that_shouldnt_change = 'some-new-value'
|
103
|
+
entity.save
|
102
104
|
end
|
103
105
|
```
|
104
|
-
This method is the one executed when we want to invalidate sessions for the authenticated
|
106
|
+
This method is the one executed when we want to invalidate sessions for the authenticated entity. An option to achieve that can be to override the value that will be then compared in every request with `entity_custom_validation_value` method, so that initial stored value mismatch with the new different value.
|
105
107
|
> This works only if `entity_custom_validation_value` has been overridden.
|
106
108
|
|
107
109
|
|
108
110
|
### Some other useful configurations
|
109
111
|
|
110
|
-
#### Want to modify tokens
|
112
|
+
#### Want to modify tokens TTL or maximum useful days? Set an initializer:
|
111
113
|
|
112
114
|
```ruby
|
113
|
-
|
114
|
-
|
115
|
+
# config/initializers/wor_authentication.rb
|
116
|
+
Wor::Authentication.configure do |config|
|
117
|
+
config.expiration_days = 5
|
118
|
+
config.maximum_useful_days = 20
|
115
119
|
end
|
116
120
|
```
|
117
121
|
|
118
|
-
|
119
|
-
|
120
|
-
```ruby
|
121
|
-
def token_maximum_useful_date
|
122
|
-
(Time.zone.now + 30.days).to_i
|
123
|
-
end
|
124
|
-
```
|
122
|
+
Or, even easier, run `rails generate wor:authentication:install` in your root folder.
|
125
123
|
|
126
124
|
## Contributing
|
127
125
|
|
@@ -142,7 +140,7 @@ This project is maintained by [Alejandro Bezdjian](https://github.com/alebian) a
|
|
142
140
|
|
143
141
|
**wor-authentication** is available under the MIT [license](https://raw.githubusercontent.com/Wolox/wor-authentication/master/LICENSE.md).
|
144
142
|
|
145
|
-
Copyright (c) 2017
|
143
|
+
Copyright (c) 2017 Wolox
|
146
144
|
|
147
145
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
148
146
|
of this software and associated documentation files (the "Software"), to deal
|
data/Rakefile
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Wor
|
2
|
+
module Authentication
|
3
|
+
module Generators
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('../../../templates', __FILE__)
|
6
|
+
desc 'Creates wor_authentication initializer for your application'
|
7
|
+
|
8
|
+
def copy_initializer
|
9
|
+
template 'wor_authentication.rb', 'config/initializers/wor_authentication.rb'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/wor/authentication.rb
CHANGED
@@ -7,6 +7,39 @@ require_relative 'authentication/version'
|
|
7
7
|
|
8
8
|
module Wor
|
9
9
|
module Authentication
|
10
|
-
|
10
|
+
@config = {
|
11
|
+
expiration_days: 2,
|
12
|
+
maximum_useful_days: 30
|
13
|
+
}
|
14
|
+
|
15
|
+
def self.configure
|
16
|
+
yield self
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.expiration_days=(expiration_days)
|
20
|
+
unless expiration_days.is_a? Integer
|
21
|
+
raise Wor::Authentication::Exceptions::InvalidExpirationDaysError
|
22
|
+
end
|
23
|
+
@config[:expiration_days] = expiration_days
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.maximum_useful_days=(maximum_useful_days)
|
27
|
+
unless maximum_useful_days.is_a? Integer
|
28
|
+
raise Wor::Authentication::Exceptions::InvalidMaximumUsefulDaysError
|
29
|
+
end
|
30
|
+
@config[:maximum_useful_days] = maximum_useful_days
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.config
|
34
|
+
@config
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.expiration_days
|
38
|
+
@config[:expiration_days]
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.maximum_useful_days
|
42
|
+
@config[:maximum_useful_days]
|
43
|
+
end
|
11
44
|
end
|
12
45
|
end
|
@@ -3,14 +3,25 @@ require 'devise'
|
|
3
3
|
module Wor
|
4
4
|
module Authentication
|
5
5
|
module Controller
|
6
|
-
|
7
6
|
def authenticate_request
|
8
7
|
entity = find_authenticable_entity(decoded_token)
|
9
8
|
decoded_token.validate!(entity_custom_validation_value(entity))
|
10
9
|
end
|
11
10
|
|
12
11
|
def decoded_token
|
13
|
-
@decoded_token ||= Wor::Authentication::TokenManager.new(
|
12
|
+
@decoded_token ||= Wor::Authentication::TokenManager.new(
|
13
|
+
token_key
|
14
|
+
).decode(authentication_token)
|
15
|
+
end
|
16
|
+
|
17
|
+
def new_token_expiration_date
|
18
|
+
expiration_days = Wor::Authentication.expiration_days
|
19
|
+
(Time.zone.now + expiration_days.days).to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
def token_maximum_useful_date
|
23
|
+
maximum_useful_days = Wor::Authentication.maximum_useful_days
|
24
|
+
(Time.zone.now + maximum_useful_days.days).to_i
|
14
25
|
end
|
15
26
|
|
16
27
|
##
|
@@ -21,19 +32,11 @@ module Wor
|
|
21
32
|
Devise.friendly_token(32)
|
22
33
|
end
|
23
34
|
|
24
|
-
def new_token_expiration_date
|
25
|
-
(Time.zone.now + 2.days).to_i
|
26
|
-
end
|
27
|
-
|
28
|
-
def token_maximum_useful_date
|
29
|
-
(Time.zone.now + 30.days).to_i
|
30
|
-
end
|
31
|
-
|
32
35
|
def authentication_token
|
33
36
|
request.headers['Authorization'].split(' ').last
|
34
37
|
end
|
35
38
|
|
36
|
-
def entity_custom_validation_value(
|
39
|
+
def entity_custom_validation_value(_entity)
|
37
40
|
nil
|
38
41
|
end
|
39
42
|
|
@@ -41,20 +44,29 @@ module Wor
|
|
41
44
|
entity_custom_validation_value(entity)
|
42
45
|
end
|
43
46
|
|
44
|
-
def entity_custom_validation_invalidate_all_value(
|
47
|
+
def entity_custom_validation_invalidate_all_value(_entity)
|
45
48
|
nil
|
46
49
|
end
|
47
50
|
|
48
|
-
# Explain in README
|
49
51
|
def token_key
|
50
52
|
raise Wor::Authentication::Exceptions::SubclassMustImplementError unless defined?(Rails)
|
51
|
-
|
53
|
+
if Rails.application.secrets.secret_key_base.blank?
|
54
|
+
raise Wor::Authentication::Exceptions::NoKeyProvidedError
|
55
|
+
end
|
52
56
|
Rails.application.secrets.secret_key_base
|
53
57
|
end
|
54
58
|
|
55
|
-
def authenticate_entity(
|
56
|
-
|
57
|
-
|
59
|
+
def authenticate_entity(_params)
|
60
|
+
{}
|
61
|
+
end
|
62
|
+
|
63
|
+
def find_authenticable_entity(_decoded_token)
|
64
|
+
{}
|
65
|
+
end
|
66
|
+
|
67
|
+
def entity_payload(_entity)
|
68
|
+
{}
|
69
|
+
end
|
58
70
|
end
|
59
71
|
end
|
60
72
|
end
|
@@ -8,7 +8,9 @@ module Wor
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def validate!(entity_custom_validation = nil)
|
11
|
-
|
11
|
+
unless valid_entity_custom_validation?(entity_custom_validation)
|
12
|
+
raise Wor::Authentication::Exceptions::EntityCustomValidationError
|
13
|
+
end
|
12
14
|
raise Wor::Authentication::Exceptions::NotRenewableTokenError unless able_to_renew?
|
13
15
|
raise Wor::Authentication::Exceptions::ExpiredTokenError if expired?
|
14
16
|
end
|
@@ -20,13 +22,13 @@ module Wor
|
|
20
22
|
end
|
21
23
|
|
22
24
|
def expired?
|
23
|
-
return false
|
25
|
+
return false if fetch(:expiration_date).blank?
|
24
26
|
# TODO: Use a ruby standard library for time
|
25
27
|
Time.zone.now.to_i > fetch(:expiration_date)
|
26
28
|
end
|
27
29
|
|
28
30
|
def able_to_renew?
|
29
|
-
return false
|
31
|
+
return false if fetch(:maximum_useful_date).blank?
|
30
32
|
# TODO: Use a ruby standard library for time
|
31
33
|
Time.zone.now.to_i < fetch(:maximum_useful_date)
|
32
34
|
end
|
@@ -39,7 +41,7 @@ module Wor
|
|
39
41
|
private
|
40
42
|
|
41
43
|
def valid_entity_custom_validation?(entity_custom_validation)
|
42
|
-
return true
|
44
|
+
return true if fetch(:entity_custom_validation).blank?
|
43
45
|
entity_custom_validation == fetch(:entity_custom_validation)
|
44
46
|
end
|
45
47
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
module Wor
|
2
2
|
module Authentication
|
3
3
|
module Exceptions
|
4
|
-
class
|
5
|
-
class
|
6
|
-
class
|
7
|
-
class
|
8
|
-
class
|
4
|
+
class InvalidExpirationDaysError < StandardError; end
|
5
|
+
class InvalidMaximumUsefulDaysError < StandardError; end
|
6
|
+
class SubclassMustImplementError < StandardError; end
|
7
|
+
class NoKeyProvidedError < StandardError; end
|
8
|
+
class ExpiredTokenError < StandardError; end
|
9
|
+
class NotRenewableTokenError < StandardError; end
|
10
|
+
class EntityCustomValidationError < StandardError; end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Wor
|
2
2
|
module Authentication
|
3
3
|
module SessionsController
|
4
|
-
|
5
4
|
def create
|
6
5
|
entity = authenticate_entity(authenticate_params)
|
7
6
|
if entity
|
@@ -37,7 +36,7 @@ module Wor
|
|
37
36
|
maximum_useful_date: token_maximum_useful_date,
|
38
37
|
renew_id: renew_id
|
39
38
|
)
|
40
|
-
|
39
|
+
access_token_object(token_key, payload, renew_id)
|
41
40
|
end
|
42
41
|
|
43
42
|
def renew_access_token(entity)
|
@@ -49,19 +48,25 @@ module Wor
|
|
49
48
|
|
50
49
|
private
|
51
50
|
|
51
|
+
def access_token_object(token_key, payload, renew_id)
|
52
|
+
{
|
53
|
+
token: Wor::Authentication::TokenManager.new(token_key).encode(payload),
|
54
|
+
renew_id: renew_id
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
52
58
|
def current_entity
|
53
|
-
current_entity ||= find_authenticable_entity(decoded_token)
|
59
|
+
@current_entity ||= find_authenticable_entity(decoded_token)
|
54
60
|
end
|
55
61
|
|
56
62
|
def render_error(error_message, status)
|
57
63
|
render json: { error: error_message }, status: status
|
58
64
|
end
|
59
65
|
|
60
|
-
# I'm pretty sure this should be set by gems users and not us
|
61
66
|
def authenticate_params
|
62
|
-
params.require(:session)
|
67
|
+
params.require(:session)
|
63
68
|
end
|
64
|
-
|
69
|
+
|
65
70
|
def renew_token_params
|
66
71
|
params.require(:session).permit(:renew_id)
|
67
72
|
end
|
data/wor-authentication.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.authors = ['alebian', 'mishuagopian']
|
13
13
|
spec.email = ['alejandro.bezdjian@wolox.com.ar', 'michel.agopian@wolox.com.ar']
|
14
14
|
|
15
|
-
spec.summary = '
|
15
|
+
spec.summary = 'Easily add authentication to your application!.'
|
16
16
|
spec.description = 'Gem to add authentication to your application using JWT, with expirable, renewable and customizable tokens.'
|
17
17
|
spec.homepage = 'https://github.com/Wolox/wor-authentication'
|
18
18
|
spec.license = 'MIT'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wor-authentication
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- alebian
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-05-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: railties
|
@@ -239,10 +239,13 @@ files:
|
|
239
239
|
- ".gitignore"
|
240
240
|
- ".rubocop.yml"
|
241
241
|
- ".travis.yml"
|
242
|
+
- CHANGELOG.md
|
242
243
|
- Gemfile
|
243
244
|
- LICENSE.md
|
244
245
|
- README.md
|
245
246
|
- Rakefile
|
247
|
+
- lib/generators/templates/wor_authentication.rb
|
248
|
+
- lib/generators/wor/authentication/install_generator.rb
|
246
249
|
- lib/wor/authentication.rb
|
247
250
|
- lib/wor/authentication/controller.rb
|
248
251
|
- lib/wor/authentication/decoded_token.rb
|
@@ -271,8 +274,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
271
274
|
version: '0'
|
272
275
|
requirements: []
|
273
276
|
rubyforge_project:
|
274
|
-
rubygems_version: 2.
|
277
|
+
rubygems_version: 2.4.5
|
275
278
|
signing_key:
|
276
279
|
specification_version: 4
|
277
|
-
summary:
|
280
|
+
summary: Easily add authentication to your application!.
|
278
281
|
test_files: []
|