grape_token_auth 0.1.0.rc2 → 0.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 +9 -4
- data/grape_token_auth.gemspec +1 -1
- data/lib/grape_token_auth.rb +39 -15
- data/lib/grape_token_auth/api_helpers.rb +1 -1
- data/lib/grape_token_auth/apis/omniauth_api.rb +2 -5
- data/lib/grape_token_auth/apis/password_api.rb +0 -4
- data/lib/grape_token_auth/apis/session_api.rb +6 -4
- data/lib/grape_token_auth/authentication_header.rb +21 -4
- data/lib/grape_token_auth/authorizer_data.rb +19 -6
- data/lib/grape_token_auth/mail/mail.rb +0 -12
- data/lib/grape_token_auth/mail/smtp_mailer.rb +7 -0
- data/lib/grape_token_auth/middleware.rb +2 -2
- data/lib/grape_token_auth/mount_helpers.rb +22 -17
- data/lib/grape_token_auth/omniauth/omniauth_failure_html.rb +0 -2
- data/lib/grape_token_auth/omniauth/omniauth_resource.rb +1 -10
- data/lib/grape_token_auth/omniauth/omniauth_success_html.rb +0 -2
- data/lib/grape_token_auth/orm_integrations/active_record_token_auth.rb +4 -23
- data/lib/grape_token_auth/resource/resource_creator.rb +1 -3
- data/lib/grape_token_auth/resource/resource_crud_base.rb +1 -10
- data/lib/grape_token_auth/token_authorizer.rb +3 -3
- data/lib/grape_token_auth/utility.rb +16 -0
- data/lib/grape_token_auth/version.rb +1 -1
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6211636ade2d82f854a1581aa553db28d969bae2
|
4
|
+
data.tar.gz: 67430fb3d2e77ab25f6adcf881e81549dd66de4f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48cb9baa1072a05831fc280bc671cd81ba65e056439d499abcdb1ba6617132768fe14e37682d1e3debd2b8792026662b45baf165ccc07ca2ba1ecbf44d2653c0
|
7
|
+
data.tar.gz: 9b7f0fbd5cc1c06c7a323583130ea4ee580775f49bb0450e7dff27920c7a9fe2569ff21c2c4c50c24d4dfd2dab3a2c6878a22ca0105f16172922c06b6d820125
|
data/README.md
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
# GrapeTokenAuth
|
2
2
|
[![Code Climate GPA][11]][12] [![Test Coverage][13]][14] [![Circle CI][15]][16]
|
3
3
|
|
4
|
-
> __This gem is in active development__ but approaching a 0.1.0 release. If you
|
5
|
-
are interested in helping out, please clone the release candidate and submit issues
|
6
|
-
and PRs to help get it into a production-ready state!
|
7
|
-
|
8
4
|
GrapeTokenAuth is a token authentication solution for grape. It is compatible
|
9
5
|
with [ng-token-auth][1] (for _angular_) and [j-toker][2] (for _jQuery_), and is
|
10
6
|
meant as a [grape][4] (rather than _rails_) version of [devise_token_auth][3]. As
|
@@ -35,11 +31,15 @@ gem 'grape_token_auth'
|
|
35
31
|
|
36
32
|
And then execute:
|
37
33
|
|
34
|
+
```
|
38
35
|
$ bundle
|
36
|
+
```
|
39
37
|
|
40
38
|
Or install it yourself as:
|
41
39
|
|
40
|
+
```
|
42
41
|
$ gem install grape_token_auth
|
42
|
+
```
|
43
43
|
|
44
44
|
## Quick-Start Setup
|
45
45
|
|
@@ -116,6 +116,10 @@ end
|
|
116
116
|
**Note on Secret**: generate a unique secret using `rake secret` in a rails app
|
117
117
|
or via [these directions][secret].
|
118
118
|
|
119
|
+
In addition, if you are using the mail features in grape_token_auth you will
|
120
|
+
want to set the appropriate configuration options. See the [mail wiki page][mail] for
|
121
|
+
more information.
|
122
|
+
|
119
123
|
|
120
124
|
### Mounting authentication APIs
|
121
125
|
|
@@ -247,3 +251,4 @@ To run tests, you will need postgres to be setup and configured correctly. Run
|
|
247
251
|
[secret]: http://www.jamesbadger.ca/2012/12/18/generate-new-secret-token/
|
248
252
|
[dta-contributors]: https://github.com/lynndylanhurley/devise_token_auth#callouts
|
249
253
|
[devise]: https://github.com/plataformatec/devise
|
254
|
+
[mail]: https://github.com/mcordell/grape_token_auth/wiki/Email
|
data/grape_token_auth.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_dependency 'grape', '
|
21
|
+
spec.add_dependency 'grape', '>= 0.12.0'
|
22
22
|
spec.add_dependency 'warden', '~> 1.2.3'
|
23
23
|
spec.add_dependency 'bcrypt', '~> 3.0'
|
24
24
|
spec.add_dependency 'mail', '~> 2.0'
|
data/lib/grape_token_auth.rb
CHANGED
@@ -1,7 +1,44 @@
|
|
1
|
-
require '
|
1
|
+
require 'bcrypt'
|
2
2
|
require 'forwardable'
|
3
3
|
require 'grape'
|
4
|
-
|
4
|
+
|
5
|
+
# Load base classes first
|
6
|
+
require 'grape_token_auth/mail/message_base'
|
7
|
+
require 'grape_token_auth/omniauth/omniauth_html_base'
|
8
|
+
require 'grape_token_auth/resource/resource_crud_base'
|
9
|
+
|
10
|
+
require 'grape_token_auth/api_helpers'
|
11
|
+
require 'grape_token_auth/apis/confirmation_api'
|
12
|
+
require 'grape_token_auth/apis/omniauth_api'
|
13
|
+
require 'grape_token_auth/apis/password_api'
|
14
|
+
require 'grape_token_auth/apis/registration_api'
|
15
|
+
require 'grape_token_auth/apis/session_api'
|
16
|
+
require 'grape_token_auth/apis/token_validation_api'
|
17
|
+
require 'grape_token_auth/authentication_header'
|
18
|
+
require 'grape_token_auth/authorizer_data'
|
19
|
+
require 'grape_token_auth/configuration'
|
20
|
+
require 'grape_token_auth/exceptions'
|
21
|
+
require 'grape_token_auth/key_generator'
|
22
|
+
require 'grape_token_auth/lookup_token'
|
23
|
+
require 'grape_token_auth/mail/messages/confirmation/confirmation_email'
|
24
|
+
require 'grape_token_auth/mail/messages/password_reset/password_reset_email'
|
25
|
+
require 'grape_token_auth/mail/mail'
|
26
|
+
require 'grape_token_auth/mail/smtp_mailer'
|
27
|
+
require 'grape_token_auth/middleware'
|
28
|
+
require 'grape_token_auth/mount_helpers'
|
29
|
+
require 'grape_token_auth/omniauth/omniauth_failure_html'
|
30
|
+
require 'grape_token_auth/omniauth/omniauth_resource'
|
31
|
+
require 'grape_token_auth/omniauth/omniauth_success_html'
|
32
|
+
require 'grape_token_auth/orm_integrations/active_record_token_auth'
|
33
|
+
require 'grape_token_auth/resource/resource_creator'
|
34
|
+
require 'grape_token_auth/resource/resource_finder'
|
35
|
+
require 'grape_token_auth/resource/resource_updater'
|
36
|
+
require 'grape_token_auth/token'
|
37
|
+
require 'grape_token_auth/token_authentication'
|
38
|
+
require 'grape_token_auth/token_authorizer'
|
39
|
+
require 'grape_token_auth/unauthorized_middleware'
|
40
|
+
require 'grape_token_auth/utility'
|
41
|
+
require 'grape_token_auth/version'
|
5
42
|
|
6
43
|
module GrapeTokenAuth
|
7
44
|
class << self
|
@@ -26,23 +63,10 @@ module GrapeTokenAuth
|
|
26
63
|
configure(&block) if block_given?
|
27
64
|
end
|
28
65
|
|
29
|
-
def configure_warden(warden_manager)
|
30
|
-
configuration.mappings.each do |scope, klass|
|
31
|
-
warden_manager.serialize_into_session(scope) do |record|
|
32
|
-
klass.serialize_into_session(record)
|
33
|
-
end
|
34
|
-
|
35
|
-
warden_manager.serialize_from_session(scope) do |key|
|
36
|
-
klass.serialize_from_session(*key)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
66
|
def setup_warden!(builder)
|
42
67
|
builder.use Warden::Manager do |manager|
|
43
68
|
manager.failure_app = GrapeTokenAuth::UnauthorizedMiddleware
|
44
69
|
manager.default_scope = :user
|
45
|
-
GrapeTokenAuth.configure_warden(manager)
|
46
70
|
end
|
47
71
|
end
|
48
72
|
|
@@ -20,10 +20,6 @@ module GrapeTokenAuth
|
|
20
20
|
html
|
21
21
|
end
|
22
22
|
|
23
|
-
def sign_in_resource(resource, scope)
|
24
|
-
request.env['warden'].session_serializer.store(resource, scope)
|
25
|
-
end
|
26
|
-
|
27
23
|
def redirect_or_render(success_html)
|
28
24
|
if %w(inAppBrowser newWindow).include?(success_html.window_type)
|
29
25
|
render_html(success_html.render_html)
|
@@ -80,7 +76,8 @@ module GrapeTokenAuth
|
|
80
76
|
auth_hash,
|
81
77
|
omniauth_params)
|
82
78
|
if success_html.persist_oauth_attributes!
|
83
|
-
|
79
|
+
data = AuthorizerData.load_from_env_or_create(env)
|
80
|
+
data.store_resource(success_html.resource, base.resource_scope)
|
84
81
|
redirect_or_render(success_html)
|
85
82
|
else
|
86
83
|
status 500
|
@@ -10,10 +10,6 @@ module GrapeTokenAuth
|
|
10
10
|
throw(:warden, errors: message)
|
11
11
|
end
|
12
12
|
|
13
|
-
def resource_class
|
14
|
-
@rescource_class ||= scope_to_class(resource_scope)
|
15
|
-
end
|
16
|
-
|
17
13
|
def bad_request(messages, code = 422)
|
18
14
|
status(code)
|
19
15
|
{ 'status' => 'error', 'error' => messages.join(',') }
|
@@ -2,8 +2,8 @@ module GrapeTokenAuth
|
|
2
2
|
module SessionsAPICore
|
3
3
|
def self.included(base)
|
4
4
|
base.helpers do
|
5
|
-
def find_resource(
|
6
|
-
token_authorizer = TokenAuthorizer.new(
|
5
|
+
def find_resource(data, mapping)
|
6
|
+
token_authorizer = TokenAuthorizer.new(data)
|
7
7
|
token_authorizer.find_resource(mapping)
|
8
8
|
end
|
9
9
|
end
|
@@ -23,7 +23,7 @@ module GrapeTokenAuth
|
|
23
23
|
throw(:warden, errors: { errors: [error_message], status: 'error' })
|
24
24
|
end
|
25
25
|
|
26
|
-
data = AuthorizerData.
|
26
|
+
data = AuthorizerData.load_from_env_or_create(env)
|
27
27
|
env['rack.session'] ||= {}
|
28
28
|
data.store_resource(resource, base.resource_scope)
|
29
29
|
auth_header = AuthenticationHeader.new(data, start_time)
|
@@ -35,10 +35,12 @@ module GrapeTokenAuth
|
|
35
35
|
end
|
36
36
|
|
37
37
|
base.delete '/sign_out' do
|
38
|
-
|
38
|
+
data = AuthorizerData.load_from_env_or_create(env)
|
39
|
+
resource = find_resource(data, base.resource_scope)
|
39
40
|
|
40
41
|
if resource
|
41
42
|
resource.tokens.delete(env[Configuration::CLIENT_KEY])
|
43
|
+
data.skip_auth_headers = true
|
42
44
|
resource.save
|
43
45
|
status 200
|
44
46
|
else
|
@@ -9,19 +9,32 @@ module GrapeTokenAuth
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def headers
|
12
|
-
return {} unless resource && resource.valid? && client_id
|
12
|
+
return {} unless resource && resource.valid? && client_id && !skip_auth_headers
|
13
13
|
auth_headers_from_resource
|
14
14
|
end
|
15
15
|
|
16
|
+
def self.build_auth_headers(token, uid)
|
17
|
+
{
|
18
|
+
'access-token' => token.to_s,
|
19
|
+
'expiry' => token.expiry.to_s,
|
20
|
+
'client' => token.client_id.to_s,
|
21
|
+
'token-type' => 'Bearer',
|
22
|
+
'uid' => uid.to_s
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
16
26
|
private
|
17
27
|
|
18
|
-
|
19
|
-
|
28
|
+
attr_reader :request_start, :resource, :data
|
29
|
+
|
30
|
+
def_delegators :data, :token, :client_id, :skip_auth_headers
|
20
31
|
|
21
32
|
def auth_headers_from_resource
|
22
33
|
auth_headers = {}
|
23
34
|
resource.while_record_locked do
|
24
|
-
if
|
35
|
+
if was_not_authenticated_with_token
|
36
|
+
auth_headers = resource.create_new_auth_token
|
37
|
+
elsif !GrapeTokenAuth.change_headers_on_each_request
|
25
38
|
auth_headers = resource.extend_batch_buffer(token, client_id)
|
26
39
|
elsif batch_request?
|
27
40
|
resource.extend_batch_buffer(token, client_id)
|
@@ -32,6 +45,10 @@ module GrapeTokenAuth
|
|
32
45
|
coerce_headers_to_strings(auth_headers)
|
33
46
|
end
|
34
47
|
|
48
|
+
def was_not_authenticated_with_token
|
49
|
+
!data.authed_with_token
|
50
|
+
end
|
51
|
+
|
35
52
|
def coerce_headers_to_strings(auth_headers)
|
36
53
|
auth_headers.each { |k, v| auth_headers[k] = v.to_s }
|
37
54
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module GrapeTokenAuth
|
2
2
|
class AuthorizerData
|
3
|
+
RACK_ENV_KEY = 'gta.auth_data'
|
4
|
+
attr_accessor :authed_with_token, :skip_auth_headers
|
3
5
|
attr_reader :uid, :client_id, :token, :expiry, :warden
|
4
6
|
|
5
7
|
def initialize(uid = nil, client_id = nil, token = nil,
|
@@ -9,24 +11,35 @@ module GrapeTokenAuth
|
|
9
11
|
@token = token
|
10
12
|
@expiry = expiry
|
11
13
|
@warden = warden
|
14
|
+
@authed_with_token = false
|
15
|
+
@skip_auth_headers = false
|
12
16
|
end
|
13
17
|
|
14
18
|
def self.from_env(env)
|
15
|
-
new(
|
19
|
+
data = new(
|
16
20
|
*data_from_env(env),
|
17
21
|
env['warden']
|
18
22
|
)
|
23
|
+
inject_into_env(data, env)
|
19
24
|
end
|
20
25
|
|
21
26
|
def self.data_from_env(env)
|
22
27
|
[Configuration::UID_KEY,
|
23
|
-
|
24
|
-
|
25
|
-
|
28
|
+
Configuration::CLIENT_KEY,
|
29
|
+
Configuration::ACCESS_TOKEN_KEY,
|
30
|
+
Configuration::EXPIRY_KEY].map do |key|
|
26
31
|
env[key] || env['HTTP_' + key.gsub('-', '_').upcase]
|
27
32
|
end
|
28
33
|
end
|
29
34
|
|
35
|
+
def self.inject_into_env(data, env)
|
36
|
+
env[RACK_ENV_KEY] = data
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.load_from_env_or_create(env)
|
40
|
+
env[RACK_ENV_KEY] || from_env(env)
|
41
|
+
end
|
42
|
+
|
30
43
|
def exisiting_warden_user(scope)
|
31
44
|
warden_user = warden.user(scope)
|
32
45
|
return unless warden_user && warden_user.tokens[client_id].nil?
|
@@ -40,11 +53,11 @@ module GrapeTokenAuth
|
|
40
53
|
end
|
41
54
|
|
42
55
|
def fetch_stored_resource(scope)
|
43
|
-
warden.
|
56
|
+
warden.user(scope)
|
44
57
|
end
|
45
58
|
|
46
59
|
def store_resource(resource, scope)
|
47
|
-
warden.
|
60
|
+
warden.set_user(resource, scope: scope, store: false)
|
48
61
|
end
|
49
62
|
|
50
63
|
def first_authenticated_resource
|
@@ -1,7 +1,3 @@
|
|
1
|
-
require_relative 'message_base'
|
2
|
-
require_relative 'messages/password_reset/password_reset_email'
|
3
|
-
require_relative 'messages/confirmation/confirmation_email'
|
4
|
-
|
5
1
|
module GrapeTokenAuth
|
6
2
|
module Mail
|
7
3
|
DEFAULT_MESSAGES = {
|
@@ -15,14 +11,6 @@ module GrapeTokenAuth
|
|
15
11
|
return nil unless messages.key?(message_type)
|
16
12
|
messages[message_type].new(opts)
|
17
13
|
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def valid_email_options?(opts)
|
22
|
-
to_address = opts[:to] || opts['to']
|
23
|
-
return false unless to_address
|
24
|
-
true
|
25
|
-
end
|
26
14
|
end
|
27
15
|
end
|
28
16
|
end
|
@@ -8,6 +8,7 @@ module GrapeTokenAuth
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def send_mail
|
11
|
+
set_smtp_config
|
11
12
|
email.deliver
|
12
13
|
end
|
13
14
|
|
@@ -32,6 +33,12 @@ module GrapeTokenAuth
|
|
32
33
|
|
33
34
|
protected
|
34
35
|
|
36
|
+
def set_smtp_config
|
37
|
+
config = GrapeTokenAuth.configuration.smtp_configuration
|
38
|
+
return if config.empty?
|
39
|
+
email.delivery_method(:smtp, config)
|
40
|
+
end
|
41
|
+
|
35
42
|
def prepare_html
|
36
43
|
part = ::Mail::Part.new
|
37
44
|
part.body = message.html_body
|
@@ -7,7 +7,7 @@ module GrapeTokenAuth
|
|
7
7
|
def call(env)
|
8
8
|
setup(env)
|
9
9
|
begin
|
10
|
-
|
10
|
+
response_with_auth_headers(*@app.call(env))
|
11
11
|
rescue Unauthorized
|
12
12
|
return unauthorized
|
13
13
|
end
|
@@ -30,7 +30,7 @@ module GrapeTokenAuth
|
|
30
30
|
@authorizer_data = AuthorizerData.from_env(env)
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
33
|
+
def response_with_auth_headers(status, headers, response)
|
34
34
|
auth_headers = AuthenticationHeader.new(authorizer_data, request_start)
|
35
35
|
[
|
36
36
|
status,
|
@@ -14,8 +14,7 @@ module GrapeTokenAuth
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def mount_confirmation(opts = {})
|
17
|
-
|
18
|
-
mount_api('ConfirmationAPI', opts)
|
17
|
+
mount_api('ConfirmationAPI', set_mount_point(opts, '/confirmation'))
|
19
18
|
end
|
20
19
|
|
21
20
|
def mount_token_validation(opts = {})
|
@@ -23,15 +22,14 @@ module GrapeTokenAuth
|
|
23
22
|
end
|
24
23
|
|
25
24
|
def mount_password_reset(opts = {})
|
26
|
-
|
27
|
-
mount_api('PasswordAPI', opts)
|
25
|
+
mount_api('PasswordAPI', set_mount_point(opts, '/password'))
|
28
26
|
end
|
29
27
|
|
30
28
|
def mount_omniauth(opts = {})
|
31
|
-
path = opts
|
29
|
+
path = opts.fetch(:to, '/')
|
32
30
|
|
33
|
-
if
|
34
|
-
api = create_api_subclass('OmniAuthAPI',
|
31
|
+
if opts.key?(:for)
|
32
|
+
api = create_api_subclass('OmniAuthAPI', opts[:for])
|
35
33
|
else
|
36
34
|
api = GrapeTokenAuth::OmniAuthAPI
|
37
35
|
end
|
@@ -48,10 +46,15 @@ module GrapeTokenAuth
|
|
48
46
|
|
49
47
|
private
|
50
48
|
|
49
|
+
def set_mount_point(opts, route)
|
50
|
+
opts[:to] = "#{opts[:to].to_s.chomp('/')}#{route}"
|
51
|
+
opts
|
52
|
+
end
|
53
|
+
|
51
54
|
def mount_api(api_class_name, opts)
|
52
|
-
path = opts
|
55
|
+
path = opts.fetch(:to, '/')
|
53
56
|
|
54
|
-
if opts
|
57
|
+
if opts.key?(:for)
|
55
58
|
api = create_api_subclass(api_class_name, opts[:for])
|
56
59
|
else
|
57
60
|
api = GrapeTokenAuth.const_get(api_class_name)
|
@@ -63,17 +66,19 @@ module GrapeTokenAuth
|
|
63
66
|
def create_api_subclass(class_name, mapping)
|
64
67
|
resource_class = GrapeTokenAuth.configuration.scope_to_class(mapping)
|
65
68
|
fail ScopeUndefinedError.new(nil, mapping) unless resource_class
|
66
|
-
scope_name =
|
67
|
-
|
69
|
+
scope_name = Utility.humanize(mapping)
|
70
|
+
api = create_grape_api
|
71
|
+
api.instance_variable_set(:@resource_scope, mapping)
|
72
|
+
api.include(GrapeTokenAuth.const_get("#{class_name}Core"))
|
73
|
+
GrapeTokenAuth.const_set("#{scope_name}#{class_name}", api)
|
74
|
+
end
|
75
|
+
|
76
|
+
def create_grape_api
|
77
|
+
Class.new(Grape::API) do
|
68
78
|
class << self
|
69
|
-
|
70
|
-
@resource_scope
|
71
|
-
end
|
79
|
+
attr_reader :resource_scope
|
72
80
|
end
|
73
81
|
end
|
74
|
-
klass.instance_variable_set(:@resource_scope, mapping)
|
75
|
-
klass.include(GrapeTokenAuth.const_get("#{class_name}Core"))
|
76
|
-
GrapeTokenAuth.const_set("#{scope_name}#{class_name}", klass)
|
77
82
|
end
|
78
83
|
end
|
79
84
|
end
|
@@ -82,7 +82,7 @@ module GrapeTokenAuth
|
|
82
82
|
scoped_list = whitelist[scope] || whitelist[scope.to_s]
|
83
83
|
return unless scoped_list
|
84
84
|
scoped_list.each_with_object({}) do |key, permitted|
|
85
|
-
value = find_with_indifference(omniauth_params, key)
|
85
|
+
value = Utility.find_with_indifference(omniauth_params, key)
|
86
86
|
permitted[key] = value if value
|
87
87
|
end
|
88
88
|
end
|
@@ -93,15 +93,6 @@ module GrapeTokenAuth
|
|
93
93
|
.find { |k,v| v == klass }.try(:[], 0)
|
94
94
|
end
|
95
95
|
|
96
|
-
def find_with_indifference(hash, key)
|
97
|
-
if hash.key?(key.to_sym)
|
98
|
-
return hash[key.to_sym]
|
99
|
-
elsif hash.key?(key.to_s)
|
100
|
-
return hash[key.to_s]
|
101
|
-
end
|
102
|
-
nil
|
103
|
-
end
|
104
|
-
|
105
96
|
def sync_token_to_resource
|
106
97
|
resource.tokens[token.client_id] = token.to_h
|
107
98
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'bcrypt'
|
2
|
-
|
3
1
|
module GrapeTokenAuth
|
4
2
|
module ActiveRecord
|
5
3
|
module TokenAuth
|
@@ -55,17 +53,8 @@ module GrapeTokenAuth
|
|
55
53
|
confirmable
|
56
54
|
end
|
57
55
|
|
58
|
-
def serialize_into_session(record)
|
59
|
-
[record.to_key, record.authenticatable_salt]
|
60
|
-
end
|
61
|
-
|
62
|
-
def serialize_from_session(key, salt)
|
63
|
-
record = get(key)
|
64
|
-
record if record && record.authenticatable_salt == salt
|
65
|
-
end
|
66
|
-
|
67
56
|
def get(key)
|
68
|
-
find(key)
|
57
|
+
find(key)
|
69
58
|
end
|
70
59
|
|
71
60
|
attr_writer :reset_token_lifespan
|
@@ -103,7 +92,7 @@ module GrapeTokenAuth
|
|
103
92
|
tokens[token.client_id] = token.to_h.merge(last_token: last_token)
|
104
93
|
self.save!
|
105
94
|
|
106
|
-
|
95
|
+
AuthenticationHeader.build_auth_headers(token, uid)
|
107
96
|
end
|
108
97
|
|
109
98
|
def valid_token?(token, client_id)
|
@@ -132,7 +121,8 @@ module GrapeTokenAuth
|
|
132
121
|
token_hash[:updated_at] = Time.now
|
133
122
|
expiry = token_hash[:expiry] || token_hash['expiry']
|
134
123
|
save!
|
135
|
-
|
124
|
+
AuthenticationHeader.build_auth_headers(
|
125
|
+
Token.new(client_id, token, expiry), uid)
|
136
126
|
end
|
137
127
|
|
138
128
|
# Copied out of Devise. Excludes the serialization blacklist.
|
@@ -296,15 +286,6 @@ module GrapeTokenAuth
|
|
296
286
|
time > Time.now - GrapeTokenAuth.batch_request_buffer_throttle
|
297
287
|
end
|
298
288
|
|
299
|
-
def build_auth_header(token)
|
300
|
-
{
|
301
|
-
'access-token' => token.to_s,
|
302
|
-
'expiry' => token.expiry.to_s,
|
303
|
-
'client' => token.client_id.to_s,
|
304
|
-
'token-type' => 'Bearer',
|
305
|
-
'uid' => uid.to_s
|
306
|
-
}
|
307
|
-
end
|
308
289
|
end
|
309
290
|
end
|
310
291
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative 'resource_crud_base'
|
2
|
-
|
3
1
|
module GrapeTokenAuth
|
4
2
|
class ResourceCreator < ResourceCrudBase
|
5
3
|
def create!
|
@@ -35,7 +33,7 @@ module GrapeTokenAuth
|
|
35
33
|
def unpack_params
|
36
34
|
[:email, :password_confirmation, :password]
|
37
35
|
.each_with_object({}) do |key, unpacked|
|
38
|
-
unpacked[key] = find_with_indifference(params, key)
|
36
|
+
unpacked[key] = Utility.find_with_indifference(params, key)
|
39
37
|
end
|
40
38
|
end
|
41
39
|
|
@@ -26,18 +26,9 @@ module GrapeTokenAuth
|
|
26
26
|
|
27
27
|
def permitted_params
|
28
28
|
permitted_attributes.each_with_object({}) do |key, permitted|
|
29
|
-
value = find_with_indifference(params, key)
|
29
|
+
value = Utility.find_with_indifference(params, key)
|
30
30
|
permitted[key] = value if value
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
34
|
-
def find_with_indifference(hash, key)
|
35
|
-
if hash.key?(key.to_sym)
|
36
|
-
return hash[key.to_sym]
|
37
|
-
elsif hash.key?(key.to_s)
|
38
|
-
return hash[key.to_s]
|
39
|
-
end
|
40
|
-
nil
|
41
|
-
end
|
42
33
|
end
|
43
34
|
end
|
@@ -24,7 +24,7 @@ module GrapeTokenAuth
|
|
24
24
|
|
25
25
|
load_user_from_uid
|
26
26
|
return nil unless user_authenticated?
|
27
|
-
|
27
|
+
data.authed_with_token = true
|
28
28
|
user
|
29
29
|
end
|
30
30
|
|
@@ -38,9 +38,9 @@ module GrapeTokenAuth
|
|
38
38
|
|
39
39
|
def load_user_from_uid
|
40
40
|
@user = resource_class.find_by_uid(data.uid)
|
41
|
-
|
41
|
+
# TODO: hacky solution to the fact that this statement can fail sporadically
|
42
42
|
# with multiple requests. Nil returned from the statement. but
|
43
|
-
# re-executing the request causes it to pass?
|
43
|
+
# re-executing the request causes it to pass? Database lock?
|
44
44
|
rescue ::ActiveRecord::StatementInvalid
|
45
45
|
@user = resource_class.find_by_uid(data.uid)
|
46
46
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module GrapeTokenAuth
|
2
|
+
class Utility
|
3
|
+
def self.find_with_indifference(hash, key)
|
4
|
+
if hash.key?(key.to_sym)
|
5
|
+
return hash[key.to_sym]
|
6
|
+
elsif hash.key?(key.to_s)
|
7
|
+
return hash[key.to_s]
|
8
|
+
end
|
9
|
+
nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.humanize(snake_cased)
|
13
|
+
snake_cased.to_s.split('_').collect(&:capitalize).join
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape_token_auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Cordell
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10
|
11
|
+
date: 2015-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grape
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 0.12.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.12.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -309,6 +309,7 @@ files:
|
|
309
309
|
- lib/grape_token_auth/token_authentication.rb
|
310
310
|
- lib/grape_token_auth/token_authorizer.rb
|
311
311
|
- lib/grape_token_auth/unauthorized_middleware.rb
|
312
|
+
- lib/grape_token_auth/utility.rb
|
312
313
|
- lib/grape_token_auth/version.rb
|
313
314
|
homepage: https://github.com/mcordell/grape_token_auth
|
314
315
|
licenses:
|
@@ -325,9 +326,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
325
326
|
version: '0'
|
326
327
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
327
328
|
requirements:
|
328
|
-
- - "
|
329
|
+
- - ">="
|
329
330
|
- !ruby/object:Gem::Version
|
330
|
-
version:
|
331
|
+
version: '0'
|
331
332
|
requirements: []
|
332
333
|
rubyforge_project:
|
333
334
|
rubygems_version: 2.4.5
|
@@ -335,3 +336,4 @@ signing_key:
|
|
335
336
|
specification_version: 4
|
336
337
|
summary: Token auth for grape apps
|
337
338
|
test_files: []
|
339
|
+
has_rdoc:
|