Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/personal_access_tokens/revoke_token_family_service.rb')
-rw-r--r--app/services/personal_access_tokens/revoke_token_family_service.rb36
1 files changed, 36 insertions, 0 deletions
diff --git a/app/services/personal_access_tokens/revoke_token_family_service.rb b/app/services/personal_access_tokens/revoke_token_family_service.rb
new file mode 100644
index 00000000000..547ba6c3bdc
--- /dev/null
+++ b/app/services/personal_access_tokens/revoke_token_family_service.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module PersonalAccessTokens
+ class RevokeTokenFamilyService
+ def initialize(token)
+ @token = token
+ end
+
+ def execute
+ # Despite using #update_all, there should only be a single active token.
+ # A token family is a chain of rotated tokens. Once rotated, the
+ # previous token is revoked.
+ pat_family.active.update_all(revoked: true)
+
+ ServiceResponse.success
+ end
+
+ private
+
+ attr_reader :token
+
+ def pat_family
+ # rubocop: disable CodeReuse/ActiveRecord
+ cte = Gitlab::SQL::RecursiveCTE.new(:personal_access_tokens_cte)
+ personal_access_token_table = Arel::Table.new(:personal_access_tokens)
+
+ cte << PersonalAccessToken
+ .where(personal_access_token_table[:previous_personal_access_token_id].eq(token.id))
+ cte << PersonalAccessToken
+ .from([personal_access_token_table, cte.table])
+ .where(personal_access_token_table[:previous_personal_access_token_id].eq(cte.table[:id]))
+ PersonalAccessToken.with.recursive(cte.to_arel).from(cte.alias_to(personal_access_token_table))
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+ end
+end