api_engine_base 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +37 -6
  3. data/app/controllers/api_engine_base/admin_controller.rb +104 -0
  4. data/app/controllers/api_engine_base/application_controller.rb +45 -11
  5. data/app/controllers/api_engine_base/auth/plain_text_controller.rb +1 -1
  6. data/app/controllers/api_engine_base/user_controller.rb +49 -0
  7. data/app/models/api_engine_base/application_record.rb +38 -0
  8. data/app/models/user.rb +13 -4
  9. data/app/services/api_engine_base/README.md +49 -0
  10. data/app/services/api_engine_base/argument_validation/README.md +192 -0
  11. data/app/services/api_engine_base/argument_validation/class_methods.rb +2 -3
  12. data/app/services/api_engine_base/argument_validation/instance_methods.rb +13 -1
  13. data/app/services/api_engine_base/authorize/validate.rb +49 -0
  14. data/app/services/api_engine_base/jwt/authenticate_user.rb +22 -7
  15. data/app/services/api_engine_base/jwt/login_create.rb +1 -1
  16. data/app/services/api_engine_base/service_base.rb +4 -5
  17. data/app/services/api_engine_base/user_attributes/modify.rb +68 -0
  18. data/app/services/api_engine_base/user_attributes/roles.rb +27 -0
  19. data/config/routes.rb +11 -0
  20. data/db/migrate/20241117043720_create_api_engine_base_users.rb +2 -0
  21. data/lib/api_engine_base/authorization/default.yml +34 -0
  22. data/lib/api_engine_base/authorization/entity.rb +101 -0
  23. data/lib/api_engine_base/authorization/role.rb +101 -0
  24. data/lib/api_engine_base/authorization.rb +85 -0
  25. data/lib/api_engine_base/configuration/admin/config.rb +18 -0
  26. data/lib/api_engine_base/configuration/application/config.rb +2 -2
  27. data/lib/api_engine_base/configuration/authorization/config.rb +24 -0
  28. data/lib/api_engine_base/configuration/config.rb +19 -1
  29. data/lib/api_engine_base/configuration/user/config.rb +56 -0
  30. data/lib/api_engine_base/engine.rb +38 -6
  31. data/lib/api_engine_base/error.rb +5 -0
  32. data/lib/api_engine_base/schema/admin/users.rb +15 -0
  33. data/lib/api_engine_base/schema/error/invalid_argument_response.rb +1 -1
  34. data/lib/api_engine_base/schema/page.rb +14 -0
  35. data/lib/api_engine_base/schema/user.rb +28 -0
  36. data/lib/api_engine_base/schema.rb +5 -0
  37. data/lib/api_engine_base/spec_helper.rb +4 -3
  38. data/lib/api_engine_base/version.rb +1 -1
  39. data/lib/api_engine_base.rb +2 -2
  40. metadata +22 -4
@@ -9,6 +9,9 @@ require "api_engine_base/configuration/login/config"
9
9
  require "api_engine_base/configuration/otp/config"
10
10
  require "api_engine_base/configuration/username/config"
11
11
  require "api_engine_base/configuration/application/config"
12
+ require "api_engine_base/configuration/admin/config"
13
+ require "api_engine_base/configuration/authorization/config"
14
+ require "api_engine_base/configuration/user/config"
12
15
 
13
16
  module ApiEngineBase
14
17
  module Configuration
@@ -48,9 +51,24 @@ module ApiEngineBase
48
51
  # allow shorthand to be used
49
52
  alias_method :app, :application
50
53
 
54
+ add_composer :authorization,
55
+ desc: "Authorization via rbac configurations",
56
+ allowed: Configuration::Authorization::Config,
57
+ default: Configuration::Authorization::Config.new
58
+
59
+ add_composer :user,
60
+ desc: "User configuration for the app. Includes what to display and what attributes can be changed",
61
+ allowed: Configuration::User::Config,
62
+ default: Configuration::User::Config.new
63
+
64
+ add_composer :admin,
65
+ desc: "Admin configuration for the app",
66
+ allowed: Configuration::Admin::Config,
67
+ default: Configuration::Admin::Config.new
68
+
51
69
  # To be Deleted
52
70
  add_composer :otp,
53
- desc: "One Time Password generator is used for all Code validation. This describes defaults not set in other configurations",
71
+ desc: "One Time Password generation is used for ease in quickly validating a users actions. This is good for short term validation requirements as opposed to UserSecrets",
54
72
  allowed: Configuration::Otp::Config,
55
73
  default: Configuration::Otp::Config.new
56
74
  end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "class_composer"
