command_tower 0.10.0 → 0.11.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 (189) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -3
  3. data/app/auth/command_tower/auth/auth_context.rb +10 -4
  4. data/app/controllers/command_tower/admin/application_controller.rb +27 -0
  5. data/app/controllers/command_tower/admin/audit/events_controller.rb +61 -0
  6. data/app/controllers/command_tower/admin/messaging/announcements_controller.rb +1 -8
  7. data/app/controllers/command_tower/admin/users/identities_controller.rb +77 -0
  8. data/app/controllers/command_tower/admin/users/impersonation_sessions_controller.rb +33 -0
  9. data/app/controllers/command_tower/admin/users/roles_controller.rb +40 -0
  10. data/app/controllers/command_tower/admin/users_controller.rb +46 -0
  11. data/app/controllers/command_tower/admin/workspace_controller.rb +15 -0
  12. data/app/controllers/command_tower/application_controller.rb +17 -1
  13. data/app/controllers/command_tower/auth/impersonation_session_controller.rb +27 -0
  14. data/app/controllers/command_tower/auth/logout_controller.rb +3 -1
  15. data/app/controllers/command_tower/auth/principal_capabilities_controller.rb +19 -0
  16. data/app/controllers/command_tower/me/audit_events_controller.rb +59 -0
  17. data/app/controllers/concerns/command_tower/api/application_response_renderer.rb +5 -0
  18. data/app/controllers/concerns/command_tower/auth/authentication_boundary.rb +3 -2
  19. data/app/controllers/concerns/command_tower/execution/http_boundary.rb +65 -0
  20. data/app/deserializers/command_tower/deserializers/admin/scope_parameter.rb +49 -0
  21. data/app/deserializers/command_tower/deserializers/admin/users.rb +218 -0
  22. data/app/deserializers/command_tower/deserializers/audit/events.rb +224 -0
  23. data/app/deserializers/command_tower/deserializers/clients/types.rb +27 -0
  24. data/app/errors/command_tower/errors/auth/admin_unavailable_during_impersonation_error.rb +17 -0
  25. data/app/errors/command_tower/errors/auth/default_membership_assignment_error.rb +17 -0
  26. data/app/errors/command_tower/errors/auth/impersonation_session_expired_error.rb +17 -0
  27. data/app/errors/command_tower/errors/auth/impersonation_session_missing_error.rb +21 -0
  28. data/app/errors/command_tower/errors/auth/nested_impersonation_error.rb +17 -0
  29. data/app/errors/command_tower/errors/auth/self_impersonation_error.rb +21 -0
  30. data/app/errors/command_tower/errors/continuation_exhausted_error.rb +25 -0
  31. data/app/jobs/command_tower/application_job.rb +7 -0
  32. data/app/jobs/command_tower/execution/job_boundary.rb +19 -0
  33. data/app/mailers/command_tower/application_mailer.rb +11 -1
  34. data/app/mailers/command_tower/messaging/channel_mailer.rb +1 -2
  35. data/app/models/command_tower/audit/event.rb +36 -0
  36. data/app/models/command_tower/impersonation/session.rb +51 -0
  37. data/app/serializers/command_tower/serializers/admin/users.rb +69 -0
  38. data/app/serializers/command_tower/serializers/admin/workspace/manifest_serializer.rb +58 -0
  39. data/app/serializers/command_tower/serializers/audit/events/filter_options_serializer.rb +44 -0
  40. data/app/serializers/command_tower/serializers/audit/events.rb +42 -0
  41. data/app/serializers/command_tower/serializers/auth/principal_capabilities_serializer.rb +15 -0
  42. data/app/serializers/command_tower/serializers/auth/session_response_serializer.rb +26 -2
  43. data/app/serializers/command_tower/serializers/impersonation/session_serializer.rb +19 -0
  44. data/app/services/command_tower/README.md +4 -10
  45. data/app/services/command_tower/authorize/validate.rb +7 -4
  46. data/app/services/command_tower/jwt/authenticate_user.rb +8 -2
  47. data/app/services/command_tower/jwt/authentication_outcome.rb +5 -4
  48. data/app/services/command_tower/jwt/login_create.rb +7 -4
  49. data/app/services/command_tower/messaging/accept/operation_logger.rb +3 -3
  50. data/app/services/command_tower/messaging/contract/observability/correlation.rb +3 -1
  51. data/app/services/command_tower/messaging/contract/observability/operation_logger.rb +3 -3
  52. data/app/services/command_tower/messaging/contract/observability/publisher.rb +44 -0
  53. data/app/services/command_tower/messaging/execution/operation_logger.rb +1 -1
  54. data/app/services/command_tower/messaging/handoff/operation_logger.rb +1 -1
  55. data/app/services/command_tower/messaging/inbox/operation_logger.rb +1 -1
  56. data/app/services/command_tower/messaging/planner/operation_logger.rb +1 -1
  57. data/app/services/command_tower/messaging/recipient_readiness/evaluate.rb +1 -1
  58. data/app/services/command_tower/service_base.rb +30 -43
  59. data/app/services/command_tower/service_logging.rb +2 -36
  60. data/app/services/command_tower/services/account/clear_phone.rb +8 -0
  61. data/app/services/command_tower/services/account/phone_verification/verify.rb +1 -0
  62. data/app/services/command_tower/services/account/update_phone.rb +9 -1
  63. data/app/services/command_tower/services/admin/users.rb +377 -0
  64. data/app/services/command_tower/services/admin/workspace/manifest.rb +49 -0
  65. data/app/services/command_tower/services/application_service.rb +37 -0
  66. data/app/services/command_tower/services/audit/events/filter_options.rb +75 -0
  67. data/app/services/command_tower/services/audit/events.rb +199 -0
  68. data/app/services/command_tower/services/auth/assign_default_membership_role.rb +44 -0
  69. data/app/services/command_tower/services/auth/authenticate_session.rb +33 -6
  70. data/app/services/command_tower/services/auth/email_verification/verify.rb +2 -0
  71. data/app/services/command_tower/services/auth/password_reset/reset.rb +13 -3
  72. data/app/services/command_tower/services/auth/plain_text/login.rb +9 -1
  73. data/app/services/command_tower/services/auth/principal_capabilities/project.rb +48 -0
  74. data/app/services/command_tower/services/impersonation/create.rb +29 -0
  75. data/app/services/command_tower/services/impersonation/end.rb +28 -0
  76. data/app/services/command_tower/services/impersonation/record_activity.rb +30 -0
  77. data/app/services/command_tower/services/impersonation/terminate_open_sessions.rb +51 -0
  78. data/app/services/command_tower/services/me/change_password.rb +12 -0
  79. data/app/shared_sequences/command_tower/shared_sequences/admin/users/resolve_scoped_user.rb +42 -0
  80. data/app/workflows/command_tower/transactional.rb +65 -0
  81. data/app/workflows/command_tower/workflows/admin/messaging/create_announcement_workflow.rb +11 -0
  82. data/app/workflows/command_tower/workflows/admin/scope_resolution.rb +17 -0
  83. data/app/workflows/command_tower/workflows/admin/users/error_mapping.rb +26 -0
  84. data/app/workflows/command_tower/workflows/admin/users/identity_mutation.rb +30 -0
  85. data/app/workflows/command_tower/workflows/admin/users/list_assignable_roles_workflow.rb +30 -0
  86. data/app/workflows/command_tower/workflows/admin/users/list_workflow.rb +54 -0
  87. data/app/workflows/command_tower/workflows/admin/users/set_email_validated_workflow.rb +45 -0
  88. data/app/workflows/command_tower/workflows/admin/users/show_workflow.rb +49 -0
  89. data/app/workflows/command_tower/workflows/admin/users/update_email_workflow.rb +45 -0
  90. data/app/workflows/command_tower/workflows/admin/users/update_name_workflow.rb +49 -0
  91. data/app/workflows/command_tower/workflows/admin/users/update_roles_workflow.rb +61 -0
  92. data/app/workflows/command_tower/workflows/admin/users/update_username_workflow.rb +45 -0
  93. data/app/workflows/command_tower/workflows/admin/workspace/manifest_workflow.rb +25 -0
  94. data/app/workflows/command_tower/workflows/application_workflow.rb +163 -24
  95. data/app/workflows/command_tower/workflows/audit/error_mapping.rb +24 -0
  96. data/app/workflows/command_tower/workflows/audit/events/filter_options_for_admin_workflow.rb +34 -0
  97. data/app/workflows/command_tower/workflows/audit/events/filter_options_for_user_workflow.rb +34 -0
  98. data/app/workflows/command_tower/workflows/audit/events/list_for_admin_workflow.rb +74 -0
  99. data/app/workflows/command_tower/workflows/audit/events/list_for_user_workflow.rb +45 -0
  100. data/app/workflows/command_tower/workflows/audit/events/show_for_admin_workflow.rb +54 -0
  101. data/app/workflows/command_tower/workflows/audit/events/show_for_user_workflow.rb +42 -0
  102. data/app/workflows/command_tower/workflows/auth/authenticate_request_workflow.rb +3 -2
  103. data/app/workflows/command_tower/workflows/auth/authentication_response_effects.rb +5 -1
  104. data/app/workflows/command_tower/workflows/auth/logout_workflow.rb +41 -1
  105. data/app/workflows/command_tower/workflows/auth/plain_text/login_workflow.rb +2 -0
  106. data/app/workflows/command_tower/workflows/auth/principal_capabilities/show_workflow.rb +27 -0
  107. data/app/workflows/command_tower/workflows/auth/register_workflow.rb +56 -24
  108. data/app/workflows/command_tower/workflows/auth/session/show_workflow.rb +15 -1
  109. data/app/workflows/command_tower/workflows/auth/session_error_status.rb +1 -0
  110. data/app/workflows/command_tower/workflows/impersonation/error_mapping.rb +27 -0
  111. data/app/workflows/command_tower/workflows/impersonation/start_workflow.rb +97 -0
  112. data/app/workflows/command_tower/workflows/impersonation/stop_workflow.rb +66 -0
  113. data/app/workflows/command_tower/workflows/me/update_name_workflow.rb +1 -0
  114. data/app/workflows/command_tower/workflows/profile/show_workflow.rb +1 -0
  115. data/app/workflows/command_tower/workflows/workflow_result.rb +31 -7
  116. data/config/routes.rb +20 -0
  117. data/db/migrate/20260816000001_create_command_tower_audit_events.rb +45 -0
  118. data/db/migrate/20260817000001_add_scope_columns_to_command_tower_audit_events.rb +34 -0
  119. data/db/migrate/20260817000003_create_command_tower_impersonation_sessions.rb +26 -0
  120. data/docs/admin_workspace.md +158 -0
  121. data/docs/api_reference.md +175 -14
  122. data/docs/architecture.md +5 -0
  123. data/docs/audit.md +195 -0
  124. data/docs/authentication.md +14 -0
  125. data/docs/authentication_authorization_guide.md +15 -11
  126. data/docs/authorization.md +25 -4
  127. data/docs/controllers.md +7 -1
  128. data/docs/eventing.md +179 -0
  129. data/docs/extending.md +32 -1
  130. data/docs/host_integration_guide.md +103 -12
  131. data/docs/initializing.md +2 -2
  132. data/docs/messaging_integration_guide.md +1 -1
  133. data/docs/models.md +4 -0
  134. data/docs/pagination.md +2 -2
  135. data/docs/principal_capabilities.md +89 -0
  136. data/docs/upgrades/0.10.0.md +2 -2
  137. data/docs/upgrades/0.11.0.md +92 -0
  138. data/docs/upgrades/README.md +1 -0
  139. data/lib/command_tower/admin_scope/apply_audit_scoping.rb +45 -0
  140. data/lib/command_tower/admin_scope/apply_users_narrowing.rb +21 -0
  141. data/lib/command_tower/admin_scope/manifest_projection.rb +102 -0
  142. data/lib/command_tower/admin_scope/resolve.rb +31 -0
  143. data/lib/command_tower/admin_scope/scope_context.rb +7 -0
  144. data/lib/command_tower/admin_scope/scope_option.rb +7 -0
  145. data/lib/command_tower/admin_scope.rb +20 -0
  146. data/lib/command_tower/admin_workspace.rb +16 -0
  147. data/lib/command_tower/audit/attribution.rb +90 -0
  148. data/lib/command_tower/audit/emit.rb +113 -0
  149. data/lib/command_tower/audit/masking.rb +41 -0
  150. data/lib/command_tower/audit/payload.rb +128 -0
  151. data/lib/command_tower/audit/persistence/subscriber.rb +85 -0
  152. data/lib/command_tower/audit.rb +27 -0
  153. data/lib/command_tower/authorization/assignable_roles.rb +36 -0
  154. data/lib/command_tower/authorization/default.yml +99 -5
  155. data/lib/command_tower/authorization/effective_entity_grants.rb +55 -0
  156. data/lib/command_tower/authorization/entity.rb +15 -5
  157. data/lib/command_tower/authorization/role.rb +5 -4
  158. data/lib/command_tower/authorization.rb +71 -10
  159. data/lib/command_tower/configuration/admin_scope/config.rb +104 -0
  160. data/lib/command_tower/configuration/admin_scope/tool_registration.rb +28 -0
  161. data/lib/command_tower/configuration/authorization/config.rb +6 -0
  162. data/lib/command_tower/configuration/config.rb +20 -0
  163. data/lib/command_tower/configuration/impersonation/config.rb +38 -0
  164. data/lib/command_tower/configuration/registry/admin_workspace/config.rb +199 -0
  165. data/lib/command_tower/configuration/registry/admin_workspace/tool_definition.rb +150 -0
  166. data/lib/command_tower/configuration/registry/audit/config.rb +403 -0
  167. data/lib/command_tower/configuration/registry/audit/event_definition.rb +155 -0
  168. data/lib/command_tower/configuration/registry/config.rb +34 -0
  169. data/lib/command_tower/configuration/registry/principal_capabilities/capability_definition.rb +43 -0
  170. data/lib/command_tower/configuration/registry/principal_capabilities/config.rb +136 -0
  171. data/lib/command_tower/current.rb +12 -0
  172. data/lib/command_tower/engine.rb +19 -4
  173. data/lib/command_tower/events.rb +184 -0
  174. data/lib/command_tower/execution.rb +111 -0
  175. data/lib/command_tower/impersonation/activity_declaration.rb +23 -0
  176. data/lib/command_tower/impersonation/apply_overlay.rb +88 -0
  177. data/lib/command_tower/impersonation/clear_overlay_for_audit.rb +23 -0
  178. data/lib/command_tower/impersonation/establish_identity.rb +44 -0
  179. data/lib/command_tower/install/baseline.rb +3 -0
  180. data/lib/command_tower/logging/lifecycle_declaration.rb +27 -0
  181. data/lib/command_tower/logging/projection.rb +67 -0
  182. data/lib/command_tower/logging/subscriber.rb +103 -0
  183. data/lib/command_tower/principal_capabilities.rb +15 -0
  184. data/lib/command_tower/version.rb +1 -1
  185. data/lib/command_tower.rb +12 -0
  186. data/spec/factories/impersonation_session.rb +17 -0
  187. data/spec/factories/user.rb +16 -0
  188. metadata +112 -2
  189. data/app/services/command_tower/messaging/contract/observability/structured_logger.rb +0 -56
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CommandTower
4
+ module Impersonation
5
+ # Temporarily clear overlay identity so impersonation_ended audits attribute
6
+ # as admin_direct to the actor. Lives outside workflows/services so leaf
7
+ # layers do not establish Current execution boundaries themselves.
8
+ module ClearOverlayForAudit
9
+ module_function
10
+
11
+ def call(actor_user_id:)
12
+ CommandTower::Current.set(
13
+ user_id: actor_user_id,
14
+ effective_user_id: actor_user_id,
15
+ originating_administrator_id: nil,
16
+ impersonation_active: false
17
+ ) do
18
+ yield
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CommandTower
4
+ module Impersonation
5
+ EstablishedIdentity = Data.define(:user, :actor, :session, :status) do
6
+ def expired?
7
+ status == :expired
8
+ end
9
+
10
+ def active?
11
+ status == :active
12
+ end
13
+ end
14
+
15
+ module EstablishIdentity
16
+ module_function
17
+
18
+ def call(actor:, impersonation_session_id:, mode: :enforce)
19
+ overlay = ApplyOverlay.call(actor:, session_id: impersonation_session_id, mode:)
20
+ if overlay.status == :expired && mode.to_sym == :enforce
21
+ CommandTower::Execution::IdentityEnrichment.from_user(actor)
22
+ return EstablishedIdentity.new(user: actor, actor:, session: overlay.session, status: :expired)
23
+ end
24
+
25
+ if overlay.status == :active
26
+ CommandTower::Execution::IdentityEnrichment.from_impersonation_session(
27
+ overlay.session,
28
+ actor: overlay.actor,
29
+ target: overlay.target
30
+ )
31
+ return EstablishedIdentity.new(
32
+ user: overlay.target,
33
+ actor: overlay.actor,
34
+ session: overlay.session,
35
+ status: :active
36
+ )
37
+ end
38
+
39
+ CommandTower::Execution::IdentityEnrichment.from_user(actor)
40
+ EstablishedIdentity.new(user: actor, actor:, session: overlay.session, status: overlay.status)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -11,6 +11,9 @@ module CommandTower
11
11
  20260805000003_create_command_tower_messaging_core.rb
