authentik-client 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 24871367b4b0088be76770175ded67c9b75cdb9ab2caae7998a90ccb08d25fcd
4
+ data.tar.gz: 8cd0c9eb33a1190635f70ac09ee4a3beb69a2a73dd4bee48a8c41ef2bd315f66
5
+ SHA512:
6
+ metadata.gz: 257b35255cfea42bca4769f907e73734ec6e8e0795371fe7d4c3fc90efae70100c4c4fc3e99404e38edd2d456586a71770d0202838cb97fb46d6d9f188fbe6fb
7
+ data.tar.gz: 9aa0e218a8ee23ae0aaefb8ac8a5c036556ee8523bb40b7d787bd24f3d5ac8bbf6ba241efd85337413ffef906965ac57c313b35b3299c4407e9e52566d161ced
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## 0.1.0 - 2026-04-08
4
+
5
+ - Initial release
@@ -0,0 +1,10 @@
1
+ # Code of Conduct
2
+
3
+ This project follows [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct) in all "collaborative space", which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.):
4
+
5
+ * Participants will be tolerant of opposing views.
6
+ * Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
7
+ * When interpreting the words and actions of others, participants should always assume good intentions.
8
+ * Behavior which can be reasonably considered harassment will not be tolerated.
9
+
10
+ If you have any concerns about behavior within this project, please contact us at ["david.uhlig@gmail.com"](mailto:"david.uhlig@gmail.com").
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ # The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 David Uhlig
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,294 @@
1
+ # 🔓 authentik API Client
2
+
3
+ [![Gem Version](http://img.shields.io/gem/v/authentik-client.svg)][gem]
4
+ [![License: MIT](https://img.shields.io/github/license/david-uhlig/authentik-client?label=License&labelColor=343B42&color=blue)][license]
5
+ [![Tests](https://github.com/david-uhlig/authentik-client/actions/workflows/main.yml/badge.svg)][tests]
6
+
7
+ An idiomatic Ruby interface for the [authentik] API; the open-source Identity Provider (IdP) and Single Sign On (SSO) platform.
8
+
9
+ This library lets you manage configuration objects in authentik - such as users, groups, and more - through a clean Ruby interface. It is *not* intended for handling SSO within your own application.
10
+
11
+ Built as a developer-friendly wrapper around the auto-generated [authentik-api] gem (via OpenAPI Generator), it simplifies common tasks and abstracts away much of the low-level complexity of the underlying client.
12
+
13
+ > [!TIP]
14
+ > For guidance on handling authentication, see [Authentication with authentik in Ruby](#authentication-with-authentik-in-ruby).
15
+
16
+ ## Installation
17
+
18
+ Add the following line to your application's Gemfile:
19
+
20
+ ```bash
21
+ gem "authentik-client"
22
+ ```
23
+
24
+ Then install the dependencies with `bundle install`. Alternatively, you can add the gem directly from the commandline: `bundle add "authentik-client"`.
25
+
26
+ This installs the latest release of the baseline [authentik-api] client, which tracks the most recent authentik release.
27
+
28
+ To ensure compatibility with a specific authentik version, explicitly require a matching `authentik-api` version:
29
+
30
+ ```ruby
31
+ # Use the latest `2026.2.x` series release (excluding release candidates).
32
+ gem "authentik-api" "~> 2026.2.0"
33
+ gem "authentik-client"
34
+ # Pin to an exact patch version.
35
+ gem "authentik-api" "2026.2.1"
36
+ gem "authentik-client"
37
+ # Test a release candidate.
38
+ gem "authentik-api" "2026.5.0-rc1"
39
+ gem "authentik-client"
40
+ # Use the latest unreleased code from GitHub.
41
+ # Tracks authentik's main branch and updates daily when the OpenAPI schema changes.
42
+ gem "authentik-api", github: "david-uhlig/authentik-api"
43
+ gem "authentik-client"
44
+ ```
45
+
46
+ ## Usage
47
+
48
+ ### Configuration
49
+
50
+ This gem offers three ways to initialize the authentik API client:
51
+
52
+ * [At startup](#configuring-at-startup), with an initializer
53
+ * [A Rails configuration file](#rails-integration), e.g. `config/application.rb`
54
+ * [At runtime](#creating-a-client)
55
+
56
+ You can freely mix startup and runtime initialization; i.e., initialize the host in a Rails configuration file and provide the token at runtime.
57
+
58
+ #### Configuring at startup
59
+
60
+ You can configure `Authentik::Client` once globally. For example, at application startup (e.g., in a Rails initializer), and then create client instances without repeating connection details:
61
+
62
+ ```ruby
63
+ # config/initializers/authentik.rb
64
+ Authentik::Client.configure do |config|
65
+ config.host = "authentik.example.com"
66
+ config.token = "your-api-token"
67
+ end
68
+ ```
69
+
70
+ With a global configuration in place, clients can be created without arguments:
71
+
72
+ ```ruby
73
+ client = Authentik::Client.new
74
+ ```
75
+
76
+ But you can also overwrite any globally configured attribute:
77
+
78
+ ```ruby
79
+ client = Authentik::Client.new(token: "your-runtime-api-token")
80
+ ```
81
+
82
+ > [!NOTE]
83
+ > Global configuration is fully optional.
84
+
85
+ #### Rails integration
86
+
87
+ Alternatively, when using the gem in a Rails application, it automatically loads a [Railtie](lib/authentik/client/railtie.rb) that exposes `config.authentik_client` as a standard Rails configuration accessor.
88
+
89
+ `config.authentik_client` is the same configuration class instance as `Authentik::Client.configuration`, so both styles are always in sync.
90
+
91
+ ```ruby
92
+ # config/application.rb (or any environment file)
93
+
94
+ # ...
95
+ module YourApplication
96
+ class Application < Rails::Application
97
+ # ...
98
+ config.authentik_client.host = "authentik.example.com"
99
+ config.authentik_client.token = ENV["AUTHENTIK_TOKEN"]
100
+ end
101
+ end
102
+ ```
103
+
104
+ You can also use environment-specific files:
105
+
106
+ ```ruby
107
+ # config/environments/production.rb
108
+
109
+ # ...
110
+ module YourApplication
111
+ class Application < Rails::Application
112
+ # ...
113
+ config.authentik_client.verify_ssl = true
114
+ end
115
+ end
116
+ ```
117
+
118
+ #### Creating a client
119
+
120
+ Finally, you can configure client instances at runtime.
121
+
122
+ ```ruby
123
+ client = Authentik::Client.new(
124
+ host: "authentik.example.com",
125
+ token: "your-api-token"
126
+ )
127
+ ```
128
+
129
+ Additional configuration options are forwarded to the underlying, auto-generated OpenAPI client:
130
+
131
+ ```ruby
132
+ client = Authentik::Client.new(
133
+ host: "authentik.example.com",
134
+ token: "your-api-token",
135
+ scheme: "https", # default
136
+ verify_ssl: false, # disable SSL verification (e.g. for development)
137
+ timeout: 60 # request timeout in seconds
138
+ )
139
+ ```
140
+
141
+ See [`Authentik::Api::Configuration`](https://github.com/david-uhlig/authentik-api/blob/main/lib/authentik/api/configuration.rb) for a list of all available configuration options.
142
+
143
+ ### Calling API endpoints
144
+
145
+ The client exposes each API group as a method. Calling an API group method returns a proxy object that forwards calls to the corresponding auto-generated API class, with the redundant group prefix stripped for brevity.
146
+
147
+ ```ruby
148
+ # Core API – lists applications.
149
+ #
150
+ # Calls `Authentik::Api::CoreApi.core_applications_list`.
151
+ # Issues a `GET` request to the `/api/v3/core/applications/` endpoint,
152
+ # see: https://api.goauthentik.io/reference/core-applications-list/.
153
+ client.core.applications_list
154
+
155
+ # Admin API – retrieves the authentik version.
156
+ client.admin.version_retrieve
157
+
158
+ # OAuth2 API – lists access tokens.
159
+ client.oauth2.access_tokens_list
160
+
161
+ # Propertymappings API – lists all property mappings.
162
+ client.propertymappings.all_list
163
+ ```
164
+
165
+ The full list of API groups and their methods is available in the
166
+ [auto-generated README](https://github.com/david-uhlig/authentik-api/blob/main/README_API.md) and on [api.goauthentik.io](https://api.goauthentik.io/).
167
+
168
+ **Each API group is only initialized once when first requested.**
169
+
170
+ > [!TIP]
171
+ > If you're primarily using one API group, you can assign it to a variable and do:
172
+ > ```ruby
173
+ > propmap_api = client.propertymappings
174
+ > propmap_api.all_list
175
+ > ```
176
+ > instead of:
177
+ > ```ruby
178
+ > client.propertymappings.all_list
179
+ > ```
180
+
181
+ ### Available API groups
182
+
183
+ The full API reference is available at [api.goauthentik.io](https://api.goauthentik.io/).
184
+
185
+ | Method | API class |
186
+ |---------------------------|-----------------------|
187
+ | `client.admin` | `AdminApi` |
188
+ | `client.authenticators` | `AuthenticatorsApi` |
189
+ | `client.core` | `CoreApi` |
190
+ | `client.crypto` | `CryptoApi` |
191
+ | `client.enterprise` | `EnterpriseApi` |
192
+ | `client.events` | `EventsApi` |
193
+ | `client.flows` | `FlowsApi` |
194
+ | `client.managed` | `ManagedApi` |
195
+ | `client.oauth2` | `Oauth2Api` |
196
+ | `client.outposts` | `OutpostsApi` |
197
+ | `client.policies` | `PoliciesApi` |
198
+ | `client.propertymappings` | `PropertymappingsApi` |
199
+ | `client.providers` | `ProvidersApi` |
200
+ | `client.rac` | `RacApi` |
201
+ | `client.rbac` | `RbacApi` |
202
+ | `client.root` | `RootApi` |
203
+ | `client.schema` | `SchemaApi` |
204
+ | `client.sources` | `SourcesApi` |
205
+ | `client.ssf` | `SsfApi` |
206
+ | `client.stages` | `StagesApi` |
207
+ | `client.tasks` | `TasksApi` |
208
+ | `client.tenants` | `TenantsApi` |
209
+
210
+ New API groups introduced by future authentik releases are automatically discovered without changes to `Authentik::Client` wrapper.
211
+
212
+ ## Versioning
213
+
214
+ This library aims to adhere to [Semantic Versioning 2.0.0](http://semver.org/). Violations of this scheme should be reported as bugs.
215
+
216
+ ## Development
217
+
218
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt.
219
+
220
+ To regenerate the underlying OpenAPI client run `bin/generate-api`.
221
+
222
+ ## Contributing
223
+
224
+ Bug reports and pull requests are welcome on GitHub at https://github.com/david-uhlig/authentik-client. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/david-uhlig/authentik-client/blob/main/CODE_OF_CONDUCT.md).
225
+
226
+ ## License
227
+
228
+ The gem is available as open source under the terms of the [MIT License](LICENSE.md).
229
+
230
+ ## Code of Conduct
231
+
232
+ Everyone interacting in this project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [code of conduct](https://github.com/david-uhlig/authentik-client/blob/main/CODE_OF_CONDUCT.md).
233
+
234
+ ## Attribution
235
+
236
+ * [authentik]: The open-source IdP and SSO platform. Providing flexible and scalable authentication.
237
+
238
+ > [!NOTE]
239
+ > This project is not affiliated with or endorsed by Authentik Security Inc.
240
+
241
+ ## Appendix
242
+
243
+ ### Authentication with authentik in Ruby
244
+
245
+ For integrating authentik authentication into your Ruby application, you can use [OmniAuth](https://github.com/omniauth/omniauth) with the [omniauth_oidc](https://github.com/msuliq/omniauth_oidc) gem, and an OAuth2/OIDC provider configured in authentik.
246
+
247
+ #### Quick Setup Guide for Rails
248
+
249
+ 1\. Configure an OAuth2/OIDC provider under: `https://authentik.example.com/if/admin/#/core/providers`
250
+
251
+ 2\. Add the gems to your Gemfile:
252
+ ```ruby
253
+ gem 'omniauth'
254
+ gem 'omniauth_oidc'
255
+ ```
256
+
257
+ 3\. Configure OmniAuth
258
+ ```ruby
259
+ # config/initializers/omniauth.rb
260
+ Rails.application.config.middleware.use OmniAuth::Builder do
261
+ provider :oidc, {
262
+ name: :authentik,
263
+ client_options: {
264
+ identifier: ENV["CLIENT_ID"],
265
+ secret: ENV["CLIENT_SECRET"],
266
+ config_endpoint: "https://authentik.example.com/application/o/provider-slug/.well-known/openid-configuration"
267
+ }
268
+ }
269
+ end
270
+ ```
271
+
272
+ 4\. Add routes in `config/routes.rb`, e.g.:
273
+ ```ruby
274
+ get "/auth/:provider/callback", to: "sessions#create"
275
+ get "/auth/failure", to: "sessions#failure"
276
+ ```
277
+
278
+ 5\. Create a simple sessions controller:
279
+ ```ruby
280
+ class SessionsController < ApplicationController
281
+ def create
282
+ user = User.from_omniauth(request.env['omniauth.auth'])
283
+ session[:user_id] = user.id
284
+ redirect_to root_path, notice: 'Signed in successfully!'
285
+ end
286
+ end
287
+ ```
288
+
289
+ [authentik-api]: https://github.com/david-uhlig/authentik-api
290
+ [authentik]: https://github.com/goauthentik/authentik
291
+ [OpenAPI Generator]: https://openapi-generator.tech/
292
+ [gem]: https://rubygems.org/gems/authentik-client
293
+ [license]: https://github.com/david-uhlig/authentik-client/blob/main/LICENSE.md
294
+ [tests]: https://github.com/david-uhlig/authentik-client/actions/workflows/main.yml
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "standard/rake"
9
+
10
+ task default: %i[spec standard]
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authentik
4
+ # ApiProxy wraps an auto-generated OpenAPI API class and forwards method calls
5
+ # to it, stripping the redundant API group prefix from method names.
6
+ #
7
+ # For example, when accessed via +client.core+, the prefix +"core_"+ is
8
+ # stripped, so +client.core.applications_list+ calls
9
+ # +CoreApi#core_applications_list+.
10
+ #
11
+ # @api private
12
+ class ApiProxy
13
+ # @param api_instance [Object] The underlying OpenAPI API class instance
14
+ # @param prefix [String] The method prefix to strip (e.g., +"core_"+)
15
+ def initialize(api_instance, prefix)
16
+ @api = api_instance
17
+ @prefix = prefix
18
+ end
19
+
20
+ # Forwards method calls to the underlying API instance.
21
+ # First tries with the prefix prepended (unless already prefixed), then without.
22
+ def method_missing(name, *args, **kwargs, &block)
23
+ prefixed = name.to_s.start_with?(@prefix) ? name : :"#{@prefix}#{name}"
24
+ if @api.respond_to?(prefixed)
25
+ @api.send(prefixed, *args, **kwargs, &block)
26
+ elsif @api.respond_to?(name)
27
+ @api.send(name, *args, **kwargs, &block)
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ def respond_to_missing?(name, include_private = false)
34
+ prefixed = name.to_s.start_with?(@prefix) ? name : :"#{@prefix}#{name}"
35
+ @api.respond_to?(prefixed) ||
36
+ @api.respond_to?(name) ||
37
+ super
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authentik
4
+ class Client
5
+ # Global configuration for {Authentik::Client}. Subclasses
6
+ # {Authentik::Api::Configuration} so all underlying API settings
7
+ # (e.g., +verify_ssl+, +timeout+, +debugging+) are available directly.
8
+ # Adds a +token+ accessor as a friendlier alias for +access_token+.
9
+ #
10
+ # Use {Authentik::Client.configure} to set configuration at startup.
11
+ #
12
+ # @example Configure at startup (e.g., in a Rails initializer)
13
+ # Authentik::Client.configure do |config|
14
+ # config.host = "authentik.example.com"
15
+ # config.token = "your-api-token"
16
+ # end
17
+ class Configuration < Authentik::Api::Configuration
18
+ def initialize
19
+ super
20
+ # Override parent defaults: host is intentionally nil until the user
21
+ # sets it, so Client can detect when it has not been configured.
22
+ @host = nil
23
+ @scheme = "https"
24
+ end
25
+
26
+ # @return [String, nil] The API bearer token for authentication.
27
+ # Alias for +access_token+.
28
+ def token
29
+ access_token
30
+ end
31
+
32
+ # @param value [String, nil]
33
+ def token=(value)
34
+ self.access_token = value
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/railtie"
4
+ require "authentik/client"
5
+
6
+ module Authentik
7
+ class Client
8
+ # Railtie integrates authentik-client with Ruby on Rails. It is
9
+ # automatically loaded when Rails is present, so no manual require is
10
+ # needed.
11
+ #
12
+ # Exposes +config.authentik_client+ so the client can be configured
13
+ # directly from Rails configuration files (e.g., +config/application.rb+
14
+ # or environment files). +config.authentik_client+ is the same
15
+ # {Authentik::Client::Configuration} instance returned by
16
+ # {Authentik::Client.configuration}, so both styles are always in sync.
17
+ #
18
+ # @example config/application.rb
19
+ # config.authentik_client.host = "authentik.example.com"
20
+ # config.authentik_client.token = ENV["AUTHENTIK_TOKEN"]
21
+ #
22
+ # @example config/environments/production.rb
23
+ # config.authentik_client.verify_ssl = true
24
+ #
25
+ # @example config/initializers/authentik_client.rb (traditional style, still works)
26
+ # Authentik::Client.configure do |config|
27
+ # config.host = "authentik.example.com"
28
+ # config.token = ENV["AUTHENTIK_TOKEN"]
29
+ # end
30
+ class Railtie < Rails::Railtie
31
+ config.authentik_client = Authentik::Client.configuration
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authentik
4
+ class Client
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "authentik/api"
4
+ require "logger"
5
+ require "zeitwerk"
6
+
7
+ loader = Zeitwerk::Loader.for_gem_extension(Authentik)
8
+ loader.ignore("#{__dir__}/client/railtie.rb")
9
+ loader.setup
10
+
11
+ module Authentik
12
+ # Client provides a Ruby interface to the authentik API. It wraps the
13
+ # auto-generated OpenAPI client and organizes API calls into groups that
14
+ # correspond to the underlying API classes.
15
+ #
16
+ # API groups are accessed as methods on the client. Each group returns an
17
+ # {ApiProxy} that forwards method calls to the corresponding OpenAPI API
18
+ # class, stripping the redundant API group prefix for brevity.
19
+ #
20
+ # New API groups added to the underlying OpenAPI client are automatically
21
+ # discovered and available without changes to this class.
22
+ #
23
+ # @example Configure at startup and create a client
24
+ # Authentik::Client.configure do |config|
25
+ # config.host = "authentik.example.com"
26
+ # config.token = "your-api-token"
27
+ # end
28
+ #
29
+ # client = Authentik::Client.new
30
+ #
31
+ # @example Create a client with inline options
32
+ # client = Authentik::Client.new(
33
+ # host: "authentik.example.com",
34
+ # token: "your-api-token"
35
+ # )
36
+ #
37
+ # @example List all applications
38
+ # client.core.applications_list
39
+ #
40
+ # @example Get the admin version
41
+ # client.admin.version_retrieve
42
+ #
43
+ # @example List OAuth2 access tokens
44
+ # client.oauth2.access_tokens_list
45
+ class Client
46
+ # Yields the global {Configuration} object so that settings can be applied
47
+ # at startup (e.g., in a Rails initializer).
48
+ #
49
+ # @example
50
+ # Authentik::Client.configure do |config|
51
+ # config.host = "authentik.example.com"
52
+ # config.token = "your-api-token"
53
+ # end
54
+ #
55
+ # @yieldparam config [Configuration]
56
+ def self.configure
57
+ yield(configuration)
58
+ end
59
+
60
+ # Returns the global {Configuration} instance, creating it on first call.
61
+ #
62
+ # @return [Configuration]
63
+ def self.configuration
64
+ @configuration ||= Configuration.new
65
+ end
66
+
67
+ # Resets the global configuration to a fresh {Configuration} instance.
68
+ #
69
+ # @return [Configuration]
70
+ def self.reset_configuration!
71
+ @configuration = Configuration.new
72
+ end
73
+
74
+ # @param host [String, nil] The authentik server hostname
75
+ # (e.g., +"authentik.example.com"+). Falls back to the value set in
76
+ # {.configuration} when not provided.
77
+ # @param token [String, nil] The API bearer token for authentication.
78
+ # Falls back to the value set in {.configuration} when not provided.
79
+ # @param scheme [String, nil] The URL scheme (+"https"+ or +"http"+).
80
+ # Falls back to the value set in {.configuration}, which defaults to
81
+ # +"https"+.
82
+ # @param options [Hash] Additional per-instance options forwarded to
83
+ # +Authentik::Api::Configuration+ (e.g., +verify_ssl: false+,
84
+ # +timeout: 60+). Take precedence over values set in {.configuration}.
85
+ # @raise [ArgumentError] if +host+ is not provided here or in the global
86
+ # configuration
87
+ # @raise [ArgumentError] if +token+ is not provided here or in the global
88
+ # configuration
89
+ def initialize(host: nil, token: nil, scheme: nil, **options)
90
+ cfg = self.class.configuration
91
+ resolved_host = host || cfg.host
92
+ resolved_token = token || cfg.access_token
93
+ resolved_scheme = scheme || cfg.scheme
94
+
95
+ raise ArgumentError, "host is required" if resolved_host.nil?
96
+ raise ArgumentError, "token is required" if resolved_token.nil?
97
+
98
+ @api_client = build_api_client(
99
+ cfg,
100
+ host: resolved_host,
101
+ token: resolved_token,
102
+ scheme: resolved_scheme,
103
+ **options
104
+ )
105
+ @api_instances = {}
106
+ end
107
+
108
+ # Provides access to an API group by name. Returns an {ApiProxy} that
109
+ # wraps the corresponding OpenAPI API class instance.
110
+ #
111
+ # The method name is the API class name (without the +"Api"+ suffix)
112
+ # in lowercase. For example, +:core+ maps to +CoreApi+, +:admin+ to
113
+ # +AdminApi+, and +:oauth2+ to +OAuth2Api+.
114
+ #
115
+ # @return [ApiProxy] A proxy wrapping the underlying API class instance
116
+ # @raise [NoMethodError] if the name does not match any known API group
117
+ def method_missing(name, ...)
118
+ api_info = self.class.api_map[name]
119
+ return super unless api_info
120
+
121
+ @api_instances[name] ||= ApiProxy.new(api_info[:klass].new(@api_client), api_info[:prefix])
122
+ end
123
+
124
+ def respond_to_missing?(name, include_private = false)
125
+ self.class.api_map.key?(name) || super
126
+ end
127
+
128
+ # Returns a hash mapping API group name symbols to their API class and
129
+ # prefix. Automatically discovers all classes in +Authentik::Api+
130
+ # that end with +"Api"+.
131
+ #
132
+ # @return [Hash{Symbol => Hash}]
133
+ def self.api_map
134
+ @api_map ||= Authentik::Api.constants
135
+ .select { |c| c.to_s.end_with?("Api") }
136
+ .filter_map do |c|
137
+ klass = Authentik::Api.const_get(c)
138
+ next unless klass.is_a?(Class)
139
+
140
+ base = c.to_s.delete_suffix("Api").downcase
141
+ [base.to_sym, {klass: klass, prefix: "#{base}_"}]
142
+ end
143
+ .to_h
144
+ end
145
+
146
+ private
147
+
148
+ def build_api_client(base_config, host:, token:, scheme:, **options)
149
+ config = base_config.dup
150
+ config.host = host
151
+ config.access_token = token
152
+ config.scheme = scheme
153
+ options.each { |k, v| config.public_send(:"#{k}=", v) if config.respond_to?(:"#{k}=") }
154
+ Authentik::Api::ApiClient.new(config)
155
+ end
156
+ end
157
+ end
158
+
159
+ require "authentik/client/railtie" if defined?(Rails::Railtie)
data/mise.toml ADDED
@@ -0,0 +1,29 @@
1
+ [tools]
2
+ ruby = "3.3"
3
+
4
+ [tasks.ci]
5
+ description = "Run all CI tasks"
6
+ run = [
7
+ { task = "rake:spec" },
8
+ { tasks = ["rake:standard", "zizmor"] }
9
+ ]
10
+
11
+ [tasks.zizmor]
12
+ description = "Static analysis for GitHub Actions."
13
+ run = "zizmor ./.github"
14
+
15
+ [tasks."zizmor:fix"]
16
+ description = "Run zizmor and auto fix."
17
+ run = "zizmor --fix=all ./.github"
18
+
19
+ [tasks.rake]
20
+ description = "Run the rake default tasks."
21
+ run = "rake"
22
+
23
+ [tasks."rake:spec"]
24
+ description = "Run specs."
25
+ run = "rake spec"
26
+
27
+ [tasks."rake:standard"]
28
+ description = "Run standardrb linting."
29
+ run = "rake standard"
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: authentik-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - David Uhlig
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2026-04-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: authentik-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: zeitwerk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.6'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: irb
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '13.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '13.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: railties
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: standard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.3'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.3'
111
+ description: 'A developer-friendly Ruby wrapper around the auto-generated authentik-api
112
+ gem, offering an idiomatic interface for interacting with authentik configuration
113
+ objects and abstracting away the complexity of the underlying OpenAPI client.
114
+
115
+ '
116
+ email:
117
+ - david.uhlig@gmail.com
118
+ executables: []
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - CHANGELOG.md
123
+ - CODE_OF_CONDUCT.md
124
+ - LICENSE.md
125
+ - README.md
126
+ - Rakefile
127
+ - lib/authentik/api_proxy.rb
128
+ - lib/authentik/client.rb
129
+ - lib/authentik/client/configuration.rb
130
+ - lib/authentik/client/railtie.rb
131
+ - lib/authentik/client/version.rb
132
+ - mise.toml
133
+ homepage: https://github.com/david-uhlig/authentik-client
134
+ licenses:
135
+ - MIT
136
+ metadata:
137
+ allowed_push_host: https://rubygems.org
138
+ homepage_uri: https://github.com/david-uhlig/authentik-client
139
+ source_code_uri: https://github.com/david-uhlig/authentik-client
140
+ changelog_uri: https://github.com/david-uhlig/authentik-client/blob/main/CHANGELOG.md
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: 3.3.0
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubygems_version: 3.5.22
157
+ signing_key:
158
+ specification_version: 4
159
+ summary: A developer-friendly Ruby wrapper for the authentik API that simplifies managing
160
+ authentik configuration objects.
161
+ test_files: []