Skip to content
代码片段 群组 项目
未验证 提交 765c467a 编辑于 作者: Nicholas Wittstruck's avatar Nicholas Wittstruck 提交者: GitLab
浏览文件

Admin Token API: Revoke pipeline trigger tokens

上级 0f596aaa
No related branches found
No related tags found
2 合并请求!3031Merge per-main-jh to main-jh by luzhiyuan,!3030Merge per-main-jh to main-jh
# frozen_string_literal: true
module Ci
module PipelineTriggers
class ExpireService
include Gitlab::Allowable
def initialize(user:, trigger:)
@current_user = user
@trigger = trigger
end
def execute
unless can?(current_user, :manage_trigger, trigger)
return ServiceResponse.error(
message: _('The current user is not authorized to manage the pipeline trigger token'),
reason: :forbidden
).freeze
end
if trigger.update(expires_at: Time.current)
ServiceResponse.success
else
ServiceResponse.error(message: trigger.errors.full_messages.to_sentence)
end
end
private
attr_reader :current_user, :trigger
end
end
end
---
name: token_api_expire_pipeline_triggers
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/517491
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181598
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/520713
milestone: '17.10'
group: group::pipeline execution
type: beta
default_enabled: false
...@@ -122,6 +122,7 @@ Example response: ...@@ -122,6 +122,7 @@ Example response:
- [OAuth application secrets added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179035) in GitLab 17.9. - [OAuth application secrets added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179035) in GitLab 17.9.
- [Incoming email tokens added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180763) in GitLab 17.9. - [Incoming email tokens added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180763) in GitLab 17.9.
- [Feature flags client tokens added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181096) in GitLab 17.9. - [Feature flags client tokens added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181096) in GitLab 17.9.
- [Pipeline trigger tokens added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181598) in GitLab 17.10 [with a flag](../../administration/feature_flags.md) named `token_api_expire_pipeline_triggers`. Disabled by default.
{{< /history >}} {{< /history >}}
...@@ -143,6 +144,7 @@ Revokes or resets a given token based on the token type. This endpoint supports ...@@ -143,6 +144,7 @@ Revokes or resets a given token based on the token type. This endpoint supports
| [Group access tokens](../../security/tokens/_index.md#group-access-tokens) | Revoke | | [Group access tokens](../../security/tokens/_index.md#group-access-tokens) | Revoke |
| [Deploy tokens](../../user/project/deploy_tokens/_index.md) | Revoke | | [Deploy tokens](../../user/project/deploy_tokens/_index.md) | Revoke |
| [Cluster agent tokens](../../security/tokens/_index.md#gitlab-cluster-agent-tokens) | Revoke | | [Cluster agent tokens](../../security/tokens/_index.md#gitlab-cluster-agent-tokens) | Revoke |
| [Pipeline trigger tokens](../../ci/triggers/_index.md#create-a-pipeline-trigger-token) | Revoke |
| [Feed tokens](../../security/tokens/_index.md#feed-token) | Reset | | [Feed tokens](../../security/tokens/_index.md#feed-token) | Reset |
| [Runner authentication tokens](../../security/tokens/_index.md#runner-authentication-tokens) | Reset | | [Runner authentication tokens](../../security/tokens/_index.md#runner-authentication-tokens) | Reset |
| [OAuth application secrets](../../integration/oauth_provider.md) | Reset | | [OAuth application secrets](../../integration/oauth_provider.md) | Reset |
......
...@@ -18,10 +18,14 @@ def present_with ...@@ -18,10 +18,14 @@ def present_with
::API::Entities::Trigger ::API::Entities::Trigger
end end
def revoke!(_current_user) def revoke!(current_user)
raise ::Authn::AgnosticTokenIdentifier::NotFoundError, 'Not Found' if revocable.blank? raise ::Authn::AgnosticTokenIdentifier::NotFoundError, 'Not Found' if revocable.blank?
raise ::Authn::AgnosticTokenIdentifier::UnsupportedTokenError, 'Unsupported token type' unless Feature.enabled?(:token_api_expire_pipeline_triggers, revocable.project)
raise ::Authn::AgnosticTokenIdentifier::UnsupportedTokenError, 'Unsupported token type'
end
::Ci::PipelineTriggers::ExpireService.new(user: current_user, trigger: revocable).execute
end end
end end
end end
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Authn::Tokens::CiTriggerToken, feature_category: :system_access do RSpec.describe Authn::Tokens::CiTriggerToken, :aggregate_failures, feature_category: :system_access do
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, maintainers: [user]) }
let(:ci_trigger) { create(:ci_trigger) } let_it_be(:ci_trigger) { create(:ci_trigger, project: project) }
subject(:token) { described_class.new(plaintext, :api_admin_token) } subject(:token) { described_class.new(plaintext, :api_admin_token) }
...@@ -16,10 +17,21 @@ ...@@ -16,10 +17,21 @@
it_behaves_like 'finding the valid revocable' it_behaves_like 'finding the valid revocable'
describe '#revoke!' do describe '#revoke!' do
it 'does not support revocation yet' do it 'expires the token' do
expect do expect { token.revoke!(user) }.to change { ci_trigger.reload.expired? }
token.revoke!(user) expect(token.revoke!(user).success?).to be_truthy
end.to raise_error(::Authn::AgnosticTokenIdentifier::UnsupportedTokenError, 'Unsupported token type') end
context 'with feature flag disabled' do
before do
stub_feature_flags(token_api_expire_pipeline_triggers: false)
end
it 'does not support revocation yet' do
expect do
token.revoke!(user)
end.to raise_error(::Authn::AgnosticTokenIdentifier::UnsupportedTokenError, 'Unsupported token type')
end
end end
end end
end end
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
end end
let_it_be(:admin) { create(:admin) } let_it_be(:admin) { create(:admin) }
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project, maintainers: [admin]) }
let_it_be(:group) { create(:group) } let_it_be(:group) { create(:group) }
let_it_be(:url) { '/admin/token' } let_it_be(:url) { '/admin/token' }
let(:api_user) { admin } let(:api_user) { admin }
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
let(:cluster_agent_token) { create(:cluster_agent_token, token_encrypted: nil) } let(:cluster_agent_token) { create(:cluster_agent_token, token_encrypted: nil) }
let(:runner_authentication_token) { create(:ci_runner, registration_type: :authenticated_user) } let(:runner_authentication_token) { create(:ci_runner, registration_type: :authenticated_user) }
let(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) } let(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
let(:ci_trigger) { create(:ci_trigger) } let_it_be(:ci_trigger) { create(:ci_trigger, project: project) }
let(:ci_build) { create(:ci_build, status: :running) } let(:ci_build) { create(:ci_build, status: :running) }
let(:feature_flags_client) { create(:operations_feature_flags_client) } let(:feature_flags_client) { create(:operations_feature_flags_client) }
...@@ -200,6 +200,30 @@ ...@@ -200,6 +200,30 @@
end end
end end
context 'when the token is a ci pipeline trigger token' do
let(:plaintext) { ci_trigger.token }
it 'expires the trigger token' do
expect { delete_token }.to change { ci_trigger.reload.expired? }
expect(response).to have_gitlab_http_status(:no_content)
end
context 'when expiring the token fails' do
before do
errors = ActiveModel::Errors.new(ci_trigger).tap { |e| e.add(:base, 'Some error') }
allow(ci_trigger).to receive_messages(update: false, errors: errors)
allow(::Ci::Trigger).to receive(:find_by_token).with(plaintext).and_return(ci_trigger)
end
it_behaves_like 'returning response status', :bad_request
it 'returns the error message' do
delete_token
expect(response.body).to include('Some error')
end
end
end
context 'when the revocation feature is disabled' do context 'when the revocation feature is disabled' do
before do before do
stub_feature_flags(api_admin_token_revoke: false) stub_feature_flags(api_admin_token_revoke: false)
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::PipelineTriggers::ExpireService, :aggregate_failures, feature_category: :continuous_integration do
describe '#execute' do
let_it_be(:project) { create(:project) }
let_it_be(:current_user) { create(:user) }
let_it_be(:pipeline_trigger) { create(:ci_trigger, project: project) }
subject(:execute) { described_class.new(user: current_user, trigger: pipeline_trigger).execute }
context 'when user does not have permission' do
before_all do
project.add_developer(current_user)
end
it 'returns an error' do
is_expected.to be_error.and have_attributes(
message: 'The current user is not authorized to manage the pipeline trigger token',
reason: :forbidden
)
end
end
context 'when user has permission' do
before_all do
project.add_maintainer(current_user)
end
it 'expires the pipeline trigger token' do
expect { execute }.to change { pipeline_trigger.reload.expired? }.from(false).to(true)
expect(execute).to be_success
end
context 'when update fails' do
before do
errors = ActiveModel::Errors.new(pipeline_trigger).tap { |e| e.add(:base, 'Some error') }
allow(pipeline_trigger).to receive_messages(update: false, errors: errors)
end
it { is_expected.to be_error.and have_attributes(message: 'Some error') }
end
end
end
end
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册