virtuatable-core 1.4.0 → 1.6.0.dev1

Sign up to get free protection for your applications and to get access to all the features.
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