virtuatable-core 1.0.0 → 1.2.1

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/lib/core/controllers/base.rb +63 -0
  3. data/lib/core/controllers.rb +9 -0
  4. data/lib/core/helpers/accounts.rb +22 -0
  5. data/lib/core/helpers/applications.rb +26 -0
  6. data/lib/core/helpers/declarators.rb +83 -0
  7. data/lib/core/helpers/errors/bad_request.rb +15 -0
  8. data/lib/core/helpers/errors/base.rb +36 -0
  9. data/lib/core/helpers/errors/forbidden.rb +15 -0
  10. data/lib/core/helpers/errors/not_found.rb +15 -0
  11. data/lib/core/helpers/errors.rb +48 -0
  12. data/lib/core/helpers/fields.rb +35 -0
  13. data/lib/core/helpers/parameters.rb +25 -0
  14. data/lib/core/helpers/responses.rb +50 -0
  15. data/lib/core/helpers/routes.rb +21 -0
  16. data/lib/core/helpers/sessions.rb +30 -0
  17. data/lib/core/helpers.rb +18 -0
  18. data/lib/core/models/account.rb +2 -5
  19. data/lib/core/models/authentication/session.rb +2 -0
  20. data/lib/core/models/campaign.rb +7 -1
  21. data/lib/core/models/campaigns/invitation.rb +2 -0
  22. data/lib/core/models/campaigns/map.rb +37 -0
  23. data/lib/core/models/campaigns/tag.rb +2 -0
  24. data/lib/core/models/campaigns/token.rb +31 -0
  25. data/lib/core/models/campaigns/token_position.rb +39 -0
  26. data/lib/core/models/campaigns.rb +3 -0
  27. data/lib/core/models/chatrooms/campaign.rb +3 -0
  28. data/lib/core/models/chatrooms/message.rb +3 -1
  29. data/lib/core/models/concerns/activable.rb +1 -1
  30. data/lib/core/models/concerns/premiumable.rb +1 -1
  31. data/lib/core/models/concerns.rb +0 -1
  32. data/lib/core/models/files/document.rb +2 -0
  33. data/lib/core/models/files/permission.rb +2 -0
  34. data/lib/core/models/notification.rb +1 -1
  35. data/lib/core/models/oauth/access_token.rb +2 -0
  36. data/lib/core/models/oauth/application.rb +3 -1
  37. data/lib/core/models/oauth/authorization.rb +2 -0
  38. data/lib/core/models/oauth/refresh_token.rb +2 -0
  39. data/lib/core/models/permissions/category.rb +2 -0
  40. data/lib/core/models/permissions/group.rb +5 -3
  41. data/lib/core/models/permissions/right.rb +2 -0
  42. data/lib/core/models/{monitoring → permissions}/route.rb +7 -16
  43. data/lib/core/models/permissions.rb +1 -0
  44. data/lib/core/models/ruleset.rb +2 -0
  45. data/lib/core/models.rb +0 -3
  46. data/lib/core/services/accounts.rb +16 -0
  47. data/lib/core/services/base.rb +11 -0
  48. data/lib/core/services/registry.rb +15 -0
  49. data/lib/core/services/sessions.rb +33 -0
  50. data/lib/core/services.rb +8 -0
  51. data/lib/core/version.rb +1 -1
  52. data/lib/core.rb +3 -0
  53. metadata +84 -43
  54. data/lib/core/models/chatrooms/conversation.rb +0 -9
  55. data/lib/core/models/chatrooms/membership.rb +0 -17
  56. data/lib/core/models/concerns/diagnosticable.rb +0 -24
  57. data/lib/core/models/decorators/errors/env_variable_missing.rb +0 -16
  58. data/lib/core/models/decorators/errors.rb +0 -11
  59. data/lib/core/models/decorators/gateway.rb +0 -111
  60. data/lib/core/models/factories/errors/gateway_not_found.rb +0 -16
  61. data/lib/core/models/factories/errors.rb +0 -11
  62. data/lib/core/models/factories.rb +0 -10
  63. data/lib/core/models/monitoring/service.rb +0 -33
  64. data/lib/core/models/monitoring.rb +0 -10
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Core
4
+ module Models
5
+ module Campaigns
6
+ # A token represents an player or a monster in the game. It can be placed as a TokenPosition.
7
+ # @author Vincent Courtois <courtois.vincent@outlook.com>
8
+ class Token
9
+ include Mongoid::Document
10
+ include Mongoid::Timestamps
11
+
12
+ store_in collection: 'tokens'
13
+
14
+ # @!attribute [rw] name
15
+ # @return [String] the name of the token that will be displayed on the map
16
+ field :name, type: String
17
+
18
+ # @!attribute [rw] campaign
19
+ # @return [Core::Models::Campaign] the campaign in which this token can be used
20
+ embedded_in :campaign, class_name: 'Core::Models::Campaign', inverse_of: :tokens
21
+ # @!attribute [rw] creator
22
+ # @return [Core::Models::Account] the account of the player creating the token
23
+ belongs_to :creator, class_name: 'Core::Models::Account', inverse_of: :tokens
24
+
25
+ validates :name,
26
+ presence: {message: 'required'},
27
+ length: {minimum: 6, message: 'minlength', if: :name?}
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Core
4
+ module Models
5
+ module Campaigns
6
+ # This is the instanciation of a token in one of the map of the campaign
7
+ # @author Vincent Courtois <courtois.vincent@outlook.com>
8
+ class TokenPosition
9
+ include Mongoid::Document
10
+ include Mongoid::Timestamps
11
+
12
+ store_in collection: 'token_positions'
13
+
14
+ # @!attribute [rw] x
15
+ # @return [Integer] the number of cells from the left before this token
16
+ field :x, type: Integer, default: 0
17
+ # @!attribute [rw] y
18
+ # @return [Integer] the number of cells from the top before this token
19
+ field :y, type: Integer, default: 0
20
+
21
+ # @!attribute [rw] map
22
+ # @return [Core::Models::Campaigns::Map] the map where this token is instanciated.
23
+ embedded_in :map, class_name: 'Core::Models::Campaigns::Map', inverse_of: :positions
24
+
25
+ # @!attribute [rw] token
26
+ # @return [Core::Models::Campaigns::Token] the source of the token, used to determine its appearance.
27
+ belongs_to :token, class_name: 'Core::Models::Campaigns::Token', inverse_of: :positions
28
+
29
+ validate :coordinates_bounds
30
+
31
+ # Validates that the coordinates of the token position are in the map bounds.
32
+ def coordinates_bounds
33
+ errors.add(:x, 'bounds') if map.nil? or x < 0 or x >= map.width
34
+ errors.add(:y, 'bounds') if map.nil? or y < 0 or y >= map.height
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -4,7 +4,10 @@ module Core
4
4
  # @author Vincent Courtois <courtois.vincent@outlook.com>
