touth 1.0.1 → 1.1.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 -24
- data/lib/touth.rb +4 -18
- data/lib/touth/action_controller_support.rb +22 -38
- data/lib/touth/active_record_support.rb +16 -2
- data/lib/touth/authenticator.rb +57 -0
- data/lib/touth/version.rb +1 -1
- metadata +3 -3
- data/lib/touth/acts_as_token_authenticatable.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb6f3f37d102cc22a9be19c43f1d56a174b32ed1
|
4
|
+
data.tar.gz: f691dac5c428d62b7077ffdaa09eaa0df4ba29a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d166f9d6c80bf09865253d54c67e9338eb7888566df916203e798a2ed1823c0143c4200dedfa0de9788e125e4537920591593bfacf430ba030388008668bd18
|
7
|
+
data.tar.gz: 4ac78b3026d68cc44331b71392e029e5bf54ca7d5241a72353cf045a8421e80bbed61a637b1aa294d05f79f159059ab7f3c349346c67174f9c6887cbaa274e67
|
data/README.md
CHANGED
@@ -47,11 +47,7 @@ Checking if a user is signed in, and getting the current signed-in user, the fol
|
|
47
47
|
|
48
48
|
### Hooks
|
49
49
|
|
50
|
-
- `
|
51
|
-
|
52
|
-
### Fallbacks
|
53
|
-
|
54
|
-
- `token_authentication_error!(type)`
|
50
|
+
- `authenticate_token!`
|
55
51
|
|
56
52
|
|
57
53
|
Usage
|
@@ -63,12 +59,14 @@ Usage
|
|
63
59
|
user_account = UserAccount.first
|
64
60
|
|
65
61
|
|
66
|
-
# create access token
|
67
|
-
t1 = user_account.access_token
|
62
|
+
# create access token
|
63
|
+
t1 = user_account.access_token
|
64
|
+
#=> "0c63df99a514563a274377bb5f382c3be3bc0ff75b3758be5cd145984134d73608fe77339f7f38abf71eec38ba6800c0e2e4af08227f251b0f81163878aa25ab04085b086310557365724163636f756e7469066c2b07cc536b54"
|
68
65
|
|
69
66
|
|
70
67
|
# create token expires in 20 secounds
|
71
|
-
t2 = user_account.access_token 20
|
68
|
+
t2 = user_account.access_token 20
|
69
|
+
#=> "622bf3498d0c6d846f31f8bd486cbedf3dce0076661d98111231726b35709d3f6a46a419b4799fb84b94258025eafa304baf8196877c281145a434e6b859b90504085b086310557365724163636f756e7469066c2b07e1536b54"
|
72
70
|
|
73
71
|
user_account.valid_access_token? t2 #=> true
|
74
72
|
sleep 20
|
@@ -78,8 +76,7 @@ user_account.valid_access_token? t2 #=> false
|
|
78
76
|
### Authentication by request headers
|
79
77
|
|
80
78
|
```
|
81
|
-
X-
|
82
|
-
X-Auth-Token: 9619feb4b8d54352ae07588d011da48385c8c4f072ab889d3996d127ad2142fc6213d553
|
79
|
+
X-Access-Token: 2a20d42585159a9f1c9564afd051d48e2209af5e18d83c9685de1ae0df66c2b76c2bc7633e4b14748f1cf94b09e94d1a33804b1e74dad9d02d231b12e6c840b504085b086310557365724163636f756e7469066c2b0737546b54
|
83
80
|
```
|
84
81
|
|
85
82
|
### Invalidation
|
@@ -114,6 +111,9 @@ Touth.setup do |config|
|
|
114
111
|
# :encrypted_password will work nice with devise model.
|
115
112
|
config.password_field = :encrypted_password
|
116
113
|
|
114
|
+
# Header name
|
115
|
+
config.header_name = 'X-Access-Token'
|
116
|
+
|
117
117
|
end
|
118
118
|
```
|
119
119
|
|
@@ -123,23 +123,9 @@ Contributing
|
|
123
123
|
|
124
124
|
Contributions are always welcome!
|
125
125
|
|
126
|
-
### Bug reports
|
127
|
-
|
128
|
-
1. Ensure the bug can be reproduced on the latest master.
|
129
|
-
1. Check it's not a duplicate.
|
130
|
-
1. Raise an issue.
|
131
|
-
|
132
|
-
|
133
|
-
### Pull requests
|
134
|
-
|
135
|
-
1. Fork the repository.
|
136
|
-
1. Create a branch.
|
137
|
-
1. Create a new pull request.
|
138
|
-
|
139
126
|
|
140
127
|
License
|
141
128
|
-------
|
142
129
|
|
143
130
|
This project is copyright by [Creasty](http://www.creasty.com), released under the MIT lisence.
|
144
131
|
See `LICENSE` file for details.
|
145
|
-
|
data/lib/touth.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
3
|
|
4
|
-
# Touth
|
5
|
-
#-----------------------------------------------
|
6
4
|
module Touth
|
7
5
|
|
8
6
|
extend ActiveSupport::Autoload
|
9
7
|
|
10
|
-
autoload :
|
8
|
+
autoload :Authenticator
|
11
9
|
autoload :ActiveRecordSupport
|
12
10
|
autoload :ActionControllerSupport
|
13
11
|
autoload :VERSION
|
@@ -16,12 +14,14 @@ module Touth
|
|
16
14
|
|
17
15
|
attr_accessor :access_token_lifetime,
|
18
16
|
:client_secret_key,
|
19
|
-
:password_field
|
17
|
+
:password_field,
|
18
|
+
:header_name
|
20
19
|
|
21
20
|
def initialize
|
22
21
|
@access_token_lifetime = 60 * (24 * 60 * 60) # 60 days
|
23
22
|
@client_secret_key = '' # use SecureRandom.hex(64) to generate one
|
24
23
|
@password_field = :encrypted_password
|
24
|
+
@header_name = 'X-Access-Token'
|
25
25
|
end
|
26
26
|
|
27
27
|
end
|
@@ -54,18 +54,4 @@ module Touth
|
|
54
54
|
|
55
55
|
end
|
56
56
|
|
57
|
-
|
58
|
-
# Setup
|
59
|
-
#-----------------------------------------------
|
60
57
|
Touth.setup
|
61
|
-
|
62
|
-
|
63
|
-
# Include
|
64
|
-
#-----------------------------------------------
|
65
|
-
ActiveSupport.on_load(:active_record) do
|
66
|
-
extend Touth::ActiveRecordSupport::ClassMethods
|
67
|
-
end
|
68
|
-
ActiveSupport.on_load(:action_controller) do
|
69
|
-
extend Touth::ActionControllerSupport::ClassMethods
|
70
|
-
include Touth::ActionControllerSupport::InstanceMethods
|
71
|
-
end
|
@@ -1,27 +1,24 @@
|
|
1
1
|
module Touth
|
2
2
|
module ActionControllerSupport
|
3
|
-
|
4
3
|
module ClassMethods
|
5
4
|
|
6
|
-
mattr_accessor :
|
7
|
-
|
8
|
-
def token_authentication_for(scope)
|
9
|
-
scope = scope.to_s
|
10
|
-
name = scope.gsub('::', '_').underscore
|
5
|
+
mattr_accessor :access_token_resources
|
11
6
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
}
|
7
|
+
def token_authentication_for(resource_name)
|
8
|
+
resource_name = resource_name.to_s
|
9
|
+
name = resource_name.gsub('::', '_').underscore
|
16
10
|
|
17
|
-
|
11
|
+
unless self.access_token_resources
|
12
|
+
self.access_token_resources = {}
|
13
|
+
before_action :authenticate_token!
|
14
|
+
end
|
18
15
|
|
19
16
|
define_method "#{name}_signed_in?" do
|
20
|
-
!!self.class.
|
17
|
+
!!self.class.access_token_resources[resource_name]
|
21
18
|
end
|
22
19
|
|
23
20
|
define_method "current_#{name}" do
|
24
|
-
self.class.
|
21
|
+
self.class.access_token_resources[resource_name]
|
25
22
|
end
|
26
23
|
end
|
27
24
|
|
@@ -31,36 +28,23 @@ module Touth
|
|
31
28
|
|
32
29
|
protected
|
33
30
|
|
34
|
-
def
|
35
|
-
|
36
|
-
id: request.headers['X-Auth-ID'],
|
37
|
-
token: request.headers['X-Auth-Token'],
|
38
|
-
}
|
39
|
-
end
|
31
|
+
def authenticate_token!
|
32
|
+
token = request.headers[Touth.header_name]
|
40
33
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
model = id.present? \
|
45
|
-
&& self.class.token_authentication_on[:class].find(id)
|
46
|
-
|
47
|
-
unless model
|
48
|
-
return token_authentication_error! :no_entity
|
34
|
+
if Authenticator.valid_access_token? token
|
35
|
+
render nothing: true, status: :unauthorized
|
36
|
+
return false
|
49
37
|
end
|
50
38
|
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
self.class.token_authentication_on[:current] = model
|
56
|
-
end
|
57
|
-
|
58
|
-
def token_authentication_error!(type)
|
59
|
-
render nothing: true, status: :unauthorized
|
60
|
-
false
|
39
|
+
model = Authenticator.get_model token
|
40
|
+
self.class.access_token_resources[model.name] = model
|
61
41
|
end
|
62
42
|
|
63
43
|
end
|
64
|
-
|
65
44
|
end
|
66
45
|
end
|
46
|
+
|
47
|
+
ActiveSupport.on_load(:action_controller) do
|
48
|
+
extend Touth::ActionControllerSupport::ClassMethods
|
49
|
+
include Touth::ActionControllerSupport::InstanceMethods
|
50
|
+
end
|
@@ -1,13 +1,27 @@
|
|
1
1
|
module Touth
|
2
2
|
module ActiveRecordSupport
|
3
|
-
|
4
3
|
module ClassMethods
|
5
4
|
|
6
5
|
def acts_as_token_authenticatable
|
7
|
-
include Touth::
|
6
|
+
include Touth::ActiveRecordSupport::InstanceMethods
|
8
7
|
end
|
9
8
|
|
10
9
|
end
|
11
10
|
|
11
|
+
module InstanceMethods
|
12
|
+
|
13
|
+
def access_token(*args)
|
14
|
+
Authenticator.issue_access_token self, *args
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid_access_token?(token)
|
18
|
+
Authenticator.get_model(token) == self
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
12
22
|
end
|
13
23
|
end
|
24
|
+
|
25
|
+
ActiveSupport.on_load(:active_record) do
|
26
|
+
extend Touth::ActiveRecordSupport::ClassMethods
|
27
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Touth
|
2
|
+
module Authenticator
|
3
|
+
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def issue_access_token(model, lifetime = Touth.access_token_lifetime)
|
7
|
+
expires_at = Time.now.to_i + lifetime
|
8
|
+
|
9
|
+
data = Marshal.dump([
|
10
|
+
model.class,
|
11
|
+
model.id,
|
12
|
+
expires_at,
|
13
|
+
])
|
14
|
+
|
15
|
+
data_sign = Touth.digest data
|
16
|
+
data_key = gen_data_key model, data_sign
|
17
|
+
|
18
|
+
[
|
19
|
+
data_sign,
|
20
|
+
data_key,
|
21
|
+
data,
|
22
|
+
].join.unpack('H*')[0]
|
23
|
+
end
|
24
|
+
|
25
|
+
def valid_access_token?(token)
|
26
|
+
!!get_model(token)
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_model(token)
|
30
|
+
@access_token_data_cache ||= {}
|
31
|
+
model = @access_token_data_cache[token]
|
32
|
+
|
33
|
+
return model if model
|
34
|
+
|
35
|
+
begin
|
36
|
+
data_sign, data_key, data = [token].pack('H*').unpack 'A32A32A*'
|
37
|
+
|
38
|
+
if data_sign == Touth.digest(data)
|
39
|
+
model_class, id, expires_at = Marshal.load data
|
40
|
+
|
41
|
+
model = model_class.find id
|
42
|
+
|
43
|
+
if gen_data_key(model, data_sign) == data_key && Time.now.to_i < expires_at
|
44
|
+
@access_token_data_cache[token] = model
|
45
|
+
end
|
46
|
+
end
|
47
|
+
rescue
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def gen_data_key(model, data_sign)
|
53
|
+
Touth.digest [data_sign, model.send(Touth.password_field)].join
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/touth/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: touth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuki Iwanaga
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -73,7 +73,7 @@ files:
|
|
73
73
|
- lib/touth.rb
|
74
74
|
- lib/touth/action_controller_support.rb
|
75
75
|
- lib/touth/active_record_support.rb
|
76
|
-
- lib/touth/
|
76
|
+
- lib/touth/authenticator.rb
|
77
77
|
- lib/touth/version.rb
|
78
78
|
- touth.gemspec
|
79
79
|
homepage: https://github.com/creasty/touth
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module Touth
|
2
|
-
module ActsAsTokenAuthenticatable
|
3
|
-
|
4
|
-
def access_token(lifetime = Touth.access_token_lifetime)
|
5
|
-
expires_at = Time.now.to_i + lifetime
|
6
|
-
|
7
|
-
[access_token_id(expires_at), [expires_at].pack('V')].join.unpack('H*')[0]
|
8
|
-
end
|
9
|
-
|
10
|
-
def valid_access_token?(token)
|
11
|
-
begin
|
12
|
-
data = [token].pack 'H*'
|
13
|
-
token_id, timestamp = data.unpack 'A32A*'
|
14
|
-
expires_at = timestamp.unpack('V')[0]
|
15
|
-
|
16
|
-
access_token_id(expires_at) == token_id && Time.now.to_i < expires_at
|
17
|
-
rescue
|
18
|
-
false
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def access_token_id(expires_at)
|
25
|
-
raw = [
|
26
|
-
expires_at,
|
27
|
-
self.class.name,
|
28
|
-
self.id,
|
29
|
-
self.send(Touth.password_field),
|
30
|
-
].join ':'
|
31
|
-
|
32
|
-
Touth.digest raw
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|