virtuatable-core 1.3.1 → 1.6.0.dev0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|