5
5
  module Campaigns
6
6
  autoload :Invitation, 'core/models/campaigns/invitation'
7
+ autoload :Map , 'core/models/campaigns/map'
7
8
  autoload :Tag , 'core/models/campaigns/tag'
9
+ autoload :Token , 'core/models/campaigns/token'
10
+ autoload :TokenPosition, 'core/models/campaigns/token_position'
8
11
  end
9
12
  end
10
13
  end
@@ -7,6 +7,9 @@ module Core
7
7
  # @!attribute [rw] campaign
8
8
  # @return [Core::Models::Campaign] the campaign the chatroom is linked to.
9
9
  embedded_in :campaign, class_name: 'Core::Models::Campaign', inverse_of: :chatroom
10
+ # @!attribute [rw] messages
11
+ # @return [Array<Core::Models::Chatrooms::Messages>] the messages said in this conversation
12
+ has_many :messages, class_name: 'Core::Models::Chatrooms::Message', inverse_of: :chatroom
10
13
  end
11
14
  end
12
15
  end
@@ -8,6 +8,8 @@ module Core
8
8
  include Mongoid::Timestamps
9
9
  include Core::Models::Concerns::Enumerable
10
10
 
11
+ store_in collection: 'chatrooms'
12
+
11
13
  # @!attribute [rw] type
12
14
  # @return [Symbol] the type of message (plain text or command) contained in the data, used to parse and display it.
13
15
  enum_field :type, [:text, :command], default: :text
@@ -19,7 +21,7 @@ module Core
19
21
  field :raw, type: String, default: ''
20
22
  # @!attribute [rw] deleted
21
23
  # @return [Boolean] TRUE if the message has been marked as deleted by its user, FALSE otherwise.
22
- field :deleted, type: Boolean, default: false
24
+ field :deleted, type: Mongoid::Boolean, default: false
23
25
 
24
26
  # @!attribute [rw] campaign
25
27
  # @return [Core::Models::Chatrooms::Campaign] the chatroom in which the message has been emitted.
@@ -9,7 +9,7 @@ module Core
9
9
  included do
