Commit f16377e7 authored by James Edwards-Jones's avatar James Edwards-Jones
Browse files

Protected Tags backend review changes

Added changelog
parent 6ff0374c8cde
class Projects::ProtectedBranchesController < Projects::ProtectedRefsController
protected
def protected_ref
@protected_branch
end
def protected_ref=(val)
@protected_branch = val
end
def matching_refs=(val)
@matching_branches = val
end
def project_refs
@project.repository.branches
end
def create_service
def create_service_class
::ProtectedBranches::CreateService
end
def update_service
def update_service_class
::ProtectedBranches::UpdateService
end
def load_protected_ref
self.protected_ref = @project.protected_branches.find(params[:id])
@protected_ref = @project.protected_branches.find(params[:id])
end
def protected_ref_params
......
class Projects::ProtectedRefsController < Projects::ApplicationController
include RepositorySettingsRedirect
# Authorize
before_action :require_non_empty_project
before_action :authorize_admin_project!
......@@ -12,33 +13,31 @@ def index
end
def create
self.protected_ref = create_service.new(@project, current_user, protected_ref_params).execute
protected_ref = create_service_class.new(@project, current_user, protected_ref_params).execute
unless protected_ref.persisted?
flash[:alert] = protected_ref.errors.full_messages.join(', ').html_safe
end
redirect_to_repository_settings(@project)
end
def show
self.matching_refs = protected_ref.matching(project_refs)
@matching_refs = @protected_ref.matching(project_refs)
end
def update
self.protected_ref = update_service.new(@project, current_user, protected_ref_params).execute(protected_ref)
@protected_ref = update_service_class.new(@project, current_user, protected_ref_params).execute(@protected_ref)
if protected_ref.valid?
respond_to do |format|
format.json { render json: protected_ref, status: :ok }
end
if @protected_ref.valid?
render json: @protected_ref, status: :ok
else
respond_to do |format|
format.json { render json: protected_ref.errors, status: :unprocessable_entity }
end
render json: @protected_ref.errors, status: :unprocessable_entity
end
end
def destroy
protected_ref.destroy
@protected_ref.destroy
respond_to do |format|
format.html { redirect_to_repository_settings(@project) }
......
class Projects::ProtectedTagsController < Projects::ProtectedRefsController
protected
def protected_ref
@protected_tag
end
def protected_ref=(val)
@protected_tag = val
end
def matching_refs=(val)
@matching_tags = val
end
def project_refs
@project.repository.tags
end
def create_service
def create_service_class
::ProtectedTags::CreateService
end
def update_service
def update_service_class
::ProtectedTags::UpdateService
end
def load_protected_ref
self.protected_ref = @project.protected_tags.find(params[:id])
@protected_ref = @project.protected_tags.find(params[:id])
end
def protected_ref_params
......
......@@ -29,4 +29,8 @@ def can_push_branch?(project, branch_name)
def project_branches
options_for_select(@project.repository.branch_names, @project.default_branch)
end
def protected_branch?(project, branch)
ProtectedBranch.protected?(project, branch.name)
end
end
......@@ -5,6 +5,7 @@ module ProtectedBranchAccess
include ProtectedRefAccess
belongs_to :protected_branch
delegate :project, to: :protected_branch
end
end
......@@ -3,6 +3,7 @@ module ProtectedRef
included do
belongs_to :project
validates :name, presence: true
validates :project, presence: true
......
......@@ -5,6 +5,7 @@ module ProtectedTagAccess
include ProtectedRefAccess
belongs_to :protected_tag
delegate :project, to: :protected_tag
end
end
......@@ -134,7 +134,7 @@ def update_forks_visibility_level
has_many :snippets, dependent: :destroy, class_name: 'ProjectSnippet'
has_many :hooks, dependent: :destroy, class_name: 'ProjectHook'
has_many :protected_branches, dependent: :destroy
has_many :protected_tags, dependent: :destroy
has_many :protected_tags, dependent: :destroy
has_many :project_authorizations
has_many :authorized_users, through: :project_authorizations, source: :user, class_name: 'User'
......
......@@ -6,8 +6,7 @@ def initialize(project, ref_type)
# Tags/branches which are yet to be individually protected
def protectable_ref_names
non_wildcard_protections = protections.reject(&:wildcard?)
refs.map(&:name) - non_wildcard_protections.map(&:name)
@protectable_ref_names ||= ref_names - non_wildcard_protected_ref_names
end
def hash
......@@ -20,7 +19,15 @@ def refs
@project.repository.public_send(@ref_type)
end
def ref_names
refs.map(&:name)
end
def protections
@project.public_send("protected_#{@ref_type}")
end
def non_wildcard_protected_ref_names
protections.reject(&:wildcard?).map(&:name)
end
end
module ProtectedBranches
class UpdateService < BaseService
attr_reader :protected_branch
def execute(protected_branch)
raise Gitlab::Access::AccessDeniedError unless can?(current_user, :admin_project, project)
@protected_branch = protected_branch
@protected_branch.update(params)
@protected_branch
protected_branch.update(params)
protected_branch
end
end
end
module ProtectedTags
class UpdateService < BaseService
attr_reader :protected_tag
def execute(protected_tag)
raise Gitlab::Access::AccessDeniedError unless can?(current_user, :admin_project, project)
@protected_tag = protected_tag
@protected_tag.update(params)
@protected_tag
protected_tag.update(params)
protected_tag
end
end
end
......@@ -15,7 +15,7 @@
%span.label.label-info.has-tooltip{ title: "Merged into #{@repository.root_ref}" }
merged
- if ProtectedBranch.protected?(@project, branch.name)
- if protected_branch?(@project, branch)
%span.label.label-success
protected
.controls.hidden-xs<
......
- page_title @protected_branch.name, "Protected Branches"
- page_title @protected_ref.name, "Protected Branches"
.row.prepend-top-default.append-bottom-default
.col-lg-3
%h4.prepend-top-0
= @protected_branch.name
= @protected_ref.name
.col-lg-9
%h5 Matching Branches
- if @matching_branches.present?
- if @matching_refs.present?
.table-responsive
%table.table.protected-branches-list
%colgroup
......@@ -18,7 +18,7 @@
%th Branch
%th Last commit
%tbody
- @matching_branches.each do |matching_branch|
- @matching_refs.each do |matching_branch|
= render partial: "matching_branch", object: matching_branch
- else
%p.settings-message.text-center
......
- page_title @protected_tag.name, "Protected Tags"
- page_title @protected_ref.name, "Protected Tags"
.row.prepend-top-default.append-bottom-default
.col-lg-3
%h4.prepend-top-0
= @protected_tag.name
= @protected_ref.name
.col-lg-9
%h5 Matching Tags
- if @matching_tags.present?
- if @matching_refs.present?
.table-responsive
%table.table.protected-tags-list
%colgroup
......@@ -18,7 +18,7 @@
%th Tag
%th Last commit
%tbody
- @matching_tags.each do |matching_tag|
- @matching_refs.each do |matching_tag|
= render partial: "matching_tag", object: matching_tag
- else
%p.settings-message.text-center
......
---
title: Protected Tags feature
merge_request: 10356
author:
class CreateProtectedTags < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
GITLAB_ACCESS_MASTER = 40
......
......@@ -70,14 +70,8 @@ def tag_checks
def protected_tag_checks
return unless tag_protected?
if update?
return "Protected tags cannot be updated."
end
if deletion?
return "Protected tags cannot be deleted."
end
return "Protected tags cannot be updated." if update?
return "Protected tags cannot be deleted." if deletion?
unless user_access.can_create_tag?(@tag_name)
return "You are not allowed to create this tag as it is protected."
......
......@@ -3,6 +3,7 @@
describe Projects::ProtectedBranchesController do
describe "GET #index" do
let(:project) { create(:project_empty_repo, :public) }
it "redirects empty repo to projects page" do
get(:index, namespace_id: project.namespace.to_param, project_id: project)
end
......
......@@ -3,6 +3,7 @@
describe Projects::ProtectedTagsController do
describe "GET #index" do
let(:project) { create(:project_empty_repo, :public) }
it "redirects empty repo to projects page" do
get(:index, namespace_id: project.namespace.to_param, project_id: project)
end
......
......@@ -2,7 +2,9 @@
ProtectedBranch::PushAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)|
it "allows creating protected branches that #{access_type_name} can push to" do
visit namespace_project_protected_branches_path(project.namespace, project)
set_protected_branch_name('master')
within('.new_protected_branch') do
allowed_to_push_button = find(".js-allowed-to-push")
......@@ -11,6 +13,7 @@
within(".dropdown.open .dropdown-menu") { click_on access_type_name }
end
end
click_on "Protect"
expect(ProtectedBranch.count).to eq(1)
......@@ -19,7 +22,9 @@
it "allows updating protected branches so that #{access_type_name} can push to them" do
visit namespace_project_protected_branches_path(project.namespace, project)
set_protected_branch_name('master')
click_on "Protect"
expect(ProtectedBranch.count).to eq(1)
......@@ -34,6 +39,7 @@
end
wait_for_ajax
expect(ProtectedBranch.last.push_access_levels.map(&:access_level)).to include(access_type_id)
end
end
......@@ -41,7 +47,9 @@
ProtectedBranch::MergeAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)|
it "allows creating protected branches that #{access_type_name} can merge to" do
visit namespace_project_protected_branches_path(project.namespace, project)
set_protected_branch_name('master')
within('.new_protected_branch') do
allowed_to_merge_button = find(".js-allowed-to-merge")
......@@ -50,6 +58,7 @@
within(".dropdown.open .dropdown-menu") { click_on access_type_name }
end
end
click_on "Protect"
expect(ProtectedBranch.count).to eq(1)
......@@ -58,7 +67,9 @@
it "allows updating protected branches so that #{access_type_name} can merge to them" do
visit namespace_project_protected_branches_path(project.namespace, project)
set_protected_branch_name('master')
click_on "Protect"
expect(ProtectedBranch.count).to eq(1)
......@@ -73,6 +84,7 @@
end
wait_for_ajax
expect(ProtectedBranch.last.merge_access_levels.map(&:access_level)).to include(access_type_id)
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