diff --git a/spec/factories/personal_access_tokens.rb b/spec/factories/personal_access_tokens.rb index 2da729bcdec14af7575866e715046ed2a7333120..c976730a788ad8e5467e99dd5d72d7d9ac89de72 100644 --- a/spec/factories/personal_access_tokens.rb +++ b/spec/factories/personal_access_tokens.rb @@ -47,5 +47,35 @@ factory :resource_access_token, parent: :personal_access_token do user { association :user, :project_bot } + + transient do + rotated_at { 6.months.ago } + resource { create(:group) } # rubocop:disable RSpec/FactoryBot/InlineAssociation -- this is not direct association of the factory created here + access_level { Gitlab::Access::DEVELOPER } + end + + after(:create) do |token, evaluator| + if Feature.enabled?(:retain_resource_access_token_user_after_revoke, evaluator.resource.root_ancestor) + evaluator.resource.add_member(token.user, evaluator.access_level) + else + evaluator.resource.add_member(token.user, evaluator.access_level, expires_at: token.expires_at) + end + end + + trait :with_rotated_token do + after(:create) do |token, evaluator| + rotated_at = evaluator.rotated_at + previous_access_token = create( # rubocop:disable RSpec/FactoryBot/StrategyInCallback -- this is not direct association of the factory created here + :personal_access_token, + :revoked, + user: token.user, + created_at: rotated_at - 6.months, + expires_at: rotated_at, + updated_at: rotated_at + ) + + token.update!(previous_personal_access_token_id: previous_access_token.id) + end + end end end diff --git a/spec/workers/resource_access_tokens/inactive_tokens_deletion_cron_worker_spec.rb b/spec/workers/resource_access_tokens/inactive_tokens_deletion_cron_worker_spec.rb index 124910c85ce20e39c1cbeb87c1ecbd7ec082a507..879ac528eade02545f02af61a8e26d9a4e2169bf 100644 --- a/spec/workers/resource_access_tokens/inactive_tokens_deletion_cron_worker_spec.rb +++ b/spec/workers/resource_access_tokens/inactive_tokens_deletion_cron_worker_spec.rb @@ -101,6 +101,12 @@ create(:resource_access_token, updated_at: cut_off) non_revoked_resource_access_token_updated_after_cut_off = create(:personal_access_token, updated_at: cut_off + 1.second) + resource_access_token_with_rotated_token_before_cut_off = + create(:resource_access_token, :with_rotated_token, rotated_at: cut_off - 1.second) + resource_access_token_with_rotated_token_at_cut_off = + create(:resource_access_token, :with_rotated_token, rotated_at: cut_off) + resource_access_token_with_rotated_token_after_cut_off = + create(:resource_access_token, :with_rotated_token, rotated_at: cut_off + 1.second) tokens_to_keep = [ active_personal_access_token, @@ -121,13 +127,18 @@ resource_access_token_revoked_after_cut_off, non_revoked_resource_access_token_updated_before_cut_off, non_revoked_resource_access_token_updated_at_cut_off, - non_revoked_resource_access_token_updated_after_cut_off + non_revoked_resource_access_token_updated_after_cut_off, + resource_access_token_with_rotated_token_at_cut_off, + resource_access_token_with_rotated_token_after_cut_off ] users_to_keep = tokens_to_keep.map(&:user) tokens_to_delete = [ resource_access_token_expired_before_cut_off, - resource_access_token_revoked_before_cut_off + resource_access_token_revoked_before_cut_off, + # This token should be kept. + # See bug related to https://gitlab.com/gitlab-org/gitlab/-/issues/492871 + resource_access_token_with_rotated_token_before_cut_off ] users_to_delete = tokens_to_delete.map(&:user)