Commit 60f3577e authored by Etienne Baqué's avatar Etienne Baqué Committed by Mark Lapierre

Moved project deploy tokens back to repository

Reverted deploy token section from ci/cd to repository.
Updated relevants assets, views, controllers, rspecs.
parent a349a7be
......@@ -3,7 +3,6 @@ import SecretValues from '~/behaviors/secret_values';
import AjaxVariableList from '~/ci_variable_list/ajax_variable_list';
import registrySettingsApp from '~/registry/settings/registry_settings_bundle';
import initVariableList from '~/ci_variable_list';
import DueDateSelectors from '~/due_date_select';
import initDeployKeys from '~/deploy_keys';
document.addEventListener('DOMContentLoaded', () => {
......@@ -41,9 +40,6 @@ document.addEventListener('DOMContentLoaded', () => {
autoDevOpsExtraSettings.classList.toggle('hidden', !target.checked);
});
// eslint-disable-next-line no-new
new DueDateSelectors();
registrySettingsApp();
initDeployKeys();
});
......@@ -7,6 +7,6 @@ class Projects::DeployTokensController < Projects::ApplicationController
@token = @project.deploy_tokens.find(params[:id])
@token.revoke!
redirect_to project_settings_ci_cd_path(project, anchor: 'js-deploy-tokens')
redirect_to project_settings_repository_path(project, anchor: 'js-deploy-tokens')
end
end
......@@ -48,33 +48,6 @@ module Projects
redirect_to namespace_project_settings_ci_cd_path
end
def create_deploy_token
result = Projects::DeployTokens::CreateService.new(@project, current_user, deploy_token_params).execute
@new_deploy_token = result[:deploy_token]
if result[:status] == :success
respond_to do |format|
format.json do
# IMPORTANT: It's a security risk to expose the token value more than just once here!
json = API::Entities::DeployTokenWithToken.represent(@new_deploy_token).as_json
render json: json, status: result[:http_status]
end
format.html do
flash.now[:notice] = s_('DeployTokens|Your new project deploy token has been created.')
render :show
end
end
else
respond_to do |format|
format.json { render json: { message: result[:message] }, status: result[:http_status] }
format.html do
flash.now[:alert] = result[:message]
render :show
end
end
end
end
private
def update_params
......@@ -93,10 +66,6 @@ module Projects
end
end
def deploy_token_params
params.require(:deploy_token).permit(:name, :expires_at, :read_repository, :read_registry, :write_registry, :username)
end
def run_autodevops_pipeline(service)
return unless service.run_auto_devops_pipeline?
......@@ -116,7 +85,6 @@ module Projects
def define_variables
define_runners_variables
define_ci_variables
define_deploy_token_variables
define_triggers_variables
define_badges_variables
define_auto_devops_variables
......@@ -168,12 +136,6 @@ module Projects
@auto_devops = @project.auto_devops || ProjectAutoDevops.new
end
def define_deploy_token_variables
@deploy_tokens = @project.deploy_tokens.active
@new_deploy_token = DeployToken.new
end
def define_deploy_keys
@deploy_keys = DeployKeysPresenter.new(@project, current_user: current_user)
end
......
......@@ -4,7 +4,10 @@ module Projects
module Settings
class RepositoryController < Projects::ApplicationController
before_action :authorize_admin_project!
before_action :remote_mirror, only: [:show]
before_action :define_variables, only: [:create_deploy_token]
before_action do
push_frontend_feature_flag(:ajax_new_deploy_token, @project)
end
def show
render_show
......@@ -24,15 +27,47 @@ module Projects
redirect_to project_settings_repository_path(project)
end
def create_deploy_token
result = Projects::DeployTokens::CreateService.new(@project, current_user, deploy_token_params).execute
@new_deploy_token = result[:deploy_token]
if result[:status] == :success
respond_to do |format|
format.json do
# IMPORTANT: It's a security risk to expose the token value more than just once here!
json = API::Entities::DeployTokenWithToken.represent(@new_deploy_token).as_json
render json: json, status: result[:http_status]
end
format.html do
flash.now[:notice] = s_('DeployTokens|Your new project deploy token has been created.')
render :show
end
end
else
respond_to do |format|
format.json { render json: { message: result[:message] }, status: result[:http_status] }
format.html do
flash.now[:alert] = result[:message]
render :show
end
end
end
end
private
def render_show
define_protected_refs
remote_mirror
define_variables
render 'show'
end
def define_variables
define_deploy_token_variables
define_protected_refs
remote_mirror
end
# rubocop: disable CodeReuse/ActiveRecord
def define_protected_refs
@protected_branches = @project.protected_branches.order(:name).page(params[:page])
......@@ -51,6 +86,10 @@ module Projects
@remote_mirror = project.remote_mirrors.first_or_initialize
end
def deploy_token_params
params.require(:deploy_token).permit(:name, :expires_at, :read_repository, :read_registry, :write_registry, :username)
end
def access_levels_options
{
create_access_levels: levels_for_dropdown,
......@@ -74,6 +113,12 @@ module Projects
{ open_branches: ProtectableDropdown.new(@project, :branches).hash }
end
def define_deploy_token_variables
@deploy_tokens = @project.deploy_tokens.active
@new_deploy_token ||= DeployToken.new
end
def load_gon_index
gon.push(protectable_tags_for_dropdown)
gon.push(protectable_branches_for_dropdown)
......
......@@ -2368,7 +2368,7 @@ class Project < ApplicationRecord
end
def deploy_token_create_url(opts = {})
Gitlab::Routing.url_helpers.create_deploy_token_project_settings_ci_cd_path(self, opts)
Gitlab::Routing.url_helpers.create_deploy_token_project_settings_repository_path(self, opts)
end
def deploy_token_revoke_url_for(token)
......
......@@ -4,7 +4,6 @@
- expanded = expanded_by_default?
- general_expanded = @project.errors.empty? ? expanded : true
- deploy_token_description = s_('DeployTokens|Deploy tokens allow access to your repository and registry images.')
%section.settings#js-general-pipeline-settings.no-animate{ class: ('expanded' if general_expanded) }
.settings-header
......@@ -52,8 +51,6 @@
.settings-content
= render 'ci/variables/index', save_endpoint: project_variables_path(@project)
= render "shared/deploy_tokens/index", group_or_project: @project, description: deploy_token_description
= render @deploy_keys
%section.settings.no-animate#js-pipeline-triggers{ class: ('expanded' if expanded) }
......
- breadcrumb_title _("Repository Settings")
- page_title _("Repository")
- @content_class = "limit-container-width" unless fluid_layout
- deploy_token_description = s_('DeployTokens|Deploy tokens allow access to your repository and registry images.')
= render "projects/default_branch/show"
= render_if_exists "projects/push_rules/index"
......@@ -11,6 +12,7 @@
-# Those are used throughout the actual views. These `shared` views are then
-# reused in EE.
= render "projects/settings/repository/protected_branches"
= render "shared/deploy_tokens/index", group_or_project: @project, description: deploy_token_description
= render "projects/cleanup/show"
= render_if_exists 'shared/promotions/promote_repository_features'
......@@ -73,7 +73,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resource :ci_cd, only: [:show, :update], controller: 'ci_cd' do
post :reset_cache
put :reset_registration_token
post :create_deploy_token, path: 'deploy_token/create'
post :create_deploy_token, path: 'deploy_token/create', to: 'repository#create_deploy_token'
end
resource :operations, only: [:show, :update] do
......@@ -87,7 +87,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resource :repository, only: [:show], controller: :repository do
# TODO: Removed this "create_deploy_token" route after change was made in app/helpers/ci_variables_helper.rb:14
# See MR comment for more detail: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27059#note_311585356
post :create_deploy_token, path: 'deploy_token/create', to: 'ci_cd#create_deploy_token'
post :create_deploy_token, path: 'deploy_token/create'
post :cleanup
end
end
......
......@@ -8,8 +8,8 @@ module EE
extend ActiveSupport::Concern
prepended do
before_action :assign_variables_to_gon, only: [:show, :create_deploy_token]
before_action :define_protected_env_variables, only: [:show, :create_deploy_token]
before_action :assign_variables_to_gon, only: [:show]
before_action :define_protected_env_variables, only: [:show]
end
# rubocop:disable Gitlab/ModuleWithInstanceVariables
......
......@@ -9,7 +9,7 @@ module EE
prepended do
include SafeMirrorParams
before_action :push_rule, only: [:show]
before_action :push_rule, only: [:show, :create_deploy_token]
end
private
......@@ -41,15 +41,10 @@ module EE
gon.push(current_project_id: project.id) if project
end
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def render_show
@deploy_tokens = @project.deploy_tokens.active
define_protected_refs
push_rule
remote_mirror
render 'show'
super
end
end
end
......
---
title: Move project deploy tokens section back to Repository settings
merge_request: 29280
author:
type: changed
......@@ -13,20 +13,10 @@ module QA
element :variables_settings_content
end
view 'app/views/shared/deploy_tokens/_index.html.haml' do
element :deploy_tokens_settings
end
view 'app/views/projects/deploy_keys/_index.html.haml' do
element :deploy_keys_settings
end
def expand_deploy_tokens(&block)
expand_section(:deploy_tokens_settings) do
Settings::DeployTokens.perform(&block)
end
end
def expand_deploy_keys(&block)
expand_section(:deploy_keys_settings) do
Settings::DeployKeys.perform(&block)
......
......@@ -15,6 +15,16 @@ module QA
element :mirroring_repositories_settings_section
end
view 'app/views/shared/deploy_tokens/_index.html.haml' do
element :deploy_tokens_settings
end
def expand_deploy_tokens(&block)
expand_section(:deploy_tokens_settings) do
Settings::DeployTokens.perform(&block)
end
end
def expand_protected_branches(&block)
expand_section(:protected_branches_settings) do
ProtectedBranches.perform(&block)
......
......@@ -6,16 +6,16 @@ module QA
attr_accessor :name, :expires_at
attribute :username do
Page::Project::Settings::CICD.perform do |cicd_page|
cicd_page.expand_deploy_tokens do |token|
Page::Project::Settings::Repository.perform do |repository_page|
repository_page.expand_deploy_tokens do |token|
token.token_username
end
end
end
attribute :password do
Page::Project::Settings::CICD.perform do |cicd_page|
cicd_page.expand_deploy_tokens do |token|
Page::Project::Settings::Repository.perform do |repository_page|
repository_page.expand_deploy_tokens do |token|
token.token_password
end
end
......@@ -31,10 +31,10 @@ module QA
def fabricate!
project.visit!
Page::Project::Menu.perform(&:go_to_ci_cd_settings)
Page::Project::Menu.perform(&:go_to_repository_settings)
Page::Project::Settings::CICD.perform do |cicd|
cicd.expand_deploy_tokens do |page|
Page::Project::Settings::Repository.perform do |setting|
setting.expand_deploy_tokens do |page|
page.fill_token_name(name)
page.fill_token_expires_at(expires_at)
page.fill_scopes(read_repository: true, read_registry: false)
......
......@@ -266,84 +266,4 @@ describe Projects::Settings::CiCdController do
end
end
end
describe 'POST create_deploy_token' do
context 'when ajax_new_deploy_token feature flag is disabled for the project' do
before do
stub_feature_flags(ajax_new_deploy_token: { enabled: false, thing: project })
end
it_behaves_like 'a created deploy token' do
let(:entity) { project }
let(:create_entity_params) { { namespace_id: project.namespace, project_id: project } }
let(:deploy_token_type) { DeployToken.deploy_token_types[:project_type] }
end
end
context 'when ajax_new_deploy_token feature flag is enabled for the project' do
let(:good_deploy_token_params) do
{
name: 'name',
expires_at: 1.day.from_now.to_s,
username: 'deployer',
read_repository: '1',
deploy_token_type: DeployToken.deploy_token_types[:project_type]
}
end
let(:request_params) do
{
namespace_id: project.namespace.to_param,
project_id: project.to_param,
deploy_token: deploy_token_params
}
end
subject { post :create_deploy_token, params: request_params, format: :json }
context('a good request') do
let(:deploy_token_params) { good_deploy_token_params }
let(:expected_response) do
{
'id' => be_a(Integer),
'name' => deploy_token_params[:name],
'username' => deploy_token_params[:username],
'expires_at' => Time.parse(deploy_token_params[:expires_at]),
'token' => be_a(String),
'scopes' => deploy_token_params.inject([]) do |scopes, kv|
key, value = kv
key.to_s.start_with?('read_') && !value.to_i.zero? ? scopes << key.to_s : scopes
end
}
end
it 'creates the deploy token' do
subject
expect(response).to have_gitlab_http_status(:created)
expect(response).to match_response_schema('public_api/v4/deploy_token')
expect(json_response).to match(expected_response)
end
end
context('a bad request') do
let(:deploy_token_params) { good_deploy_token_params.except(:read_repository) }
let(:expected_response) { { 'message' => "Scopes can't be blank" } }
it 'does not create the deploy token' do
subject
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response).to match(expected_response)
end
end
context('an invalid request') do
let(:deploy_token_params) { good_deploy_token_params.except(:name) }
it 'raises a validation error' do
expect { subject }.to raise_error(ActiveRecord::StatementInvalid)
end
end
end
end
end
......@@ -32,4 +32,84 @@ describe Projects::Settings::RepositoryController do
expect(RepositoryCleanupWorker).to have_received(:perform_async).once
end
end
describe 'POST create_deploy_token' do
context 'when ajax_new_deploy_token feature flag is disabled for the project' do
before do
stub_feature_flags(ajax_new_deploy_token: { enabled: false, thing: project })
end
it_behaves_like 'a created deploy token' do
let(:entity) { project }
let(:create_entity_params) { { namespace_id: project.namespace, project_id: project } }
let(:deploy_token_type) { DeployToken.deploy_token_types[:project_type] }
end
end
context 'when ajax_new_deploy_token feature flag is enabled for the project' do
let(:good_deploy_token_params) do
{
name: 'name',
expires_at: 1.day.from_now.to_s,
username: 'deployer',
read_repository: '1',
deploy_token_type: DeployToken.deploy_token_types[:project_type]
}
end
let(:request_params) do
{
namespace_id: project.namespace.to_param,
project_id: project.to_param,
deploy_token: deploy_token_params
}
end
subject { post :create_deploy_token, params: request_params, format: :json }
context('a good request') do
let(:deploy_token_params) { good_deploy_token_params }
let(:expected_response) do
{
'id' => be_a(Integer),
'name' => deploy_token_params[:name],
'username' => deploy_token_params[:username],
'expires_at' => Time.parse(deploy_token_params[:expires_at]),
'token' => be_a(String),
'scopes' => deploy_token_params.inject([]) do |scopes, kv|
key, value = kv
key.to_s.start_with?('read_') && !value.to_i.zero? ? scopes << key.to_s : scopes
end
}
end
it 'creates the deploy token' do
subject
expect(response).to have_gitlab_http_status(:created)
expect(response).to match_response_schema('public_api/v4/deploy_token')
expect(json_response).to match(expected_response)
end
end
context('a bad request') do
let(:deploy_token_params) { good_deploy_token_params.except(:read_repository) }
let(:expected_response) { { 'message' => "Scopes can't be blank" } }
it 'does not create the deploy token' do
subject
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response).to match(expected_response)
end
end
context('an invalid request') do
let(:deploy_token_params) { good_deploy_token_params.except(:name) }
it 'raises a validation error' do
expect { subject }.to raise_error(ActiveRecord::StatementInvalid)
end
end
end
end
end
......@@ -7,22 +7,6 @@ describe 'Projects > Settings > CI / CD settings' do
let_it_be(:user) { create(:user) }
let_it_be(:role) { :maintainer }
context 'Deploy tokens' do
let!(:deploy_token) { create(:deploy_token, projects: [project]) }
before do
project.add_role(user, role)
sign_in(user)
stub_container_registry_config(enabled: true)
stub_feature_flags(ajax_new_deploy_token: { enabled: false, thing: project })
visit project_settings_ci_cd_path(project)
end
it_behaves_like 'a deploy token in settings' do
let(:entity_type) { 'project' }
end
end
context 'Deploy Keys', :js do
let_it_be(:private_deploy_key) { create(:deploy_key, title: 'private_deploy_key', public: false) }
let_it_be(:public_deploy_key) { create(:another_deploy_key, title: 'public_deploy_key', public: true) }
......
......@@ -25,6 +25,20 @@ describe 'Projects > Settings > Repository settings' do
context 'for maintainer' do
let(:role) { :maintainer }
context 'Deploy tokens' do
let!(:deploy_token) { create(:deploy_token, projects: [project]) }
before do
stub_container_registry_config(enabled: true)
stub_feature_flags(ajax_new_deploy_token: { enabled: false, thing: project })
visit project_settings_repository_path(project)
end
it_behaves_like 'a deploy token in settings' do
let(:entity_type) { 'project' }
end
end
context 'remote mirror settings' do
before do
visit project_settings_repository_path(project)
......
......@@ -12,7 +12,7 @@ describe 'Repository Settings > User sees revoke deploy token modal', :js do
project.add_role(user, role)
sign_in(user)
stub_feature_flags(ajax_new_deploy_token: { enabled: false, thing: project })
visit(project_settings_ci_cd_path(project))
visit(project_settings_repository_path(project))
click_link('Revoke')
end
......
......@@ -800,9 +800,8 @@ describe 'project routing' do
it_behaves_like 'redirecting a legacy project path', "/gitlab/gitlabhq/settings/repository", "/gitlab/gitlabhq/-/settings/repository"
# TODO: remove this test as part of https://gitlab.com/gitlab-org/gitlab/issues/207079 (12.9)
it 'to ci_cd#create_deploy_token' do
expect(post('gitlab/gitlabhq/-/settings/ci_cd/deploy_token/create')).to route_to('projects/settings/ci_cd#create_deploy_token', namespace_id: 'gitlab', project_id: 'gitlabhq')
it 'to repository#create_deploy_token' do
expect(post('gitlab/gitlabhq/-/settings/ci_cd/deploy_token/create')).to route_to('projects/settings/repository#create_deploy_token', namespace_id: 'gitlab', project_id: 'gitlabhq')
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment