From 93aa6d04c2e81193d7833890d2281fc1df7d7129 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 29 Sep 2017 12:14:39 +0100 Subject: [PATCH] moved fork checks into policies --- app/policies/global_policy.rb | 6 ++++++ app/policies/namespace_policy.rb | 4 ++++ app/views/projects/buttons/_fork.html.haml | 6 +++--- app/views/projects/forks/new.html.haml | 11 +++++------ spec/policies/global_policy_spec.rb | 23 ++++++++++++++++++++++ spec/policies/namespace_policy_spec.rb | 20 +++++++++++++++++++ 6 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 spec/policies/namespace_policy_spec.rb diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb index 8f7c01bb71f..64e550d19d0 100644 --- a/app/policies/global_policy.rb +++ b/app/policies/global_policy.rb @@ -11,6 +11,8 @@ class GlobalPolicy < BasePolicy with_options scope: :user, score: 0 condition(:access_locked) { @user.access_locked? } + condition(:can_create_fork, scope: :user) { @user.manageable_namespaces.any? { |namespace| @user.can?(:create_projects, namespace) } } + rule { anonymous }.policy do prevent :log_in prevent :access_api @@ -40,6 +42,10 @@ class GlobalPolicy < BasePolicy enable :create_group end + rule { can_create_fork }.policy do + enable :create_fork + end + rule { access_locked }.policy do prevent :log_in end diff --git a/app/policies/namespace_policy.rb b/app/policies/namespace_policy.rb index 85b67f0a237..92213f0155e 100644 --- a/app/policies/namespace_policy.rb +++ b/app/policies/namespace_policy.rb @@ -1,10 +1,14 @@ class NamespacePolicy < BasePolicy rule { anonymous }.prevent_all + condition(:personal_project, scope: :subject) { @subject.kind == 'user' } + condition(:can_create_personal_project, scope: :user) { @user.can_create_project? } condition(:owner) { @subject.owner == @user } rule { owner | admin }.policy do enable :create_projects enable :admin_namespace end + + rule { personal_project & ~can_create_personal_project }.prevent :create_projects end diff --git a/app/views/projects/buttons/_fork.html.haml b/app/views/projects/buttons/_fork.html.haml index 840b5ce1f84..f880556a9f7 100644 --- a/app/views/projects/buttons/_fork.html.haml +++ b/app/views/projects/buttons/_fork.html.haml @@ -5,10 +5,10 @@ = custom_icon('icon_fork') %span= s_('GoToYourFork|Fork') - else - - can_fork = current_user.can_create_project? || current_user.manageable_namespaces.count > 1 + - can_create_fork = current_user.can?(:create_fork) = link_to new_project_fork_path(@project), - class: "btn btn-default #{'has-tooltip disabled' unless can_fork}", - title: (_('You have reached your project limit') unless can_fork) do + class: "btn btn-default #{'has-tooltip disabled' unless can_create_fork}", + title: (_('You have reached your project limit') unless can_create_fork) do = custom_icon('icon_fork') %span= s_('CreateNewFork|Fork') .count-with-arrow diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml index 008de97d6d3..906774a21e3 100644 --- a/app/views/projects/forks/new.html.haml +++ b/app/views/projects/forks/new.html.haml @@ -1,5 +1,4 @@ - page_title "Fork project" -- can_create_project = current_user.can_create_project? .row.prepend-top-default .col-lg-3 @@ -14,7 +13,7 @@ - if @namespaces.present? %label.label-light %span - #{ "Click to fork the project to a #{'user or' if can_create_project} group" } + Click to fork the project - @namespaces.in_groups_of(6, false) do |group| .row - group.each do |namespace| @@ -30,12 +29,12 @@ .caption = namespace.human_name - else - - is_disabled = namespace.kind === 'user' && !can_create_project - .fork-thumbnail{ class: ("disabled" if is_disabled) } + - can_create_project = current_user.can?(:create_projects, namespace) + .fork-thumbnail{ class: ("disabled" unless can_create_project) } = link_to project_forks_path(@project, namespace_key: namespace.id), method: "POST", - class: ("disabled has-tooltip" if is_disabled), - title: (_('You have reached your project limit') if is_disabled) do + class: ("disabled has-tooltip" unless can_create_project), + title: (_('You have reached your project limit') unless can_create_project) do - if /no_((\w*)_)*avatar/.match(avatar) .no-avatar = icon 'question' diff --git a/spec/policies/global_policy_spec.rb b/spec/policies/global_policy_spec.rb index 983f0e52d31..5b8cf2e6ab5 100644 --- a/spec/policies/global_policy_spec.rb +++ b/spec/policies/global_policy_spec.rb @@ -52,6 +52,29 @@ describe GlobalPolicy do end end + describe "create fork" do + context "when user has not exceeded project limit" do + it { is_expected.to be_allowed(:create_fork) } + end + + context "when user has exceeded project limit" do + let(:current_user) { create(:user, projects_limit: 0) } + + it { is_expected.not_to be_allowed(:create_fork) } + end + + context "when user is a master in a group" do + let(:group) { create(:group) } + let(:current_user) { create(:user, projects_limit: 0) } + + before do + group.add_master(current_user) + end + + it { is_expected.to be_allowed(:create_fork) } + end + end + describe 'custom attributes' do context 'regular user' do it { is_expected.not_to be_allowed(:read_custom_attribute) } diff --git a/spec/policies/namespace_policy_spec.rb b/spec/policies/namespace_policy_spec.rb new file mode 100644 index 00000000000..e52ff02e5f0 --- /dev/null +++ b/spec/policies/namespace_policy_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe NamespacePolicy do + let(:current_user) { create(:user) } + let(:namespace) { current_user.namespace } + + subject { described_class.new(current_user, namespace) } + + context "create projects" do + context "user namespace" do + it { is_expected.to be_allowed(:create_projects) } + end + + context "user who has exceeded project limit" do + let(:current_user) { create(:user, projects_limit: 0) } + + it { is_expected.not_to be_allowed(:create_projects) } + end + end +end