4
+
5
+ module ApiEngineBase
6
+ module Configuration
7
+ module User
8
+ class Config
9
+ include ClassComposer::Generator
10
+
11
+ ATTRIBUTES_TO_CHANGE = [
12
+ :email,
13
+ :first_name,
14
+ :last_name,
15
+ :last_known_timezone,
16
+ :username,
17
+ :verifier_token,
18
+ ]
19
+
20
+ ATTRIBUTES_TO_SHOW = [
21
+ *ATTRIBUTES_TO_CHANGE,
22
+ :id,
23
+ :roles,
24
+ :created_at,
25
+ ]
26
+
27
+ ATTRIBUTES_CHANGE_EXECUTE = Proc.new do |key, value|
28
+ ApiEngineBase::UserAttributes::Modify.assign!
29
+ end
30
+
31
+ ATTRIBUTES_SHOWN_EXECUTE = Proc.new do |key, value|
32
+ ApiEngineBase::Schema::User.assign!
33
+ end
34
+
35
+ add_composer :additional_attributes_for_change,
36
+ desc: "On top of the default attributes to change, this adds additional values for the user to change on their account",
37
+ allowed: Array,
38
+ default: [],
39
+ default_shown: "[]"
40
+
41
+ add_composer :default_attributes_for_change,
42
+ desc: "[Not Recommended for change] Default attributes that are allowed to change",
43
+ allowed: Array,
44
+ default: ATTRIBUTES_TO_CHANGE,
45
+ &ATTRIBUTES_CHANGE_EXECUTE
46
+
47
+ add_composer :default_attributes,
48
+ desc: "[Not Recommended for change] Default attributes that are shown to the user",
49
+ allowed: Array,
50
+ default_shown: ATTRIBUTES_TO_SHOW,
51
+ dynamic_default: -> (instance) { (ATTRIBUTES_TO_SHOW + instance.additional_attributes_for_change).uniq },
52
+ &ATTRIBUTES_SHOWN_EXECUTE
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "api_engine_base/authorization"
3
4
  require "api_engine_base/schema"
4
5
 
5
6
  module ApiEngineBase
@@ -8,14 +9,45 @@ module ApiEngineBase
8
9
 
9
10
  # Run after Rails loads the initializes and environment files
10
11
  # Ensures User has already set their desired config before we lock this down
11
- initializer "api_engine_base.config.instantiate", after: :load_config_initializers do |_app|
12
- # ensure defaults are instantiated and all variables are assigned
13
- ApiEngineBase.config.class_composer_assign_defaults!(children: true)
12
+ config.after_initialize do
13
+ db_rake_task = defined?(Rake) && (Rake.application.top_level_tasks.any? { |task| task =~ /db:/ } rescue nil)
14
+ if db_rake_task
15
+ # Because we call the Database during configuration setup,
16
+ # We want to skip calling the DB during a DB migration
17
+ else
18
+ # ensure defaults are instantiated and all variables are assigned
19
+ ApiEngineBase.config.class_composer_assign_defaults!(children: true)
14
20
 
15
- unless Rails.env.test?
16
- # Now that we can confirm all variables are defined, freeze all objects an their children
17
- ApiEngineBase.config.class_composer_freeze_objects!(behavior: :raise, children: true)
21
+ unless Rails.env.test?
22
+ # Now that we can confirm all variables are defined, freeze all objects an their children
23
+ ApiEngineBase.config.class_composer_freeze_objects!(behavior: :raise, children: true)
24
+ end
18
25
  end
19
26
  end
27
+
28
+
29
+ ####
30
+ # Bug: @matt-taylor
31
+ # RBAC code memoizes the controller object into a class variable
32
+ # In development when code changes, all classes get reloaded
33
+ # Inherently, this causes the `object_id` of the class to change
34
+ # This means the memoized class is no longer equal to the newly reloaded class
35
+ # NOTE: This is only a problem on reload! in development. Not an issue in Production
36
+ # Once this is fixed, it can go into a regular initializer and does not need to get re-computed on each reload
37
+ ###
38
+ # Potential solution:
39
+ # => Don't store the object as the comparison key
40
+ # => Or...When doing comparisons, convert everything to a string for comparison
41
+ # Changes to names should be infrequent/should have a full app restart
42
+
43
+ # Add all RBAC based role definitions prior to fork/loading
44
+ # Load once use forever
45
+ config.to_prepare do
46
+ ApiEngineBase::Authorization::Role.roles_reset!
47
+ ApiEngineBase::Authorization::Entity.entities_reset!
48
+ ApiEngineBase::Authorization.mapped_controllers_reset!
49
+
50
+ ApiEngineBase::Authorization.default_defined!
51
+ end
20
52
  end
