noresponse 7.0.5 → 7.1.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/lib/no_response/keys.rb +866 -0
  3. data/lib/no_response/late_results.rb +5 -3
  4. data/lib/no_response/models/operations/createkey_request.rb +37 -0
  5. data/lib/no_response/models/operations/createkey_request.rbi +20 -0
  6. data/lib/no_response/models/operations/createkey_response.rb +32 -0
  7. data/lib/no_response/models/operations/createkey_response.rbi +20 -0
  8. data/lib/no_response/models/operations/getsettings_request.rb +41 -0
  9. data/lib/no_response/models/operations/getsettings_request.rbi +20 -0
  10. data/lib/no_response/models/operations/getsettings_response.rb +32 -0
  11. data/lib/no_response/models/operations/getsettings_response.rbi +20 -0
  12. data/lib/no_response/models/operations/listaccounts_request.rb +1 -1
  13. data/lib/no_response/models/operations/listkeys_request.rb +33 -0
  14. data/lib/no_response/models/operations/listkeys_request.rbi +14 -0
  15. data/lib/no_response/models/operations/listkeys_response.rb +32 -0
  16. data/lib/no_response/models/operations/listkeys_response.rbi +20 -0
  17. data/lib/no_response/models/operations/revokekey_request.rb +37 -0
  18. data/lib/no_response/models/operations/revokekey_request.rbi +20 -0
  19. data/lib/no_response/models/operations/revokekey_response.rb +32 -0
  20. data/lib/no_response/models/operations/revokekey_response.rbi +20 -0
  21. data/lib/no_response/models/operations/updatesettings_request.rb +52 -0
  22. data/lib/no_response/models/operations/updatesettings_request.rbi +26 -0
  23. data/lib/no_response/models/operations/updatesettings_response.rb +32 -0
  24. data/lib/no_response/models/operations/updatesettings_response.rbi +20 -0
  25. data/lib/no_response/models/operations.rb +10 -0
  26. data/lib/no_response/models/shared/admission.rb +19 -0
  27. data/lib/no_response/models/shared/admission.rbi +9 -0
  28. data/lib/no_response/models/shared/conflicterrorcode.rb +2 -0
  29. data/lib/no_response/models/shared/defaultdepth.rb +19 -0
  30. data/lib/no_response/models/shared/defaultdepth.rbi +9 -0
  31. data/lib/no_response/models/shared/enforcement.rb +1 -1
  32. data/lib/no_response/models/shared/enforcementaction.rb +2 -1
  33. data/lib/no_response/models/shared/enforcementrequest.rb +1 -1
  34. data/lib/no_response/models/shared/flowchange.rb +136 -0
  35. data/lib/no_response/models/shared/flowchange.rbi +62 -0
  36. data/lib/no_response/models/shared/flowsettings.rb +127 -0
  37. data/lib/no_response/models/shared/flowsettings.rbi +56 -0
  38. data/lib/no_response/models/shared/key.rb +158 -0
  39. data/lib/no_response/models/shared/key.rbi +80 -0
  40. data/lib/no_response/models/shared/{scope.rb → key_scope.rb} +2 -1
  41. data/lib/no_response/models/shared/{scope.rbi → key_scope.rbi} +2 -2
  42. data/lib/no_response/models/shared/keyenvironment.rb +19 -0
  43. data/lib/no_response/models/shared/keyenvironment.rbi +9 -0
  44. data/lib/no_response/models/shared/keylist.rb +32 -0
  45. data/lib/no_response/models/shared/keylist.rbi +14 -0
  46. data/lib/no_response/models/shared/keyrequest.rb +49 -0
  47. data/lib/no_response/models/shared/keyrequest.rbi +20 -0
  48. data/lib/no_response/models/shared/keyrequest_scope.rb +21 -0
  49. data/lib/no_response/models/shared/keyrequest_scope.rbi +9 -0
  50. data/lib/no_response/models/shared/keyrotation.rb +2 -2
  51. data/lib/no_response/models/shared/keyrotation_scope.rb +24 -0
  52. data/lib/no_response/models/shared/keyrotation_scope.rbi +9 -0
  53. data/lib/no_response/models/shared/keystatus.rb +20 -0
  54. data/lib/no_response/models/shared/keystatus.rbi +9 -0
  55. data/lib/no_response/models/shared/onexpiry.rb +20 -0
  56. data/lib/no_response/models/shared/onexpiry.rbi +9 -0
  57. data/lib/no_response/models/shared/permissiondeniederrorcode.rb +1 -0
  58. data/lib/no_response/models/shared/settings.rb +116 -0
  59. data/lib/no_response/models/shared/settings.rbi +56 -0
  60. data/lib/no_response/models/shared/settingsflows.rb +56 -0
  61. data/lib/no_response/models/shared/settingsflows.rbi +26 -0
  62. data/lib/no_response/models/shared/settingsrequest.rb +55 -0
  63. data/lib/no_response/models/shared/settingsrequest.rbi +26 -0
  64. data/lib/no_response/models/shared/settingsrequestflows.rb +65 -0
  65. data/lib/no_response/models/shared/settingsrequestflows.rbi +32 -0
  66. data/lib/no_response/models/shared/sourceid.rb +23 -0
  67. data/lib/no_response/models/shared/sourceid.rbi +9 -0
  68. data/lib/no_response/models/shared.rb +18 -1
  69. data/lib/no_response/noresponseclient.rb +2 -1
  70. data/lib/no_response/sdkconfiguration.rb +2 -2
  71. data/lib/no_response/settings.rb +633 -0
  72. data/lib/noresponse.rb +1 -0
  73. metadata +58 -3