12
12
  20260805000004_create_messaging_notification_preferences.rb
13
13
  20260805000005_create_messaging_endpoints_and_pushover_credentials.rb
14
+ 20260816000001_create_command_tower_audit_events.rb
15
+ 20260817000001_add_scope_columns_to_command_tower_audit_events.rb
16
+ 20260817000003_create_command_tower_impersonation_sessions.rb
14
17
  ].freeze
15
18
 
16
19
  module_function
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CommandTower
4
+ module Logging
5
+ module LifecycleDeclaration
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ module ClassMethods
11
+ def log_lifecycle!
12
+ @lifecycle_loggable = true
13
+ end
14
+
15
+ def disable_lifecycle_logging!
16
+ @lifecycle_loggable = false
17
+ end
18
+
19
+ def lifecycle_loggable?
20
+ return @lifecycle_loggable unless @lifecycle_loggable.nil?
21
+
22
+ superclass.respond_to?(:lifecycle_loggable?) ? superclass.lifecycle_loggable? : false
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CommandTower
4
+ module Logging
5
+ module Projection
6
+ DROP = %i[event_uuid layer log_lifecycle log_level].freeze
7
+
8
+ module_function
9
+
10
+ def call(event)
11
+ payload = symbolize(event.payload)
12
+ projected = { event: event.name }
13
+
14
+ copy_if_present(projected, payload, :subject)
15
+ copy_if_present(projected, payload, :execution_uuid)
16
+ copy_if_present(projected, payload, :correlation_id)
17
+ copy_if_present(projected, payload, :outcome)
18
+ copy_if_present(projected, payload, :duration_ms)
19
+ copy_if_present(projected, payload, :user_id)
20
+ copy_if_present(projected, payload, :error_class)
21
+ copy_if_present(projected, payload, :error_codes)
22
+ copy_if_present(projected, payload, :causation_id)
23
+ copy_if_present(projected, payload, :originating_administrator_id)
24
+
25
+ request_id = payload[:request_id]
26
+ if !request_id.nil? && request_id != payload[:correlation_id]
27
+ projected[:request_id] = request_id
28
+ end
29
+
30
+ source = payload[:source]
31
+ projected[:source] = source if !source.nil? && source.to_s != "http"
32
+
33
+ effective = payload[:effective_user_id]
34
+ projected[:effective_user_id] = effective if !effective.nil? && effective != payload[:user_id]
35
+
36
+ projected[:impersonation_active] = true if payload[:impersonation_active] == true
37
+
38
+ payload.each do |key, value|
39
+ next if DROP.include?(key)
40
+ next if projected.key?(key)
41
+ next if value.nil?
42
+ next if key == :impersonation_active
43
+ next if key == :source
44
+ next if key == :request_id
45
+ next if key == :effective_user_id
46
+
47
+ projected[key] = value
48
+ end
49
+
50
+ projected
51
+ end
52
+
53
+ def symbolize(payload)
54
+ hash = payload.respond_to?(:to_h) ? payload.to_h : {}
55
+ hash.each_with_object({}) do |(key, value), memo|
56
+ memo[key.to_sym] = value
57
+ end
58
+ end
59
+
60
+ def copy_if_present(projected, payload, key)
61
+ value = payload[key]
62
+ projected[key] = value unless value.nil?
63
+ end
64
+ private_class_method :symbolize, :copy_if_present
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CommandTower
4
+ module Logging
5
+ class Subscriber < ActiveSupport::LogSubscriber
6
+ PATTERNS = [
7
+ /\Acommand_tower\.lifecycle(?:\.|\z)/,
8
+ /\Acommand_tower\.log(?:\.|\z)/,
9
+ /\Acommand_tower\.messaging(?:\.|\z)/
10
+ ].freeze
11
+ SEVERITIES = %i[debug info warn error].freeze
12
+
13
+ class << self
14
+ def logger
15
+ @logger || super
16
+ end
17
+
18
+ def logger=(value)
19
+ @logger = value
20
+ end
21
+
22
+ def attach!
23
+ detach!
24
+ subscriber = new
25
+ @subscriptions = PATTERNS.map do |pattern|
26
+ ActiveSupport::Notifications.subscribe(pattern) do |name, started, finished, id, payload|
27
+ event = ActiveSupport::Notifications::Event.new(name, started, finished, id, payload)
28
+ subscriber.call(event)
29
+ end
30
+ end
31
+ end
32
+
33
+ def detach!
34
+ Array(@subscriptions).each { |subscription| ActiveSupport::Notifications.unsubscribe(subscription) }
35
+ @subscriptions = []
36
+ end
37
+
38
+ def subscriptions
39
+ Array(@subscriptions)
40
+ end
41
+ end
42
+
43
+ def call(event)
44
+ return if logger.nil?
45
+ return unless materialize?(event)
46
+
47
+ severity = severity_for(event)
48
+ logger.public_send(severity, log_entry(event))
49
+ rescue StandardError
50
+ begin
51
+ logger&.error({ event: "command_tower.logging.subscriber_failed", error_class: $!.class.name })
52
+ rescue StandardError
53
+ nil
54
+ end
55
+ end
56
+
57
+ def logger
58
+ self.class.logger
59
+ end
60
+
61
+ private
62
+
63
+ def materialize?(event)
64
+ name = event.name
65
+ return true if name.start_with?("command_tower.log.")
66
+ return true if name.start_with?("command_tower.messaging.")
67
+ return false unless name.start_with?("command_tower.lifecycle.")
68
+ return false if name.end_with?(".started")
69
+
70
+ outcome = (event.payload[:outcome] || event.payload["outcome"]).to_s
71
+ return true if %w[failure error].include?(outcome)
72
+
73
+ event.payload[:log_lifecycle] == true || event.payload["log_lifecycle"] == true
74
+ end
75
+
76
+ def log_entry(event)
77
+ CommandTower::Logging::Projection.call(event)
78
+ end
79
+
80
+ def severity_for(event)
81
+ name = event.name
82
+ if name.start_with?("command_tower.log.")
83
+ return named_severity(name.split(".").last)
84
+ end
85
+
86
+ payload_level = event.payload[:log_level] || event.payload["log_level"]
87
+ return named_severity(payload_level) if payload_level
88
+
89
+ return :debug if name.end_with?(".started")
90
+
91
+ outcome = event.payload[:outcome] || event.payload["outcome"]
92
+ return :error if outcome.to_s == "error"
93
+
94
+ :info
95
+ end
96
+
97
+ def named_severity(value)
98
+ level = value.to_sym
99
+ SEVERITIES.include?(level) ? level : :info
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CommandTower
4
+ module PrincipalCapabilities
5
+ class Error < CommandTower::Error; end
6
+
7
+ class UnregisteredCapabilityError < Error; end
8
+ class DuplicateCapabilityError < Error; end
9
+ class HostOverrideError < Error; end
10
+ class InvalidCapabilityNameError < Error; end
11
+ class InvalidCapabilityDefinitionError < Error; end
12
+ class MissingRequiredEntityError < Error; end
13
+ class FrozenRegistryError < Error; end
14
+ end
15
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CommandTower
4
- VERSION = "0.10.0"
4
+ VERSION = "0.11.0"
5
5
  end
