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