virtuatable-core 1.4.0 → 1.6.0.dev1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb7485c8bb6e781dcf4b6d3299d3065769a4556e01421fba08eb2404a3d982a5
4
- data.tar.gz: 281cce31ddad58a7ffb44e8fd78de1bdefdc5d5f1f2f6b53f8a89e9125e8792e
3
+ metadata.gz: d04349e236702f20e0c4a2542187eb4d1a0ef59d6ff4b44f90ff7d1a2484f783
4
+ data.tar.gz: f1e41d1f2b0a89c2851d617c2642222351a96cda77f0baeefed1a67eb98150d5
5
5
  SHA512:
6
- metadata.gz: 2df4695bf1450c3c99cc3d86e5cee1cc91050275b6f54e40c587553376e93bd9752aac1683692a556c3265c16bab9fb06daa530b30645b3b4fdb6748a5e741ec
7
- data.tar.gz: eee4af9a5591e1ef3fa5a7a5a1071791680a02af442df91bcfb03d5f4f63cc334ea6fe78edfbfb848a358af3d0df9327fb13429b0d104637e9622ae71c568d64
6
+ metadata.gz: d1a87bca549bdc10d5f9dbee7c483051a0af0d7ec0cfb5594051a64b617e07fe8e32f8fcb7231398a078e4ca30d4d51e3434eb703bbdf5f5790474da897d8c6d
7
+ data.tar.gz: 910921c135060a8b78065c146e41ccc6e13f32e24ed75bafd4b3f507058ccb22a47c88f75ecfff991831c65382e1c56c3971124b07855e7e7513242871eec184
@@ -0,0 +1,9 @@
1
+ module Core
2
+ module Decorators
3
+ class Account < Core::Decorators::Base
4
+ def has_password?(password)
5
+ BCrypt::Password.new(object.password_digest) == password
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ module Core
2
+ module Decorators
3
+ class Application < Core::Decorators::Base
4
+ def to_h
5
+ {
6
+ client_id: client_id,
7
+ name: name,
8
+ premium: premium
9
+ }
10
+ end
11
+
12
+ def has_secret?(secret)
13
+ object.client_secret == secret
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module Core
2
+ module Decorators
3
+ class Base < Draper::Decorator
4
+ delegate_all
5
+
6
+ def id
7
+ object.id.to_s
8
+ end
9
+
10
+ def to_json
11
+ to_h.to_json
12
+ end
13
+ end
14
+ end
15
+ end
@@ -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
@@ -0,0 +1,13 @@
1
+ module Core
2
+ module Decorators
3
+ class Session < Core::Decorators::Base
4
+ def to_h
5
+ {
6
+ token: token,
7
+ account_id: account.id.to_s,
8
+ created_at: created_at.iso8601
9
+ }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ module Core
2
+ module Decorators
3
+ class Token < Core::Decorators::Base
4
+
5
+ def to_h
6
+ {
7
+ token: value
8
+ }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module Core
2
+ module Decorators
3
+ autoload :Account, 'core/decorators/account'
4
+ autoload :Application, 'core/decorators/application'
5
+ autoload :Base, 'core/decorators/base'
6
+ autoload :Campaign, 'core/decorators/campaign'
7
+ autoload :Session, 'core/decorators/session'
8
+ autoload :Token, 'core/decorators/token'
9
+ end
10
+ end
@@ -13,9 +13,9 @@ module Core
13
13
  # @param verb [String] the HTTP method for the route.
14
14
  # @param path [String] the whole URI with parameters for the route.
15
15
  # @param options [Hash] the additional options for the route.
16
- def api_route(verb, path, premium: false, scopes: ['data::usage'], &block)
16
+ def api_route(verb, path, premium: false, scopes: [], &block)
17
17
  send(verb, path) do
18
- scope_objects = fetch_scopes(scopes)
18
+ scope_objects = fetch_scopes(scopes + ['data::usage'])
19
19
  appli = application(premium: premium)
20
20
  check_app_scopes(appli, scope_objects)
21
21
  check_token_scopes(token, scope_objects)
