virtuatable-core 1.3.1 → 1.6.0.dev0
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/lib/core/controllers/base.rb +3 -2
- data/lib/core/decorators/base.rb +15 -0
- data/lib/core/decorators/campaign.rb +20 -0
- data/lib/core/decorators/token.rb +12 -0
- data/lib/core/decorators.rb +7 -0
- data/lib/core/helpers/accounts.rb +2 -2
- data/lib/core/helpers/declarators.rb +6 -62
- data/lib/core/helpers/parameters.rb +5 -1
- data/lib/core/helpers/responses.rb +3 -13
- data/lib/core/helpers/scopes.rb +22 -0
- data/lib/core/helpers/tokens.rb +28 -0
- data/lib/core/helpers.rb +2 -1
- data/lib/core/models/account.rb +0 -4
- data/lib/core/models/oauth/access_token.rb +9 -24
- data/lib/core/models/oauth/authorization.rb +5 -1
- data/lib/core/models.rb +0 -1
- data/lib/core/services/accounts.rb +6 -2
- data/lib/core/services/applications.rb +43 -0
- data/lib/core/services/authorizations.rb +55 -0
- data/lib/core/services/base.rb +21 -4
- data/lib/core/services/campaigns.rb +28 -0
- data/lib/core/services/registry.rb +29 -5
- data/lib/core/services/sessions.rb +9 -8
- data/lib/core/services/tokens.rb +51 -0
- data/lib/core/services.rb +4 -0
- data/lib/core/version.rb +1 -1
- data/lib/core.rb +7 -1
- metadata +28 -11
- data/lib/core/helpers/sessions.rb +0 -30
- data/lib/core/models/oauth/refresh_token.rb +0 -29
- data/lib/core/models/permissions/category.rb +0 -17
- data/lib/core/models/permissions/group.rb +0 -32
- data/lib/core/models/permissions/right.rb +0 -21
- data/lib/core/models/permissions/route.rb +0 -35
- data/lib/core/models/permissions.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ebed77d032ef7111c0bde0982cdfc947a4a1933c1dc22e2cb09a3edeca12af1
|
4
|
+
data.tar.gz: '081072a04de88c52c94df498047f6cec83147fccf8c163e2c5856a9bde5398ac'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db0b0b6d2343f36483293ce34e0e93e6d0cc9a803959f1f84caafaf338309984aaf6b226f33a363a612e4b3724c9b225dc2dfc97139a729d55dfeb2f6a9ef70f
|
7
|
+
data.tar.gz: 7fc28600dbd1fa9c0a2cab48fc8431e0778e599a07ab98af8d87d3e9f4dc1e34423d1bfe0daa3fffdaa1744be92097dbab7aa9f32a59961d2e913675ad08b73e
|
@@ -13,8 +13,9 @@ module Core
|
|
13
13
|
# Includes the custom errors throwers and responses helpers.
|
14
14
|
include Core::Helpers::Errors
|
15
15
|
include Core::Helpers::Responses
|
16
|
-
# Includes the checking methods for
|
17
|
-
include Core::Helpers::
|
16
|
+
# Includes the checking methods for access tokens.
|
17
|
+
include Core::Helpers::Tokens
|
18
|
+
include Core::Helpers::Scopes
|
18
19
|
# Include the checkers and getters for OAuth apps
|
19
20
|
include Core::Helpers::Applications
|
20
21
|
# Include checkers for field requirement and check
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Core
|
2
|
+
module Decorators
|
3
|
+
class Campaign < Draper::Decorator
|
4
|
+
delegate_all
|
5
|
+
|
6
|
+
def to_simple_h
|
7
|
+
{
|
8
|
+
id: id.to_s,
|
9
|
+
title: title,
|
10
|
+
description: description,
|
11
|
+
tags: tags,
|
12
|
+
players: {
|
13
|
+
current: invitations.where(status: :accepted).count,
|
14
|
+
max: max_players
|
15
|
+
}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -10,8 +10,8 @@ module Core
|
|
10
10
|
def account
|
11
11
|
return @account unless @account.nil?
|
12
12
|
|
13
|
-
|
14
|
-
@account
|
13
|
+
@account = token.authorization.account
|
14
|
+
@account
|
15
15
|
end
|
16
16
|
|
17
17
|
def account_id_not_found
|
@@ -6,9 +6,6 @@ module Core
|
|
6
6
|
# to declare routes whithin a service, performing needed checks and filters.
|
7
7
|
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
8
8
|
module Declarators
|
9
|
-
# @!attribute [r] routes
|
10
|
-
# @return [Array<Core::Models::Permissions::Route>] the currently declared routes.
|
11
|
-
attr_reader :api_routes
|
12
9
|
|
13
10
|
# Main method to declare new routes, persisting them in the database and
|
14
11
|
# declaring it in the Sinatra application with the needed before checks.
|
@@ -16,68 +13,15 @@ module Core
|
|
16
13
|
# @param verb [String] the HTTP method for the route.
|
17
14
|
# @param path [String] the whole URI with parameters for the route.
|
18
15
|
# @param options [Hash] the additional options for the route.
|
19
|
-
def api_route(verb, path,
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
# add some treatments but avoid many problems if route.premium
|
26
|
-
send(route.verb, route.path) do
|
27
|
-
application(premium: current_route.premium)
|
28
|
-
session if current_route.authenticated
|
16
|
+
def api_route(verb, path, premium: false, scopes: [], &block)
|
17
|
+
send(verb, path) do
|
18
|
+
scope_objects = fetch_scopes(scopes + ['data::usage'])
|
19
|
+
appli = application(premium: premium)
|
20
|
+
check_app_scopes(appli, scope_objects)
|
21
|
+
check_token_scopes(token, scope_objects)
|
29
22
|
instance_eval(&block)
|
30
23
|
end
|
31
24
|
end
|
32
|
-
|
33
|
-
# Add a route to the database, then to the routes array.
|
34
|
-
# @param verb [String] the HTTP method used to request this route.
|
35
|
-
# @param path [String] the path used to request this route.
|
36
|
-
# @return [Core::Models::Permissions::Route] the created route.
|
37
|
-
def add_route(verb:, path:, options:)
|
38
|
-
route = Core::Models::Permissions::Route.find_or_create_by!(
|
39
|
-
path: path,
|
40
|
-
verb: verb.downcase,
|
41
|
-
premium: options[:premium],
|
42
|
-
authenticated: options[:authenticated]
|
43
|
-
)
|
44
|
-
api_routes.nil? ? @api_routes = [route] : push_route(route)
|
45
|
-
add_permissions(route)
|
46
|
-
route
|
47
|
-
end
|
48
|
-
|
49
|
-
# Pushes the route in the api routes list, by creating it if needed
|
50
|
-
# @param route [Core::Models::Permissions::Route] the route to push in the list of routes.
|
51
|
-
def push_route(route)
|
52
|
-
@api_routes << route if api_routes.none? do |tmp_route|
|
53
|
-
route.id == tmp_route.id
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# Add the default access permissions to a route. Any group tagged superuser
|
58
|
-
# can automatically access any newly declared_route.
|
59
|
-
# params route [Core::Models::Permissions::Route] the route to add the permissions to.
|
60
|
-
def add_permissions(route)
|
61
|
-
groups = Core::Models::Permissions::Group.where(is_superuser: true)
|
62
|
-
groups.each do |group|
|
63
|
-
unless route.groups.where(id: group.id).exists?
|
64
|
-
route.groups << group
|
65
|
-
route.save!
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# The default options for a route, being the most used value for each key.
|
71
|
-
# @return [Hash] the default options as a hash.
|
72
|
-
def default_options
|
73
|
-
{
|
74
|
-
# If TRUE the application MUST be premium to access the route.
|
75
|
-
# Mainly used to protect administration routes against illegal accesses.
|
76
|
-
premium: false,
|
77
|
-
# If TRUE the user MUST be authenticated to access the route.
|
78
|
-
authenticated: true
|
79
|
-
}
|
80
|
-
end
|
81
25
|
end
|
82
26
|
end
|
83
27
|
end
|
@@ -12,8 +12,12 @@ module Core
|
|
12
12
|
super.merge(body_params)
|
13
13
|
end
|
14
14
|
|
15
|
+
def sym_params
|
16
|
+
params.map { |k, v| [k.to_sym, v] }.to_h
|
17
|
+
end
|
18
|
+
|
15
19
|
# The parameters from the JSON body if it is sent.
|
16
|
-
# @return [Hash] the JSON body parsed as a
|
20
|
+
# @return [Hash] the JSON body parsed as a dict ionary.
|
17
21
|
def body_params
|
18
22
|
request.body.rewind
|
19
23
|
JSON.parse(request.body.read.to_s)
|
@@ -13,7 +13,7 @@ module Core
|
|
13
13
|
def api_list(items)
|
14
14
|
halt 200, {
|
15
15
|
count: items.count,
|
16
|
-
items: items.map { |item|
|
16
|
+
items: items.map { |item| item.to_h }
|
17
17
|
}.to_json
|
18
18
|
end
|
19
19
|
|
@@ -21,13 +21,13 @@ module Core
|
|
21
21
|
# returning the informations about the created item.
|
22
22
|
# @param item [Object] any object that responds to #to_h to display to the user.
|
23
23
|
def api_created(item)
|
24
|
-
halt 201,
|
24
|
+
halt 201, item.to_json
|
25
25
|
end
|
26
26
|
|
27
27
|
# Displays an item with the standards of the API.
|
28
28
|
# @param item [Object] the item to display as a JSON formatted hash.
|
29
29
|
def api_item(item)
|
30
|
-
halt 200,
|
30
|
+
halt 200, item.to_json
|
31
31
|
end
|
32
32
|
|
33
33
|
# Displays a message with a 200 status code
|
@@ -35,16 +35,6 @@ module Core
|
|
35
35
|
def api_ok(message)
|
36
36
|
api_item message: message
|
37
37
|
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def enhanced_h(item)
|
42
|
-
(item.respond_to?(:enhance) ? item.enhance : item).to_h
|
43
|
-
end
|
44
|
-
|
45
|
-
def enhanced_json(item)
|
46
|
-
enhanced_h(item).to_json
|
47
|
-
end
|
48
38
|
end
|
49
39
|
end
|
50
40
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Core
|
2
|
+
module Helpers
|
3
|
+
module Scopes
|
4
|
+
|
5
|
+
def fetch_scopes(names)
|
6
|
+
(names.map { |n| Core::Models::OAuth::Scope.find_by(name: n) }).select { |s| !s.nil? }
|
7
|
+
end
|
8
|
+
|
9
|
+
def check_token_scopes(token, scopes)
|
10
|
+
scopes.each do |scope|
|
11
|
+
api_forbidden 'scope.forbidden' if !token.scopes.include? scope
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_app_scopes(application, scopes)
|
16
|
+
scopes.each do |scope|
|
17
|
+
api_forbidden 'scope.forbidden' if !application.scopes.include? scope
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Core
|
4
|
+
module Helpers
|
5
|
+
# This helper aims at providing vanity methods concerning OAuth tokens.
|
6
|
+
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
7
|
+
module Tokens
|
8
|
+
# Returns the database object representing the current OAuth token, or
|
9
|
+
# raises an error if the token seems to be invalid for any reason.
|
10
|
+
# @return [Core::Models::Oauth::AccessToken] the token if everything went well.
|
11
|
+
# @raise [Core::Helpers::Errors::BadRequest] if the token is not given.
|
12
|
+
# @raise [Core::Helpers::Errors::NotFound] if the token is not found in the
|
13
|
+
# database searching for the value passed as parameter.
|
14
|
+
# @raise [Core::Helpers::Errors::Forbidden] if the token belongs to another
|
15
|
+
# application.
|
16
|
+
def token
|
17
|
+
return @token unless @token.nil?
|
18
|
+
|
19
|
+
check_presence 'token'
|
20
|
+
@token = Core::Models::OAuth::AccessToken.find_by(value: params['token'])
|
21
|
+
api_not_found 'token.unknown' if @token.nil?
|
22
|
+
token_app_id = token.authorization.application.id.to_s
|
23
|
+
api_forbidden 'token.mismatch' if token_app_id != application.id.to_s
|
24
|
+
@token
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/core/helpers.rb
CHANGED
@@ -13,6 +13,7 @@ module Core
|
|
13
13
|
autoload :Parameters, 'core/helpers/parameters'
|
14
14
|
autoload :Responses, 'core/helpers/responses'
|
15
15
|
autoload :Routes, 'core/helpers/routes'
|
16
|
-
autoload :
|
16
|
+
autoload :Scopes, 'core/helpers/scopes'
|
17
|
+
autoload :Tokens, 'core/helpers/tokens'
|
17
18
|
end
|
18
19
|
end
|
data/lib/core/models/account.rb
CHANGED
@@ -37,10 +37,6 @@ module Core
|
|
37
37
|
# @!attribute [w] password_confirmation
|
38
38
|
# @return [String] the confirmation of the password, do not get, just set it ; it must be the same as the password.
|
39
39
|
has_secure_password validations: false
|
40
|
-
|
41
|
-
# @!attribute [rw] groups
|
42
|
-
# @return [Array<Core::Models::Permissions::Group>] the groups giving their corresponding rights to the current account.
|
43
|
-
has_and_belongs_to_many :groups, class_name: 'Core::Models::Permissions::Group', inverse_of: :accounts
|
44
40
|
|
45
41
|
# @!attribute [rw] applications
|
46
42
|
# @return [Array<Core::Models::OAuth::Application] the applications this user has created and owns.
|
@@ -13,44 +13,29 @@ module Core
|
|
13
13
|
# @!attribute [rw] value
|
14
14
|
# @return [String] the value of the token, returned to the application when built.
|
15
15
|
field :value, type: String, default: ->{ SecureRandom.hex }
|
16
|
-
# @!attribute [rw] expiration
|
17
|
-
# @return [Integer] the time, in seconds, after which the token is declared expired, and thus can't be used anymore.
|
18
|
-
field :expiration, type: Integer, default: 86400
|
19
16
|
|
20
17
|
# @!attribute [rw] authorization
|
21
18
|
# @return [Core::Models::OAuth::Authorization] the authorization code that issued this token to the application for this user.
|
22
|
-
belongs_to :authorization, class_name: 'Core::Models::OAuth::Authorization', inverse_of: :tokens
|
19
|
+
belongs_to :authorization, class_name: 'Core::Models::OAuth::Authorization', inverse_of: :tokens, optional: true
|
20
|
+
# @!attribute [rw] generator
|
21
|
+
# @return [Core::Models::Oauth::AccessToken] the token that generated this one.
|
22
|
+
belongs_to :generator, class_name: 'Core::Models::OAuth::AccessToken', inverse_of: :generated, optional: true
|
23
23
|
|
24
|
-
|
25
|
-
#
|
26
|
-
|
27
|
-
# @return [Core::Models::OAuth::RefreshToken] the refresh token linked to this token
|
28
|
-
has_one :refresh_token, class_name: 'Core::Models::OAuth::RefreshToken', inverse_of: :token
|
24
|
+
# @!attribute [rw] generated
|
25
|
+
# @return [Core::Models::OAuth::AccessToken] the token that has been generated by the current one.
|
26
|
+
has_one :generated, class_name: 'Core::Models::OAuth::AccessToken', inverse_of: :generator
|
29
27
|
|
30
28
|
validates :value,
|
31
29
|
presence: {message: 'required'},
|
32
30
|
uniqueness: {message: 'uniq'}
|
33
31
|
|
34
|
-
# Checks if the current date is inferior to the creation date + expiration period
|
35
|
-
# @return [Boolean] TRUE if the token is expired, FALSE otherwise.
|
36
|
-
def expired?
|
37
|
-
# Handles the case where the token is given to a premium app (our apps have infinite tokens).
|
38
|
-
return false if premium?
|
39
|
-
return true if refresh_token.used?
|
40
|
-
|
41
|
-
created_at.to_time.to_i + expiration < Time.now.to_i
|
42
|
-
end
|
43
|
-
|
44
32
|
# Returns the scopes this access token can use to access the application
|
45
33
|
# @return [Array<Core::Models::OAuth::Scope>] the array of scopes from the linked authorization
|
46
34
|
def scopes
|
47
|
-
|
48
|
-
return Core::Models::OAuth::Scope.all.to_a if premium?
|
49
|
-
|
50
|
-
authorization.scopes
|
35
|
+
premium ? Core::Models::OAuth::Scope.all.to_a : authorization.scopes
|
51
36
|
end
|
52
37
|
|
53
|
-
def premium
|
38
|
+
def premium
|
54
39
|
authorization.application.premium
|
55
40
|
end
|
56
41
|
end
|
@@ -17,7 +17,7 @@ module Core
|
|
17
17
|
field :code, type: String, default: ->{ SecureRandom.hex }
|
18
18
|
# @!attribute [rw] expiration
|
19
19
|
# @return [Integer] the time, in seconds, after which the authorization is declared expired.
|
20
|
-
field :expiration, type: Integer, default:
|
20
|
+
field :expiration, type: Integer, default: 60
|
21
21
|
|
22
22
|
# @!attribute [rw] account
|
23
23
|
# @return [Arkaaan::Account] the account granting the authorization to access its data to the application.
|
@@ -41,6 +41,10 @@ module Core
|
|
41
41
|
def expired?
|
42
42
|
created_at.to_time.to_i + expiration < Time.now.to_i
|
43
43
|
end
|
44
|
+
|
45
|
+
def used?
|
46
|
+
tokens.count > 0
|
47
|
+
end
|
44
48
|
end
|
45
49
|
end
|
46
50
|
end
|
data/lib/core/models.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Core
|
2
4
|
module Services
|
3
|
-
class Accounts
|
5
|
+
class Accounts
|
6
|
+
include Singleton
|
7
|
+
|
4
8
|
def get_by_username(username)
|
5
9
|
account = Core::Models::Account.find_by(username: username)
|
6
10
|
if account.nil?
|
@@ -13,4 +17,4 @@ module Core
|
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
16
|
-
end
|
20
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Core
|
4
|
+
module Services
|
5
|
+
# Service managing applications, allowing easy access to them with or without
|
6
|
+
# providing client secret for example.
|
7
|
+
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
8
|
+
class Applications < Core::Services::Base
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
# Gets an application given its credentials (client UUID and client secret).
|
12
|
+
#
|
13
|
+
# @param client_id [String] the unique public identifier of the application.
|
14
|
+
# @param client_secret [String] the password for the application.
|
15
|
+
# @return [Core::Models::OAuth::Application] the application if it has been found.
|
16
|
+
#
|
17
|
+
# @raise [Core::Helpers::Errors::BadRequest] if a parameter is not correctly given.
|
18
|
+
# @raise [Core::Helpers::Errors::Forbidden] if the client secret is wrong for this application.
|
19
|
+
# @raise [Core::Helpers::Errors::Unknown] if the application is not found.
|
20
|
+
def get_by_credentials(client_id: nil, client_secret: nil, **_ignored)
|
21
|
+
require_parameters client_secret: client_secret
|
22
|
+
application = get_by_id(client_id: client_id)
|
23
|
+
raise forbidden_err(field: 'client_secret', error: 'wrong') if application.client_secret != client_secret
|
24
|
+
|
25
|
+
application
|
26
|
+
end
|
27
|
+
|
28
|
+
# Gets an application given its client UUID.
|
29
|
+
#
|
30
|
+
# @param client_id [String] the unique identifier of the application to get
|
31
|
+
# @return [Core::Models::OAuth::Application] the application found if no error is raised.
|
32
|
+
#
|
33
|
+
# @raise [Core::Helpers::Errors::Unknown] if the application is not found.
|
34
|
+
def get_by_id(client_id: nil, **_ignored)
|
35
|
+
require_parameters client_id: client_id
|
36
|
+
application = Core::Models::OAuth::Application.find_by(client_id: client_id)
|
37
|
+
raise unknown_err(field: 'client_id') if application.nil?
|
38
|
+
|
39
|
+
application
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Core
|
4
|
+
module Services
|
5
|
+
# Service managing authorization codes. These codes represent the access a user
|
6
|
+
# is giving to an application on all or part of its data.
|
7
|
+
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
8
|
+
class Authorizations < Core::Services::Base
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
# Gets the authorization code corresponding to the provided value if it is linked to the
|
12
|
+
# application matching the provided credentials. Otherwise it raises errors.
|
13
|
+
#
|
14
|
+
# @param client_id [String] the UUID of the application.
|
15
|
+
# @param client_secret [String] the password of the application.
|
16
|
+
# @param authorization_code [String] the code of the authorization you're trying to get.
|
17
|
+
#
|
18
|
+
# @return [Core::Models::OAuth::Authorization] the authorization code object if found.
|
19
|
+
#
|
20
|
+
# @raise [Core::Helpers::Errors::NotFound] if the application or the authorization is unknown
|
21
|
+
# @raise [Core::Helpers::Errors::BadRequest] if any parameter is nil.
|
22
|
+
# @raise [Core::Helpers::Errors::Forbidden] if the secret does not match the application,
|
23
|
+
# or the authorization code does not belong to the application.
|
24
|
+
def get_by_credentials(client_id: nil, client_secret: nil, authorization_code: nil, **_ignored)
|
25
|
+
require_parameters authorization_code: authorization_code
|
26
|
+
application = Core.svc.applications.get_by_credentials(
|
27
|
+
client_id: client_id,
|
28
|
+
client_secret: client_secret
|
29
|
+
)
|
30
|
+
authorization = get_by_code(authorization_code: authorization_code)
|
31
|
+
raise mismatch_error if authorization.application.id.to_s != application.id.to_s
|
32
|
+
|
33
|
+
authorization
|
34
|
+
end
|
35
|
+
|
36
|
+
# Gets an authorization code by its corresponding value.
|
37
|
+
# @param authorization_code [String] the code value of the authorization object.
|
38
|
+
# @return [Core::Models::OAuth::Authorization] the authorization object.
|
39
|
+
# @raise [Core::Helpers::Errors::NotFound] if the authorization code is not found.
|
40
|
+
def get_by_code(authorization_code: nil, **_ignored)
|
41
|
+
require_parameters authorization_code: authorization_code
|
42
|
+
authorization = Core::Models::OAuth::Authorization.find_by(code: authorization_code)
|
43
|
+
raise unknown_err(field: 'authorization_code') if authorization.nil?
|
44
|
+
|
45
|
+
authorization
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def mismatch_error
|
51
|
+
bad_request_err(field: 'client_id', error: 'mismatch')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/core/services/base.rb
CHANGED
@@ -1,11 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Core
|
2
4
|
module Services
|
3
5
|
class Base
|
4
|
-
|
6
|
+
# Raises an error if any parameter is nil, and nothing if all parameters are found.
|
7
|
+
# @raise [Core::Helpers::Errors::BadRequest] an error if any parameter is nil.
|
8
|
+
def require_parameters(**parameters)
|
9
|
+
parameters.keys.each do |key|
|
10
|
+
value = parameters[key]
|
11
|
+
raise bad_request_err(field: key.to_s, error: 'required') if value.nil?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def bad_request_err(field: nil, error: nil)
|
16
|
+
Core::Helpers::Errors::BadRequest.new(field: field, error: error)
|
17
|
+
end
|
18
|
+
|
19
|
+
def unknown_err(field: nil, error: 'unknown')
|
20
|
+
Core::Helpers::Errors::NotFound.new(field: field, error: error)
|
21
|
+
end
|
5
22
|
|
6
|
-
def
|
7
|
-
|
23
|
+
def forbidden_err(field: nil, error: 'forbidden')
|
24
|
+
Core::Helpers::Errors::Forbidden.new(field: field, error: error)
|
8
25
|
end
|
9
26
|
end
|
10
27
|
end
|
11
|
-
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Core
|
4
|
+
module Services
|
5
|
+
class Campaigns
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
# Lists all the campaigns of a user identified by its account.
|
9
|
+
#
|
10
|
+
# @param account [Core::Models::Account] the user requesting its campaigns.
|
11
|
+
# @param page [Integer] the page in the list of campaigns to return to the users.
|
12
|
+
# @param per_page [Integer] the number of campaigns per page.
|
13
|
+
#
|
14
|
+
# @return [Array<Hash>] an array of hash representing campaigns.
|
15
|
+
def list(account, page: 0, per_page: 20, **_ignored)
|
16
|
+
campaigns = campaigns(account).skip(page * per_page).limit(per_page)
|
17
|
+
campaigns.map do |campaign|
|
18
|
+
Core::Decorators::Campaign.new(campaign).to_simple_h
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def campaigns(account)
|
23
|
+
invitations = account.invitations.where(enum_status: 'creator')
|
24
|
+
Core::Models::Campaign.where(:id.in => invitations.map(&:campaign_id))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,15 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Core
|
2
4
|
module Services
|
3
5
|
# The registry holds references to all the services accessible in the library. To access
|
4
|
-
# all services and be able to manage resources easily, just instanciate the
|
6
|
+
# all services and be able to manage resources easily, just instanciate the
|
5
7
|
class Registry
|
8
|
+
include Singleton
|
6
9
|
|
7
|
-
|
10
|
+
# @!attribute [r] accounts
|
11
|
+
# @return [Core::Services::Accounts] the service managing accounts
|
12
|
+
attr_reader :accounts
|
13
|
+
# @!attribute [r] sessions
|
14
|
+
# @return [Core::Services::Sessions] the service managing sessions
|
15
|
+
attr_reader :sessions
|
16
|
+
# @!attribute [r] campaigns
|
17
|
+
# @return [Core::Services::Campaigns] the service managing campaigns
|
18
|
+
attr_reader :campaigns
|
19
|
+
# @!attribute [r] applications
|
20
|
+
# @return [Core::Services::Applications] the service managing applications
|
21
|
+
attr_reader :applications
|
22
|
+
# @!attribute [r] authorizations
|
23
|
+
# @return [Core::Services::Authorizations] the service managing authorizations
|
24
|
+
attr_reader :authorizations
|
25
|
+
# @!attribute [r] tokens
|
26
|
+
# @return [Core::Services::Tokens] the service managing OAuth access tokens
|
27
|
+
attr_reader :tokens
|
8
28
|
|
9
29
|
def initialize
|
10
|
-
@accounts = Core::Services::Accounts.
|
11
|
-
@sessions = Core::Services::Sessions.
|
30
|
+
@accounts = Core::Services::Accounts.instance
|
31
|
+
@sessions = Core::Services::Sessions.instance
|
32
|
+
@campaigns = Core::Services::Campaigns.instance
|
33
|
+
@applications = Core::Services::Applications.instance
|
34
|
+
@authorizations = Core::Services::Authorizations.instance
|
35
|
+
@tokens = Core::Services::Tokens.instance
|
12
36
|
end
|
13
37
|
end
|
14
38
|
end
|
15
|
-
end
|
39
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bcrypt'
|
2
4
|
require 'securerandom'
|
3
5
|
|
@@ -5,7 +7,8 @@ module Core
|
|
5
7
|
module Services
|
6
8
|
# Service concerning sessions (log in and log out)
|
7
9
|
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
8
|
-
class Sessions
|
10
|
+
class Sessions
|
11
|
+
include Singleton
|
9
12
|
# Creates a new session from the given user credentials. IT will
|
10
13
|
# * check that the user exists in the database
|
11
14
|
# * check that the password matches the user encrypted password
|
@@ -16,18 +19,16 @@ module Core
|
|
16
19
|
# @param password [string] the password the user has provided
|
17
20
|
# @return [Core::Models::Authentication::Session] the login session
|
18
21
|
def create(username, password)
|
19
|
-
account =
|
22
|
+
account = Core.svc.accounts.get_by_username(username)
|
20
23
|
if BCrypt::Password.new(account.password_digest) != password
|
21
|
-
raise Core::Helpers::Errors::Forbidden.new(
|
22
|
-
field: 'password',
|
23
|
-
error: 'wrong'
|
24
|
-
)
|
24
|
+
raise Core::Helpers::Errors::Forbidden.new(field: 'password', error: 'wrong')
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
|
+
Core::Models::Authentication::Session.create(
|
27
28
|
account: account,
|
28
29
|
token: SecureRandom.uuid
|
29
30
|
)
|
30
31
|
end
|
31
32
|
end
|
32
33
|
end
|
33
|
-
end
|
34
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Core
|
4
|
+
module Services
|
5
|
+
# Service handling every operations concerning access tokens. This should mainly be
|
6
|
+
# used in the authentication backend as we should be the only ones to manage tokens.
|
7
|
+
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
8
|
+
class Tokens < Core::Services::Base
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
def create_from_authorization(client_id: nil, client_secret: nil, authorization_code: nil, **_ignored)
|
12
|
+
authorization = Core.svc.authorizations.get_by_credentials(
|
13
|
+
client_id: client_id,
|
14
|
+
client_secret: client_secret,
|
15
|
+
authorization_code: authorization_code
|
16
|
+
)
|
17
|
+
raise forbidden_err(field: 'authorization_code', error: 'used') if authorization.used?
|
18
|
+
|
19
|
+
created = Core::Models::OAuth::AccessToken.create(authorization: authorization)
|
20
|
+
Core::Decorators::Token.new(created)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Refreshes the token for the next request the client wants to issue by re-creating it
|
24
|
+
# from the previous token to add it to the tokens chain.
|
25
|
+
#
|
26
|
+
def create_from_token(client_id: nil, client_secret: nil, token: nil, **_ignored)
|
27
|
+
token = get_by_value(token: token)
|
28
|
+
authorization = Core.svc.authorizations.get_by_credentials(
|
29
|
+
client_id: client_id,
|
30
|
+
client_secret: client_secret,
|
31
|
+
authorization_code: token.authorization.code
|
32
|
+
)
|
33
|
+
raise forbidden_err(field: 'token', error: 'used') unless token.generated.nil?
|
34
|
+
|
35
|
+
created = Core::Models::OAuth::AccessToken.create(
|
36
|
+
generator: token,
|
37
|
+
authorization: authorization
|
38
|
+
)
|
39
|
+
Core::Decorators::Token.new(created)
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_by_value(token: nil, **_ignored)
|
43
|
+
require_parameters token: token
|
44
|
+
token = Core::Models::OAuth::AccessToken.find_by(value: token)
|
45
|
+
raise unknown_err(field: 'token') if token.nil?
|
46
|
+
|
47
|
+
Core::Decorators::Token.new(token)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/core/services.rb
CHANGED
@@ -5,8 +5,12 @@ module Core
|
|
5
5
|
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
6
6
|
module Services
|
7
7
|
autoload :Accounts, 'core/services/accounts'
|
8
|
+
autoload :Applications, 'core/services/applications'
|
9
|
+
autoload :Authorizations, 'core/services/authorizations'
|
8
10
|
autoload :Base, 'core/services/base'
|
11
|
+
autoload :Campaigns, 'core/services/campaigns'
|
9
12
|
autoload :Registry, 'core/services/registry'
|
10
13
|
autoload :Sessions, 'core/services/sessions'
|
14
|
+
autoload :Tokens, 'core/services/tokens'
|
11
15
|
end
|
12
16
|
end
|
data/lib/core/version.rb
CHANGED
data/lib/core.rb
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
%w[active_model mongoid active_support].each { |g| require g }
|
3
|
+
%w[active_model mongoid active_support draper].each { |g| require g }
|
4
4
|
|
5
5
|
# Main module of the application, holding all the subsequent classes.
|
6
6
|
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
7
7
|
module Core
|
8
8
|
autoload :Controllers, 'core/controllers'
|
9
|
+
autoload :Decorators, 'core/decorators'
|
9
10
|
autoload :Helpers, 'core/helpers'
|
10
11
|
autoload :Models, 'core/models'
|
11
12
|
autoload :Services, 'core/services'
|
13
|
+
|
14
|
+
# Returns the registry of services for easier access to each of them.
|
15
|
+
def self.svc
|
16
|
+
Core::Services::Registry.instance
|
17
|
+
end
|
12
18
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: virtuatable-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0.dev0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vincent Courtois
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: database_cleaner
|
@@ -276,6 +276,20 @@ dependencies:
|
|
276
276
|
- - '='
|
277
277
|
- !ruby/object:Gem::Version
|
278
278
|
version: 2.1.0
|
279
|
+
- !ruby/object:Gem::Dependency
|
280
|
+
name: draper
|
281
|
+
requirement: !ruby/object:Gem::Requirement
|
282
|
+
requirements:
|
283
|
+
- - ">="
|
284
|
+
- !ruby/object:Gem::Version
|
285
|
+
version: '0'
|
286
|
+
type: :runtime
|
287
|
+
prerelease: false
|
288
|
+
version_requirements: !ruby/object:Gem::Requirement
|
289
|
+
requirements:
|
290
|
+
- - ">="
|
291
|
+
- !ruby/object:Gem::Version
|
292
|
+
version: '0'
|
279
293
|
description: This gem holds the model layer for my table-top RPG games application.
|
280
294
|
email: courtois.vincent@outlook.com
|
281
295
|
executables: []
|
@@ -285,6 +299,10 @@ files:
|
|
285
299
|
- lib/core.rb
|
286
300
|
- lib/core/controllers.rb
|
287
301
|
- lib/core/controllers/base.rb
|
302
|
+
- lib/core/decorators.rb
|
303
|
+
- lib/core/decorators/base.rb
|
304
|
+
- lib/core/decorators/campaign.rb
|
305
|
+
- lib/core/decorators/token.rb
|
288
306
|
- lib/core/helpers.rb
|
289
307
|
- lib/core/helpers/accounts.rb
|
290
308
|
- lib/core/helpers/applications.rb
|
@@ -298,7 +316,8 @@ files:
|
|
298
316
|
- lib/core/helpers/parameters.rb
|
299
317
|
- lib/core/helpers/responses.rb
|
300
318
|
- lib/core/helpers/routes.rb
|
301
|
-
- lib/core/helpers/
|
319
|
+
- lib/core/helpers/scopes.rb
|
320
|
+
- lib/core/helpers/tokens.rb
|
302
321
|
- lib/core/models.rb
|
303
322
|
- lib/core/models/account.rb
|
304
323
|
- lib/core/models/authentication.rb
|
@@ -331,19 +350,17 @@ files:
|
|
331
350
|
- lib/core/models/oauth/access_token.rb
|
332
351
|
- lib/core/models/oauth/application.rb
|
333
352
|
- lib/core/models/oauth/authorization.rb
|
334
|
-
- lib/core/models/oauth/refresh_token.rb
|
335
353
|
- lib/core/models/oauth/scope.rb
|
336
|
-
- lib/core/models/permissions.rb
|
337
|
-
- lib/core/models/permissions/category.rb
|
338
|
-
- lib/core/models/permissions/group.rb
|
339
|
-
- lib/core/models/permissions/right.rb
|
340
|
-
- lib/core/models/permissions/route.rb
|
341
354
|
- lib/core/models/ruleset.rb
|
342
355
|
- lib/core/services.rb
|
343
356
|
- lib/core/services/accounts.rb
|
357
|
+
- lib/core/services/applications.rb
|
358
|
+
- lib/core/services/authorizations.rb
|
344
359
|
- lib/core/services/base.rb
|
360
|
+
- lib/core/services/campaigns.rb
|
345
361
|
- lib/core/services/registry.rb
|
346
362
|
- lib/core/services/sessions.rb
|
363
|
+
- lib/core/services/tokens.rb
|
347
364
|
- lib/core/version.rb
|
348
365
|
homepage: https://rubygems.org/gems/virtuatable-core
|
349
366
|
licenses:
|
@@ -360,9 +377,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
360
377
|
version: '0'
|
361
378
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
362
379
|
requirements:
|
363
|
-
- - "
|
380
|
+
- - ">"
|
364
381
|
- !ruby/object:Gem::Version
|
365
|
-
version:
|
382
|
+
version: 1.3.1
|
366
383
|
requirements: []
|
367
384
|
rubygems_version: 3.2.3
|
368
385
|
signing_key:
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Core
|
4
|
-
module Helpers
|
5
|
-
# This helper gives access to methods about user's session on the API.
|
6
|
-
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
7
|
-
module Sessions
|
8
|
-
# Checks the session of the user requesting the API and returns an error
|
9
|
-
# if it either not exists with the given token, or the token is not given.
|
10
|
-
#
|
11
|
-
# @raise [Virtuatable::API::Errors::NotFound] if the session is not found
|
12
|
-
# or the token not given in the parameters of the request.
|
13
|
-
# @raise [Virtuatable::API::Errors::BadRequest] if the session token is
|
14
|
-
# not correctly given in the parameters.
|
15
|
-
#
|
16
|
-
# @return [Core::Models::Authentication::Session] the current session of the user.
|
17
|
-
def session
|
18
|
-
return @session unless @session.nil?
|
19
|
-
|
20
|
-
check_presence 'session_id'
|
21
|
-
@session = session_model.find_by(token: params['session_id'])
|
22
|
-
@session.nil? ? api_not_found('session_id.unknown') : @session
|
23
|
-
end
|
24
|
-
|
25
|
-
def session_model
|
26
|
-
Core::Models::Authentication::Session
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Core
|
2
|
-
module Models
|
3
|
-
module OAuth
|
4
|
-
# A refresh token is used when an access token is expired, to get a new one. It is then recreated for the next expiration.
|
5
|
-
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
6
|
-
class RefreshToken
|
7
|
-
include Mongoid::Document
|
8
|
-
include Mongoid::Timestamps
|
9
|
-
|
10
|
-
store_in collection: 'oauth_refresh_tokens'
|
11
|
-
|
12
|
-
# @!attribute [rw] value
|
13
|
-
# @return [String] the value of the token, returned to the application when built.
|
14
|
-
field :value, type: String, default: ->{ SecureRandom.hex }
|
15
|
-
# @!attribute [rw] used_at
|
16
|
-
# @return [DateTime] the date and time at which this refresh token has been useds to create a new access token.
|
17
|
-
field :used_at, type: DateTime, default: nil
|
18
|
-
|
19
|
-
# @!attribute [rw] authorization
|
20
|
-
# @return [Core::Models::OAuth::Authorization] the authorization code that issued this token to the application for this user.
|
21
|
-
belongs_to :token, class_name: 'Core::Models::OAuth::AccessToken', inverse_of: :refresh_token
|
22
|
-
|
23
|
-
def used?
|
24
|
-
!used_at.nil? && used_at < DateTime.now
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Core
|
2
|
-
module Models
|
3
|
-
module Permissions
|
4
|
-
# A category of rights regroups one or several rights for convenience purposes.
|
5
|
-
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
6
|
-
class Category
|
7
|
-
include Mongoid::Document
|
8
|
-
include Mongoid::Timestamps
|
9
|
-
include Core::Models::Concerns::Sluggable
|
10
|
-
|
11
|
-
store_in collection: 'categories'
|
12
|
-
|
13
|
-
has_many :rights, class_name: 'Core::Models::Permissions::Right', inverse_of: :category
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module Core
|
2
|
-
module Models
|
3
|
-
module Permissions
|
4
|
-
# A group gathers one or several users to give them the same rights for conviniency purposes.
|
5
|
-
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
6
|
-
class Group
|
7
|
-
include Mongoid::Document
|
8
|
-
include Mongoid::Timestamps
|
9
|
-
include Core::Models::Concerns::Sluggable
|
10
|
-
|
11
|
-
store_in collection: 'groups'
|
12
|
-
|
13
|
-
# @!attribute [rw] is_default
|
14
|
-
# @return [Boolean] a boolean indicating whether this group is given when a new user registered or not.
|
15
|
-
field :is_default, type: Mongoid::Boolean, default: false
|
16
|
-
# @!attribute [rw] is_superuser
|
17
|
-
# @return [Boolean] a boolean indicating whether this group should have access to all groups and rights or not.
|
18
|
-
field :is_superuser, type: Mongoid::Boolean, default: false
|
19
|
-
|
20
|
-
# @!attribute [rw] accounts
|
21
|
-
# @return [Array<Core::Models::Account>] the accounts having the rights granted by this group.
|
22
|
-
has_and_belongs_to_many :accounts, class_name: 'Core::Models::Account', inverse_of: :groups
|
23
|
-
# @!attribute [rw] rights
|
24
|
-
# @return [Array<Core::Models::Permissions::Right>] the rights granted by belonging to this group.
|
25
|
-
has_and_belongs_to_many :rights, class_name: 'Core::Models::Permissions::Right', inverse_of: :groups
|
26
|
-
# @!attribute [rw] routes
|
27
|
-
# @return [Array<Core::Models::Monitoring::Route>] the routes this group can access in the API.
|
28
|
-
has_and_belongs_to_many :routes, class_name: 'Core::Models::Permissions::Route', inverse_of: :groups
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Core
|
2
|
-
module Models
|
3
|
-
module Permissions
|
4
|
-
# A right is the access to one or several features in the application. It's applied to a group, and transitively to an account.
|
5
|
-
# @author Vincent Courtois <courtois;vincent@outlook.com>
|
6
|
-
class Right
|
7
|
-
include Mongoid::Document
|
8
|
-
include Mongoid::Timestamps
|
9
|
-
include Core::Models::Concerns::Sluggable
|
10
|
-
|
11
|
-
store_in collection: 'rights'
|
12
|
-
|
13
|
-
# @!attribute [rw] groups
|
14
|
-
# @return [Array<Core::Models::Permissions::Group>] the groups granted with the permission to access features opened by this right.
|
15
|
-
has_and_belongs_to_many :groups, class_name: 'Core::Models::Permissions::Group', inverse_of: :rights
|
16
|
-
|
17
|
-
belongs_to :category, class_name: 'Core::Models::Permissions::Category', inverse_of: :rights
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module Core
|
2
|
-
module Models
|
3
|
-
module Permissions
|
4
|
-
# A route is an endpoint accessible in the API. Each route has to have an associated endpoint in the deployed instances.
|
5
|
-
# @param Vincent Courtois <courtois.vincent@outlook.com>
|
6
|
-
class Route
|
7
|
-
include Mongoid::Document
|
8
|
-
include Mongoid::Timestamps
|
9
|
-
include Core::Models::Concerns::Premiumable
|
10
|
-
include Core::Models::Concerns::Activable
|
11
|
-
|
12
|
-
store_in collection: 'routes'
|
13
|
-
|
14
|
-
# @!attribute [rw] path
|
15
|
-
# @return [String] the path (URI) of the route in the API.
|
16
|
-
field :path, type: String, default: '/'
|
17
|
-
# @!attribute [rw] verb
|
18
|
-
# @return [String] the verb (HTTP method) of this route in the API.
|
19
|
-
field :verb, type: String, default: 'get'
|
20
|
-
# @!attribute [rw] authenticated
|
21
|
-
# @return [Boolean] if true, the session_id is needed for this route, if false it is not.
|
22
|
-
field :authenticated, type: Mongoid::Boolean, default: true
|
23
|
-
# @!attribute [rw] groups
|
24
|
-
# @return [Array<Core::Models::Permissions::Group>] the groups having permission to access this route.
|
25
|
-
has_and_belongs_to_many :groups, class_name: 'Core::Models::Permissions::Group', inverse_of: :groups
|
26
|
-
|
27
|
-
validates :path,
|
28
|
-
format: {with: /\A(\/|((\/:?[a-zA-Z0-9_]+)+))\z/, message: 'pattern', if: :path?}
|
29
|
-
|
30
|
-
validates :verb,
|
31
|
-
inclusion: {message: 'unknown', in: ['get', 'post', 'put', 'delete', 'patch', 'option']}
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module Core
|
2
|
-
module Models
|
3
|
-
# This module holds the logic for all the classes concerning the permissions abd rights for the user.
|
4
|
-
# A permission is restricting the access to one or several features to the users having it.
|
5
|
-
# @author Vincent Courtois <courtois.vincent@outlook.com>
|
6
|
-
module Permissions
|
7
|
-
autoload :Right , 'core/models/permissions/right'
|
8
|
-
autoload :Group , 'core/models/permissions/group'
|
9
|
-
autoload :Category, 'core/models/permissions/category'
|
10
|
-
autoload :Route , 'core/models/permissions/route'
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|