@@ -0,0 +1,158 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module NoResponse
5
+ module Models
6
+ module Shared
7
+ # One API key of your workspace. A key belongs to exactly one environment. key, the secret credential, is present only in the answer that created the key: NoResponse keeps a peppered digest of it, so store it now. Every other field is safe to show.
8
+ class Key
9
+ extend T::Sig
10
+ include Crystalline::MetadataFields
11
+
12
+ # The key's public id, a 26-character ULID.
13
+ field :id, ::String, {'format_json': {'letter_case': ::NoResponse::Utils.field_name("id"), required: true}}
14
+ # The workspace id, which is also its live environment's workspace id; the test environment's is the same id with :test appended. A workspace created through the API is tnt_ and a 26-character ULID.
15
+ field(
16
+ :workspace_id,
17
+ ::String,
18
+ {'format_json': {'letter_case': ::NoResponse::Utils.field_name("workspace_id"), required: true}}
19
+ )
20
+ # The environment the key belongs to. A live key assesses with live sources; a test key answers from the deterministic simulator.
21
+ field(
22
+ :environment,
23
+ Models::Shared::KeyEnvironment,
24
+ {
25
+ 'format_json': {
26
+ 'letter_case': ::NoResponse::Utils.field_name("environment"),
27
+ required: true,
28
+ 'decoder': ::NoResponse::Utils.open_enum_from_string(Models::Shared::KeyEnvironment, false)
29
+ }
30
+ }
31
+ )
32
+ # The public start of the credential, nrk_<environment>_<key id>, which identifies the key in logs and secret stores without its secret.
33
+ field(
34
+ :prefix,
35
+ ::String,
36
+ {'format_json': {'letter_case': ::NoResponse::Utils.field_name("prefix"), required: true}}
37
+ )
38
+ # The key's scopes, each at most once.
39
+ field(
40
+ :scopes,
41
+ Crystalline::Array.new(Models::Shared::KeyScope),
42
+ {'format_json': {'letter_case': ::NoResponse::Utils.field_name("scopes"), required: true}}
43
+ )
44
+ # active: the key authenticates. expired: a rotation's overlap window has ended (expires_at). revoked: the key was revoked (revoked_at) and answers 401.
45
+ field(
46
+ :status,
47
+ Models::Shared::KeyStatus,
48
+ {
49
+ 'format_json': {
50
+ 'letter_case': ::NoResponse::Utils.field_name("status"),
51
+ required: true,
52
+ 'decoder': ::NoResponse::Utils.open_enum_from_string(Models::Shared::KeyStatus, false)
53
+ }
54
+ }
55
+ )
56
+
57
+ field(
58
+ :created_at,
59
+ ::String,
60
+ {'format_json': {'letter_case': ::NoResponse::Utils.field_name("created_at"), required: true}}
61
+ )
62
+ # The external user id of the member who created the key through the console, or the prefix (nrk_<environment>_<key id>) of the management key that created it. Absent for a key NoResponse issued or a rotation made.
63
+ field(
64
+ :created_by,
65
+ Crystalline::Nilable.new(::String),
66
+ {'format_json': {'letter_case': ::NoResponse::Utils.field_name("created_by")}}
67
+ )
68
+ # When a rotated key stops authenticating (POST /v1/keys/rotate). Absent for a key with no end.
69
+ field(
70
+ :expires_at,
71
+ Crystalline::Nilable.new(::String),
72
+ {'format_json': {'letter_case': ::NoResponse::Utils.field_name("expires_at")}}
73
+ )
74
+
75
+ field(
76
+ :revoked_at,
77
+ Crystalline::Nilable.new(::String),
78
+ {'format_json': {'letter_case': ::NoResponse::Utils.field_name("revoked_at")}}
79
+ )
80
+ # The external user id of the member who revoked the key through the console, or the prefix of the management key that revoked it. Absent when the key is not revoked or NoResponse revoked it.
81
+ field(
82
+ :revoked_by,
83
+ Crystalline::Nilable.new(::String),
84
+ {'format_json': {'letter_case': ::NoResponse::Utils.field_name("revoked_by")}}
85
+ )
86
+ # The credential, nrk_<environment>_<key id>_<secret>. Present only in the 201 answer that created the key.
87
+ field(
88
+ :key,
89
+ Crystalline::Nilable.new(::String),
90
+ {'format_json': {'letter_case': ::NoResponse::Utils.field_name("key")}}
91
+ )
92
+
93
+ sig {
94
+ params(
95
+ id: ::String,
96
+ workspace_id: ::String,
97
+ environment: Models::Shared::KeyEnvironment,
98
+ prefix: ::String,
99
+ scopes: T::Array[Models::Shared::KeyScope],
100
+ status: Models::Shared::KeyStatus,
101
+ created_at: ::String,
102
+ created_by: T.nilable(::String),
103
+ expires_at: T.nilable(::String),
104
+ revoked_at: T.nilable(::String),
105
+ revoked_by: T.nilable(::String),
106
+ key: T.nilable(::String)
107
+ )
108
+ .void
109
+ }
110
+ def initialize(
111
+ id:,
112
+ workspace_id:,
113
+ environment:,
114
+ prefix:,
115
+ scopes:,
116
+ status:,
117
+ created_at:,
118
+ created_by: nil,
119
+ expires_at: nil,
120
+ revoked_at: nil,
121
+ revoked_by: nil,
122
+ key: nil
123
+ )
124
+ @id = id
125
+ @workspace_id = workspace_id
126
+ @environment = environment
127
+ @prefix = prefix
128
+ @scopes = scopes
129
+ @status = status
130
+ @created_at = created_at
131
+ @created_by = created_by
132
+ @expires_at = expires_at
133
+ @revoked_at = revoked_at
134
+ @revoked_by = revoked_by
135
+ @key = key
136
+ end
137
+
138
+ sig { params(other: T.untyped).returns(T::Boolean) }
139
+ def ==(other)
140
+ return false unless other.is_a?(self.class)
141
+ return false unless @id == other.id
142
+ return false unless @workspace_id == other.workspace_id
143
+ return false unless @environment == other.environment
144
+ return false unless @prefix == other.prefix
145
+ return false unless @scopes == other.scopes
146
+ return false unless @status == other.status
147
+ return false unless @created_at == other.created_at
148
+ return false unless @created_by == other.created_by
149
+ return false unless @expires_at == other.expires_at
150
+ return false unless @revoked_at == other.revoked_at
151
+ return false unless @revoked_by == other.revoked_by
152
+ return false unless @key == other.key
153
+ true
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,80 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ class NoResponse::Models::Shared::Key
5
+ extend ::Crystalline::MetadataFields::ClassMethods
6
+ end
7
+
8
+ class NoResponse::Models::Shared::Key
9
+ def id
10
+ end
11
+
12
+ def id=(str_)
13
+ end
14
+
15
+ def workspace_id
16
+ end
17
+
18
+ def workspace_id=(str_)
19
+ end
20
+
21
+ def environment
22
+ end
23
+
24
+ def environment=(str_)
25
+ end
26
+
27
+ def prefix
28
+ end
29
+
30
+ def prefix=(str_)
31
+ end
32
+
33
+ def scopes
34
+ end
35
+
36
+ def scopes=(str_)
37
+ end
38
+
39
+ def status
40
+ end
41
+
42
+ def status=(str_)
43
+ end
44
+
45
+ def created_at
46
+ end
47
+
48
+ def created_at=(str_)
49
+ end
50
+
51
+ def created_by
52
+ end
53
+
54
+ def created_by=(str_)
55
+ end
56
+
57
+ def expires_at
58
+ end
59
+
60
+ def expires_at=(str_)
61
+ end
62
+
63
+ def revoked_at
64
+ end
65
+
66
+ def revoked_at=(str_)
67
+ end
68
+
69
+ def revoked_by
70
+ end
71
+
72
+ def revoked_by=(str_)
73
+ end
74
+
75
+ def key
76
+ end
77
+
78
+ def key=(str_)
79
+ end
80
+ end
@@ -5,7 +5,7 @@ module NoResponse
5
5
  module Models