10
10
  # @!attribute [rw] active
11
11
  # @return [Boolean] the active status of the instance, indicating if someone has deactivated it or not.
12
- field :active, type: Boolean, default: true
12
+ field :active, type: Mongoid::Boolean, default: true
13
13
 
14
14
  scope :active , ->{ where(active: true) }
15
15
  scope :inactive, ->{ where(active: false) }
@@ -9,7 +9,7 @@ module Core
9
9
  included do
10
10
  # @!attribute [rw] premium
11
11
  # @return [Boolean] TRUE if the entity is made to be accessible only to premiuma pplications, FALSE otherwise.
12
- field :premium, type: Boolean, default: false
12
+ field :premium, type: Mongoid::Boolean, default: false
13
13
  end
14
14
  end
15
15
  end
@@ -4,7 +4,6 @@ module Core
4
4
  # @author Vincent Courtois <courtois.vincent@outlook.com>
5
5
  module Concerns
6
6
  autoload :Activable , 'core/models/concerns/activable'
7
- autoload :Diagnosticable, 'core/models/concerns/diagnosticable'
8
7
  autoload :Enumerable , 'core/models/concerns/enumerable'
9
8
  autoload :Historizable , 'core/models/concerns/historizable'
10
9
  autoload :MimeTypable , 'core/models/concerns/mime_typable'
@@ -7,6 +7,8 @@ module Core
7
7
  include Mongoid::Document
8
8
  include Mongoid::Timestamps
9
9
 
10
+ store_in collection: 'documents'
11
+
10
12
  # @!attribute [rw] name
11
13
  # @return [String] the filename the user entered when uploading the file.
12
14
  field :name, type: String
@@ -8,6 +8,8 @@ module Core
8
8
  include Mongoid::Timestamps
9
9
  include Core::Models::Concerns::Enumerable
10
10
 
11
+ store_in collection: 'document_permissions'
12
+
11
13
  # @!attribute [rw] type
12
14
  # @return [Symbol] the type of permission granted (is the user able to delete the file ?)
13
15
  enum_field :type, [:read, :read_write]
@@ -11,7 +11,7 @@ module Core
11
11
  field :type, type: String, default: 'NOTIFICATIONS.DEFAULT'
12
12
  # @!attribute [rw] read
13
13
  # @return [Boolean] TRUE if the notification has been read (seen by the user), FALSE otherwise.
14
- field :read, type: Boolean, default: false
14
+ field :read, type: Mongoid::Boolean, default: false
15
15
  # @!attribute [rw] data
16
16
  # @return [Hash] the custom data that can be attached to this notification, for example for an invitation it can be the invited username.
17
17
  field :data, type: Hash, default: {}
@@ -8,6 +8,8 @@ module Core
8
8
  include Mongoid::Document
9
9
  include Mongoid::Timestamps
10
10
 
11
+ store_in collection: 'oauth_access_token'
12
+
11
13
  # @!attribute [rw] value
12
14
  # @return [String] the value of the token, returned to the application when built.
13
15
  field :value, type: String, default: ->{ SecureRandom.hex }
@@ -7,6 +7,8 @@ module Core
7
7
  include Mongoid::Document
8
8
  include Mongoid::Timestamps
9
9
 
10
+ store_in collection: 'oauth_application'
11
+
10
12
  # @!attribute [rw] name
11
13
  # @return [String] the unique name of the application, mainly used to identify and display it.
12
14
  field :name, type: String
@@ -15,7 +17,7 @@ module Core
15
17
  field :key, type: String, default: ->{ SecureRandom.hex }
16
18
  # @!attribute [rw] premium
17
19
  # @return [Boolean] a value indicating whether the application should automatically receive a token when an account is created, or not.
18
- field :premium, type: Boolean, default: false
20
+ field :premium, type: Mongoid::Boolean, default: false
19
21
  # @!attirbute [rw] redirect_uris
20
22
  # @return [Array<String>] the redirection URIs used for this application.
21
23
  field :redirect_uris, type: Array, default: []
@@ -10,6 +10,8 @@ module Core
10
10
  include Mongoid::Document
11
11
  include Mongoid::Timestamps
12
12
 
13
+ store_in collection: 'oauth_authorization'
14
+
13
15
  # @!attribute [rw] code
14
16
  # @return [String] the value corresponding to the authentication code in the RFC of OAuth2.0, kep for historic purpose.
15
17
  field :code, type: String, default: ->{ SecureRandom.hex }
