morpho 0.3.4 → 1.0.0

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/app/api/morpho/entities/authentication_token.rb +9 -0
  3. data/app/api/morpho/entities/credentials.rb +8 -0
  4. data/app/api/morpho/entities/external.rb +10 -0
  5. data/app/api/morpho/entities/message.rb +7 -0
  6. data/app/api/morpho/entities/refresh_token.rb +7 -0
  7. data/app/api/morpho/entities/user_email.rb +7 -0
  8. data/app/api/morpho/entities/user_sign_up.rb +3 -3
  9. data/app/api/morpho/helpers/http_responses.rb +54 -18
  10. data/app/api/morpho/helpers/jwt_utils.rb +16 -25
  11. data/app/api/morpho/resources/activations.rb +22 -11
  12. data/app/api/morpho/resources/externals.rb +15 -6
  13. data/app/api/morpho/resources/hello.rb +36 -0
  14. data/app/api/morpho/resources/passwords.rb +23 -8
  15. data/app/api/morpho/resources/tokens.rb +45 -10
  16. data/app/api/morpho/resources/unlocks.rb +22 -11
  17. data/app/api/morpho/resources/users.rb +19 -4
  18. data/app/concepts/morpho/user/contract/activate.rb +8 -0
  19. data/app/concepts/morpho/user/contract/external_sign_in.rb +14 -0
  20. data/app/concepts/morpho/user/contract/refresh_token.rb +8 -0
  21. data/app/concepts/morpho/user/contract/reset_password.rb +8 -0
  22. data/app/concepts/morpho/user/contract/sign_in.rb +10 -0
  23. data/app/concepts/morpho/user/contract/sign_up.rb +14 -0
  24. data/app/concepts/morpho/user/contract/unlock.rb +8 -0
  25. data/app/concepts/morpho/user/operation/activate.rb +45 -0
  26. data/app/concepts/morpho/user/operation/external_sign_in.rb +82 -0
  27. data/app/concepts/morpho/user/operation/refresh_token.rb +35 -0
  28. data/app/concepts/morpho/user/operation/reset_password.rb +49 -0
  29. data/app/concepts/morpho/user/operation/sign_in.rb +71 -0
  30. data/app/concepts/morpho/user/operation/sign_up.rb +36 -0
  31. data/app/concepts/morpho/user/operation/unlock.rb +45 -0
  32. data/app/models/morpho/user.rb +5 -3
  33. data/app/services/morpho/jwt/authentication_token.rb +11 -0
  34. data/app/services/morpho/jwt/decode.rb +11 -0
  35. data/app/services/morpho/jwt/encode.rb +11 -0
  36. data/app/services/morpho/jwt/payload.rb +11 -0
  37. data/app/services/morpho/jwt/token.rb +13 -0
  38. data/app/views/layouts/morpho/application.html.erb +1 -1
  39. data/config/initializers/grape_swagger.rb +1 -0
  40. data/config/locales/morpho.en.yml +2 -1
  41. data/config/locales/morpho.es.yml +2 -1
  42. data/lib/generators/morpho/install/install_generator.rb +1 -0
  43. data/lib/generators/morpho/install/templates/app/api/morpho/api.rb +1 -0
  44. data/lib/generators/morpho/install/templates/config/initializers/morpho.rb +4 -2
  45. data/lib/morpho/cipher.rb +2 -2
  46. data/lib/morpho/configurations/mailer.rb +2 -2
  47. data/lib/morpho/grape/data_parser.rb +35 -0
  48. data/lib/morpho/grape/data_wrapper.rb +25 -0
  49. data/lib/morpho/loader.rb +4 -1
  50. data/lib/morpho/version.rb +1 -1
  51. data/lib/morpho.rb +2 -0
  52. metadata +97 -38
  53. data/app/api/morpho/entities/sign_in/authentication_token.rb +0 -11
  54. data/app/api/morpho/entities/sign_in/credentials.rb +0 -10
  55. data/app/api/morpho/entities/sign_in/external.rb +0 -12
  56. data/app/api/morpho/entities/sign_in/refresh_token.rb +0 -9
  57. data/app/api/morpho/entities/sign_in/success.rb +0 -9
  58. data/app/api/morpho/helpers/user_activation.rb +0 -11
  59. data/app/api/morpho/helpers/user_external_login.rb +0 -53
  60. data/app/api/morpho/helpers/user_login.rb +0 -42
  61. data/app/api/morpho/helpers/user_password_reset.rb +0 -11
  62. data/app/api/morpho/helpers/user_refresh_authentication_token.rb +0 -24
  63. data/app/api/morpho/helpers/user_registration.rb +0 -17
  64. data/app/api/morpho/helpers/user_unlock.rb +0 -11