21
53
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApiEngineBase
4
+ class Error < StandardError; end
5
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "api_engine_base/schema/user"
4
+ require "api_engine_base/schema/page"
5
+
6
+ module ApiEngineBase
7
+ module Schema
8
+ module Admin
9
+ class Users < JsonSchematize::Generator
10
+ add_field name: :users, array_of_types: true, type: ApiEngineBase::Schema::User
11
+ add_field name: :pagination, type: ApiEngineBase::Schema::Page, required: false
12
+ end
13
+ end
14
+ end
15
+ end
@@ -9,7 +9,7 @@ module ApiEngineBase
9
9
  add_field name: :message, type: String, required: true
10
10
  add_field name: :status, type: String, required: true
11
11
  add_field name: :invalid_arguments, array_of_types: true, type: InvalidArgument
12
- add_field name: :invalid_argument_keys, type: Array
12
+ add_field name: :invalid_argument_keys, type: Array
13
13
  end
14
14
  end
15
15
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApiEngineBase
4
+ module Schema
5
+ class Page < JsonSchematize::Generator
6
+ schema_default option: :dig_type, value: :string
7
+
8
+ add_field name: :count, type: Integer
9
+ add_field name: :cursor, type: Integer
10
+ add_field name: :limit, type: Integer
11
+ add_field name: :next, type: String
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApiEngineBase
4
+ module Schema
5
+ class User < JsonSchematize::Generator
6
+ schema_default option: :dig_type, value: :string
7
+
8
+ def self.convert_user_object(user:)
9
+ attributes = ApiEngineBase.config.user.default_attributes.map(&:to_s)
10
+ object = user.attributes.slice(*attributes)
11
+
12
+ new(object)
13
+ end
14
+
15
+ # Gets assigned during configuration phase via
16
+ # lib/api_engine_base/configuration/user/config.rb
17
+ def self.assign!
18
+ attributes = ApiEngineBase.config.user.default_attributes
19
+ attributes.each do |attribute|
20
+ if metadata = ::User.attribute_to_type_mapping[attribute]
21
+ type = metadata[:serialized_type] ? metadata[:serialized_type] : metadata[:base]
22
+ add_field(name: attribute, type:)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -21,5 +21,10 @@ module ApiEngineBase
21
21
 
22
22
  require "api_engine_base/schema/plain_text/login_request"
23
23
  require "api_engine_base/schema/plain_text/login_response"
24
+
25
+ require "api_engine_base/schema/admin/users"
26
+
27
+ require "api_engine_base/schema/user"
28
+ require "api_engine_base/schema/page"
24
29
  end
25
30
  end
@@ -2,17 +2,18 @@
2
2
 
3
3
  module ApiEngineBase
4
4
  module SpecHelper
5
- def set_jwt_token!(user:, token: nil)
5
+ def set_jwt_token!(user:, with_reset: false, token: nil)
6
6
  if token.nil?
7
7
  result = ApiEngineBase::Jwt::LoginCreate.(user:)
8
8
  token = result.token
9
9
  end
10
10
 
11
- @request.headers[ApiEngineBase::ApplicationController::AUTHORIZATION_HEADER] = "Bearer: #{token}"
11
+ @request.headers[ApiEngineBase::ApplicationController::AUTHENTICATION_HEADER] = "Bearer: #{token}"
12
+ @request.headers[ApiEngineBase::ApplicationController::AUTHENTICATION_WITH_RESET] = "true" if with_reset
12
13
  end
13
14
 
14
15
  def unset_jwt_token!
15
- @request.headers[ApiEngineBase::ApplicationController::AUTHORIZATION_HEADER] = nil
16
+ @request.headers[ApiEngineBase::ApplicationController::AUTHENTICATION_HEADER] = nil
16
17
  end
17
18
  end
18
19
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApiEngineBase
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
@@ -1,10 +1,10 @@
1
+ require "api_engine_base/error"
2
+
1
3
  require "api_engine_base/version"
2
4
  require "api_engine_base/engine"
3
5
  require "api_engine_base/configuration/config"
4
6
 
5
7
  module ApiEngineBase
6
- class Error < StandardError; end
7
-
8
8
  def self.config
9
9
  @config ||= Configuration::Config.new
10
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_engine_base
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - matt-taylor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-02 00:00:00.000000000 Z
11
+ date: 2025-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rotp
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '0.10'
103
+ version: '0.11'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '0.10'
110
+ version: '0.11'
111
111
  description: ApiEngineBase is the Base API to handle all the things you don't want
112
112
  to for a Rails API only backend serving a Dedicated frontend
113
113
  email:
@@ -119,8 +119,10 @@ files:
119
119
  - MIT-LICENSE
120
120
  - README.md
121
121
  - Rakefile
122
+ - app/controllers/api_engine_base/admin_controller.rb
122
123
  - app/controllers/api_engine_base/application_controller.rb
123
124
  - app/controllers/api_engine_base/auth/plain_text_controller.rb
125
+ - app/controllers/api_engine_base/user_controller.rb
124
126
  - app/controllers/api_engine_base/username_controller.rb
125
127
  - app/controllers/concerns/api_engine_base/schematizable.rb
126
128
  - app/helpers/api_engine_base/application_helper.rb
@@ -131,9 +133,12 @@ files:
131
133
  - app/models/api_engine_base/application_record.rb
132
134
  - app/models/user.rb
133
135
  - app/models/user_secret.rb
136
+ - app/services/api_engine_base/README.md
134
137
  - app/services/api_engine_base/argument_validation.rb
138
+ - app/services/api_engine_base/argument_validation/README.md
135
139
  - app/services/api_engine_base/argument_validation/class_methods.rb
136
140
  - app/services/api_engine_base/argument_validation/instance_methods.rb
141
+ - app/services/api_engine_base/authorize/validate.rb
137
142
  - app/services/api_engine_base/jwt/authenticate_user.rb
138
143
  - app/services/api_engine_base/jwt/decode.rb
139
144
  - app/services/api_engine_base/jwt/encode.rb
@@ -151,13 +156,21 @@ files:
151
156
  - app/services/api_engine_base/secrets/verify.rb
152
157
  - app/services/api_engine_base/service_base.rb
153
158
  - app/services/api_engine_base/service_logging.rb
159
+ - app/services/api_engine_base/user_attributes/modify.rb
160
+ - app/services/api_engine_base/user_attributes/roles.rb
154
161
  - app/services/api_engine_base/username/available.rb
155
162
  - app/views/api_engine_base/email_verification_mailer/verify_email.html.erb
156
163
  - config/routes.rb
157
164
  - db/migrate/20241117043720_create_api_engine_base_users.rb
158
165
  - db/migrate/20241204065708_create_api_engine_base_user_secrets.rb
159
166
  - lib/api_engine_base.rb
167
+ - lib/api_engine_base/authorization.rb
168
+ - lib/api_engine_base/authorization/default.yml
169
+ - lib/api_engine_base/authorization/entity.rb
170
+ - lib/api_engine_base/authorization/role.rb
171
+ - lib/api_engine_base/configuration/admin/config.rb
160
172
  - lib/api_engine_base/configuration/application/config.rb
173
+ - lib/api_engine_base/configuration/authorization/config.rb
161
174
  - lib/api_engine_base/configuration/base.rb
162
175
  - lib/api_engine_base/configuration/config.rb
163
176
  - lib/api_engine_base/configuration/email/config.rb
@@ -167,13 +180,17 @@ files:
167
180
  - lib/api_engine_base/configuration/login/strategy/plain_text/email_verify.rb
168
181
  - lib/api_engine_base/configuration/login/strategy/plain_text/lockable.rb
169
182
  - lib/api_engine_base/configuration/otp/config.rb
183
+ - lib/api_engine_base/configuration/user/config.rb
170
184
  - lib/api_engine_base/configuration/username/check.rb
171
185
  - lib/api_engine_base/configuration/username/config.rb
172
186
  - lib/api_engine_base/engine.rb
187
+ - lib/api_engine_base/error.rb
173
188
  - lib/api_engine_base/schema.rb
189
+ - lib/api_engine_base/schema/admin/users.rb
174
190
  - lib/api_engine_base/schema/error/base.rb
175
191
  - lib/api_engine_base/schema/error/invalid_argument.rb
176
192
  - lib/api_engine_base/schema/error/invalid_argument_response.rb
193
+ - lib/api_engine_base/schema/page.rb
177
194
  - lib/api_engine_base/schema/plain_text/create_user_request.rb
178
195
  - lib/api_engine_base/schema/plain_text/create_user_response.rb
179
196
  - lib/api_engine_base/schema/plain_text/email_verify_request.rb
@@ -182,6 +199,7 @@ files:
182
199
  - lib/api_engine_base/schema/plain_text/email_verify_send_response.rb
183
200
  - lib/api_engine_base/schema/plain_text/login_request.rb
184
201
  - lib/api_engine_base/schema/plain_text/login_response.rb
202
+ - lib/api_engine_base/schema/user.rb
185
203
  - lib/api_engine_base/spec_helper.rb
186
204
  - lib/api_engine_base/version.rb
187
205
  - lib/generators/api_engine_base/configure/USAGE