6
6
  module Shared
7
7
 
8
- class Scope
8
+ class KeyScope
9
9
  include ::Crystalline::Enum
10
10
  enums do
11
11
  ASSESS = new("assess")
@@ -14,6 +14,7 @@ module NoResponse
14
14
  WEBHOOKS = new("webhooks")
15
15
  DETAILED = new("detailed")
16
16
  INTEGRATIONS = new("integrations")
17
+ MANAGEMENT = new("management")
17
18
  end
18
19
 
19
20
  open!
@@ -1,9 +1,9 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
- class NoResponse::Models::Shared::Scope
4
+ class NoResponse::Models::Shared::KeyScope
5
5
  extend ::Crystalline::MetadataFields::ClassMethods
6
6
  end
7
7
 
8
- class NoResponse::Models::Shared::Scope
8
+ class NoResponse::Models::Shared::KeyScope
9
9
  end
@@ -0,0 +1,19 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module NoResponse
5
+ module Models
6
+ module Shared
7
+ # KeyEnvironment - The environment the key belongs to. A live key assesses with live sources; a test key answers from the deterministic simulator.
8
+ class KeyEnvironment
9
+ include ::Crystalline::Enum
10
+ enums do
11
+ LIVE = new("live")
12
+ TEST = new("test")
13
+ end
14
+
15
+ open!
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ class NoResponse::Models::Shared::KeyEnvironment
5
+ extend ::Crystalline::MetadataFields::ClassMethods
6
+ end
7
+
8
+ class NoResponse::Models::Shared::KeyEnvironment
9
+ end
@@ -0,0 +1,32 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module NoResponse
5
+ module Models
6
+ module Shared
7
+ # GET /v1/workspaces/{workspace_id}/keys: the keys of both of the workspace's environments, newest first, at most 200 of each, revoked and expired keys included. No item carries a secret.
8
+ class KeyList
9
+ extend T::Sig
10
+ include Crystalline::MetadataFields
11
+
12
+ field(
13
+ :items,
14
+ Crystalline::Array.new(Models::Shared::Key),
15
+ {'format_json': {'letter_case': ::NoResponse::Utils.field_name("items"), required: true}}
16
+ )
17
+
18
+ sig { params(items: T::Array[Models::Shared::Key]).void }
19
+ def initialize(items:)
20
+ @items = items
21
+ end
22
+
23
+ sig { params(other: T.untyped).returns(T::Boolean) }
24
+ def ==(other)
25
+ return false unless other.is_a?(self.class)
26
+ return false unless @items == other.items
27
+ true
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,14 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ class NoResponse::Models::Shared::KeyList
5
+ extend ::Crystalline::MetadataFields::ClassMethods
6
+ end
7
+
8
+ class NoResponse::Models::Shared::KeyList
9
+ def items
10
+ end
11
+
12
+ def items=(str_)
13
+ end
14
+ end
@@ -0,0 +1,49 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module NoResponse
5
+ module Models
6
+ module Shared
7
+ # POST /v1/workspaces/{workspace_id}/keys body. Creates an API key in one environment of the workspace with the scopes named, and returns its secret once. A live key needs the admin or owner role; a test key needs developer or above. An API key with the management scope creates keys in its own environment with scopes it holds itself. Each scope may appear once.
8
+ class KeyRequest
9
+ extend T::Sig
10
+ include Crystalline::MetadataFields
11
+
12
+ # The environment the key belongs to. A live key assesses with live sources; a test key answers from the deterministic simulator.
13
+ field(
14
+ :environment,
15
+ Models::Shared::KeyEnvironment,
16
+ {
17
+ 'format_json': {
18
+ 'letter_case': ::NoResponse::Utils.field_name("environment"),
19
+ required: true,
20
+ 'decoder': ::NoResponse::Utils.open_enum_from_string(Models::Shared::KeyEnvironment, false)
21
+ }
22
+ }
23
+ )
24
+ # The key's scopes, each at most once.
25
+ field(
26
+ :scopes,
27
+ Crystalline::Array.new(Models::Shared::KeyRequestScope),
28
+ {'format_json': {'letter_case': ::NoResponse::Utils.field_name("scopes"), required: true}}
29
+ )
30
+
31
+ sig {
32
+ params(environment: Models::Shared::KeyEnvironment, scopes: T::Array[Models::Shared::KeyRequestScope]).void
33
+ }
34
+ def initialize(environment:, scopes:)
35
+ @environment = environment
36
+ @scopes = scopes
37
+ end
38
+
39
+ sig { params(other: T.untyped).returns(T::Boolean) }
40
+ def ==(other)
41
+ return false unless other.is_a?(self.class)
42
+ return false unless @environment == other.environment
43
+ return false unless @scopes == other.scopes
44
+ true
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,20 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ class NoResponse::Models::Shared::KeyRequest
5
+ extend ::Crystalline::MetadataFields::ClassMethods
6
+ end
7
+
8
+ class NoResponse::Models::Shared::KeyRequest
9
+ def environment
10
+ end
11
+
12
+ def environment=(str_)
13
+ end
14
+
15
+ def scopes
16
+ end
17
+
18
+ def scopes=(str_)
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module NoResponse
5
+ module Models
6
+ module Shared
7
+
8
+ class KeyRequestScope < T::Enum
9
+ enums do
10
+ ASSESS = new("assess")
11
+ HISTORY = new("history")
12
+ DELETE = new("delete")
13
+ WEBHOOKS = new("webhooks")
14
+ DETAILED = new("detailed")
15
+ INTEGRATIONS = new("integrations")
16
+ MANAGEMENT = new("management")
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ class NoResponse::Models::Shared::KeyRequestScope
5
+ extend ::Crystalline::MetadataFields::ClassMethods
6
+ end
7
+
8
+ class NoResponse::Models::Shared::KeyRequestScope
9
+ end
@@ -20,7 +20,7 @@ module NoResponse
20
20
  # The scopes of the new key: those of the presented key.