@@ -0,0 +1,45 @@
1
+ module Morpho
2
+ class User::Operation::Activate < Trailblazer::Operation
3
+ step :validate
4
+ fail :not_valid, fail_fast: true
5
+ step :find
6
+ fail :not_found, fail_fast: true
7
+ step :check
8
+ fail :not_allowed, fail_fast: true
9
+ step :activation_email
10
+ fail :not_delivered, fail_fast: true
11
+
12
+ def validate (options, **)
13
+ options['contract'] = Morpho::User::Contract::Activate.new(OpenStruct.new)
14
+ options['contract'].validate(options['data'])
15
+ end
16
+
17
+ def find (options, **)
18
+ options['model'] = Morpho::User.find_by(email: options['data']['email'])
19
+ end
20
+
21
+ def check (options, **)
22
+ !options['model'].active?
23
+ end
24
+
25
+ def activation_email (options, **)
26
+ options['model'].resend_activation_needed_email!
27
+ end
28
+
29
+ def not_valid (options, **)
30
+ options['error'] = :not_valid
31
+ end
32
+
33
+ def not_found (options, **)
34
+ options['error'] = :not_found
35
+ end
36
+
37
+ def not_allowed (options, **)
38
+ options['error'] = :not_allowed
39
+ end
40
+
41
+ def not_delivered (options, **)
42
+ options['error'] = :not_delivered
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,82 @@
1
+ module Morpho
2
+ class User::Operation::ExternalSignIn < Trailblazer::Operation
3
+ step :validate
4
+ fail :not_valid, fail_fast: true
5
+ pass :find_authentication
6
+ pass :find_user
7
+ pass :sign_in
8
+ pass :register
9
+ pass :sign_up
10
+ step :generate_refresh_token
11
+ step :register_last_login_activity
12
+ step :authentication_token
13
+
14
+ def validate (options, **)
15
+ options['contract'] = Morpho::User::Contract::ExternalSignIn.new(OpenStruct.new)
16
+ options['contract'].validate(options['data'])
17
+ end
18
+
19
+ def find_authentication (options, **)
20
+ options['authentication.model'] = Morpho::Authentication.find_by(
21
+ uid: options['data']['uid'],
22
+ provider: options['data']['provider']
23
+ )
24
+ end
25
+
26
+ def find_user (options, **)
27
+ options['user.model'] = Morpho::User.find_by(email: options['data']['email'])
28
+ end
29
+
30
+ def sign_in (options, **)
31
+ if options['authentication.model']
32
+ options['user.model'] = options['authentication.model'].user
33
+ end
34
+ end
35
+
36
+ def register (options, **)
37
+ if options['user.model'] && !options['authentication.model']
38
+ provider = options['data']['provider'].downcase
39
+
40
+ options['user.model'].add_provider_to_user(provider, options['data']['uid'])
41
+ end
42
+ end
43
+
44
+ def sign_up (options, **)
45
+ if !options['user.model'] && !options['authentication.model']
46
+ provider = options['data']['provider'].downcase
47
+
48
+ options['user.model'] = Morpho::User.create_from_provider(provider, options['data']['uid'], {
49
+ email: options['data']['email']
50
+ })
51
+ end
52
+ end
53
+
54
+ def generate_refresh_token (options, **)
55
+ options['user.model'].generate_refresh_token!
56
+ end
57
+
58
+ def register_last_login_activity (options, **)
59
+ options['user.model'].register_last_login_activity!(options['ip'])
60
+ end
61
+
62
+ def not_valid (options, **)
63
+ options['error'] = :not_valid
64
+ end
65
+
66
+ def not_signed_in (options, **)
67
+ options['error'] = :not_signed_in
68
+ end
69
+
70
+ def not_registered (options, **)
71
+ options['error'] = :not_registered
72
+ end
73
+
74
+ def not_signed_up (options, **)
75
+ options['error'] = :not_signed_up
76
+ end
77
+
78
+ def authentication_token (options, **)
79
+ options['token'] = Morpho::JWT::Payload.new(options['user.model'])
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,35 @@
1
+ module Morpho
2
+ class User::Operation::RefreshToken < Trailblazer::Operation
3
+ step :validate
4
+ fail :not_valid, fail_fast: true
5
+ step :find
6
+ fail :not_found, fail_fast: true
7
+ step :generate_refresh_token
8
+ step :authentication_token
9
+
10
+ def validate (options, **)
11
+ options['contract'] = Morpho::User::Contract::RefreshToken.new(OpenStruct.new)
12
+ options['contract'].validate(options['data'])
13
+ end
14
+
15
+ def find (options, **)
16
+ options['model'] = Morpho::User.find_by(refresh_token: options['data']['refresh_token'])
17
+ end
18
+
19
+ def generate_refresh_token (options, **)
20
+ options['model'].generate_refresh_token!
21
+ end
22
+
23
+ def not_valid (options, **)
24
+ options['error'] = :not_valid
25
+ end
26
+
27
+ def not_found (options, **)
28
+ options['error'] = :not_found
29
+ end
30
+
31
+ def authentication_token (options, **)
32
+ options['token'] = Morpho::JWT::Payload.new(options['model'])
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,49 @@
1
+ module Morpho
2
+ class User::Operation::ResetPassword < Trailblazer::Operation
3
+ step :validate
4
+ fail :not_valid, fail_fast: true
5
+ step :find
6
+ fail :not_found, fail_fast: true
7
+ step :check
8
+ fail :not_allowed, fail_fast: true
9
+ step :reset_password_email
10
+ fail :not_delivered, fail_fast: true
11
+
12
+ def validate (options, **)
13
+ options['contract'] = Morpho::User::Contract::ResetPassword.new(OpenStruct.new)
14
+ options['contract'].validate(options['data'])
15
+ end
16
+
17
+ def find (options, **)
18
+ options['model'] = Morpho::User.find_by(email: options['data']['email'])
19
+ end
20
+
21
+ def check (options, **)
22
+ !options['model'].external?
23
+ end
24
+
25
+ def reset_password_email (options, **)
26
+ options['model'].deliver_reset_password_instructions!
27
+ end
28
+
29
+ def not_valid (options, **)
30
+ options['error'] = :not_valid
31
+ end
32
+
33
+ def not_found (options, **)
34
+ options['error'] = :not_found
35
+ end
36
+
37
+ def not_allowed (options, **)
38
+ options['error'] = :not_allowed
39
+ end
40
+
41
+ def not_delivered (options, **)
42
+ options['error'] = :not_delivered
43
+ end
44
+
45
+ def render (options, **)
46
+ options['model']
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,71 @@
1
+ module Morpho
2
+ class User::Operation::SignIn < Trailblazer::Operation
3
+ step :validate
4
+ fail :not_valid, fail_fast: true
5
+ step :find
6
+ fail :not_found, fail_fast: true
7
+ step :check_active
8
+ fail :not_active, fail_fast: true
9
+ step :check_unlocked
10
+ fail :locked, fail_fast: true
11
+ step :check_password
12
+ fail :wrong_password, fail_fast: true
13
+ step :generate_refresh_token
14
+ step :register_last_login_activity
15
+ step :authentication_token
16
+
17
+ def validate (options, **)
18
+ options['contract'] = Morpho::User::Contract::SignIn.new(OpenStruct.new)
19
+ options['contract'].validate(options['data'])
20
+ end
21
+
22
+ def find (options, **)
23
+ options['model'] = Morpho::User.find_by(email: options['data']['email'])
24
+ end
25
+
26
+ def check_active (options, **)
27
+ options['model'].active?
28
+ end
29
+
30
+ def check_unlocked (options, **)
31
+ options['model'].unlocked?
32
+ end
33
+
34
+ def check_password (options, **)
35
+ options['model'].valid_password?(options['data']['password'])
36
+ end
37
+
38
+ def generate_refresh_token (options, **)
39
+ options['model'].generate_refresh_token!
40
+ end
41
+
42
+ def register_last_login_activity (options, **)
43
+ options['model'].register_last_login_activity!(options['ip'])
44
+ end
45
+
46
+ def not_valid (options, **)
47
+ options['error'] = :not_valid
48
+ end
49
+
50
+ def not_found (options, **)
51
+ options['error'] = :not_found
52
+ end
53
+
54
+ def not_active (options, **)
55
+ options['error'] = :not_active
56
+ end
57
+
58
+ def locked (options, **)
59
+ options['error'] = :locked
60
+ end
61
+
62
+ def wrong_password (options, **)
63
+ options['model'].register_failed_login!
64
+ options['error'] = :wrong_password
65
+ end
66
+
67
+ def authentication_token (options, **)
68
+ options['token'] = Morpho::JWT::Payload.new(options['model'])
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,36 @@
1
+ module Morpho
2
+ class User::Operation::SignUp < Trailblazer::Operation
3
+ step :validate
4
+ fail :not_valid, fail_fast: true
5
+ step :sync
6
+ fail :not_synced, fail_fast: true
7
+ step :save
8
+ fail :not_saved, fail_fast: true
9
+
10
+ def validate(options, **)
11
+ options['contract'] = Morpho::User::Contract::SignUp.new(Morpho::User.new)
12
+ options['contract'].validate(options['data'])
13
+ end
14
+
15
+ def sync(options, **)
16
+ options['contract'].sync
17
+ end
18
+
19
+ def save (options, **)
20
+ options['model'] = options['contract'].model
21
+ options['model'].save
22
+ end
23
+
24
+ def not_valid(options, **)
25
+ options['error'] = :not_valid
26
+ end
27
+
28
+ def not_synced(options, **)
29
+ options['error'] = :not_synced
30
+ end
31
+
32
+ def not_saved(options, **)
33
+ options['error'] = :not_saved
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,45 @@
1
+ module Morpho
2
+ class User::Operation::Unlock < Trailblazer::Operation
3
+ step :validate
4
+ fail :not_valid, fail_fast: true
5
+ step :find
6
+ fail :not_found, fail_fast: true
7
+ step :check
8
+ fail :not_allowed, fail_fast: true
9
+ step :unlock_token_email
10
+ fail :not_delivered, fail_fast: true
11
+
12
+ def validate (options, **)
13
+ options['contract'] = Morpho::User::Contract::Unlock.new(OpenStruct.new)
14
+ options['contract'].validate(options['data'])
15
+ end
16
+
17
+ def find (options, **)
18
+ options['model'] = Morpho::User.find_by(email: options['data']['email'])
19
+ end
20
+
21
+ def check (options, **)
22
+ options['model'].login_locked?
23
+ end
24
+
25
+ def unlock_token_email (options, **)
26
+ options['model'].resend_unlock_token_email!
27
+ end
28
+
29
+ def not_valid (options, **)
30
+ options['error'] = :not_valid
31
+ end
32
+
33
+ def not_found (options, **)
34
+ options['error'] = :not_found
35
+ end
36
+
37
+ def not_allowed (options, **)
38
+ options['error'] = :not_allowed
39
+ end
40
+
41
+ def not_delivered (options, **)
42
+ options['error'] = :not_delivered
43
+ end
44
+ end
45
+ end
@@ -1,17 +1,19 @@
1
1
  module Morpho
