api_guard 0.2.2 → 0.3.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 +4 -4
- data/README.md +21 -4
- data/app/controllers/api_guard/authentication_controller.rb +4 -4
- data/app/controllers/api_guard/passwords_controller.rb +1 -1
- data/app/controllers/api_guard/registration_controller.rb +2 -2
- data/app/controllers/api_guard/tokens_controller.rb +3 -3
- data/config/locales/en.yml +22 -0
- data/lib/api_guard/jwt_auth/authentication.rb +6 -5
- data/lib/api_guard/jwt_auth/blacklist_token.rb +2 -0
- data/lib/api_guard/jwt_auth/json_web_token.rb +1 -0
- data/lib/api_guard/jwt_auth/refresh_jwt_token.rb +2 -0
- data/lib/api_guard/response_formatters/renderer.rb +2 -2
- data/lib/api_guard/version.rb +1 -1
- data/lib/generators/api_guard/controllers/controllers_generator.rb +5 -5
- data/lib/generators/api_guard/controllers/templates/authentication_controller.rb +4 -4
- data/lib/generators/api_guard/controllers/templates/passwords_controller.rb +3 -3
- data/lib/generators/api_guard/controllers/templates/registration_controller.rb +3 -3
- data/lib/generators/api_guard/controllers/templates/tokens_controller.rb +7 -4
- data/lib/generators/api_guard/initializer/templates/initializer.rb +4 -4
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e4c4d5d2ef0490d9c1cfbb9bf408d09c5152fc3
|
4
|
+
data.tar.gz: 21f401a251b77bf72dfffccf92965f3ecd501f81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19a27ce1e5ae8f87482e891895de91ce3e08fae8912392ef09f24b4e3763b3e9a1db2315578acb784b6097548fb2ec02e3a9ab8d1776f71c5b0eafaf466e42fa
|
7
|
+
data.tar.gz: c76a2d4620091808a89f903abbf65672b25cddcd8c7974c6e8fdccdb195da88d96258bab30f3f0221954bb371705c619828f3167878dd45b0bfc06cf25d55f30
|
data/README.md
CHANGED
@@ -35,6 +35,7 @@ for cryptographic signing.
|
|
35
35
|
* [Overriding defaults](#overriding-defaults)
|
36
36
|
* [Controllers](#controllers)
|
37
37
|
* [Routes](#routes)
|
38
|
+
* [Customizing / translating response messages using I18n](#customizing--translating-response-messages-using-i18n)
|
38
39
|
* [Testing](#testing)
|
39
40
|
* [Contributing](#contributing)
|
40
41
|
* [License](#license)
|
@@ -353,19 +354,19 @@ configurations.
|
|
353
354
|
ApiGuard.setup do |config|
|
354
355
|
# Validity of the JWT access token
|
355
356
|
# Default: 1 day
|
356
|
-
config.token_validity = 1.day
|
357
|
+
# config.token_validity = 1.day
|
357
358
|
|
358
359
|
# Secret key for signing (encoding & decoding) the JWT access token
|
359
360
|
# Default: 'secret_key_base' from Rails secrets
|
360
|
-
config.token_signing_secret =
|
361
|
+
# config.token_signing_secret = 'my_signing_secret'
|
361
362
|
|
362
363
|
# Invalidate old tokens on changing the password
|
363
364
|
# Default: false
|
364
|
-
config.invalidate_old_tokens_on_password_change = false
|
365
|
+
# config.invalidate_old_tokens_on_password_change = false
|
365
366
|
|
366
367
|
# Blacklist JWT access token after refreshing
|
367
368
|
# Default: false
|
368
|
-
config.blacklist_token_after_refreshing = false
|
369
|
+
# config.blacklist_token_after_refreshing = false
|
369
370
|
end
|
370
371
|
```
|
371
372
|
|
@@ -555,6 +556,22 @@ end
|
|
555
556
|
Above configuration will replace default registration routes `users/sign_up` & `users/delete` with `account/create` &
|
556
557
|
`account/delete`
|
557
558
|
|
559
|
+
### Customizing / translating response messages using I18n
|
560
|
+
|
561
|
+
API Guard uses [I18n](https://guides.rubyonrails.org/i18n.html) for success and error messages. You can create your own
|
562
|
+
locale file and customize the messages for any language.
|
563
|
+
|
564
|
+
```yaml
|
565
|
+
en:
|
566
|
+
api_guard:
|
567
|
+
authentication:
|
568
|
+
signed_in: 'Signed in successfully'
|
569
|
+
signed_out: 'Signed out successfully'
|
570
|
+
```
|
571
|
+
|
572
|
+
You can find the complete list of available keys in this file:
|
573
|
+
https://github.com/Gokul595/api_guard/blob/master/config/locales/en.yml
|
574
|
+
|
558
575
|
## Testing
|
559
576
|
|
560
577
|
API Guard comes with helper for creating JWT access token and refresh token for the resource which you can use it for
|
@@ -8,22 +8,22 @@ module ApiGuard
|
|
8
8
|
def create
|
9
9
|
if resource.authenticate(params[:password])
|
10
10
|
create_token_and_set_header(resource, resource_name)
|
11
|
-
render_success(message: '
|
11
|
+
render_success(message: I18n.t('api_guard.authentication.signed_in'))
|
12
12
|
else
|
13
|
-
render_error(422, message: '
|
13
|
+
render_error(422, message: I18n.t('api_guard.authentication.invalid_login_credentials'))
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def destroy
|
18
18
|
blacklist_token
|
19
|
-
render_success(message: '
|
19
|
+
render_success(message: I18n.t('api_guard.authentication.signed_out'))
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
23
23
|
|
24
24
|
def find_resource
|
25
25
|
self.resource = resource_class.find_by(email: params[:email].downcase.strip) if params[:email].present?
|
26
|
-
render_error(422, message: '
|
26
|
+
render_error(422, message: I18n.t('api_guard.authentication.invalid_login_credentials')) unless resource
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -12,7 +12,7 @@ module ApiGuard
|
|
12
12
|
destroy_all_refresh_tokens(current_resource)
|
13
13
|
|
14
14
|
create_token_and_set_header(current_resource, resource_name)
|
15
|
-
render_success(message: '
|
15
|
+
render_success(message: I18n.t('api_guard.password.changed'))
|
16
16
|
else
|
17
17
|
render_error(422, object: current_resource)
|
18
18
|
end
|
@@ -8,7 +8,7 @@ module ApiGuard
|
|
8
8
|
init_resource(sign_up_params)
|
9
9
|
if resource.save
|
10
10
|
create_token_and_set_header(resource, resource_name)
|
11
|
-
render_success(message: '
|
11
|
+
render_success(message: I18n.t('api_guard.registration.signed_up'))
|
12
12
|
else
|
13
13
|
render_error(422, object: resource)
|
14
14
|
end
|
@@ -16,7 +16,7 @@ module ApiGuard
|
|
16
16
|
|
17
17
|
def destroy
|
18
18
|
current_resource.destroy
|
19
|
-
render_success(message:
|
19
|
+
render_success(message: I18n.t('api_guard.registration.account_deleted'))
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
@@ -11,7 +11,7 @@ module ApiGuard
|
|
11
11
|
@refresh_token.destroy
|
12
12
|
blacklist_token if ApiGuard.blacklist_token_after_refreshing
|
13
13
|
|
14
|
-
render_success(message: '
|
14
|
+
render_success(message: I18n.t('api_guard.access_token.refreshed'))
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
@@ -21,9 +21,9 @@ module ApiGuard
|
|
21
21
|
|
22
22
|
if refresh_token_from_header
|
23
23
|
@refresh_token = find_refresh_token_of(current_resource, refresh_token_from_header)
|
24
|
-
return render_error(401, message: '
|
24
|
+
return render_error(401, message: I18n.t('api_guard.refresh_token.invalid')) unless @refresh_token
|
25
25
|
else
|
26
|
-
render_error(401, message: '
|
26
|
+
render_error(401, message: I18n.t('api_guard.refresh_token.missing'))
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
en:
|
2
|
+
api_guard:
|
3
|
+
authentication:
|
4
|
+
signed_in: 'Signed in successfully'
|
5
|
+
signed_out: 'Signed out successfully'
|
6
|
+
invalid_login_credentials: 'Invalid login credentials'
|
7
|
+
password:
|
8
|
+
changed: 'Password changed successfully'
|
9
|
+
registration:
|
10
|
+
signed_up: 'Signed up successfully'
|
11
|
+
account_deleted: 'Account deleted successfully'
|
12
|
+
access_token:
|
13
|
+
refreshed: 'Token refreshed successfully'
|
14
|
+
missing: 'Access token is missing in the request'
|
15
|
+
invalid: 'Invalid access token'
|
16
|
+
expired: 'Access token expired'
|
17
|
+
refresh_token:
|
18
|
+
invalid: 'Invalid refresh token'
|
19
|
+
missing: 'Refresh token is missing in the request'
|
20
|
+
response:
|
21
|
+
success: 'success'
|
22
|
+
error: 'error'
|
@@ -19,17 +19,17 @@ module ApiGuard
|
|
19
19
|
@resource_name = resource_name
|
20
20
|
|
21
21
|
@token = request.headers['Authorization']&.split('Bearer ')&.last
|
22
|
-
return render_error(401, message: '
|
22
|
+
return render_error(401, message: I18n.t('api_guard.access_token.missing')) unless @token
|
23
23
|
|
24
24
|
authenticate_token
|
25
25
|
|
26
26
|
# Render error response only if no resource found and no previous render happened
|
27
|
-
render_error(401, message: '
|
27
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid')) if !current_resource && !performed?
|
28
28
|
rescue JWT::DecodeError => e
|
29
29
|
if e.message == 'Signature has expired'
|
30
|
-
render_error(401, message: '
|
30
|
+
render_error(401, message: I18n.t('api_guard.access_token.expired'))
|
31
31
|
else
|
32
|
-
render_error(401, message: '
|
32
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid'))
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -64,11 +64,12 @@ module ApiGuard
|
|
64
64
|
|
65
65
|
return if current_resource && valid_issued_at? && !blacklisted?
|
66
66
|
|
67
|
-
render_error(401, message: '
|
67
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid'))
|
68
68
|
end
|
69
69
|
|
70
70
|
def current_resource
|
71
71
|
return unless respond_to?("current_#{@resource_name}")
|
72
|
+
|
72
73
|
public_send("current_#{@resource_name}")
|
73
74
|
end
|
74
75
|
end
|
@@ -18,12 +18,14 @@ module ApiGuard
|
|
18
18
|
# Returns whether the JWT token is blacklisted or not
|
19
19
|
def blacklisted?
|
20
20
|
return false unless token_blacklisting_enabled?(current_resource)
|
21
|
+
|
21
22
|
blacklisted_tokens_for(current_resource).exists?(token: @token)
|
22
23
|
end
|
23
24
|
|
24
25
|
# Blacklist the current JWT token from future access
|
25
26
|
def blacklist_token
|
26
27
|
return unless token_blacklisting_enabled?(current_resource)
|
28
|
+
|
27
29
|
blacklisted_tokens_for(current_resource).create(token: @token, expire_at: Time.at(@decoded_token[:exp]).utc)
|
28
30
|
end
|
29
31
|
end
|
@@ -30,11 +30,13 @@ module ApiGuard
|
|
30
30
|
# Create a new refresh_token for the current resource
|
31
31
|
def new_refresh_token(resource)
|
32
32
|
return unless refresh_token_enabled?(resource)
|
33
|
+
|
33
34
|
refresh_tokens_for(resource).create(token: uniq_refresh_token(resource)).token
|
34
35
|
end
|
35
36
|
|
36
37
|
def destroy_all_refresh_tokens(resource)
|
37
38
|
return unless refresh_token_enabled?(resource)
|
39
|
+
|
38
40
|
refresh_tokens_for(resource).destroy_all
|
39
41
|
end
|
40
42
|
end
|
@@ -2,14 +2,14 @@ module ApiGuard
|
|
2
2
|
module ResponseFormatters
|
3
3
|
module Renderer
|
4
4
|
def render_success(data: nil, message: nil)
|
5
|
-
resp_data = { status: 'success' }
|
5
|
+
resp_data = { status: I18n.t('api_guard.response.success') }
|
6
6
|
resp_data[:message] = message if message
|
7
7
|
|
8
8
|
render json: resp_data, status: 200
|
9
9
|
end
|
10
10
|
|
11
11
|
def render_error(status, options = {})
|
12
|
-
data = { status: 'error' }
|
12
|
+
data = { status: I18n.t('api_guard.response.error') }
|
13
13
|
data[:error] = options[:object] ? options[:object].errors.full_messages[0] : options[:message]
|
14
14
|
|
15
15
|
render json: data, status: status
|
data/lib/api_guard/version.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
module ApiGuard
|
2
2
|
class ControllersGenerator < Rails::Generators::Base
|
3
|
-
CONTROLLERS = %i[registration authentication tokens passwords]
|
3
|
+
CONTROLLERS = %i[registration authentication tokens passwords].freeze
|
4
4
|
|
5
5
|
desc 'Generates API Guard controllers in app/controllers/'
|
6
6
|
source_root File.expand_path('../templates', __FILE__)
|
7
7
|
|
8
|
-
argument :scope, required: true,
|
9
|
-
desc: "The scope to create controllers in, e.g. users, admins"
|
8
|
+
argument :scope, required: true, desc: 'The scope to create controllers in, e.g. users, admins'
|
10
9
|
|
11
10
|
class_option :controllers, aliases: "-c", type: :array,
|
12
|
-
|
11
|
+
desc: "Specify the controllers to generate (#{CONTROLLERS.join(', ')})"
|
13
12
|
|
14
13
|
def create_controllers
|
15
14
|
@controller_scope = scope.camelize
|
16
15
|
controllers = options[:controllers] || CONTROLLERS
|
17
16
|
|
18
17
|
controllers.each do |controller_name|
|
19
|
-
template "#{controller_name}_controller.rb",
|
18
|
+
template "#{controller_name}_controller.rb",
|
19
|
+
"app/controllers/#{scope}/#{controller_name}_controller.rb"
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -6,22 +6,22 @@ module <%= @controller_scope %>
|
|
6
6
|
# def create
|
7
7
|
# if resource.authenticate(params[:password])
|
8
8
|
# create_token_and_set_header(resource, resource_name)
|
9
|
-
# render_success(
|
9
|
+
# render_success(message: I18n.t('api_guard.authentication.signed_in'))
|
10
10
|
# else
|
11
|
-
# render_error(422, message: '
|
11
|
+
# render_error(422, message: I18n.t('api_guard.authentication.invalid_login_credentials'))
|
12
12
|
# end
|
13
13
|
# end
|
14
14
|
|
15
15
|
# def destroy
|
16
16
|
# blacklist_token
|
17
|
-
# render_success(message: '
|
17
|
+
# render_success(message: I18n.t('api_guard.authentication.signed_out'))
|
18
18
|
# end
|
19
19
|
|
20
20
|
# private
|
21
21
|
|
22
22
|
# def find_resource
|
23
23
|
# self.resource = resource_class.find_by(email: params[:email].downcase.strip) if params[:email].present?
|
24
|
-
# render_error(422, message: '
|
24
|
+
# render_error(422, message: I18n.t('api_guard.authentication.invalid_login_credentials')) unless resource
|
25
25
|
# end
|
26
26
|
end
|
27
27
|
end
|
@@ -6,11 +6,11 @@ module <%= @controller_scope %>
|
|
6
6
|
# invalidate_old_jwt_tokens(current_resource)
|
7
7
|
#
|
8
8
|
# if current_resource.update_attributes(password_params)
|
9
|
-
# blacklist_token
|
9
|
+
# blacklist_token unless ApiGuard.invalidate_old_tokens_on_password_change
|
10
10
|
# destroy_all_refresh_tokens(current_resource)
|
11
11
|
#
|
12
12
|
# create_token_and_set_header(current_resource, resource_name)
|
13
|
-
# render_success(
|
13
|
+
# render_success(message: I18n.t('api_guard.password.changed'))
|
14
14
|
# else
|
15
15
|
# render_error(422, object: current_resource)
|
16
16
|
# end
|
@@ -19,7 +19,7 @@ module <%= @controller_scope %>
|
|
19
19
|
# private
|
20
20
|
|
21
21
|
# def password_params
|
22
|
-
# params.
|
22
|
+
# params.permit(:password, :password_confirmation)
|
23
23
|
# end
|
24
24
|
end
|
25
25
|
end
|
@@ -6,7 +6,7 @@ module <%= @controller_scope %>
|
|
6
6
|
# init_resource(sign_up_params)
|
7
7
|
# if resource.save
|
8
8
|
# create_token_and_set_header(resource, resource_name)
|
9
|
-
# render_success(
|
9
|
+
# render_success(message: I18n.t('api_guard.registration.signed_up'))
|
10
10
|
# else
|
11
11
|
# render_error(422, object: resource)
|
12
12
|
# end
|
@@ -14,13 +14,13 @@ module <%= @controller_scope %>
|
|
14
14
|
|
15
15
|
# def destroy
|
16
16
|
# current_resource.destroy
|
17
|
-
# render_success(message:
|
17
|
+
# render_success(message: I18n.t('api_guard.registration.account_deleted'))
|
18
18
|
# end
|
19
19
|
|
20
20
|
# private
|
21
21
|
|
22
22
|
# def sign_up_params
|
23
|
-
# params.
|
23
|
+
# params.permit(:email, :password, :password_confirmation)
|
24
24
|
# end
|
25
25
|
end
|
26
26
|
end
|
@@ -4,9 +4,12 @@ module <%= @controller_scope %>
|
|
4
4
|
# before_action :find_refresh_token, only: [:create]
|
5
5
|
|
6
6
|
# def create
|
7
|
-
# @refresh_token.destroy
|
8
7
|
# create_token_and_set_header(current_resource, resource_name)
|
9
|
-
#
|
8
|
+
#
|
9
|
+
# @refresh_token.destroy
|
10
|
+
# blacklist_token if ApiGuard.blacklist_token_after_refreshing
|
11
|
+
#
|
12
|
+
# render_success(message: I18n.t('api_guard.access_token.refreshed'))
|
10
13
|
# end
|
11
14
|
|
12
15
|
# private
|
@@ -16,9 +19,9 @@ module <%= @controller_scope %>
|
|
16
19
|
#
|
17
20
|
# if refresh_token_from_header
|
18
21
|
# @refresh_token = find_refresh_token_of(current_resource, refresh_token_from_header)
|
19
|
-
# return render_error(401, message: '
|
22
|
+
# return render_error(401, message: I18n.t('api_guard.refresh_token.invalid')) unless @refresh_token
|
20
23
|
# else
|
21
|
-
# render_error(401, message: '
|
24
|
+
# render_error(401, message: I18n.t('api_guard.refresh_token.missing'))
|
22
25
|
# end
|
23
26
|
# end
|
24
27
|
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
ApiGuard.setup do |config|
|
2
2
|
# Validity of the JWT access token
|
3
3
|
# Default: 1 day
|
4
|
-
config.token_validity = 1.day
|
4
|
+
# config.token_validity = 1.day
|
5
5
|
|
6
6
|
# Secret key for signing (encoding & decoding) the JWT access token
|
7
7
|
# Default: 'secret_key_base' from Rails secrets
|
8
|
-
config.token_signing_secret =
|
8
|
+
# config.token_signing_secret = 'my_signing_secret'
|
9
9
|
|
10
10
|
# Invalidate old tokens on changing the password
|
11
11
|
# Default: false
|
12
|
-
config.invalidate_old_tokens_on_password_change = false
|
12
|
+
# config.invalidate_old_tokens_on_password_change = false
|
13
13
|
|
14
14
|
# Blacklist JWT access token after refreshing
|
15
15
|
# Default: false
|
16
|
-
config.blacklist_token_after_refreshing = false
|
16
|
+
# config.blacklist_token_after_refreshing = false
|
17
17
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_guard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gokul Murali
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-09-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jwt
|
@@ -167,6 +167,7 @@ files:
|
|
167
167
|
- app/controllers/api_guard/tokens_controller.rb
|
168
168
|
- app/models/api_guard/application_record.rb
|
169
169
|
- app/views/layouts/api_guard/application.html.erb
|
170
|
+
- config/locales/en.yml
|
170
171
|
- config/routes.rb
|
171
172
|
- lib/api_guard.rb
|
172
173
|
- lib/api_guard/app_secret_key.rb
|