Commit 0c1bf16d authored by James Edwards-Jones's avatar James Edwards-Jones

Backport EE refactorings for Protected Tag EE-only functionality

Improvements and refactorings were made while adding role based permissions for protected tags to EE. This doesn’t backport the feature, but should improve code quality and minimize divergence.
parent 19ee16a0
...@@ -10,7 +10,7 @@ export default class ProtectedTagDropdown { ...@@ -10,7 +10,7 @@ export default class ProtectedTagDropdown {
this.$dropdown = options.$dropdown; this.$dropdown = options.$dropdown;
this.$dropdownContainer = this.$dropdown.parent(); this.$dropdownContainer = this.$dropdown.parent();
this.$dropdownFooter = this.$dropdownContainer.find('.dropdown-footer'); this.$dropdownFooter = this.$dropdownContainer.find('.dropdown-footer');
this.$protectedTag = this.$dropdownContainer.find('.create-new-protected-tag'); this.$protectedTag = this.$dropdownContainer.find('.js-create-new-protected-tag');
this.buildDropdown(); this.buildDropdown();
this.bindEvents(); this.bindEvents();
...@@ -73,7 +73,7 @@ export default class ProtectedTagDropdown { ...@@ -73,7 +73,7 @@ export default class ProtectedTagDropdown {
}; };
this.$dropdownContainer this.$dropdownContainer
.find('.create-new-protected-tag code') .find('.js-create-new-protected-tag code')
.text(tagName); .text(tagName);
} }
......
...@@ -675,14 +675,16 @@ pre.light-well { ...@@ -675,14 +675,16 @@ pre.light-well {
} }
} }
.new_protected_branch { .new_protected_branch,
.new-protected-tag {
label { label {
margin-top: 6px; margin-top: 6px;
font-weight: normal; font-weight: normal;
} }
} }
.create-new-protected-branch-button { .create-new-protected-branch-button,
.create-new-protected-tag-button {
@include dropdown-link; @include dropdown-link;
width: 100%; width: 100%;
......
...@@ -19,7 +19,7 @@ class Projects::ProtectedBranchesController < Projects::ProtectedRefsController ...@@ -19,7 +19,7 @@ class Projects::ProtectedBranchesController < Projects::ProtectedRefsController
def protected_ref_params def protected_ref_params
params.require(:protected_branch).permit(:name, params.require(:protected_branch).permit(:name,
merge_access_levels_attributes: [:access_level, :id], merge_access_levels_attributes: access_level_attributes,
push_access_levels_attributes: [:access_level, :id]) push_access_levels_attributes: access_level_attributes)
end end
end end
...@@ -44,4 +44,10 @@ class Projects::ProtectedRefsController < Projects::ApplicationController ...@@ -44,4 +44,10 @@ class Projects::ProtectedRefsController < Projects::ApplicationController
format.js { head :ok } format.js { head :ok }
end end
end end
protected
def access_level_attributes
%i(access_level id)
end
end end
...@@ -18,6 +18,6 @@ class Projects::ProtectedTagsController < Projects::ProtectedRefsController ...@@ -18,6 +18,6 @@ class Projects::ProtectedTagsController < Projects::ProtectedRefsController
end end
def protected_ref_params def protected_ref_params
params.require(:protected_tag).permit(:name, create_access_levels_attributes: [:access_level, :id]) params.require(:protected_tag).permit(:name, create_access_levels_attributes: access_level_attributes)
end end
end end
...@@ -8,32 +8,44 @@ module ProtectedRef ...@@ -8,32 +8,44 @@ module ProtectedRef
validates :project, presence: true validates :project, presence: true
delegate :matching, :matches?, :wildcard?, to: :ref_matcher delegate :matching, :matches?, :wildcard?, to: :ref_matcher
end
def commit
project.commit(self.name)
end
class_methods do
def protected_ref_access_levels(*types)
types.each do |type|
has_many :"#{type}_access_levels", dependent: :destroy
validates :"#{type}_access_levels", length: { is: 1, message: "are restricted to a single instance per #{self.model_name.human}." }
def self.protected_ref_accessible_to?(ref, user, action:) accepts_nested_attributes_for :"#{type}_access_levels", allow_destroy: true
end
end
def protected_ref_accessible_to?(ref, user, action:)
access_levels_for_ref(ref, action: action).any? do |access_level| access_levels_for_ref(ref, action: action).any? do |access_level|
access_level.check_access(user) access_level.check_access(user)
end end
end end
def self.developers_can?(action, ref) def developers_can?(action, ref)
access_levels_for_ref(ref, action: action).any? do |access_level| access_levels_for_ref(ref, action: action).any? do |access_level|
access_level.access_level == Gitlab::Access::DEVELOPER access_level.access_level == Gitlab::Access::DEVELOPER
end end
end end
def self.access_levels_for_ref(ref, action:) def access_levels_for_ref(ref, action:)
self.matching(ref).map(&:"#{action}_access_levels").flatten self.matching(ref).map(&:"#{action}_access_levels").flatten
end end
def self.matching(ref_name, protected_refs: nil) def matching(ref_name, protected_refs: nil)
ProtectedRefMatcher.matching(self, ref_name, protected_refs: protected_refs) ProtectedRefMatcher.matching(self, ref_name, protected_refs: protected_refs)
end end
end end
def commit
project.commit(self.name)
end
private private
def ref_matcher def ref_matcher
......
...@@ -2,14 +2,7 @@ class ProtectedBranch < ActiveRecord::Base ...@@ -2,14 +2,7 @@ class ProtectedBranch < ActiveRecord::Base
include Gitlab::ShellAdapter include Gitlab::ShellAdapter
include ProtectedRef include ProtectedRef
has_many :merge_access_levels, dependent: :destroy protected_ref_access_levels :merge, :push
has_many :push_access_levels, dependent: :destroy
validates :merge_access_levels, length: { is: 1, message: "are restricted to a single instance per protected branch." }
validates :push_access_levels, length: { is: 1, message: "are restricted to a single instance per protected branch." }
accepts_nested_attributes_for :push_access_levels
accepts_nested_attributes_for :merge_access_levels
# Check if branch name is marked as protected in the system # Check if branch name is marked as protected in the system
def self.protected?(project, ref_name) def self.protected?(project, ref_name)
......
...@@ -2,11 +2,7 @@ class ProtectedTag < ActiveRecord::Base ...@@ -2,11 +2,7 @@ class ProtectedTag < ActiveRecord::Base
include Gitlab::ShellAdapter include Gitlab::ShellAdapter
include ProtectedRef include ProtectedRef
has_many :create_access_levels, dependent: :destroy protected_ref_access_levels :create
validates :create_access_levels, length: { is: 1, message: "are restricted to a single instance per protected tag." }
accepts_nested_attributes_for :create_access_levels
def self.protected?(project, ref_name) def self.protected?(project, ref_name)
self.matching(ref_name, protected_refs: project.protected_tags).present? self.matching(ref_name, protected_refs: project.protected_tags).present?
......
= form_for [@project.namespace.becomes(Namespace), @project, @protected_tag], html: { class: 'js-new-protected-tag' } do |f| = form_for [@project.namespace.becomes(Namespace), @project, @protected_tag], html: { class: 'new-protected-tag js-new-protected-tag' } do |f|
.panel.panel-default .panel.panel-default
.panel-heading .panel-heading
%h3.panel-title %h3.panel-title
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
= dropdown_tag('Select tag or create wildcard', = dropdown_tag('Select tag or create wildcard',
options: { toggle_class: 'js-protected-tag-select js-filter-submit wide git-revision-dropdown-toggle', options: { toggle_class: 'js-protected-tag-select js-filter-submit wide git-revision-dropdown-toggle',
filter: true, dropdown_class: "dropdown-menu-selectable capitalize-header git-revision-dropdown", placeholder: "Search protected tag", filter: true, dropdown_class: "dropdown-menu-selectable capitalize-header git-revision-dropdown", placeholder: "Search protected tags",
footer_content: true, footer_content: true,
data: { show_no: true, show_any: true, show_upcoming: true, data: { show_no: true, show_any: true, show_upcoming: true,
selected: params[:protected_tag_name], selected: params[:protected_tag_name],
...@@ -10,6 +10,6 @@ ...@@ -10,6 +10,6 @@
%ul.dropdown-footer-list %ul.dropdown-footer-list
%li %li
= link_to '#', title: "New Protected Tag", class: "create-new-protected-tag" do %button{ class: "create-new-protected-tag-button js-create-new-protected-tag", title: "New Protected Tag" }
Create wildcard Create wildcard
%code %code
...@@ -4,13 +4,14 @@ ...@@ -4,13 +4,14 @@
.row.prepend-top-default.append-bottom-default .row.prepend-top-default.append-bottom-default
.col-lg-3 .col-lg-3
%h4.prepend-top-0 %h4.prepend-top-0
Protected tags Protected Tags
%p.prepend-top-20 %p.prepend-top-20
By default, Protected tags are designed to: By default, protected tags are designed to:
%ul %ul
%li Prevent tag creation by everybody except Masters %li Prevent tag creation by everybody except Masters
%li Prevent <strong>anyone</strong> from updating the tag %li Prevent <strong>anyone</strong> from updating the tag
%li Prevent <strong>anyone</strong> from deleting the tag %li Prevent <strong>anyone</strong> from deleting the tag
%p.append-bottom-0 Read more about #{link_to "protected tags", help_page_path("user/project/protected_tags"), class: "underlined-link"}.
.col-lg-9 .col-lg-9
- if can? current_user, :admin_project, @project - if can? current_user, :admin_project, @project
= render 'projects/protected_tags/create_protected_tag' = render 'projects/protected_tags/create_protected_tag'
......
...@@ -19,4 +19,4 @@ ...@@ -19,4 +19,4 @@
- if can_admin_project - if can_admin_project
%td %td
= link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, protected_tag], data: { confirm: 'tag will be writable for developers. Are you sure?' }, method: :delete, class: 'btn btn-warning' = link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, protected_tag], data: { confirm: 'Tag will be writable for developers. Are you sure?' }, method: :delete, class: 'btn btn-warning'
.panel.panel-default.protected-tags-list.js-protected-tags-list .panel.panel-default.protected-tags-list
- if @protected_tags.empty? - if @protected_tags.empty?
.panel-heading .panel-heading
%h3.panel-title %h3.panel-title
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
%col{ width: "25%" } %col{ width: "25%" }
%col{ width: "25%" } %col{ width: "25%" }
%col{ width: "50%" } %col{ width: "50%" }
- if can_admin_project
%col
%thead %thead
%tr %tr
%th Protected tag (#{@protected_tags.size}) %th Protected tag (#{@protected_tags.size})
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
%h4.prepend-top-0.ref-name %h4.prepend-top-0.ref-name
= @protected_ref.name = @protected_ref.name
.col-lg-9 .col-lg-9.edit_protected_tag
%h5 Matching Tags %h5 Matching Tags
- if @matching_refs.present? - if @matching_refs.present?
.table-responsive .table-responsive
......
...@@ -144,7 +144,9 @@ merge_access_levels: ...@@ -144,7 +144,9 @@ merge_access_levels:
push_access_levels: push_access_levels:
- protected_branch - protected_branch
create_access_levels: create_access_levels:
- user
- protected_tag - protected_tag
- group
container_repositories: container_repositories:
- project - project
- name - name
......
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