2
2
  class User < ApplicationRecord
3
+ include Morpho::Tokenable
3
4
  authenticates_with_sorcery!
4
5
 
5
6
  has_many :authentications, dependent: :destroy
6
7
  accepts_nested_attributes_for :authentications
7
8
 
8
- validates :email, uniqueness: true
9
- validates_email_format_of :email
10
-
11
9
  def active?
12
10
  self.activation_state == 'active'
13
11
  end
14
12
 
13
+ def unlocked?
14
+ !self.login_locked?
15
+ end
16
+
15
17
  def register_last_login_activity!(ip_address)
16
18
  self.set_last_login_at(Time.now)
17
19
  self.set_last_ip_address(ip_address)
@@ -0,0 +1,11 @@
1
+ module Morpho
2
+ class JWT::AuthenticationToken
3
+ def self.new(request)
4
+ if request.headers[Morpho.config.jwt.header].present?
5
+ request.headers[Morpho.config.jwt.header].split(' ').last
6
+ else
7
+ nil
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Morpho
2
+ class JWT::Decode
3
+ def self.new(token)
4
+ begin
5
+ Morpho::Cipher.jwt_decode(token)
6
+ rescue
7
+ nil
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Morpho
2
+ class JWT::Encode
3
+ def self.new(payload)
4
+ begin
5
+ Morpho::Cipher.jwt_encode(payload)
6
+ rescue
7
+ nil
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Morpho
2
+ class JWT::Payload
3
+ def self.new(user)
4
+ expires_at = Time.now.to_i + Morpho.config.jwt.expiration_time
5
+ issued_at = Time.now.to_i
6
+ token = Morpho::JWT::Encode.new({ exp: expires_at, iat: issued_at, email: user.email })
7
+
8
+ { authentication_token: token, expires_at: expires_at, refresh_token: user.refresh_token }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Morpho
2
+ class JWT::Token
3
+ def self.new(authentication_token)
4
+ begin
5
+ token = Morpho::JWT::Decode.new(authentication_token)
6
+
7
+ HashWithIndifferentAccess.new(token.first)
8
+ rescue
9
+ HashWithIndifferentAccess.new
10
+ end
11
+ end
12
+ end
13
+ end
@@ -5,7 +5,7 @@
5
5
  <%= csrf_meta_tags %>