data/lib/command_tower.rb CHANGED
@@ -1,5 +1,17 @@
1
1
  require "command_tower/error"
2
2
  require "command_tower/current"
3
+ require "command_tower/execution"
4
+ require "command_tower/events"
5
+ require "command_tower/audit"
6
+ require "command_tower/impersonation/activity_declaration"
7
+ require "command_tower/impersonation/apply_overlay"
8
+ require "command_tower/impersonation/clear_overlay_for_audit"
9
+ require "command_tower/impersonation/establish_identity"
10
+ require "command_tower/admin_workspace"
11
+ require "command_tower/admin_scope"
12
+ require "command_tower/logging/lifecycle_declaration"
13
+ require "command_tower/logging/projection"
14
+ require "command_tower/logging/subscriber"
3
15
 
4
16
  require "command_tower/version"
5
17
  require "command_tower/engine"
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :impersonation_session, class: "CommandTower::Impersonation::Session" do
5
+ association :actor, factory: :user
6
+ association :target, factory: :user
7
+ started_at { Time.current }
8
+ last_activity_at { Time.current }
9
+ idle_expires_at { 10.minutes.from_now }
10
+ absolute_expires_at { 1.hour.from_now }
11
+
12
+ trait :ended do
13
+ ended_at { Time.current }
14
+ end_reason { "manual" }
15
+ end
16
+ end
17
+ end
@@ -40,6 +40,22 @@ FactoryBot.define do
40
40
  roles { ["owner"] }
41
41
  end
42
42
 
43
+ trait :role_impersonation_operator do
44
+ roles { ["impersonation_operator"] }
45
+ end
46
+
47
+ trait :role_rbac_admin do
48
+ roles { ["rbac_admin"] }
49
+ end
50
+
51
+ trait :role_support_admin do
52
+ roles { ["support_admin"] }
53
+ end
54
+
55
+ trait :role_users_identity_admin do
56
+ roles { ["users_identity_admin"] }
57
+ end
58
+
43
59
  trait :without_phone do
44
60
  phone_number { nil }
45
61
  phone_number_validated { false }