api_guardian 0.1.0.pre
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/MIT-LICENSE +20 -0
- data/README.md +125 -0
- data/Rakefile +30 -0
- data/app/controllers/api_guardian/api_controller.rb +112 -0
- data/app/controllers/api_guardian/application_controller.rb +11 -0
- data/app/controllers/api_guardian/permissions_controller.rb +7 -0
- data/app/controllers/api_guardian/registration_controller.rb +38 -0
- data/app/controllers/api_guardian/roles_controller.rb +19 -0
- data/app/controllers/api_guardian/users_controller.rb +20 -0
- data/app/models/api_guardian/permission.rb +14 -0
- data/app/models/api_guardian/role.rb +97 -0
- data/app/models/api_guardian/role_permission.rb +8 -0
- data/app/models/api_guardian/user.rb +23 -0
- data/app/serializers/api_guardian/permission_serializer.rb +7 -0
- data/app/serializers/api_guardian/role_serializer.rb +7 -0
- data/app/serializers/api_guardian/user_serializer.rb +10 -0
- data/config/initializers/api_guardian.rb +10 -0
- data/config/initializers/doorkeeper.rb +143 -0
- data/config/routes.rb +20 -0
- data/db/migrate/20151117191338_api_guardian_enable_uuid_extension.rb +5 -0
- data/db/migrate/20151117191911_create_api_guardian_roles.rb +9 -0
- data/db/migrate/20151117195618_create_api_guardian_users.rb +25 -0
- data/db/migrate/20151117212826_create_api_guardian_permissions.rb +10 -0
- data/db/migrate/20151117213145_create_api_guardian_role_permissions.rb +11 -0
- data/db/migrate/20151117225238_create_doorkeeper_tables.rb +42 -0
- data/db/seeds.rb +32 -0
- data/lib/api_guardian.rb +80 -0
- data/lib/api_guardian/concerns/api_errors/handler.rb +145 -0
- data/lib/api_guardian/concerns/api_errors/renderer.rb +45 -0
- data/lib/api_guardian/concerns/api_request/validator.rb +66 -0
- data/lib/api_guardian/configuration.rb +171 -0
- data/lib/api_guardian/engine.rb +23 -0
- data/lib/api_guardian/errors/invalid_content_type_error.rb +6 -0
- data/lib/api_guardian/errors/invalid_permission_name_error.rb +6 -0
- data/lib/api_guardian/errors/invalid_request_body_error.rb +6 -0
- data/lib/api_guardian/errors/invalid_request_resource_id_error.rb +6 -0
- data/lib/api_guardian/errors/invalid_request_resource_type_error.rb +6 -0
- data/lib/api_guardian/errors/invalid_update_action_error.rb +6 -0
- data/lib/api_guardian/errors/reset_token_expired_error.rb +6 -0
- data/lib/api_guardian/errors/reset_token_user_mismatch_error.rb +6 -0
- data/lib/api_guardian/policies/application_policy.rb +65 -0
- data/lib/api_guardian/policies/permission_policy.rb +15 -0
- data/lib/api_guardian/policies/role_policy.rb +15 -0
- data/lib/api_guardian/policies/user_policy.rb +23 -0
- data/lib/api_guardian/stores/base.rb +53 -0
- data/lib/api_guardian/stores/permission_store.rb +6 -0
- data/lib/api_guardian/stores/role_store.rb +9 -0
- data/lib/api_guardian/stores/user_store.rb +86 -0
- data/lib/api_guardian/version.rb +3 -0
- data/lib/generators/api_guardian/install/USAGE +8 -0
- data/lib/generators/api_guardian/install/install_generator.rb +19 -0
- data/lib/generators/api_guardian/install/templates/README +1 -0
- data/lib/generators/api_guardian/install/templates/api_guardian.rb +5 -0
- data/lib/tasks/api_guardian_tasks.rake +4 -0
- data/spec/concerns/api_errors/handler_spec.rb +114 -0
- data/spec/concerns/api_request/validator_spec.rb +102 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +25 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +13 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/schema.rb +104 -0
- data/spec/dummy/log/test.log +5031 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/permissions.rb +6 -0
- data/spec/factories/role_permissions.rb +6 -0
- data/spec/factories/roles.rb +24 -0
- data/spec/factories/users.rb +11 -0
- data/spec/models/permission_spec.rb +28 -0
- data/spec/models/role_permission_spec.rb +27 -0
- data/spec/models/role_spec.rb +209 -0
- data/spec/models/user_spec.rb +44 -0
- data/spec/policies/application_policy_spec.rb +118 -0
- data/spec/policies/permission_policy_spec.rb +28 -0
- data/spec/policies/role_policy_spec.rb +28 -0
- data/spec/policies/user_policy_spec.rb +29 -0
- data/spec/requests/permissions_controller_spec.rb +19 -0
- data/spec/requests/registration_controller_spec.rb +151 -0
- data/spec/requests/roles_controller_spec.rb +75 -0
- data/spec/requests/users_controller_spec.rb +75 -0
- data/spec/spec_helper.rb +138 -0
- data/spec/stores/base_spec.rb +113 -0
- data/spec/stores/permission_store_spec.rb +2 -0
- data/spec/stores/role_store_spec.rb +12 -0
- data/spec/stores/user_store_spec.rb +144 -0
- data/spec/support/controller_concern_test_helpers.rb +21 -0
- data/spec/support/matchers.rb +37 -0
- data/spec/support/request_helpers.rb +111 -0
- metadata +508 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
require 'active_support/concern'
|
|
2
|
+
|
|
3
|
+
# TODO: Break this into further modules to decrease complexity
|
|
4
|
+
|
|
5
|
+
module ApiGuardian
|
|
6
|
+
module Concerns
|
|
7
|
+
module ApiErrors
|
|
8
|
+
module Handler
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
include ApiErrors::Renderer
|
|
11
|
+
|
|
12
|
+
included do
|
|
13
|
+
def api_error_handler(exception)
|
|
14
|
+
if exception.is_a? Pundit::NotAuthorizedError
|
|
15
|
+
user_not_authorized
|
|
16
|
+
elsif exception.is_a? ActionController::ParameterMissing
|
|
17
|
+
malformed_request(exception)
|
|
18
|
+
elsif exception.is_a? ActiveRecord::RecordInvalid
|
|
19
|
+
record_invalid(exception)
|
|
20
|
+
elsif exception.is_a? ActiveRecord::RecordNotFound
|
|
21
|
+
render_not_found
|
|
22
|
+
elsif exception.is_a? ApiGuardian::Errors::InvalidContentTypeError
|
|
23
|
+
invalid_content_type
|
|
24
|
+
elsif exception.is_a? ApiGuardian::Errors::InvalidRequestBodyError
|
|
25
|
+
invalid_request_body(exception)
|
|
26
|
+
elsif exception.is_a? ApiGuardian::Errors::InvalidRequestResourceTypeError
|
|
27
|
+
invalid_request_resource_type(exception)
|
|
28
|
+
elsif exception.is_a? ApiGuardian::Errors::InvalidRequestResourceIdError
|
|
29
|
+
invalid_request_resource_id(exception)
|
|
30
|
+
elsif exception.is_a? ApiGuardian::Errors::InvalidUpdateActionError
|
|
31
|
+
invalid_update_action
|
|
32
|
+
elsif exception.is_a? ApiGuardian::Errors::ResetTokenUserMismatchError
|
|
33
|
+
reset_token_mismatch
|
|
34
|
+
elsif exception.is_a? ApiGuardian::Errors::ResetTokenExpiredError
|
|
35
|
+
reset_token_expired
|
|
36
|
+
else
|
|
37
|
+
generic_error_handler(exception)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def doorkeeper_unauthorized_render_options(_)
|
|
42
|
+
error = construct_error(
|
|
43
|
+
401, 'not_authenticated', 'Not Authenticated',
|
|
44
|
+
'You must be logged in.'
|
|
45
|
+
)
|
|
46
|
+
{ json: { errors: [error] } }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
protected
|
|
50
|
+
|
|
51
|
+
def user_not_authorized
|
|
52
|
+
render_error(
|
|
53
|
+
403, 'not_authorized', 'Not Authorized',
|
|
54
|
+
'You are not authorized to perform this action.'
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def malformed_request(exception)
|
|
59
|
+
render_error(
|
|
60
|
+
400, 'malformed_request', 'Malformed Request',
|
|
61
|
+
exception.message
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def record_invalid(exception)
|
|
66
|
+
formatted_errors = []
|
|
67
|
+
used_fields = []
|
|
68
|
+
record = exception.record
|
|
69
|
+
record.errors.each do |error|
|
|
70
|
+
next if used_fields.include? error.to_s
|
|
71
|
+
formatted_error = {
|
|
72
|
+
field: error.to_s,
|
|
73
|
+
detail: record.errors[error][0]
|
|
74
|
+
}
|
|
75
|
+
formatted_errors.push formatted_error
|
|
76
|
+
used_fields.push error.to_s
|
|
77
|
+
end
|
|
78
|
+
formatted_errors = formatted_errors.sort_by { |k| k[:field] }
|
|
79
|
+
render_error(422, 'unprocessable_entity', 'Unprocessable Entity', formatted_errors)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def render_not_found
|
|
83
|
+
render_error(
|
|
84
|
+
404, 'not_found', 'Not Found', 'Resource or endpoint missing: ' +
|
|
85
|
+
request.original_url
|
|
86
|
+
)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def generic_error_handler(exception)
|
|
90
|
+
render_error(500, nil, nil, nil, exception)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def invalid_content_type
|
|
94
|
+
render_error(
|
|
95
|
+
415, 'invalid_content_type', 'Invalid Content Type',
|
|
96
|
+
'Supported content types are: application/vnd.api+json'
|
|
97
|
+
)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def invalid_request_body(exception)
|
|
101
|
+
render_error(
|
|
102
|
+
400, 'invalid_request_body', 'Invalid Request Body',
|
|
103
|
+
"The '#{exception.message}' property is required."
|
|
104
|
+
)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def invalid_request_resource_type(exception)
|
|
108
|
+
render_error(
|
|
109
|
+
400, 'invalid_request_resource_type', 'Invalid Request Resource Type',
|
|
110
|
+
"Expected 'type' property to be '#{exception.message}' for this resource."
|
|
111
|
+
)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def invalid_request_resource_id(exception)
|
|
115
|
+
render_error(
|
|
116
|
+
400, 'invalid_request_resource_id', 'Invalid Request Resource ID',
|
|
117
|
+
"Request 'id' property does not match 'id' of URI. Provided: #{exception.message}, Expected: #{params[:id]}"
|
|
118
|
+
)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def invalid_update_action
|
|
122
|
+
render_error(
|
|
123
|
+
405, 'method_not_allowed', 'Method Not Allowed',
|
|
124
|
+
'Resource update action expects PATCH method.'
|
|
125
|
+
)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def reset_token_mismatch
|
|
129
|
+
render_error(
|
|
130
|
+
403, 'reset_token_mismatch', 'Reset Token Mismatch',
|
|
131
|
+
'Reset token is not valid for the supplied email address.'
|
|
132
|
+
)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def reset_token_expired
|
|
136
|
+
render_error(
|
|
137
|
+
403, 'reset_token_expired', 'Reset Token Expired',
|
|
138
|
+
'This reset token has expired. Tokens are valid for 24 hours.'
|
|
139
|
+
)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'active_support/concern'
|
|
2
|
+
|
|
3
|
+
module ApiGuardian
|
|
4
|
+
module Concerns
|
|
5
|
+
module ApiErrors
|
|
6
|
+
module Renderer
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
def render_error(status, code, title, detail, exception = nil)
|
|
11
|
+
error = construct_error status, code, title, detail
|
|
12
|
+
if Rails.env.production?
|
|
13
|
+
render json: { errors: [error] }, status: status
|
|
14
|
+
else
|
|
15
|
+
if exception
|
|
16
|
+
render json: { errors: [error], exception: exception.class.name,
|
|
17
|
+
message: exception.message, trace: exception.backtrace[0, 10] },
|
|
18
|
+
status: status
|
|
19
|
+
else
|
|
20
|
+
render json: { errors: [error] }, status: status
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
protected
|
|
26
|
+
|
|
27
|
+
def construct_error(status, code, title, detail)
|
|
28
|
+
# TODO: Create error log here
|
|
29
|
+
{
|
|
30
|
+
id: SecureRandom.uuid,
|
|
31
|
+
code: code || 'unknown',
|
|
32
|
+
status: status.to_s || '500',
|
|
33
|
+
title: title || 'Unknown',
|
|
34
|
+
detail: detail || 'An unknown error has occurred and has been logged.'
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def render(**_)
|
|
39
|
+
return super if defined?(super)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require 'active_support/concern'
|
|
2
|
+
|
|
3
|
+
module ApiGuardian
|
|
4
|
+
module Concerns
|
|
5
|
+
module ApiRequest
|
|
6
|
+
module Validator
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
def validate_api_request
|
|
11
|
+
validate_content_type
|
|
12
|
+
|
|
13
|
+
# Make sure we conform to json-api request spec
|
|
14
|
+
case request.method
|
|
15
|
+
when 'POST'
|
|
16
|
+
validate_post_request
|
|
17
|
+
when 'PATCH'
|
|
18
|
+
validate_patch_request
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if action_name == 'update' && request.method != 'PATCH'
|
|
22
|
+
fail ApiGuardian::Errors::InvalidUpdateActionError, request.method
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
protected
|
|
27
|
+
|
|
28
|
+
def validate_content_type
|
|
29
|
+
if request.body.read != '' && request.headers['Content-Type'] != 'application/vnd.api+json'
|
|
30
|
+
fail ApiGuardian::Errors::InvalidContentTypeError, "Invalid content type #{request.headers['Content-Type']}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def validate_post_request
|
|
35
|
+
validate_request_type
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def validate_patch_request
|
|
39
|
+
validate_request_id
|
|
40
|
+
validate_request_type
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def validate_request_id
|
|
44
|
+
top_params = params.fetch(:data)
|
|
45
|
+
fail ApiGuardian::Errors::InvalidRequestBodyError, 'id' unless top_params.fetch(:id, nil)
|
|
46
|
+
|
|
47
|
+
expected_request_id = params[:id]
|
|
48
|
+
request_id = top_params.fetch(:id, nil)
|
|
49
|
+
|
|
50
|
+
fail ApiGuardian::Errors::InvalidRequestResourceIdError, request_id unless request_id == expected_request_id
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def validate_request_type
|
|
54
|
+
top_params = params.fetch(:data)
|
|
55
|
+
fail ApiGuardian::Errors::InvalidRequestBodyError, 'type' unless top_params.fetch(:type, nil)
|
|
56
|
+
|
|
57
|
+
expected_request_type = resource_name.pluralize.downcase
|
|
58
|
+
request_type = top_params.fetch(:type, nil)
|
|
59
|
+
|
|
60
|
+
fail ApiGuardian::Errors::InvalidRequestResourceTypeError, expected_request_type unless request_type == expected_request_type
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
module ApiGuardian
|
|
2
|
+
class Configuration
|
|
3
|
+
# Controls whether the sign up route is enabled.
|
|
4
|
+
# Defaults to `true`. Set to `false` to disable user creation routes.
|
|
5
|
+
# The setting is ignored if routes are disabled.
|
|
6
|
+
# @param [Boolean] value
|
|
7
|
+
# @return [Boolean]
|
|
8
|
+
attr_writer :allow_sign_up
|
|
9
|
+
|
|
10
|
+
# The domain to use for the clearance remember token cookie.
|
|
11
|
+
# Defaults to `nil`, which causes the cookie domain to default to the
|
|
12
|
+
# domain of the request. For more, see
|
|
13
|
+
# [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.2.3).
|
|
14
|
+
# @return [String]
|
|
15
|
+
attr_accessor :cookie_domain
|
|
16
|
+
|
|
17
|
+
# A lambda called to set the remember token cookie expires attribute.
|
|
18
|
+
# The lambda accepts the collection of cookies as an argument which
|
|
19
|
+
# allows for changing the expiration according to those cookies.
|
|
20
|
+
# This could be used, for example, to set a session cookie unless
|
|
21
|
+
# a `remember_me` cookie was also present. By default, cookie expiration
|
|
22
|
+
# is one year. For more on cookie expiration see
|
|
23
|
+
# [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.2.1).
|
|
24
|
+
# @return [Lambda]
|
|
25
|
+
attr_accessor :cookie_expiration
|
|
26
|
+
|
|
27
|
+
# The name of Clearance's remember token cookie.
|
|
28
|
+
# Defaults to `remember_token`.
|
|
29
|
+
# @return [String]
|
|
30
|
+
attr_accessor :cookie_name
|
|
31
|
+
|
|
32
|
+
# Controls which paths the remember token cookie is valid for.
|
|
33
|
+
# Defaults to `"/"` for the entire domain. For more, see
|
|
34
|
+
# [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.1.4).
|
|
35
|
+
# @return [String]
|
|
36
|
+
attr_accessor :cookie_path
|
|
37
|
+
|
|
38
|
+
# Controls whether the HttpOnly flag should be set on the remember token
|
|
39
|
+
# cookie. Defaults to `false`. If `true`, the cookie will not be made
|
|
40
|
+
# available to JavaScript. For more see
|
|
41
|
+
# [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.2.6).
|
|
42
|
+
# @return [Boolean]
|
|
43
|
+
attr_accessor :httponly
|
|
44
|
+
|
|
45
|
+
# Controls the address the password reset email is sent from.
|
|
46
|
+
# Defaults to reply@example.com.
|
|
47
|
+
# @return [String]
|
|
48
|
+
attr_accessor :mailer_sender
|
|
49
|
+
|
|
50
|
+
# The password strategy to use when authenticating and setting passwords.
|
|
51
|
+
# Defaults to {Clearance::PasswordStrategies::BCrypt}.
|
|
52
|
+
# @return [Module #authenticated? #password=]
|
|
53
|
+
attr_accessor :password_strategy
|
|
54
|
+
|
|
55
|
+
# The default path Clearance will redirect signed in users to.
|
|
56
|
+
# Defaults to `"/"`. This can often be overridden for specific scenarios by
|
|
57
|
+
# overriding controller methods that rely on it.
|
|
58
|
+
# @return [String]
|
|
59
|
+
attr_accessor :redirect_url
|
|
60
|
+
|
|
61
|
+
# Set to `false` to disable Clearance's built-in routes.
|
|
62
|
+
# Defaults to `true`. When set to false, your app is responsible for all
|
|
63
|
+
# routes. You can dump a copy of Clearance's default routes with
|
|
64
|
+
# `rails generate clearance:routes`.
|
|
65
|
+
# @return [Boolean]
|
|
66
|
+
attr_writer :routes
|
|
67
|
+
|
|
68
|
+
# Controls the secure setting on the remember token cookie.
|
|
69
|
+
# Defaults to `false`. When set, the browser will only send the
|
|
70
|
+
# cookie to the server over HTTPS. You should set this value to true in
|
|
71
|
+
# live environments to prevent session hijacking. For more, see
|
|
72
|
+
# [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.2.5).
|
|
73
|
+
# @return [Boolean]
|
|
74
|
+
attr_accessor :secure_cookie
|
|
75
|
+
|
|
76
|
+
# The array of sign in guards to run when signing a user in.
|
|
77
|
+
# Defaults to an empty array. Sign in guards respond to `call` and are
|
|
78
|
+
# initialized with a session and the current stack. Each guard can decide
|
|
79
|
+
# to fail the sign in, yield to the next guard, or allow the sign in.
|
|
80
|
+
# @return [Array<#call>]
|
|
81
|
+
attr_accessor :sign_in_guards
|
|
82
|
+
|
|
83
|
+
# The ActiveRecord class that represents users in your application.
|
|
84
|
+
# Defualts to `::User`.
|
|
85
|
+
# @return [ActiveRecord::Base]
|
|
86
|
+
attr_accessor :user_model
|
|
87
|
+
|
|
88
|
+
def initialize
|
|
89
|
+
@allow_sign_up = true
|
|
90
|
+
@cookie_expiration = ->(cookies) { 1.year.from_now.utc }
|
|
91
|
+
@cookie_domain = nil
|
|
92
|
+
@cookie_path = '/'
|
|
93
|
+
@cookie_name = "remember_token"
|
|
94
|
+
@httponly = false
|
|
95
|
+
@mailer_sender = 'reply@example.com'
|
|
96
|
+
@redirect_url = '/'
|
|
97
|
+
@routes = true
|
|
98
|
+
@secure_cookie = false
|
|
99
|
+
@sign_in_guards = []
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def user_model
|
|
103
|
+
@user_model ||= ::User
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Is the user sign up route enabled?
|
|
107
|
+
# @return [Boolean]
|
|
108
|
+
def allow_sign_up?
|
|
109
|
+
@allow_sign_up
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Specifies which controller actions are allowed for user resources.
|
|
113
|
+
# This will be `[:create]` is `allow_sign_up` is true (the default), and
|
|
114
|
+
# empty otherwise.
|
|
115
|
+
# @return [Array<Symbol>]
|
|
116
|
+
def user_actions
|
|
117
|
+
if allow_sign_up?
|
|
118
|
+
[:create]
|
|
119
|
+
else
|
|
120
|
+
[]
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# The name of foreign key parameter for the configured user model.
|
|
125
|
+
# This is derived from the `model_name` of the `user_model` setting.
|
|
126
|
+
# In the default configuration, this is `user_id`.
|
|
127
|
+
# @return [Symbol]
|
|
128
|
+
def user_id_parameter
|
|
129
|
+
"#{user_model.model_name.singular}_id".to_sym
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# @return [Boolean] are Clearance's built-in routes enabled?
|
|
133
|
+
def routes_enabled?
|
|
134
|
+
@routes
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Reloads the clearance user model class.
|
|
138
|
+
# This is called from the Clearance engine to reload the configured
|
|
139
|
+
# user class during each request while in development mode, but only once
|
|
140
|
+
# in production.
|
|
141
|
+
#
|
|
142
|
+
# @api private
|
|
143
|
+
def reload_user_model
|
|
144
|
+
if @user_model.present?
|
|
145
|
+
@user_model = @user_model.to_s.constantize
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# @return [Clearance::Configuration] Clearance's current configuration
|
|
151
|
+
def self.configuration
|
|
152
|
+
@configuration ||= Configuration.new
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Set Clearance's configuration
|
|
156
|
+
# @param config [Clearance::Configuration]
|
|
157
|
+
def self.configuration=(config)
|
|
158
|
+
@configuration = config
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Modify Clearance's current configuration
|
|
162
|
+
# @yieldparam [Clearance::Configuration] config current Clearance config
|
|
163
|
+
# ```
|
|
164
|
+
# Clearance.configure do |config|
|
|
165
|
+
# config.routes = false
|
|
166
|
+
# end
|
|
167
|
+
# ```
|
|
168
|
+
def self.configure
|
|
169
|
+
yield configuration
|
|
170
|
+
end
|
|
171
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'doorkeeper'
|
|
2
|
+
|
|
3
|
+
module ApiGuardian
|
|
4
|
+
Doorkeeper = ::Doorkeeper
|
|
5
|
+
|
|
6
|
+
class Engine < ::Rails::Engine
|
|
7
|
+
isolate_namespace ApiGuardian
|
|
8
|
+
|
|
9
|
+
config.generators do |g|
|
|
10
|
+
g.test_framework :rspec, fixture: false
|
|
11
|
+
g.fixture_replacement :factory_girl, dir: 'spec/factories'
|
|
12
|
+
g.assets false
|
|
13
|
+
g.helper false
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
config.middleware.insert_before 0, "Rack::Cors" do
|
|
17
|
+
allow do
|
|
18
|
+
origins '*'
|
|
19
|
+
resource '*', :headers => :any, :methods => [:get, :post, :options]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|