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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f6424a7f72477d07f75e3d86466f63b7309767e3
4
- data.tar.gz: ba296cbb722b4d902d5727dcd954987fc50b1c70
3
+ metadata.gz: fb6f3f37d102cc22a9be19c43f1d56a174b32ed1
4
+ data.tar.gz: f691dac5c428d62b7077ffdaa09eaa0df4ba29a1
5
5
  SHA512:
6
- metadata.gz: 8fd354d81d7ac6b1c873d31241bc6043cfca190febe0d2d3acca887371463e6cec7ad74e8d3dbbaba1fff7097dd5296ee88288a9a14ca60f499004ea334fc773
7
- data.tar.gz: 8eadb69151befd9645955bfad92273eb2c1178afdd1f491e5f1b4cb8bd97924b0ef6c0a3b67cc8564b878057aa7a1b8e369311cdce3c32ff27dbdfef0d81f25a
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
- - `authenticate_entity_from_token!`
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 for default lifetime
67
- t1 = user_account.access_token #=> "9619feb4b8d54352ae07588d011da48385c8c4f072ab889d3996d127ad2142fc6213d553"
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 #=> "ad60fa5bb2d05e72ac943c6d409e18e6cc24c15eae9833f66c8aab391241475fe2bd0954"
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-Auth-ID: 1
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
-
@@ -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 :ActsAsTokenAuthenticatable
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 :token_authentication_on
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
- self.token_authentication_on = {
13
- class: scope.camelize.constantize,
14
- current: nil,
15
- }
7
+ def token_authentication_for(resource_name)
8
+ resource_name = resource_name.to_s
9
+ name = resource_name.gsub('::', '_').underscore
16
10
 
17
- before_action :authenticate_entity_from_token!
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.token_authentication_on[:current]
17
+ !!self.class.access_token_resources[resource_name]
21
18
  end
22
19
 
23
20
  define_method "current_#{name}" do
24
- self.class.token_authentication_on[:current]
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 token_authentication_header
35
- @token_authentication_header ||= {
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
- def authenticate_entity_from_token!
42
- id = token_authentication_header[:id]
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
- unless model.valid_access_token? token_authentication_header[:token]
52
- return token_authentication_error! :invalid_token
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::ActsAsTokenAuthenticatable
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
@@ -1,3 +1,3 @@
1
1
  module Touth
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
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.1
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-18 00:00:00.000000000 Z
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/acts_as_token_authenticatable.rb
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