@@ -7,6 +7,8 @@ module Core
7
7
  include Mongoid::Document
8
8
  include Mongoid::Timestamps
9
9
 
10
+ store_in collection: 'oauth_refresh_token'
11
+
10
12
  # @!attribute [rw] value
11
13
  # @return [String] the value of the token, returned to the application when built.
12
14
  field :value, type: String, default: ->{ SecureRandom.hex }
@@ -8,6 +8,8 @@ module Core
8
8
  include Mongoid::Timestamps
9
9
  include Core::Models::Concerns::Sluggable
10
10
 
11
+ store_in collection: 'categories'
12
+
11
13
  has_many :rights, class_name: 'Core::Models::Permissions::Right', inverse_of: :category
12
14
 
13
15
  make_sluggable 'category'
@@ -8,12 +8,14 @@ module Core
8
8
  include Mongoid::Timestamps
9
9
  include Core::Models::Concerns::Sluggable
10
10
 
11
+ store_in collection: 'groups'
12
+
11
13
  # @!attribute [rw] is_default
12
14
  # @return [Boolean] a boolean indicating whether this group is given when a new user registered or not.
13
- field :is_default, type: Boolean, default: false
15
+ field :is_default, type: Mongoid::Boolean, default: false
14
16
  # @!attribute [rw] is_superuser
15
17
  # @return [Boolean] a boolean indicating whether this group should have access to all groups and rights or not.
16
- field :is_superuser, type: Boolean, default: false
18
+ field :is_superuser, type: Mongoid::Boolean, default: false
17
19
 
18
20
  # @!attribute [rw] accounts
19
21
  # @return [Array<Core::Models::Account>] the accounts having the rights granted by this group.
@@ -23,7 +25,7 @@ module Core
23
25
  has_and_belongs_to_many :rights, class_name: 'Core::Models::Permissions::Right', inverse_of: :groups
24
26
  # @!attribute [rw] routes
25
27
  # @return [Array<Core::Models::Monitoring::Route>] the routes this group can access in the API.
26
- has_and_belongs_to_many :routes, class_name: 'Core::Models::Monitoring::Route', inverse_of: :groups
28
+ has_and_belongs_to_many :routes, class_name: 'Core::Models::Permissions::Route', inverse_of: :groups
27
29
 
28
30
  make_sluggable 'group'
29
31
  end
@@ -8,6 +8,8 @@ module Core
8
8
  include Mongoid::Timestamps
9
9
  include Core::Models::Concerns::Sluggable
10
10
 
11
+ store_in collection: 'rights'
12
+
11
13
  # @!attribute [rw] groups
12
14
  # @return [Array<Core::Models::Permissions::Group>] the groups granted with the permission to access features opened by this right.
13
15
  has_and_belongs_to_many :groups, class_name: 'Core::Models::Permissions::Group', inverse_of: :rights
@@ -1,7 +1,7 @@
1
1
  module Core
2
2
  module Models
3
- module Monitoring
4
- # A route is an endpoint accessible in a service. Each route has to have an associated endpoint in the deployed instances.
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
5
  # @param Vincent Courtois <courtois.vincent@outlook.com>
6
6
  class Route
7
7
  include Mongoid::Document
@@ -9,20 +9,17 @@ module Core
9
9
  include Core::Models::Concerns::Premiumable
10
10
  include Core::Models::Concerns::Activable
11
11
 
12
+ store_in collection: 'routes'
13
+
12
14
  # @!attribute [rw] path
13
- # @return [String] the path (URI) of the route in the service?
15
+ # @return [String] the path (URI) of the route in the API.
14
16
  field :path, type: String, default: '/'
15
17
  # @!attribute [rw] verb
16
- # @return [String] the verb (HTTP method) of this route in the service.
18
+ # @return [String] the verb (HTTP method) of this route in the API.
17
19
  field :verb, type: String, default: 'get'
18
20
  # @!attribute [rw] authenticated
19
21
  # @return [Boolean] if true, the session_id is needed for this route, if false it is not.
20
- field :authenticated, type: Boolean, default: true
21
-
22
- # @!attribute [rw] service
23
- # @return [Core::Models::Monitoring::Service] the service in which this route is declared.
24
- belongs_to :service, class_name: 'Core::Models::Monitoring::Service', inverse_of: :routes
25
-
22
+ field :authenticated, type: Mongoid::Boolean, default: true
26
23
  # @!attribute [rw] groups
27
24
  # @return [Array<Core::Models::Permissions::Group>] the groups having permission to access this route.