@@ -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 dictionary.
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| enhanced_h(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, enhanced_json(item)
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, enhanced_json(item)
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
@@ -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
- # A refresh token is attached to each and every refresh token so that it can be used to deliver a new access token.
26
- # @!attribute [rx] refresh_token
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
- # Premium applications (our applications) have all the rights on the API.
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: 86400
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
@@ -1,16 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Core
2
4
  module Services
5
+ # Service managing user accounts.
6
+ # @author Vincent Courtois <courtois.vincent@outlook.com>
3
7
  class Accounts < Core::Services::Base
4
- def get_by_username(username)
8
+ include Singleton
9
+
10
+ # Gets an account given the nickname of the user.
11
+ #
12
+ # @param username [String] the nickname the user chose at account creation.
13
+ # @return [Core::Models::Account] the account linked to this username.
14
+ #
15
+ # @raise [Core::Helpers::Errors::BadRequest] if the username is not given.
16
+ # @raise [Core::Helpers::Errors::NotFound] if the username does not exist.
17
+ def get_by_username(username: nil, **ignored)
18
+ require_parameters username: username
5
19
  account = Core::Models::Account.find_by(username: username)
6
- if account.nil?
7
- raise Core::Helpers::Errors::NotFound.new(
8
- field: 'username',
9
- error: 'unknown'
10
- )
11
- end
20
+ raise unknown_err(field: 'username') if account.nil?
21
+
22
+ Core::Decorators::Account.new(account)
23
+ end
24
+
25
+ # Gets and authenticates an account using its credentials.
26
+ #
27
+ # @param username [String] the nickname the user chose at account creation.
28
+ # @param password [String] the password, in clear, to identify the user with.
29
+ # @return [Core::Decorators::Account] the account if it is correctly found.
30
+ #
31
+ # @raise [Core::Helpers::Errors::BadRequest] if a needed parameter is not given.
32
+ # @raise [Core::Helpers::Errors::NotFound] if a user with this nickname is not found.
33
+ # @raise [Core::Helpers::Errors::Forbidden] if the password does not match the user.
34
+ def get_by_credentials(username: nil, password: nil, **ignored)
35
+ require_parameters password: password
36
+ account = get_by_username(username: username)
37
+
38
+ raise forbidden_err(field: 'password', error: 'wrong') unless account.has_password?(password)
39
+
12
40
  account
13
41
  end
14
42
  end
15
43
  end
16
- end
44
+ 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') unless application.has_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
+ Core::Decorators::Application.new(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
@@ -1,11 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Core
2
4
  module Services
3
5
  class Base
4
- attr_reader :services
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 initialize(registry)
7
- @services = registry
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
- attr_reader :accounts, :sessions
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.new(self)
11
- @sessions = Core::Services::Sessions.new(self)
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
 
@@ -6,6 +8,8 @@ module Core
6
8
  # Service concerning sessions (log in and log out)
7
9
  # @author Vincent Courtois <courtois.vincent@outlook.com>
8
10
  class Sessions < Core::Services::Base
11
+ include Singleton
12
+
9
13
  # Creates a new session from the given user credentials. IT will
10
14
  # * check that the user exists in the database
11
15
  # * check that the password matches the user encrypted password
@@ -15,19 +19,31 @@ module Core
15
19
  # @param username [string] the name of the user trying to log in
16
20
  # @param password [string] the password the user has provided
17
21
  # @return [Core::Models::Authentication::Session] the login session
18
- def create(username, password)
19
- account = services.accounts.get_by_username(username)
20
- if BCrypt::Password.new(account.password_digest) != password
21
- raise Core::Helpers::Errors::Forbidden.new(
22
- field: 'password',
23
- error: 'wrong'
24
- )
25
- end
26
- return Core::Models::Authentication::Session.create(
22
+ def create_from_credentials(username: nil, password: nil, **ignored)
23
+ account = Core.svc.accounts.get_by_credentials(
24
+ username: username,
25
+ password: password
26
+ )
27
+ session = Core::Models::Authentication::Session.create(
27
28
  account: account,
28
29
  token: SecureRandom.uuid
29
30
  )
30
31
  end
32
+
33
+ # Gets the session by its unique identifier.
34
+ #
35
+ # @param session_id [String] the unique identifier of the session you're searching.
36
+ # @return [Core::Decorators::Session] the decorated session to display in the API.
37
+ #
38
+ # @raise [Core::Helpers::Errors::BadRequest] if the session ID is not given or nil
39
+ # @raise [Core::Helpers::Errors::NotFound] if no session with its ID exist in the database.
40
+ def get_by_id(session_id: nil, **ignored)
41
+ require_parameters session_id: session_id
42
+ session = Core::Models::Authentication::Session.find_by(token: session_id)
43
+ raise unknown_err(field: 'session_id') if session.nil?
44
+
45
+ Core::Decorators::Session.new(session)
46
+ end
31
47
  end
32
48
  end
33
- end
49
+ 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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Core
4
- VERSION = '1.4.0'
4
+ VERSION = '1.6.0.dev1'
5
5
  end
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.0
4
+ version: 1.6.0.dev1
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-05-08 00:00:00.000000000 Z
11
+ date: 2022-05-19 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,13 @@ 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/account.rb
304
+ - lib/core/decorators/application.rb
305
+ - lib/core/decorators/base.rb
306
+ - lib/core/decorators/campaign.rb
307
+ - lib/core/decorators/session.rb
308
+ - lib/core/decorators/token.rb
288
309
  - lib/core/helpers.rb
289
310
  - lib/core/helpers/accounts.rb
290
311
  - lib/core/helpers/applications.rb
@@ -332,14 +353,17 @@ files:
332
353
  - lib/core/models/oauth/access_token.rb
333
354
  - lib/core/models/oauth/application.rb
334
355
  - lib/core/models/oauth/authorization.rb
335
- - lib/core/models/oauth/refresh_token.rb
336
356
  - lib/core/models/oauth/scope.rb
337
357
  - lib/core/models/ruleset.rb
338
358
  - lib/core/services.rb
339
359
  - lib/core/services/accounts.rb
360
+ - lib/core/services/applications.rb
361
+ - lib/core/services/authorizations.rb
340
362
  - lib/core/services/base.rb
363
+ - lib/core/services/campaigns.rb
341
364
  - lib/core/services/registry.rb
342
365
  - lib/core/services/sessions.rb
366
+ - lib/core/services/tokens.rb
343
367
  - lib/core/version.rb
344
368
  homepage: https://rubygems.org/gems/virtuatable-core
345
369
  licenses:
@@ -356,9 +380,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
356
380
  version: '0'
357
381
  required_rubygems_version: !ruby/object:Gem::Requirement
358
382
  requirements:
359
- - - ">="
383
+ - - ">"
360
384
  - !ruby/object:Gem::Version
361
- version: '0'
385
+ version: 1.3.1
362
386
  requirements: []
363
387
  rubygems_version: 3.2.3
364
388
  signing_key:
@@ -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