grape_oauth2 0.1.1
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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.rubocop.yml +18 -0
- data/.travis.yml +42 -0
- data/Gemfile +23 -0
- data/README.md +820 -0
- data/Rakefile +11 -0
- data/gemfiles/active_record.rb +25 -0
- data/gemfiles/mongoid.rb +14 -0
- data/gemfiles/sequel.rb +24 -0
- data/grape_oauth2.gemspec +27 -0
- data/grape_oauth2.png +0 -0
- data/lib/grape_oauth2.rb +129 -0
- data/lib/grape_oauth2/configuration.rb +143 -0
- data/lib/grape_oauth2/configuration/class_accessors.rb +36 -0
- data/lib/grape_oauth2/configuration/validation.rb +71 -0
- data/lib/grape_oauth2/endpoints/authorize.rb +34 -0
- data/lib/grape_oauth2/endpoints/token.rb +72 -0
- data/lib/grape_oauth2/gem_version.rb +24 -0
- data/lib/grape_oauth2/generators/authorization.rb +44 -0
- data/lib/grape_oauth2/generators/base.rb +26 -0
- data/lib/grape_oauth2/generators/token.rb +62 -0
- data/lib/grape_oauth2/helpers/access_token_helpers.rb +54 -0
- data/lib/grape_oauth2/helpers/oauth_params.rb +41 -0
- data/lib/grape_oauth2/mixins/active_record/access_grant.rb +47 -0
- data/lib/grape_oauth2/mixins/active_record/access_token.rb +75 -0
- data/lib/grape_oauth2/mixins/active_record/client.rb +35 -0
- data/lib/grape_oauth2/mixins/mongoid/access_grant.rb +58 -0
- data/lib/grape_oauth2/mixins/mongoid/access_token.rb +88 -0
- data/lib/grape_oauth2/mixins/mongoid/client.rb +41 -0
- data/lib/grape_oauth2/mixins/sequel/access_grant.rb +68 -0
- data/lib/grape_oauth2/mixins/sequel/access_token.rb +86 -0
- data/lib/grape_oauth2/mixins/sequel/client.rb +46 -0
- data/lib/grape_oauth2/responses/authorization.rb +10 -0
- data/lib/grape_oauth2/responses/base.rb +56 -0
- data/lib/grape_oauth2/responses/token.rb +10 -0
- data/lib/grape_oauth2/scopes.rb +74 -0
- data/lib/grape_oauth2/strategies/authorization_code.rb +38 -0
- data/lib/grape_oauth2/strategies/base.rb +47 -0
- data/lib/grape_oauth2/strategies/client_credentials.rb +20 -0
- data/lib/grape_oauth2/strategies/password.rb +22 -0
- data/lib/grape_oauth2/strategies/refresh_token.rb +47 -0
- data/lib/grape_oauth2/unique_token.rb +20 -0
- data/lib/grape_oauth2/version.rb +14 -0
- data/spec/configuration/config_spec.rb +231 -0
- data/spec/configuration/version_spec.rb +12 -0
- data/spec/dummy/endpoints/custom_authorization.rb +25 -0
- data/spec/dummy/endpoints/custom_token.rb +35 -0
- data/spec/dummy/endpoints/status.rb +25 -0
- data/spec/dummy/grape_oauth2_config.rb +11 -0
- data/spec/dummy/orm/active_record/app/config/db.rb +7 -0
- data/spec/dummy/orm/active_record/app/models/access_code.rb +3 -0
- data/spec/dummy/orm/active_record/app/models/access_token.rb +3 -0
- data/spec/dummy/orm/active_record/app/models/application.rb +3 -0
- data/spec/dummy/orm/active_record/app/models/application_record.rb +3 -0
- data/spec/dummy/orm/active_record/app/models/user.rb +10 -0
- data/spec/dummy/orm/active_record/app/twitter.rb +36 -0
- data/spec/dummy/orm/active_record/config.ru +7 -0
- data/spec/dummy/orm/active_record/db/schema.rb +53 -0
- data/spec/dummy/orm/mongoid/app/config/db.rb +6 -0
- data/spec/dummy/orm/mongoid/app/config/mongoid.yml +21 -0
- data/spec/dummy/orm/mongoid/app/models/access_code.rb +3 -0
- data/spec/dummy/orm/mongoid/app/models/access_token.rb +3 -0
- data/spec/dummy/orm/mongoid/app/models/application.rb +3 -0
- data/spec/dummy/orm/mongoid/app/models/user.rb +11 -0
- data/spec/dummy/orm/mongoid/app/twitter.rb +34 -0
- data/spec/dummy/orm/mongoid/config.ru +5 -0
- data/spec/dummy/orm/sequel/app/config/db.rb +1 -0
- data/spec/dummy/orm/sequel/app/models/access_code.rb +4 -0
- data/spec/dummy/orm/sequel/app/models/access_token.rb +4 -0
- data/spec/dummy/orm/sequel/app/models/application.rb +4 -0
- data/spec/dummy/orm/sequel/app/models/application_record.rb +2 -0
- data/spec/dummy/orm/sequel/app/models/user.rb +11 -0
- data/spec/dummy/orm/sequel/app/twitter.rb +47 -0
- data/spec/dummy/orm/sequel/config.ru +5 -0
- data/spec/dummy/orm/sequel/db/schema.rb +50 -0
- data/spec/lib/scopes_spec.rb +50 -0
- data/spec/mixins/active_record/access_token_spec.rb +185 -0
- data/spec/mixins/active_record/client_spec.rb +95 -0
- data/spec/mixins/mongoid/access_token_spec.rb +185 -0
- data/spec/mixins/mongoid/client_spec.rb +95 -0
- data/spec/mixins/sequel/access_token_spec.rb +185 -0
- data/spec/mixins/sequel/client_spec.rb +96 -0
- data/spec/requests/flows/authorization_code_spec.rb +67 -0
- data/spec/requests/flows/client_credentials_spec.rb +101 -0
- data/spec/requests/flows/password_spec.rb +210 -0
- data/spec/requests/flows/refresh_token_spec.rb +222 -0
- data/spec/requests/flows/revoke_token_spec.rb +103 -0
- data/spec/requests/protected_resources_spec.rb +64 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/support/api_helper.rb +11 -0
- metadata +257 -0
data/Rakefile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
gemspec path: '../'
|
|
4
|
+
|
|
5
|
+
platforms :jruby do
|
|
6
|
+
gem 'jdbc-sqlite3'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
platforms :ruby, :mswin, :mswin64, :mingw, :x64_mingw do
|
|
10
|
+
gem 'sqlite3'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
gem 'otr-activerecord'
|
|
14
|
+
|
|
15
|
+
gem 'activerecord'
|
|
16
|
+
gem 'bcrypt'
|
|
17
|
+
|
|
18
|
+
group :test do
|
|
19
|
+
gem 'rspec-rails', '~> 3.5'
|
|
20
|
+
gem 'database_cleaner'
|
|
21
|
+
gem 'rack-test', require: 'rack/test'
|
|
22
|
+
gem 'coveralls', require: false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
data/gemfiles/mongoid.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
gemspec path: '../'
|
|
4
|
+
|
|
5
|
+
gem 'mongoid', '~> 6'
|
|
6
|
+
|
|
7
|
+
group :test do
|
|
8
|
+
gem 'rspec-rails', '~> 3.4'
|
|
9
|
+
gem 'database_cleaner'
|
|
10
|
+
gem 'rack-test', require: 'rack/test'
|
|
11
|
+
gem 'coveralls', require: false
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
data/gemfiles/sequel.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
gemspec path: '../'
|
|
4
|
+
|
|
5
|
+
platforms :jruby do
|
|
6
|
+
gem 'jdbc-sqlite3'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
platforms :ruby, :mswin, :mswin64, :mingw, :x64_mingw do
|
|
10
|
+
gem 'sqlite3'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
gem 'bcrypt'
|
|
14
|
+
gem 'sequel'
|
|
15
|
+
gem 'sequel_secure_password'
|
|
16
|
+
|
|
17
|
+
group :test do
|
|
18
|
+
gem 'rspec-rails', '~> 3.4'
|
|
19
|
+
gem 'database_cleaner'
|
|
20
|
+
gem 'rack-test', require: 'rack/test'
|
|
21
|
+
gem 'coveralls', require: false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
|
2
|
+
|
|
3
|
+
require 'grape_oauth2/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |gem|
|
|
6
|
+
gem.name = 'grape_oauth2'
|
|
7
|
+
gem.version = Grape::OAuth2.gem_version
|
|
8
|
+
gem.authors = ['Nikita Bulai']
|
|
9
|
+
gem.date = '2016-05-31'
|
|
10
|
+
gem.email = ['bulajnikita@gmail.com']
|
|
11
|
+
gem.homepage = 'http://github.com/nbulaj/grape-oauth2'
|
|
12
|
+
gem.summary = 'Grape OAuth2 provider'
|
|
13
|
+
gem.description = 'Provides flexible, ORM-agnostic, fully customizable and simple OAuth2 support for Grape APIs'
|
|
14
|
+
gem.license = 'MIT'
|
|
15
|
+
|
|
16
|
+
gem.require_paths = %w(lib)
|
|
17
|
+
gem.files = `git ls-files`.split($RS)
|
|
18
|
+
gem.test_files = Dir['spec/**/*']
|
|
19
|
+
|
|
20
|
+
gem.required_ruby_version = '>= 2.2.2'
|
|
21
|
+
|
|
22
|
+
gem.add_runtime_dependency 'grape', '~> 0.16'
|
|
23
|
+
gem.add_runtime_dependency 'rack-oauth2', '~> 1.3.0', '>= 1.3.0'
|
|
24
|
+
|
|
25
|
+
gem.add_development_dependency 'rspec-rails', '~> 3.4.0', '>= 3.4.0'
|
|
26
|
+
gem.add_development_dependency 'database_cleaner', '~> 1.5.0', '>= 1.5.0'
|
|
27
|
+
end
|
data/grape_oauth2.png
ADDED
|
Binary file
|
data/lib/grape_oauth2.rb
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require 'grape'
|
|
2
|
+
require 'rack/oauth2'
|
|
3
|
+
|
|
4
|
+
require 'grape_oauth2/version'
|
|
5
|
+
require 'grape_oauth2/configuration/validation'
|
|
6
|
+
require 'grape_oauth2/configuration/class_accessors'
|
|
7
|
+
require 'grape_oauth2/configuration'
|
|
8
|
+
require 'grape_oauth2/scopes'
|
|
9
|
+
require 'grape_oauth2/unique_token'
|
|
10
|
+
|
|
11
|
+
# NOTE: Extract to separate gems!!!
|
|
12
|
+
# This gem should contains only the core functionality and all mixins
|
|
13
|
+
# need to be moved to their own repos with their own tests.
|
|
14
|
+
|
|
15
|
+
# Mixins
|
|
16
|
+
if defined?(ActiveRecord::Base)
|
|
17
|
+
require 'grape_oauth2/mixins/active_record/access_token'
|
|
18
|
+
require 'grape_oauth2/mixins/active_record/access_grant'
|
|
19
|
+
require 'grape_oauth2/mixins/active_record/client'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if defined?(Sequel::Model)
|
|
23
|
+
require 'grape_oauth2/mixins/sequel/access_token'
|
|
24
|
+
require 'grape_oauth2/mixins/sequel/access_grant'
|
|
25
|
+
require 'grape_oauth2/mixins/sequel/client'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if defined?(Mongoid::Document)
|
|
29
|
+
require 'grape_oauth2/mixins/mongoid/access_token'
|
|
30
|
+
require 'grape_oauth2/mixins/mongoid/access_grant'
|
|
31
|
+
require 'grape_oauth2/mixins/mongoid/client'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Authorization Grants aka Flows (Strategies)
|
|
35
|
+
require 'grape_oauth2/strategies/base'
|
|
36
|
+
require 'grape_oauth2/strategies/authorization_code'
|
|
37
|
+
require 'grape_oauth2/strategies/password'
|
|
38
|
+
require 'grape_oauth2/strategies/client_credentials'
|
|
39
|
+
require 'grape_oauth2/strategies/refresh_token'
|
|
40
|
+
|
|
41
|
+
# Generators
|
|
42
|
+
require 'grape_oauth2/generators/base'
|
|
43
|
+
require 'grape_oauth2/generators/token'
|
|
44
|
+
require 'grape_oauth2/generators/authorization'
|
|
45
|
+
|
|
46
|
+
# Grape Helpers
|
|
47
|
+
require 'grape_oauth2/helpers/access_token_helpers'
|
|
48
|
+
require 'grape_oauth2/helpers/oauth_params'
|
|
49
|
+
|
|
50
|
+
# Responses
|
|
51
|
+
require 'grape_oauth2/responses/base'
|
|
52
|
+
require 'grape_oauth2/responses/authorization'
|
|
53
|
+
require 'grape_oauth2/responses/token'
|
|
54
|
+
|
|
55
|
+
# Grape Endpoints
|
|
56
|
+
require 'grape_oauth2/endpoints/token'
|
|
57
|
+
require 'grape_oauth2/endpoints/authorize'
|
|
58
|
+
|
|
59
|
+
# Use Grape namespace for the gem.
|
|
60
|
+
module Grape
|
|
61
|
+
# Main Grape::OAuth2 module.
|
|
62
|
+
module OAuth2
|
|
63
|
+
class << self
|
|
64
|
+
# Grape::OAuth2 configuration.
|
|
65
|
+
#
|
|
66
|
+
# @return [Grape::OAuth2::Configuration]
|
|
67
|
+
# configuration object
|
|
68
|
+
#
|
|
69
|
+
def config
|
|
70
|
+
@config ||= Grape::OAuth2::Configuration.new
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Configures Grape::OAuth2.
|
|
74
|
+
# Yields Grape::OAuth2::Configuration instance to the block.
|
|
75
|
+
def configure
|
|
76
|
+
yield config
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Validates Grape::OAuth2 configuration to be set correctly.
|
|
80
|
+
def check_configuration!
|
|
81
|
+
config.check!
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Grape::OAuth2 default middleware.
|
|
85
|
+
def middleware
|
|
86
|
+
[Rack::OAuth2::Server::Resource::Bearer, config.realm, config.token_authenticator]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Method for injecting Grape::OAuth2 endpoints and helpers
|
|
90
|
+
# into Grape API class. Automatically set required middleware,
|
|
91
|
+
# OAuth2 helpers and mounts all (or configured) endpoints.
|
|
92
|
+
#
|
|
93
|
+
# @param endpoints [Array<Symbol>, Array<String>] endpoints to add
|
|
94
|
+
#
|
|
95
|
+
def api(*endpoints)
|
|
96
|
+
inject_to_api do |api|
|
|
97
|
+
api.use(*Grape::OAuth2.middleware)
|
|
98
|
+
api.helpers(Grape::OAuth2::Helpers::AccessTokenHelpers)
|
|
99
|
+
|
|
100
|
+
(endpoints.presence || endpoints_mapping.keys).each do |name|
|
|
101
|
+
endpoint = endpoints_mapping[name.to_sym]
|
|
102
|
+
raise ArgumentError, "Unrecognized endpoint: #{endpoint}" if endpoint.nil?
|
|
103
|
+
|
|
104
|
+
api.mount(endpoint)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
|
|
111
|
+
def endpoints_mapping
|
|
112
|
+
{
|
|
113
|
+
token: ::Grape::OAuth2::Endpoints::Token,
|
|
114
|
+
authorize: ::Grape::OAuth2::Endpoints::Authorize
|
|
115
|
+
}
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def inject_to_api(&_block)
|
|
119
|
+
raise ArgumentError, 'block must be specified!' unless block_given?
|
|
120
|
+
|
|
121
|
+
Module.new do |mod|
|
|
122
|
+
mod.define_singleton_method :included do |base|
|
|
123
|
+
yield base
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
module Grape
|
|
2
|
+
module OAuth2
|
|
3
|
+
# Grape::OAuth2 configuration class.
|
|
4
|
+
# Contains default or customized options that would be used
|
|
5
|
+
# in OAuth2 endpoints and helpers.
|
|
6
|
+
class Configuration
|
|
7
|
+
# Default Grape::OAuth2 configuration error class.
|
|
8
|
+
Error = Class.new(StandardError)
|
|
9
|
+
# Grape::OAuth2 configuration error for missing API required for OAuth2 classes.
|
|
10
|
+
APIMissing = Class.new(Error)
|
|
11
|
+
|
|
12
|
+
include Validation
|
|
13
|
+
include ClassAccessors
|
|
14
|
+
|
|
15
|
+
# Default Access Token TTL (in seconds)
|
|
16
|
+
DEFAULT_TOKEN_LIFETIME = 7200
|
|
17
|
+
# Default Authorization Code TTL ()in seconds)
|
|
18
|
+
DEFAULT_CODE_LIFETIME = 1800
|
|
19
|
+
|
|
20
|
+
# Default realm value
|
|
21
|
+
DEFAULT_REALM = 'OAuth 2.0'.freeze
|
|
22
|
+
|
|
23
|
+
# Currently supported (be the gem) OAuth2 grant types
|
|
24
|
+
SUPPORTED_GRANT_TYPES = %w(password client_credentials refresh_token).freeze
|
|
25
|
+
|
|
26
|
+
# The names of the classes that represents OAuth2 roles
|
|
27
|
+
#
|
|
28
|
+
# @return [String] class name
|
|
29
|
+
#
|
|
30
|
+
attr_accessor :access_token_class_name, :access_grant_class_name,
|
|
31
|
+
:client_class_name, :resource_owner_class_name
|
|
32
|
+
|
|
33
|
+
# Class name for the OAuth2 helper class that validates requested scopes against Access Token scopes
|
|
34
|
+
#
|
|
35
|
+
# @return [String] scopes validator class name
|
|
36
|
+
#
|
|
37
|
+
attr_accessor :scopes_validator_class_name
|
|
38
|
+
|
|
39
|
+
# Class name for the OAuth2 helper class that generates unique token values
|
|
40
|
+
#
|
|
41
|
+
# @return [String] token generator class name
|
|
42
|
+
#
|
|
43
|
+
attr_accessor :token_generator_class_name
|
|
44
|
+
|
|
45
|
+
# OAuth2 grant types (flows) allowed to be processed
|
|
46
|
+
#
|
|
47
|
+
# @return [Array<String>] grant types
|
|
48
|
+
#
|
|
49
|
+
attr_accessor :allowed_grant_types
|
|
50
|
+
|
|
51
|
+
# Access Token and Authorization Code lifetime in seconds
|
|
52
|
+
attr_accessor :authorization_code_lifetime, :access_token_lifetime
|
|
53
|
+
|
|
54
|
+
# Specifies whether to generate a Refresh Token when creating an Access Token
|
|
55
|
+
#
|
|
56
|
+
# @return [Boolean] true if need to generate refresh token, false in other case
|
|
57
|
+
#
|
|
58
|
+
attr_accessor :issue_refresh_token
|
|
59
|
+
|
|
60
|
+
# Realm value
|
|
61
|
+
#
|
|
62
|
+
# @return [String] realm
|
|
63
|
+
#
|
|
64
|
+
attr_accessor :realm
|
|
65
|
+
|
|
66
|
+
# Access Token authenticator block option for customization
|
|
67
|
+
attr_accessor :token_authenticator
|
|
68
|
+
|
|
69
|
+
# Callback that would be invoked during processing of Refresh Token request for
|
|
70
|
+
# the original Access Token found by token value
|
|
71
|
+
attr_accessor :on_refresh
|
|
72
|
+
|
|
73
|
+
def initialize
|
|
74
|
+
reset!
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Default Access Token authenticator block.
|
|
78
|
+
# Validates token value passed with the request params.
|
|
79
|
+
def default_token_authenticator
|
|
80
|
+
lambda do |request|
|
|
81
|
+
access_token_class.authenticate(request.access_token) || request.invalid_token!
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Accessor for Access Token authenticator block. Set it to proc
|
|
86
|
+
# if called with block or returns current value of the accessor.
|
|
87
|
+
def token_authenticator(&block)
|
|
88
|
+
if block_given?
|
|
89
|
+
instance_variable_set(:'@token_authenticator', block)
|
|
90
|
+
else
|
|
91
|
+
instance_variable_get(:'@token_authenticator')
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Accessor for on_refresh callback. Set callback proc
|
|
96
|
+
# if called with block or returns current value of the accessor.
|
|
97
|
+
def on_refresh(&block)
|
|
98
|
+
if block_given?
|
|
99
|
+
instance_variable_set(:'@on_refresh', block)
|
|
100
|
+
else
|
|
101
|
+
instance_variable_get(:'@on_refresh')
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Indicates if on_refresh callback can be invoked.
|
|
106
|
+
#
|
|
107
|
+
# @return [Boolean]
|
|
108
|
+
# true if callback can be invoked and false in other cases
|
|
109
|
+
#
|
|
110
|
+
def on_refresh_runnable?
|
|
111
|
+
!on_refresh.nil? && on_refresh != :nothing
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Reset configuration to default options values.
|
|
115
|
+
def reset!
|
|
116
|
+
initialize_classes
|
|
117
|
+
initialize_authenticators
|
|
118
|
+
|
|
119
|
+
self.access_token_lifetime = DEFAULT_TOKEN_LIFETIME
|
|
120
|
+
self.authorization_code_lifetime = DEFAULT_CODE_LIFETIME
|
|
121
|
+
self.allowed_grant_types = %w(password client_credentials)
|
|
122
|
+
|
|
123
|
+
self.issue_refresh_token = false
|
|
124
|
+
self.on_refresh = :nothing
|
|
125
|
+
|
|
126
|
+
self.realm = DEFAULT_REALM
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
private
|
|
130
|
+
|
|
131
|
+
# Sets OAuth2 helpers classes to gem defaults.
|
|
132
|
+
def initialize_classes
|
|
133
|
+
self.scopes_validator_class_name = Grape::OAuth2::Scopes.name
|
|
134
|
+
self.token_generator_class_name = Grape::OAuth2::UniqueToken.name
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Sets authenticators to gem defaults.
|
|
138
|
+
def initialize_authenticators
|
|
139
|
+
self.token_authenticator = default_token_authenticator
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Grape
|
|
2
|
+
module OAuth2
|
|
3
|
+
# Grape::OAuth2 accessors for configured classes.
|
|
4
|
+
module ClassAccessors
|
|
5
|
+
# Returns Access Token class by configured name
|
|
6
|
+
def access_token_class
|
|
7
|
+
@_access_token_class ||= access_token_class_name.constantize
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Returns Resource Owner class by configured name
|
|
11
|
+
def resource_owner_class
|
|
12
|
+
@_resource_owner_class ||= resource_owner_class_name.constantize
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Returns Client class by configured name
|
|
16
|
+
def client_class
|
|
17
|
+
@_client_class ||= client_class_name.constantize
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Returns Access Grant class by configured name
|
|
21
|
+
def access_grant_class
|
|
22
|
+
@_access_grant_class ||= access_grant_class_name.constantize
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Returns Scopes Validator class by configured name
|
|
26
|
+
def scopes_validator
|
|
27
|
+
scopes_validator_class_name.constantize
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns Token Generator class by configured name
|
|
31
|
+
def token_generator
|
|
32
|
+
token_generator_class_name.constantize
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
module Grape
|
|
2
|
+
module OAuth2
|
|
3
|
+
class Configuration
|
|
4
|
+
# Validates Grape::OAuth2 configuration.
|
|
5
|
+
module Validation
|
|
6
|
+
# Checks configuration to be set correctly
|
|
7
|
+
# (required classes must be defined and implement specific set of API).
|
|
8
|
+
def check!
|
|
9
|
+
check_required_classes!
|
|
10
|
+
check_required_classes_api!
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
# API mapping.
|
|
16
|
+
# Classes, that represents OAuth2 roles, must have described methods.
|
|
17
|
+
REQUIRED_CLASSES_API = {
|
|
18
|
+
access_token_class: {
|
|
19
|
+
class_methods: %i(authenticate create_for),
|
|
20
|
+
instance_methods: %i(expired? revoked? revoke! to_bearer_token)
|
|
21
|
+
},
|
|
22
|
+
client_class: {
|
|
23
|
+
class_methods: %i(authenticate)
|
|
24
|
+
},
|
|
25
|
+
token_generator: {
|
|
26
|
+
class_methods: %i(generate)
|
|
27
|
+
},
|
|
28
|
+
scopes_validator: {
|
|
29
|
+
instance_methods: %i(valid_for?)
|
|
30
|
+
}
|
|
31
|
+
}.freeze
|
|
32
|
+
|
|
33
|
+
# Validates that required classes defined.
|
|
34
|
+
def check_required_classes!
|
|
35
|
+
REQUIRED_CLASSES_API.keys.each do |klass|
|
|
36
|
+
begin
|
|
37
|
+
object = send(klass)
|
|
38
|
+
rescue NoMethodError
|
|
39
|
+
raise Error, "'#{klass}' must be defined!" if object.nil? || !defined?(object)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Validates that required classes have all the API.
|
|
45
|
+
def check_required_classes_api!
|
|
46
|
+
REQUIRED_CLASSES_API.each do |klass, api_methods|
|
|
47
|
+
check_class_methods(klass, api_methods[:class_methods])
|
|
48
|
+
check_instance_methods(klass, api_methods[:instance_methods])
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Validates that required classes have required class methods.
|
|
53
|
+
def check_class_methods(klass, required_methods)
|
|
54
|
+
(required_methods || []).each do |method|
|
|
55
|
+
method_exist = send(klass).respond_to?(method)
|
|
56
|
+
raise APIMissing, "Class method '#{method}' must be defined for the '#{klass}'!" unless method_exist
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Validates that required classes have required instance methods.
|
|
61
|
+
def check_instance_methods(klass, required_methods)
|
|
62
|
+
(required_methods || []).each do |method|
|
|
63
|
+
unless send(klass).method_defined?(method)
|
|
64
|
+
raise APIMissing, "Instance method '#{method}' must be defined for the '#{klass}'!"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|