21
21
  field(
22
22
  :scopes,
23
- Crystalline::Array.new(Models::Shared::Scope),
23
+ Crystalline::Array.new(Models::Shared::KeyRotationScope),
24
24
  {'format_json': {'letter_case': ::NoResponse::Utils.field_name("scopes"), required: true}}
25
25
  )
26
26
 
@@ -46,7 +46,7 @@ module NoResponse
46
46
  params(
47
47
  key: ::String,
48
48
  key_id: ::String,
49
- scopes: T::Array[Models::Shared::Scope],
49
+ scopes: T::Array[Models::Shared::KeyRotationScope],
50
50
  created_at: ::String,
51
51
  previous_key_id: ::String,
52
52
  previous_key_expires_at: ::String
@@ -0,0 +1,24 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module NoResponse
5
+ module Models
6
+ module Shared
7
+
8
+ class KeyRotationScope
9
+ include ::Crystalline::Enum
10
+ enums do
11
+ ASSESS = new("assess")
12
+ HISTORY = new("history")
13
+ DELETE = new("delete")
14
+ WEBHOOKS = new("webhooks")
15
+ DETAILED = new("detailed")
16
+ INTEGRATIONS = new("integrations")
17
+ MANAGEMENT = new("management")
18
+ end
19
+
20
+ open!
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ class NoResponse::Models::Shared::KeyRotationScope
5
+ extend ::Crystalline::MetadataFields::ClassMethods
6
+ end
7
+
8
+ class NoResponse::Models::Shared::KeyRotationScope
9
+ end
@@ -0,0 +1,20 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module NoResponse
5
+ module Models
6
+ module Shared
7
+ # KeyStatus - active: the key authenticates. expired: a rotation's overlap window has ended (expires_at). revoked: the key was revoked (revoked_at) and answers 401.
8
+ class KeyStatus
9
+ include ::Crystalline::Enum
10
+ enums do
11
+ ACTIVE = new("active")
12
+ EXPIRED = new("expired")
13
+ REVOKED = new("revoked")
14
+ end
15
+
16
+ open!
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ class NoResponse::Models::Shared::KeyStatus
5
+ extend ::Crystalline::MetadataFields::ClassMethods
6
+ end
7
+
8
+ class NoResponse::Models::Shared::KeyStatus
9
+ end
@@ -0,0 +1,20 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module NoResponse
5
+ module Models
6
+ module Shared
7
+ # OnExpiry - The decision a held assessment takes when hold_seconds pass before its investigation completes, unless the evidence so far gives a stricter one (default review). It is announced as account.risk_changed like any other change, so an expired hold is always announced. A hosted provider hook, which cannot wait, answers a held account by it at once: deny for block, allow otherwise. Kept while the flow is immediate.
8
+ class OnExpiry
9
+ include ::Crystalline::Enum
10
+ enums do
11
+ ALLOW = new("allow")
12
+ REVIEW = new("review")
13
+ BLOCK = new("block")
14
+ end
15
+
16
+ open!
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ class NoResponse::Models::Shared::OnExpiry
5
+ extend ::Crystalline::MetadataFields::ClassMethods
6
+ end
7
+
8
+ class NoResponse::Models::Shared::OnExpiry
9
+ end
@@ -9,6 +9,7 @@ module NoResponse
9
9
  include ::Crystalline::Enum
10
10
  enums do
11
11
  WORKSPACE_FORBIDDEN = new("workspace_forbidden")
12
+ ROLE_FORBIDDEN = new("role_forbidden")
12
13
  end
13
14
 
14
15
  open!