6
6
  <%= csp_meta_tag %>
7
7
 
8
- <%= stylesheet_link_tag 'morpho/application', media: 'all' %>
8
+ <%= stylesheet_link_tag 'morpho/application', media: 'all' %>
9
9
  <%= javascript_include_tag 'morpho/application' %>
10
10
  </head>
11
11
  <body>
@@ -0,0 +1 @@
1
+ GrapeSwagger.model_parsers.register(Morpho::Grape::DataParser, Morpho::Grape::DataWrapper)
@@ -137,7 +137,8 @@ en:
137
137
  not_found: 'Not found'
138
138
  method_not_allowed: 'Method not allowed'
139
139
  unprocessable_entity: 'Unprocessable entity'
140
- unauthorized_detailed:
140
+ locked: 'Locked'
141
+ sign_in:
141
142
  unexistent: 'Email address does not belongs to a registered account'
142
143
  bad_credentials: 'User email and/or password is incorrect'
143
144
  unconfirmed: 'User account has not been confirmed'
@@ -137,7 +137,8 @@ es:
137
137
  not_found: 'No encontrado'
138
138
  method_not_allowed: 'Método no permitido'
139
139
  unprocessable_entity: 'Entidad no procesable'
140
- unauthorized_detailed:
140
+ locked: 'Bloqueado'
141
+ sign_in:
141
142
  unexistent: 'Correo electrónico no pertenece a un usuario registrado'