28
25
  has_and_belongs_to_many :groups, class_name: 'Core::Models::Permissions::Group', inverse_of: :groups
@@ -32,12 +29,6 @@ module Core
32
29
 
33
30
  validates :verb,
34
31
  inclusion: {message: 'unknown', in: ['get', 'post', 'put', 'delete', 'patch', 'option']}
35
-
36
- # Returns the complete path, enriched with the path of the service.
37
- # @return [String] the complete path to access this route from the outside.
38
- def complete_path
39
- path == '/' ? service.path : "#{service.path}#{path}"
40
- end
41
32
  end
42
33
  end
43
34
  end
@@ -7,6 +7,7 @@ module Core
7
7
  autoload :Right , 'core/models/permissions/right'
8
8
  autoload :Group , 'core/models/permissions/group'
9
9
  autoload :Category, 'core/models/permissions/category'
10
+ autoload :Route , 'core/models/permissions/route'
10
11
  end
11
12
  end
12
13
  end
@@ -6,6 +6,8 @@ module Core
6
6
  include Mongoid::Document
7
7
  include Mongoid::Timestamps
8
8
 
9
+ store_in collection: 'rulesets'
10
+
9
11
  # @!attribute [rw] name
10
12
  # @return [String] the name of the ruleset (eq. "Dungeons and Dragons 4th Edition")
11
13
  field :name, type: String
data/lib/core/models.rb CHANGED
@@ -15,13 +15,10 @@ module Core
15
15
  autoload :Chatrooms , 'core/models/chatrooms'
16
16
  autoload :Concerns , 'core/models/concerns'
17
17
  autoload :Event , 'core/models/event'
18
- autoload :Factories , 'core/models/factories'
19
18
  autoload :Files , 'core/models/files'
20
- autoload :Monitoring , 'core/models/monitoring'
21
19
  autoload :Notification , 'core/models/notification'
22
20
  autoload :OAuth , 'core/models/oauth'
23
21
  autoload :Permissions , 'core/models/permissions'
24
- autoload :Phone , 'core/models/phone'
25
22
  autoload :Ruleset , 'core/models/ruleset'
26
23
  end
27
24
  end
@@ -0,0 +1,16 @@
1
+ module Core
2
+ module Services
3
+ class Accounts < Core::Services::Base
4
+ def get_by_username(username)
5
+ 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
12
+ account
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Core
2
+ module Services
3
+ class Base
4
+ attr_reader :services
5
+
6
+ def initialize(registry)
7
+ @services = registry
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Core
2
+ module Services
3
+ # 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
5
+ class Registry
6
+
7
+ attr_reader :accounts, :sessions
8
+
9
+ def initialize
10
+ @accounts = Core::Services::Accounts.new(self)
11
+ @sessions = Core::Services::Sessions.new(self)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ require 'bcrypt'
2
+ require 'securerandom'
3
+
4
+ module Core
5
+ module Services
6
+ # Service concerning sessions (log in and log out)
7
+ # @author Vincent Courtois <courtois.vincent@outlook.com>
8
+ class Sessions < Core::Services::Base
9
+ # Creates a new session from the given user credentials. IT will
10
+ # * check that the user exists in the database
11
+ # * check that the password matches the user encrypted password
12
+ # If both steps are correctly passed, it will create and return
13
+ # a session object so that the user can have a login token.
14
+ #
15
+ # @param username [string] the name of the user trying to log in
16
+ # @param password [string] the password the user has provided
17
+ # @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(
27
+ account: account,
28
+ token: SecureRandom.uuid
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,8 @@
1
+ module Core
2
+ module Services
3
+ autoload :Accounts, 'core/services/accounts'
4
+ autoload :Base, 'core/services/base'
5
+ autoload :Registry, 'core/services/registry'
6
+ autoload :Sessions, 'core/services/sessions'
7
+ end
8
+ end
data/lib/core/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Core
2
- VERSION = '1.0.0'
2
+ VERSION = '1.2.1'
3
3
  end
data/lib/core.rb CHANGED
@@ -6,5 +6,8 @@ require 'dotenv/load'
6
6
  # Main module of the application, holding all the subsequent classes.
7
7
  # @author Vincent Courtois <courtois.vincent@outlook.com>
8
8
  module Core
9
+ autoload :Controllers, 'core/controllers'
10
+ autoload :Helpers, 'core/helpers'
9
11
  autoload :Models, 'core/models'
12
+ autoload :Services, 'core/services'
10
13
  end