aptible-auth 1.2.7 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff939c12eccbed8e6f8408f1608fa8b07e036b7fd837cf230ac8da01db236bac
4
- data.tar.gz: c323895a11c8b0713b2f295c0178536e43f2bd8c01b823b4f44f4f29217c73d9
3
+ metadata.gz: a41b77f6708abdde557d4763215fd5f6e18460716a25c94c29fdd15564588dc3
4
+ data.tar.gz: a74283bb27a4a0ac4b952b2c0dd7065f0e7b35640d6354af73ab01910101f4de
5
5
  SHA512:
6
- metadata.gz: 5a4e952f3b63e0692210ec0a8c58517ec5878618fe6f4c3f47c7ae4b94f2c31a6344e67fe88447a2bd59cbdf25f5550f8dc6f6511405af21aa2e022d579ddf98
7
- data.tar.gz: ee7c792b19ae8c8acafb20710c5b404b729a7a8e202cf50632a1d7a2e096245208dbca586f8bb84050dbdb73397aae75c665dc1f0d791bc12704222b96831750
6
+ metadata.gz: 9597770fc7f1a203eb2efbb0326a58e495912cc3fde1835737cb6d9850395ab1a0d341ccea701db3502137aef32cfdd6199ada643908048148690224f55d0614
7
+ data.tar.gz: 05e43ea50940aa25ba554db3b0eb78469d52c27e96ad9af0db46b6efb9803dc39e0fe916dbd3c0c608babc606dff23f4cd7804c436d87cedc6cdd8997a4aa2ae
@@ -15,22 +15,15 @@ jobs:
15
15
  strategy:
16
16
  fail-fast: false
17
17
  matrix:
18
- RUBY_VERSION: [2.6, 2.7]
18
+ RUBY_VERSION: [2.3, 2.4, 2.5, 2.6, 2.7, 3.1, 3.2, 3.3, 3.4]
19
+ env:
20
+ RUBY_VERSION: ${{ matrix.RUBY_VERSION }}
19
21
  steps:
20
22
  - name: Check out code
21
23
  uses: actions/checkout@v4
22
24
 
23
- - name: Install Ruby
24
- uses: ruby/setup-ruby@v1
25
- with:
26
- ruby-version: ${{ matrix.RUBY_VERSION }}
27
- bundler: 1.17.3
28
-
29
- - name: Bundle install
30
- run: bundle install
31
-
32
25
  - name: Rubocop
33
- run: bundle exec rake rubocop
26
+ run: make lint
34
27
 
35
28
  - name: Rspec
