atlas-auth 0.1.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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +132 -0
  4. data/lib/atlas/authorization.rb +78 -0
  5. data/lib/atlas/client.rb +124 -0
  6. data/lib/atlas/error.rb +92 -0
  7. data/lib/atlas/handshake.rb +241 -0
  8. data/lib/atlas/jwks_cache.rb +138 -0
  9. data/lib/atlas/pagination.rb +52 -0
  10. data/lib/atlas/resources/actions.rb +46 -0
  11. data/lib/atlas/resources/actor_tokens.rb +18 -0
  12. data/lib/atlas/resources/api_keys.rb +38 -0
  13. data/lib/atlas/resources/attack_protection.rb +18 -0
  14. data/lib/atlas/resources/audit_logs.rb +14 -0
  15. data/lib/atlas/resources/base.rb +32 -0
  16. data/lib/atlas/resources/billing.rb +35 -0
  17. data/lib/atlas/resources/bot_signals.rb +26 -0
  18. data/lib/atlas/resources/branding.rb +24 -0
  19. data/lib/atlas/resources/data_subject_requests.rb +28 -0
  20. data/lib/atlas/resources/domains.rb +26 -0
  21. data/lib/atlas/resources/email_templates.rb +29 -0
  22. data/lib/atlas/resources/fga.rb +146 -0
  23. data/lib/atlas/resources/import_export.rb +35 -0
  24. data/lib/atlas/resources/instance.rb +18 -0
  25. data/lib/atlas/resources/instance_security.rb +46 -0
  26. data/lib/atlas/resources/invitations.rb +22 -0
  27. data/lib/atlas/resources/jwt_templates.rb +32 -0
  28. data/lib/atlas/resources/localizations.rb +30 -0
  29. data/lib/atlas/resources/log_streams.rb +35 -0
  30. data/lib/atlas/resources/lti_platforms.rb +30 -0
  31. data/lib/atlas/resources/managed_waf.rb +35 -0
  32. data/lib/atlas/resources/messaging.rb +32 -0
  33. data/lib/atlas/resources/network_acls.rb +30 -0
  34. data/lib/atlas/resources/oauth_clients.rb +55 -0
  35. data/lib/atlas/resources/oauth_providers.rb +44 -0
  36. data/lib/atlas/resources/organizations.rb +140 -0
  37. data/lib/atlas/resources/radius_clients.rb +30 -0
  38. data/lib/atlas/resources/rate_limit.rb +18 -0
  39. data/lib/atlas/resources/resource_servers.rb +30 -0
  40. data/lib/atlas/resources/restrictions.rb +29 -0
  41. data/lib/atlas/resources/risk_based_mfa.rb +18 -0
  42. data/lib/atlas/resources/roles.rb +55 -0
  43. data/lib/atlas/resources/scim_provisioning.rb +46 -0
  44. data/lib/atlas/resources/scim_tokens.rb +23 -0
  45. data/lib/atlas/resources/sessions.rb +29 -0
  46. data/lib/atlas/resources/sign_in_tokens.rb +17 -0
  47. data/lib/atlas/resources/sms_templates.rb +37 -0
  48. data/lib/atlas/resources/sso_connections.rb +35 -0
  49. data/lib/atlas/resources/sso_onboarding.rb +37 -0
  50. data/lib/atlas/resources/tokens.rb +15 -0
  51. data/lib/atlas/resources/users.rb +121 -0
  52. data/lib/atlas/resources/waitlist.rb +19 -0
  53. data/lib/atlas/resources/webhooks.rb +35 -0
  54. data/lib/atlas/transport.rb +158 -0
  55. data/lib/atlas/verifier.rb +227 -0
  56. data/lib/atlas/version.rb +6 -0
  57. data/lib/atlas.rb +41 -0
  58. metadata +148 -0
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/branding+ — the hosted-page / email appearance bag.
8
+ class Branding < Base
9
+ def get
10
+ request(method: :get, path: "/v1/branding")
11
+ end
12
+
13
+ # A PARTIAL merge — one field changes, the rest is preserved.
14
+ def update(body)
15
+ request(method: :patch, path: "/v1/branding", body: body)
16
+ end
17
+
18
+ # Render a draft through the live sign-in renderer without saving it.
19
+ def preview(body)
20
+ request(method: :post, path: "/v1/branding/preview", body: body)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/data_subject_requests+ — the GDPR/DSAR admin surface.
8
+ class DataSubjectRequests < Base
9
+ def list(params = {})
10
+ request(method: :get, path: "/v1/data_subject_requests", query: params)
11
+ end
12
+
13
+ def get(id)
14
+ request(method: :get, path: "/v1/data_subject_requests/#{enc(id)}")
15
+ end
16
+
17
+ # Fulfil a request now — build the export package, or run the erasure.
18
+ def fulfill(id, idempotency_key: nil)
19
+ request(method: :post, path: "/v1/data_subject_requests/#{enc(id)}/fulfill", idempotency_key: idempotency_key)
20
+ end
21
+
22
+ # Reject a request with a recorded reason. Terminal.
23
+ def reject(id, body = {}, idempotency_key: nil)
24
+ request(method: :post, path: "/v1/data_subject_requests/#{enc(id)}/reject", body: body, idempotency_key: idempotency_key)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/domains+ — custom FAPI/accounts domains and their DNS verification.
8
+ class Domains < Base
9
+ def list
10
+ request(method: :get, path: "/v1/domains")
11
+ end
12
+
13
+ def create(body, idempotency_key: nil)
14
+ request(method: :post, path: "/v1/domains", body: body, idempotency_key: idempotency_key)
15
+ end
16
+
17
+ def verify(id)
18
+ request(method: :post, path: "/v1/domains/#{enc(id)}/verify")
19
+ end
20
+
21
+ def delete(id)
22
+ request(method: :delete, path: "/v1/domains/#{enc(id)}")
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/email_templates+ — transactional email templates, keyed by name.
8
+ class EmailTemplates < Base
9
+ def list
10
+ request(method: :get, path: "/v1/email_templates")
11
+ end
12
+
13
+ # Render an unsaved draft (if a body is given) or the stored template.
14
+ def preview(name, body = {})
15
+ request(method: :post, path: "/v1/email_templates/#{enc(name)}/preview", body: body)
16
+ end
17
+
18
+ # Save an override. Keyed by template name, not an id.
19
+ def update(name, body)
20
+ request(method: :put, path: "/v1/email_templates/#{enc(name)}", body: body)
21
+ end
22
+
23
+ # Revert to the built-in.
24
+ def delete(name)
25
+ request(method: :delete, path: "/v1/email_templates/#{enc(name)}")
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/fga+ — fine-grained relationship-based authorization (Zanzibar /
8
+ # OpenFGA). A tenant owns stores; each holds versioned models and the
9
+ # relationship tuples the engine resolves.
10
+ class Fga < Base
11
+ # +fga.stores+ — store CRUD.
12
+ def stores
13
+ @stores ||= Stores.new(@transport)
14
+ end
15
+
16
+ # +fga.models+ — authorization models within a store.
17
+ def models
18
+ @models ||= Models.new(@transport)
19
+ end
20
+
21
+ # Write and/or delete tuples in one atomic call.
22
+ def write(store_id, body, idempotency_key: nil)
23
+ request(method: :post, path: "/v1/fga/stores/#{enc(store_id)}/write", body: body, idempotency_key: idempotency_key)
24
+ end
25
+
26
+ # Query stored tuples by any of user / relation / object.
27
+ def read(store_id, body)
28
+ request(method: :post, path: "/v1/fga/stores/#{enc(store_id)}/read", body: body)
29
+ end
30
+
31
+ # Resolve a single access question against the model.
32
+ def check(store_id, body)
33
+ request(method: :post, path: "/v1/fga/stores/#{enc(store_id)}/check", body: body)
34
+ end
35
+
36
+ # Resolve MANY access questions in one round trip.
37
+ def batch_check(store_id, body)
38
+ request(method: :post, path: "/v1/fga/stores/#{enc(store_id)}/batch-check", body: body)
39
+ end
40
+
41
+ # List the objects of a type a user has a relation to.
42
+ def list_objects(store_id, body)
43
+ request(method: :post, path: "/v1/fga/stores/#{enc(store_id)}/list-objects", body: body)
44
+ end
45
+
46
+ # Expand the full userset tree for an object#relation.
47
+ def expand(store_id, body)
48
+ request(method: :post, path: "/v1/fga/stores/#{enc(store_id)}/expand", body: body)
49
+ end
50
+
51
+ # Bind a default store so an app that uses one store can call
52
+ # +fga.store(id).check(...)+ instead of threading the store id through
53
+ # every call. Returns the same operations with +store_id+ pre-applied.
54
+ def store(store_id)
55
+ StoreScope.new(self, store_id)
56
+ end
57
+
58
+ class Stores < Base
59
+ def list
60
+ request(method: :get, path: "/v1/fga/stores")
61
+ end
62
+
63
+ def create(body, idempotency_key: nil)
64
+ request(method: :post, path: "/v1/fga/stores", body: body, idempotency_key: idempotency_key)
65
+ end
66
+
67
+ def get(id)
68
+ request(method: :get, path: "/v1/fga/stores/#{enc(id)}")
69
+ end
70
+
71
+ def delete(id)
72
+ request(method: :delete, path: "/v1/fga/stores/#{enc(id)}")
73
+ end
74
+ end
75
+
76
+ class Models < Base
77
+ def list(store_id)
78
+ request(method: :get, path: "/v1/fga/stores/#{enc(store_id)}/authorization-models")
79
+ end
80
+
81
+ def create(store_id, body, idempotency_key: nil)
82
+ request(method: :post, path: "/v1/fga/stores/#{enc(store_id)}/authorization-models", body: body, idempotency_key: idempotency_key)
83
+ end
84
+
85
+ def get(store_id, model_id)
86
+ request(method: :get, path: "/v1/fga/stores/#{enc(store_id)}/authorization-models/#{enc(model_id)}")
87
+ end
88
+ end
89
+
90
+ # A store-bound view of the operations, so callers skip the store id.
91
+ class StoreScope
92
+ def initialize(fga, store_id)
93
+ @fga = fga
94
+ @store_id = store_id
95
+ end
96
+
97
+ def write(body, idempotency_key: nil)
98
+ @fga.write(@store_id, body, idempotency_key: idempotency_key)
99
+ end
100
+
101
+ def read(body)
102
+ @fga.read(@store_id, body)
103
+ end
104
+
105
+ def check(body)
106
+ @fga.check(@store_id, body)
107
+ end
108
+
109
+ def batch_check(body)
110
+ @fga.batch_check(@store_id, body)
111
+ end
112
+
113
+ def list_objects(body)
114
+ @fga.list_objects(@store_id, body)
115
+ end
116
+
117
+ def expand(body)
118
+ @fga.expand(@store_id, body)
119
+ end
120
+
121
+ def models
122
+ @models ||= BoundModels.new(@fga, @store_id)
123
+ end
124
+
125
+ class BoundModels
126
+ def initialize(fga, store_id)
127
+ @fga = fga
128
+ @store_id = store_id
129
+ end
130
+
131
+ def list
132
+ @fga.models.list(@store_id)
133
+ end
134
+
135
+ def create(body, idempotency_key: nil)
136
+ @fga.models.create(@store_id, body, idempotency_key: idempotency_key)
137
+ end
138
+
139
+ def get(model_id)
140
+ @fga.models.get(@store_id, model_id)
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/user_imports+, +/v1/user_exports+, +/v1/jobs+ — bulk user import/export
8
+ # jobs (the Auth0 +jobs+ parity surface).
9
+ class ImportExport < Base
10
+ # Import users through the same per-row path sign-up uses.
11
+ def import_users(body, idempotency_key: nil)
12
+ request(method: :post, path: "/v1/user_imports", body: body, idempotency_key: idempotency_key)
13
+ end
14
+
15
+ # Export every non-deleted user, serialised without secrets.
16
+ def export_users(idempotency_key: nil)
17
+ request(method: :post, path: "/v1/user_exports", idempotency_key: idempotency_key)
18
+ end
19
+
20
+ # Poll the instance's import/export jobs, newest first.
21
+ def list_jobs(params = {})
22
+ request(method: :get, path: "/v1/jobs", query: params)
23
+ end
24
+
25
+ def get_job(id)
26
+ request(method: :get, path: "/v1/jobs/#{enc(id)}")
27
+ end
28
+
29
+ # The per-row failures recorded against a job.
30
+ def get_job_errors(id)
31
+ request(method: :get, path: "/v1/jobs/#{enc(id)}/errors")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/instance+ — instance configuration (origins, auth config).
8
+ class Instance < Base
9
+ def get
10
+ request(method: :get, path: "/v1/instance")
11
+ end
12
+
13
+ def update(body)
14
+ request(method: :patch, path: "/v1/instance", body: body)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/instance/security+ — kill switches, IP allowlist, and the write-only
8
+ # provider secrets (captcha, Kerberos, LDAP bind password).
9
+ class InstanceSecurity < Base
10
+ def get
11
+ request(method: :get, path: "/v1/instance/security")
12
+ end
13
+
14
+ def update(body)
15
+ request(method: :patch, path: "/v1/instance/security", body: body)
16
+ end
17
+
18
+ # Store the captcha provider secret. Refused while the provider is +none+.
19
+ def set_captcha_secret(body)
20
+ request(method: :put, path: "/v1/instance/captcha_secret", body: body)
21
+ end
22
+
23
+ def delete_captcha_secret
24
+ request(method: :delete, path: "/v1/instance/captcha_secret")
25
+ end
26
+
27
+ # Store the Kerberos/IWA trusted-proxy secret.
28
+ def set_kerberos_secret(body)
29
+ request(method: :put, path: "/v1/instance/kerberos_secret", body: body)
30
+ end
31
+
32
+ def delete_kerberos_secret
33
+ request(method: :delete, path: "/v1/instance/kerberos_secret")
34
+ end
35
+
36
+ # Store an LDAP connection's service-account bind password.
37
+ def set_ldap_bind_password(connection_id, body)
38
+ request(method: :put, path: "/v1/instance/ldap_connections/#{enc(connection_id)}/bind_password", body: body)
39
+ end
40
+
41
+ def delete_ldap_bind_password(connection_id)
42
+ request(method: :delete, path: "/v1/instance/ldap_connections/#{enc(connection_id)}/bind_password")
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/invitations+ — instance-level sign-up invitations.
8
+ class Invitations < Base
9
+ def list(params = {})
10
+ request(method: :get, path: "/v1/invitations", query: params)
11
+ end
12
+
13
+ def create(body, idempotency_key: nil)
14
+ request(method: :post, path: "/v1/invitations", body: body, idempotency_key: idempotency_key)
15
+ end
16
+
17
+ def revoke(id)
18
+ request(method: :post, path: "/v1/invitations/#{enc(id)}/revoke")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/jwt_templates+ — custom JWT claim templates, keyed by name.
8
+ class JwtTemplates < Base
9
+ def list
10
+ request(method: :get, path: "/v1/jwt_templates")
11
+ end
12
+
13
+ # Fetched by template name.
14
+ def get(name)
15
+ request(method: :get, path: "/v1/jwt_templates/#{enc(name)}")
16
+ end
17
+
18
+ def create(body)
19
+ request(method: :post, path: "/v1/jwt_templates", body: body)
20
+ end
21
+
22
+ # Only the claims are updatable; the name is the key.
23
+ def update(name, body)
24
+ request(method: :patch, path: "/v1/jwt_templates/#{enc(name)}", body: body)
25
+ end
26
+
27
+ def delete(name)
28
+ request(method: :delete, path: "/v1/jwt_templates/#{enc(name)}")
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/localizations+ — per-locale overrides for emails, SMS, and prompt copy.
8
+ class Localizations < Base
9
+ def list(params = {})
10
+ request(method: :get, path: "/v1/localizations", query: params)
11
+ end
12
+
13
+ def create(body, idempotency_key: nil)
14
+ request(method: :post, path: "/v1/localizations", body: body, idempotency_key: idempotency_key)
15
+ end
16
+
17
+ def get(id)
18
+ request(method: :get, path: "/v1/localizations/#{enc(id)}")
19
+ end
20
+
21
+ def update(id, body)
22
+ request(method: :patch, path: "/v1/localizations/#{enc(id)}", body: body)
23
+ end
24
+
25
+ def delete(id)
26
+ request(method: :delete, path: "/v1/localizations/#{enc(id)}")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/log_streams+ — the instance event feed forwarded to external sinks.
8
+ class LogStreams < Base
9
+ def list
10
+ request(method: :get, path: "/v1/log_streams")
11
+ end
12
+
13
+ def get(id)
14
+ request(method: :get, path: "/v1/log_streams/#{enc(id)}")
15
+ end
16
+
17
+ def create(body, idempotency_key: nil)
18
+ request(method: :post, path: "/v1/log_streams", body: body, idempotency_key: idempotency_key)
19
+ end
20
+
21
+ def update(id, body)
22
+ request(method: :patch, path: "/v1/log_streams/#{enc(id)}", body: body)
23
+ end
24
+
25
+ def delete(id)
26
+ request(method: :delete, path: "/v1/log_streams/#{enc(id)}")
27
+ end
28
+
29
+ # Send ONE synthetic event with the real credentials.
30
+ def test(id)
31
+ request(method: :post, path: "/v1/log_streams/#{enc(id)}/test")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/lti_platforms+ — LTI 1.3 platform (LMS) registrations.
8
+ class LtiPlatforms < Base
9
+ def list
10
+ request(method: :get, path: "/v1/lti_platforms")
11
+ end
12
+
13
+ def get(id)
14
+ request(method: :get, path: "/v1/lti_platforms/#{enc(id)}")
15
+ end
16
+
17
+ def create(body, idempotency_key: nil)
18
+ request(method: :post, path: "/v1/lti_platforms", body: body, idempotency_key: idempotency_key)
19
+ end
20
+
21
+ def update(id, body)
22
+ request(method: :patch, path: "/v1/lti_platforms/#{enc(id)}", body: body)
23
+ end
24
+
25
+ def delete(id)
26
+ request(method: :delete, path: "/v1/lti_platforms/#{enc(id)}")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/managed_waf+ — the managed AWS WAF captcha gate control plane.
8
+ class ManagedWaf < Base
9
+ # Read config + provisioning state, with secrets reduced to +has_*+ markers.
10
+ def get
11
+ request(method: :get, path: "/v1/managed_waf")
12
+ end
13
+
14
+ # Read just the provisioning state.
15
+ def status
16
+ request(method: :get, path: "/v1/managed_waf/status")
17
+ end
18
+
19
+ # Set config and write-only credentials; omitted fields are left unchanged.
20
+ def update(body)
21
+ request(method: :put, path: "/v1/managed_waf", body: body)
22
+ end
23
+
24
+ # Apply now — idempotent create/update + associate the WebACL.
25
+ def provision
26
+ request(method: :post, path: "/v1/managed_waf/provision")
27
+ end
28
+
29
+ # Disassociate and delete the WebACL.
30
+ def deprovision
31
+ request(method: :post, path: "/v1/managed_waf/deprovision")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/messaging_providers+ — BYOK email/SMS provider config.
8
+ class Messaging < Base
9
+ # The instance's configured email and SMS providers, secrets omitted.
10
+ def get
11
+ request(method: :get, path: "/v1/messaging_providers")
12
+ end
13
+
14
+ def set_email(body)
15
+ request(method: :put, path: "/v1/messaging_providers/email", body: body)
16
+ end
17
+
18
+ def set_sms(body)
19
+ request(method: :put, path: "/v1/messaging_providers/sms", body: body)
20
+ end
21
+
22
+ def delete_channel(channel)
23
+ request(method: :delete, path: "/v1/messaging_providers/#{enc(channel)}")
24
+ end
25
+
26
+ # Send a fixed, clearly-marked test message through the channel's provider.
27
+ def test(channel, body)
28
+ request(method: :post, path: "/v1/messaging_providers/#{enc(channel)}/test", body: body)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/network_acls+ — per-instance IP allow/deny rules, priority-ordered.
8
+ class NetworkAcls < Base
9
+ def list
10
+ request(method: :get, path: "/v1/network_acls")
11
+ end
12
+
13
+ def get(id)
14
+ request(method: :get, path: "/v1/network_acls/#{enc(id)}")
15
+ end
16
+
17
+ def create(body, idempotency_key: nil)
18
+ request(method: :post, path: "/v1/network_acls", body: body, idempotency_key: idempotency_key)
19
+ end
20
+
21
+ def update(id, body)
22
+ request(method: :patch, path: "/v1/network_acls/#{enc(id)}", body: body)
23
+ end
24
+
25
+ def delete(id)
26
+ request(method: :delete, path: "/v1/network_acls/#{enc(id)}")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Atlas
6
+ module Resources
7
+ # +/v1/oauth_clients+ — first- and third-party OAuth/OIDC clients, plus their
8
+ # resource-server grants.
9
+ class OAuthClients < Base
10
+ def list
11
+ request(method: :get, path: "/v1/oauth_clients")
12
+ end
13
+
14
+ def get(id)
15
+ request(method: :get, path: "/v1/oauth_clients/#{enc(id)}")
16
+ end
17
+
18
+ # Create reveals the client secret exactly once.
19
+ def create(body, idempotency_key: nil)
20
+ request(method: :post, path: "/v1/oauth_clients", body: body, idempotency_key: idempotency_key)
21
+ end
22
+
23
+ def update(id, body)
24
+ request(method: :patch, path: "/v1/oauth_clients/#{enc(id)}", body: body)
25
+ end
26
+
27
+ def rotate_secret(id)
28
+ request(method: :post, path: "/v1/oauth_clients/#{enc(id)}/rotate_secret")
29
+ end
30
+
31
+ def delete(id)
32
+ request(method: :delete, path: "/v1/oauth_clients/#{enc(id)}")
33
+ end
34
+
35
+ # +oauth_clients.grants+ — resource-server grants for a client.
36
+ def grants
37
+ @grants ||= Grants.new(@transport)
38
+ end
39
+
40
+ class Grants < Base
41
+ def list(client_id)
42
+ request(method: :get, path: "/v1/oauth_clients/#{enc(client_id)}/grants")
43
+ end
44
+
45
+ def create(client_id, body)
46
+ request(method: :post, path: "/v1/oauth_clients/#{enc(client_id)}/grants", body: body)
47
+ end
48
+
49
+ def delete(client_id, grant_id)
50
+ request(method: :delete, path: "/v1/oauth_clients/#{enc(client_id)}/grants/#{enc(grant_id)}")
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end