142
143
  bad_credentials: 'Correo electrónico y/o contraseña es incorrecto(a)'
143
144
  unconfirmed: 'Cuenta de usuario no ha sido confirmada'
@@ -4,5 +4,6 @@ class Morpho::InstallGenerator < Rails::Generators::Base
4
4
  def install
5
5
  copy_file 'config/initializers/morpho.rb', 'config/initializers/morpho.rb'
6
6
  copy_file 'app/api/morpho/api.rb', 'app/api/morpho/api.rb'
7
+ copy_file '.env', '.env'
7
8
  end
8
9
  end
@@ -4,6 +4,7 @@ module Morpho
4
4
  rescue_from :all
5
5
 
6
6
  mount Morpho::Resources::Users
7
+ mount Morpho::Resources::Externals
7
8
  mount Morpho::Resources::Tokens
8
9
  mount Morpho::Resources::Passwords
9
10
  mount Morpho::Resources::Unlocks
@@ -1,13 +1,15 @@
1
1
  Morpho.configure do |config|
2
2
  config.host = ENV.fetch('HOST', 'localhost:3000')
3
- config.host = ENV.fetch('PROTOCOL', 'http')
3
+ config.protocol = ENV.fetch('PROTOCOL', 'http')
4
4
  config.mailer.from = ENV.fetch('MAILER_FROM', 'no-reply@example.com')
5
5
  config.mailer.address = ENV.fetch('MAILER_ADDRESS', 'smtp.mailtrap.io')
6
6
  config.mailer.user_name = ENV.fetch('MAILER_USER_NAME', '')
7
7
  config.mailer.password = ENV.fetch('MAILER_PASSWORD', '')
8
8
  config.mailer.port = ENV.fetch('MAILER_PORT', 2525)
9
- config.mailer.authentication = ENV.fetch('MAILER_AUTHENTICATION').to_s.to_sym
9
+ config.mailer.authentication = ENV.fetch('MAILER_AUTHENTICATION', 'login')
10
10
  config.mailer.enable_starttls_auto = ENV.fetch('MAILER_ENABLE_STARTTLS_AUTO', false)