36
- run: bundle exec rspec
29
+ run: make test
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  .idea
19
+ /docker/ruby-*/
data/Dockerfile ADDED
@@ -0,0 +1,20 @@
1
+ ARG RUBY_VERSION=2.3.1
2
+ FROM ruby:${RUBY_VERSION}
3
+
4
+ ARG BUNDLER_VERSION=1.17.3
5
+ ENV BUNDLER_VERSION=${BUNDLER_VERSION}
6
+ RUN if [ "${BUNDLER_VERSION}" != "" ] ; then \
7
+ gem install bundler -v "${BUNDLER_VERSION}" ; \
8
+ fi
9
+
10
+ WORKDIR /app
11
+ COPY Gemfile /app/
12
+ COPY aptible-auth.gemspec /app/
13
+ RUN mkdir -p /app/lib/aptible/auth/
14
+ COPY lib/aptible/auth/version.rb /app/lib/aptible/auth/
15
+
16
+ RUN bundle install
17
+
18
+ COPY . /app
19
+
20
+ CMD ["bash"]
data/Makefile ADDED
@@ -0,0 +1,68 @@
1
+
2
+ export COMPOSE_IGNORE_ORPHANS ?= true
3
+ export RUBY_VERSION ?= 2.3.1
4
+ RUBY_VERSION_MAJOR = $(word 1,$(subst ., ,$(RUBY_VERSION)))
5
+ export BUNDLER_VERSION ?=
6
+ ifeq ($(BUNDLER_VERSION),)
7
+ ifeq ($(RUBY_VERSION_MAJOR),2)
8
+ export BUNDLER_VERSION = 1.17.3
9
+ endif
10
+ endif
11
+ PROJECT_NAME = $(shell ls *.gemspec | sed 's/\.gemspec//')
12
+ export COMPOSE_PROJECT_NAME ?= $(PROJECT_NAME)-$(subst .,_,$(RUBY_VERSION))
13
+
14
+ default: help
15
+
16
+ ## Show this help message
17
+ help:
18
+ @echo "\n\033[1;34mAvailable targets:\033[0m\n"
19
+ @awk 'BEGIN {FS = ":"; prev = ""} \
20
+ /^## / {prev = substr($$0, 4); next} \
21
+ /^[a-zA-Z_-]+:/ {if (prev != "") printf " \033[1;36m%-20s\033[0m %s\n", $$1, prev; prev = ""} \
22
+ {prev = ""}' $(MAKEFILE_LIST) | sort
23
+ @echo
24
+
25
+ BUILD_ARGS ?=
26
+ ## Build and pull docker compose images
27
+ build: gemfile-lock
28
+ docker compose build --pull $(BUILD_ARGS)
29
+
30
+ ## Create a Gemfile.lock specific to the container (i.e., for the ruby version)
31
+ gemfile-lock:
32
+ mkdir -pv ./docker/ruby-$(RUBY_VERSION)/ && \
33
+ echo '' > ./docker/ruby-$(RUBY_VERSION)/Gemfile.lock
34
+
35
+ ## Open shell in a docker container, supports CMD=
36
+ bash: build
37
+ $(MAKE) run CMD=bash
38
+
39
+ CMD ?= bash
40
+ ## Run command in a docker container, supports CMD=
41
+ run:
42
+ docker compose run --rm runner $(CMD)
43
+
44
+ ## Run tests in a docker container, supports ARGS=
45
+ test: build
46
+ $(MAKE) test-direct ARGS="$(ARGS)"
47
+
48
+ ## Run tests in a docker container without building, supports ARGS=
49
+ test-direct:
50
+ $(MAKE) run CMD="bundle exec rspec $(ARGS)"
51
+
52
+ ## Run rubocop in a docker container, supports ARGS=
53
+ lint: build
54
+ $(MAKE) lint-direct ARGS="$(ARGS)"
55
+
56
+ ## Run rubocop in a docker container without building, supports ARGS=
57
+ lint-direct:
58
+ $(MAKE) run CMD="bundle exec rake rubocop $(ARGS)"
59
+
60
+ ## Clean up docker compose resources
61
+ clean: clean-gemfile-lock
62
+ docker compose down --remove-orphans --volumes
63
+
64
+ ## Clean up the container specific Gemfile.lock
65
+ clean-gemfile-lock:
66
+ rm -v ./docker/ruby-$(RUBY_VERSION)/Gemfile.lock ||:
67
+
68
+ .PHONY: build bash test
data/aptible-auth.gemspec CHANGED
@@ -21,7 +21,6 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ['lib']
22
22
 
23
23
  spec.add_dependency 'aptible-resource', '~> 1.0'
24
- spec.add_dependency 'concurrent-ruby', '1.3.4'
25
24
  spec.add_dependency 'gem_config'
26
25
  spec.add_dependency 'multipart-post', '2.1.1'
27
26
  spec.add_dependency 'oauth2', '2.0.9'
@@ -31,5 +30,5 @@ Gem::Specification.new do |spec|
31
30
  spec.add_development_dependency 'rake'
32
31
  spec.add_development_dependency 'rspec', '~> 3.0'
33
32
  spec.add_development_dependency 'rspec-its'
34
- spec.add_development_dependency 'timecop', '~> 0.8.1'
33
+ spec.add_development_dependency 'timecop', '~> 0.9.10'
35
34
  end
@@ -0,0 +1,12 @@
1
+ services:
2
+ runner:
3
+ build:
4
+ context: .
5
+ args:
6
+ RUBY_VERSION: ${RUBY_VERSION:-2.3.1}
7
+ BUNDLER_VERSION: ${BUNDLER_VERSION:-}
8
+ volumes:
9
+ - type: bind
10
+ source: .
11
+ target: /app
12
+ - ./docker/ruby-${RUBY_VERSION}/Gemfile.lock:/app/Gemfile.lock
@@ -0,0 +1,24 @@
1
+ module Aptible
2
+ module Auth
3
+ class ExternalAwsOidcToken
4
+ attr_reader :aws_web_identity_token_file_content, :aws_role_arn
5
+
6
+ def initialize(attributes = {})
7
+ @aws_web_identity_token_file_content =
8
+ attributes['aws_web_identity_token_file_content'] ||
9
+ attributes[:aws_web_identity_token_file_content]
10
+ @aws_role_arn =
11
+ attributes['aws_role_arn'] ||
12
+ attributes[:aws_role_arn]
13
+ end
14
+
15
+ def to_s
16
+ aws_web_identity_token_file_content.to_s
17
+ end
18
+
19
+ def token
20
+ aws_web_identity_token_file_content
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ module Aptible
2
+ module Auth
3
+ class ExternalAwsRole < Resource
4
+ belongs_to :organization
5
+
6
+ field :id
7
+ field :external_aws_account_id
8
+ field :aws_account_id
9
+ field :role_type
10
+ field :role_arn
11
+ field :last_verified_at, type: Time
12
+ field :created_at, type: Time
13
+ field :updated_at, type: Time
14
+
15
+ def external_aws_oidc_token!
16
+ response = HyperResource::Link.new(
17
+ self,
18
+ 'href' => "#{href}/external_aws_oidc_token"
19
+ ).post(
20
+ self.class.normalize_params(
21
+ aws_account_id: attributes[:aws_account_id],
22
+ role_arn: attributes[:role_arn],
23
+ role_type: attributes[:role_type]
24
+ )
25
+ )
26
+ ExternalAwsOidcToken.new(response.body)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -5,6 +5,7 @@ module Aptible
5
5
  has_many :users
6
6
  has_many :invitations
7
7
  has_many :whitelist_memberships
8
+ has_many :external_aws_roles
8
9
  belongs_to :security_officer
9
10
 
10
11
  field :id
@@ -24,6 +24,8 @@ require 'aptible/auth/token'
24
24
  require 'aptible/auth/user'
25
25
  require 'aptible/auth/ssh_key'
26
26
  require 'aptible/auth/saml_configuration'
27
+ require 'aptible/auth/external_aws_role'
28
+ require 'aptible/auth/external_aws_oidc_token'
27
29
  require 'aptible/auth/whitelist_membership'
28
30
  require 'aptible/auth/reauthenticate_organization'
29
31
  require 'aptible/auth/ssh_key_pre_authorization'
@@ -53,7 +53,7 @@ module Aptible
53
53
  # consistent API to consumers, we override it here
54
54
  expires_in = options.delete(:expires_in)
55
55
  options[:exp] = Time.now.utc.to_i + expires_in if expires_in
56
- oauth_token = oauth.assertion.get_token({
56
+ oauth_token = oauth.assertion.get_token(**{
57
57
  iss: id,
58
58
  sub: subject
59
59
  }.merge(signing_params_from_secret(secret).merge(options)))
@@ -1,5 +1,5 @@
1
1
  module Aptible
2
2
  module Auth
3
- VERSION = '1.2.7'.freeze
3
+ VERSION = '1.4.0'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe Aptible::Auth::ExternalAwsOidcToken do
4
+ let(:token_content) { 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...' }
5
+ let(:role_arn) { 'arn:aws:iam::123456789012:role/MyRole' }
6
+
7
+ describe '#initialize' do
8
+ it 'should accept string keys' do
9
+ token = described_class.new(
10
+ 'aws_web_identity_token_file_content' => token_content,
11
+ 'aws_role_arn' => role_arn
12
+ )
13
+ expect(token.aws_web_identity_token_file_content).to eq token_content
14
+ expect(token.aws_role_arn).to eq role_arn
15
+ end
16
+
17
+ it 'should accept symbol keys' do
18
+ token = described_class.new(
19
+ aws_web_identity_token_file_content: token_content,
20
+ aws_role_arn: role_arn
21
+ )
22
+ expect(token.aws_web_identity_token_file_content).to eq token_content
23
+ expect(token.aws_role_arn).to eq role_arn
24
+ end
25
+ end
26
+
27
+ describe '#token' do
28
+ it 'should return the token content' do
29
+ token = described_class.new(
30
+ aws_web_identity_token_file_content: token_content
31
+ )
32
+ expect(token.token).to eq token_content
33
+ end
34
+ end
35
+
36
+ describe '#to_s' do
37
+ it 'should return the token content as a string' do
38
+ token = described_class.new(
39
+ aws_web_identity_token_file_content: token_content
40
+ )
41
+ expect(token.to_s).to eq token_content
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe Aptible::Auth::ExternalAwsRole do
4
+ it { should be_a Aptible::Auth::Resource }
5
+
6
+ describe '#organization' do
7
+ let(:organization) { double 'Aptible::Auth::Organization' }
8
+
9
+ it 'should return the organization' do
10
+ allow(subject).to receive(:organization) { organization }
11
+ expect(subject.organization).to eq organization
12
+ end
13
+ end
14
+
15
+ describe '#external_aws_oidc_token!' do
16
+ let(:token_content) { 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...' }
17
+ let(:role_arn) { 'arn:aws:iam::123456789012:role/MyRole' }
18
+ let(:aws_account_id) { '123456789012' }
19
+ let(:role_type) { 'deploy' }
20
+ let(:response) do
21
+ double(
22
+ 'response',
23
+ body: {
24
+ 'aws_web_identity_token_file_content' => token_content,
25
+ 'aws_role_arn' => role_arn
26
+ }
27
+ )
28
+ end
29
+ let(:link) { double('HyperResource::Link') }
30
+
31
+ before do
32
+ allow(subject).to receive(:href) { 'https://auth.aptible.com/external_aws_roles/123' }
33
+ allow(subject).to receive(:attributes).and_return(
34
+ aws_account_id: aws_account_id,
35
+ role_arn: role_arn,
36
+ role_type: role_type
37
+ )
38
+ allow(HyperResource::Link).to receive(:new).and_return(link)
39
+ allow(link).to receive(:post).and_return(response)
40
+ end
41
+
42
+ it 'should create a link with the correct URL' do
43
+ expect(HyperResource::Link).to receive(:new).with(
44
+ subject,
45
+ 'href' => 'https://auth.aptible.com/external_aws_roles/123/external_aws_oidc_token'
46
+ ).and_return(link)
47
+ subject.external_aws_oidc_token!
48
+ end
49
+
50
+ it 'should POST with the correct parameters' do
51
+ expect(link).to receive(:post).with(
52
+ hash_including(
53
+ aws_account_id: aws_account_id,
54
+ role_arn: role_arn,
55
+ role_type: role_type
56
+ )
57
+ ).and_return(response)
58
+ subject.external_aws_oidc_token!
59
+ end
60
+
61
+ it 'should return an ExternalAwsOidcToken' do
62
+ token = subject.external_aws_oidc_token!
63
+ expect(token).to be_a Aptible::Auth::ExternalAwsOidcToken
64
+ expect(token.token).to eq token_content
65
+ end
66
+
67
+ it 'should populate the returned token with response data' do
68
+ token = subject.external_aws_oidc_token!
69
+ expect(token.aws_web_identity_token_file_content).to eq token_content
70
+ expect(token.aws_role_arn).to eq role_arn
71
+ end
72
+ end
73
+ end
@@ -5,8 +5,44 @@ describe Aptible::Auth::Organization do
5
5
  let(:user) { double 'Aptible::Auth::User' }
6
6
 
7
7
  it 'should return the security officer' do
8
- subject.stub(:security_officer) { user }
8
+ allow(subject).to receive(:security_officer) { user }
9
9
  expect(subject.security_officer).to eq user
10
10
  end
11
11
  end
12
+
13
+ describe '#external_aws_roles' do
14
+ let(:external_aws_role) { double 'Aptible::Auth::ExternalAwsRole' }
15
+
16
+ it 'should return the external_aws_roles' do
17
+ allow(subject).to receive(:external_aws_roles) { [external_aws_role] }
18
+ expect(subject.external_aws_roles).to eq [external_aws_role]
19
+ end
20
+ end
21
+
22
+ describe '#create_external_aws_role!' do
23
+ let(:params) do
24
+ {
25
+ aws_account_id: '123456789012',
26
+ role_arn: 'arn:aws:iam::123456789012:role/MyRole',
27
+ role_type: 'deploy'
28
+ }
29
+ end
30
+ let(:external_aws_role) { double('Aptible::Auth::ExternalAwsRole') }
31
+ let(:external_aws_roles_link) { double('HyperResource::Link') }
32
+
33
+ before do
34
+ allow(subject).to receive(:loaded) { true }
35
+ allow(subject).to receive(:links) { { external_aws_roles: external_aws_roles_link } }
36
+ allow(external_aws_roles_link).to receive(:create).and_return(external_aws_role)
37
+ end
38
+
39
+ it 'should call create on the external_aws_roles link' do
40
+ expect(external_aws_roles_link).to receive(:create).with(params)
41
+ subject.create_external_aws_role!(params)
42
+ end
43
+
44
+ it 'should return the created external_aws_role' do
45
+ expect(subject.create_external_aws_role!(params)).to eq external_aws_role
46
+ end
47
+ end
12
48
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Aptible::Auth::Resource do
4
4
  its(:namespace) { should eq 'Aptible::Auth' }
5
- its(:root_url) { should eq 'https://auth.aptible.com' }
5
+ its(:root_url) { should eq ENV['APTIBLE_AUTH_ROOT_URL'] || 'https://auth.aptible.com' }
6
6
 
7
7
  describe '#bearer_token' do
8
8
  it 'should accept an Aptible::Auth::Token' do
@@ -6,12 +6,17 @@ describe Aptible::Auth do
6
6
  it 'should have a configurable root_url' do
7
7
  config = described_class.configuration
8
8
  expect(config).to be_a GemConfig::Configuration
9
- expect(config.root_url).to eq 'https://auth.aptible.com'
9
+ set_env 'APTIBLE_AUTH_ROOT_URL', nil do
10
+ load 'aptible/auth.rb'
11
+ config.reset
12
+ expect(config.root_url).to eq 'https://auth.aptible.com'
13
+ end
10
14
  end
11
15
 
12
- pending 'uses ENV["APTIBLE_AUTH_ROOT_URL"] if defined' do
16
+ it 'uses ENV["APTIBLE_AUTH_ROOT_URL"] if defined' do
13
17
  config = described_class.configuration
14
18
  set_env 'APTIBLE_AUTH_ROOT_URL', 'http://foobar.com' do
19
+ load 'aptible/auth.rb'
15
20
  config.reset
16
21
  expect(config.root_url).to eq 'http://foobar.com'
17
22
  end
@@ -1,4 +1,4 @@
1
- def set_env(*args, _block)
1
+ def set_env(*args, &_block)
2
2
  hash = args.first.is_a?(Hash) ? args.first : Hash[*args]
3
3
  old_values = Hash[hash.map { |k, _| [k, ENV[k]] }]
4
4
  begin
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aptible-auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.7
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank Macreery
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-07-17 00:00:00.000000000 Z
11
+ date: 2025-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aptible-resource
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
- - !ruby/object:Gem::Dependency
28
- name: concurrent-ruby
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
32
- - !ruby/object:Gem::Version
33
- version: 1.3.4
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '='
39
- - !ruby/object:Gem::Version
40
- version: 1.3.4
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: gem_config
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -156,14 +142,14 @@ dependencies:
156
142
  requirements:
157
143
  - - "~>"
158
144
  - !ruby/object:Gem::Version
159
- version: 0.8.1
145
+ version: 0.9.10
160
146
  type: :development
161
147
  prerelease: false
162
148
  version_requirements: !ruby/object:Gem::Requirement
163
149
  requirements:
164
150
  - - "~>"
165
151
  - !ruby/object:Gem::Version
166
- version: 0.8.1
152
+ version: 0.9.10
167
153
  description: Ruby client for auth.aptible.com
168
154
  email:
169
155
  - frank@macreery.com
@@ -175,16 +161,21 @@ files:
175
161
  - ".github/workflows/ci.yml"
176
162
  - ".gitignore"
177
163
  - ".rspec"
164
+ - Dockerfile
178
165
  - Gemfile
179
166
  - LICENSE.md
167
+ - Makefile
180
168
  - Procfile
181
169
  - README.md
182
170
  - Rakefile
183
171
  - SECURITY.md
184
172
  - aptible-auth.gemspec
173
+ - docker-compose.yml
185
174
  - lib/aptible/auth.rb
186
175
  - lib/aptible/auth/agent.rb
187
176
  - lib/aptible/auth/client.rb
177
+ - lib/aptible/auth/external_aws_oidc_token.rb
178
+ - lib/aptible/auth/external_aws_role.rb
188
179
  - lib/aptible/auth/invitation.rb
189
180
  - lib/aptible/auth/membership.rb
190
181
  - lib/aptible/auth/organization.rb
@@ -201,6 +192,8 @@ files:
201
192
  - lib/aptible/auth/whitelist_membership.rb
202
193
  - lib/oauth2/strategy/token_exchange.rb
203
194
  - spec/aptible/auth/agent_spec.rb
195
+ - spec/aptible/auth/external_aws_oidc_token_spec.rb
196
+ - spec/aptible/auth/external_aws_role_spec.rb
204
197
  - spec/aptible/auth/organization_spec.rb
205
198
  - spec/aptible/auth/resource_spec.rb
206
199
  - spec/aptible/auth/token_spec.rb
@@ -228,12 +221,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
228
221
  - !ruby/object:Gem::Version
229
222
  version: '0'
230
223
  requirements: []
231
- rubygems_version: 3.4.10
224
+ rubygems_version: 3.5.22
232
225
  signing_key:
233
226
  specification_version: 4
234
227
  summary: Ruby client for auth.aptible.com
235
228
  test_files:
236
229
  - spec/aptible/auth/agent_spec.rb
230
+ - spec/aptible/auth/external_aws_oidc_token_spec.rb
231
+ - spec/aptible/auth/external_aws_role_spec.rb
237
232
  - spec/aptible/auth/organization_spec.rb
238
233
  - spec/aptible/auth/resource_spec.rb
239
234
  - spec/aptible/auth/token_spec.rb