11
+ config.mailer.perform_deliveries = ENV.fetch('MAILER_PERFORM_DELIVERIES', false)
12
+ config.mailer.delivery_method = ENV.fetch('MAILER_DELIVER_METHOD', 'smtp')
11
13
  config.jwt.secret = ''
12
14
  config.jwt.algorithm = 'HS256'
13
15
  config.jwt.header = 'Authorization'
data/lib/morpho/cipher.rb CHANGED
@@ -3,11 +3,11 @@ module Morpho
3
3
  module_function
4
4
 
5
5
  def jwt_encode(payload, algorithm = Morpho.config.jwt.algorithm)
6
- JWT.encode(payload, Morpho.config.jwt.secret, algorithm)
6
+ ::JWT.encode(payload, Morpho.config.jwt.secret, algorithm)
7
7
  end
8
8
 
9
9
  def jwt_decode(token, algorithm = Morpho.config.jwt.algorithm)
10
- JWT.decode(token, Morpho.config.jwt.secret, true, algorithm: algorithm)
10
+ ::JWT.decode(token, Morpho.config.jwt.secret, true, algorithm: algorithm)
11
11
  end
12
12
  end
13
13
  end
@@ -12,8 +12,8 @@ module Morpho
12
12
  attr_accessor :delivery_method
13
13
 
14
14
  def initialize
15
- self.perform_deliveries = true
16
- self.delivery_method = :smtp
15
+ self.perform_deliveries = false
16
+ self.delivery_method = :test
17
17
  self.from = ''
18
18
  self.address = ''
19
19
  self.user_name = ''
@@ -0,0 +1,35 @@
1
+ module Morpho
2
+ module Grape
3
+ class DataParser
4
+ attr_reader :wrapper
5
+ attr_reader :endpoint
6
+
7
+ def initialize(wrapper, endpoint)
8
+ @wrapper = wrapper
9
+ @endpoint = endpoint
10
+ end
11
+
12
+ def call
13
+ memo = {}
14
+
15
+ name = endpoint.send(:expose_params_from_model, wrapper.model)
16
+
17
+ memo[wrapper.key] = if wrapper.is_array
18
+ {
19
+ type: :array,
20
+ items: {
21
+ '$ref' => "#/definitions/#{name}"
22
+ }
23
+ }
24
+ else
25
+ {
26
+ type: :object,
27
+ '$ref' => "#/definitions/#{name}"
28
+ }
29
+ end
30
+
31
+ memo
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,25 @@
1
+ module Morpho
2
+ module Grape
3
+ class DataWrapper
4
+ attr_reader :model
5
+ attr_reader :key
6
+ attr_reader :is_array
7
+ attr_reader :wrapper_name
8
+
9
+ def initialize(model, wrapper_name: nil, key: :data, is_array: false)
10
+ @model = model
11
+ @wrapper_name = wrapper_name
12
+ @key = key
13
+ @is_array = is_array
14
+ end
15
+
16
+ def ancestors
17
+ [DataWrapper]
18
+ end
19
+
20
+ def to_s
21
+ wrapper_name ? wrapper_name : "data_wrapper_#{object_id}"
22
+ end
23
+ end
24
+ end
25
+ end
data/lib/morpho/loader.rb CHANGED
@@ -9,4 +9,7 @@ require 'grape-entity'
9
9
  require 'grape-swagger'
10
10
  require 'grape-swagger/entity'
11
11
  require 'grape-swagger/representable'
12
- require 'rails-i18n'
12
+ require 'rails-i18n'
13
+ require 'reform'
14
+ require 'reform/rails'
15
+ require 'trailblazer/operation'
@@ -1,3 +1,3 @@
1
1
  module Morpho
2
- VERSION = '0.3.4'
2
+ VERSION = '1.0.0'
3
3
  end
data/lib/morpho.rb CHANGED
@@ -3,6 +3,8 @@ require 'morpho/engine'
3
3
  require 'morpho/cipher'
4
4
  require 'morpho/version'
5
5
  require 'morpho/configuration'
6
+ require 'morpho/grape/data_wrapper'
7
+ require 'morpho/grape/data_parser'
6
8
  require 'morpho/validators/contain_number_validator'
7
9
  require 'morpho/validators/contain_uppercase_validator'
8
10
  require 'morpho/validators/contain_symbol_validator'