diff options
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | app/controllers/application_controller.rb | 6 | ||||
-rw-r--r-- | app/controllers/builds_controller.rb | 3 | ||||
-rw-r--r-- | app/models/user.rb | 35 | ||||
-rw-r--r-- | app/views/builds/_build.html.haml | 2 | ||||
-rw-r--r-- | app/views/builds/show.html.haml | 2 | ||||
-rw-r--r-- | spec/models/user_spec.rb | 54 | ||||
-rw-r--r-- | spec/support/gitlab_stubs/project_8.json | 10 |
8 files changed, 105 insertions, 8 deletions
@@ -5,6 +5,7 @@ v7.10.0 - Events for admin - Events per projects - Search for runners in admin area + - Developers can cancel and retry jobs v7.9.2 - [Security] Already existing projects should not be served by shared runners diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0c8180e..c412a45 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -48,6 +48,12 @@ class ApplicationController < ActionController::Base end end + def authorize_project_developer! + unless current_user.has_developer_access?(@project.gitlab_id) + return page_404 + end + end + def authorize_manage_project! unless current_user.can_manage_project?(@project.gitlab_id) return page_404 diff --git a/app/controllers/builds_controller.rb b/app/controllers/builds_controller.rb index bb485c0..a1cb017 100644 --- a/app/controllers/builds_controller.rb +++ b/app/controllers/builds_controller.rb @@ -2,7 +2,8 @@ class BuildsController < ApplicationController before_filter :authenticate_user!, except: [:status] before_filter :project before_filter :authorize_access_project!, except: [:status] - before_filter :authorize_manage_project!, except: [:status, :show] + before_filter :authorize_manage_project!, except: [:status, :show, :retry, :cancel] + before_filter :authorize_project_developer!, only: [:retry, :cancel] before_filter :build, except: [:show] def show diff --git a/app/models/user.rb b/app/models/user.rb index 6c16035..129ddc1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,7 @@ # User object is stored in session class User + DEVELOPER_ACCESS = 30 + attr_reader :attributes def initialize(hash) @@ -33,12 +35,23 @@ class User end def can_access_project?(project_gitlab_id) - opts = { - private_token: self.private_token, - } + !!project_info(project_gitlab_id) + end + + # Indicate if user has developer access or higher + def has_developer_access?(project_gitlab_id) + data = project_info(project_gitlab_id) + + return false unless data && data["permissions"] + + permissions = data["permissions"] + + if permissions["project_access"] && permissions["project_access"]["access_level"] >= DEVELOPER_ACCESS + return true + end - Rails.cache.fetch(cache_key(project_gitlab_id, sync_at)) do - !!Network.new.project(self.url, opts, project_gitlab_id) + if permissions["group_access"] && permissions["group_access"]["access_level"] >= DEVELOPER_ACCESS + return true end end @@ -51,4 +64,16 @@ class User !!Network.new.project_hooks(self.url, opts, project_gitlab_id) end end + + private + + def project_info(project_gitlab_id) + opts = { + private_token: self.private_token, + } + + Rails.cache.fetch(cache_key("project_info", project_gitlab_id, sync_at)) do + Network.new.project(self.url, opts, project_gitlab_id) + end + end end diff --git a/app/views/builds/_build.html.haml b/app/views/builds/_build.html.haml index 271ceed..03a2321 100644 --- a/app/views/builds/_build.html.haml +++ b/app/views/builds/_build.html.haml @@ -39,7 +39,7 @@ #{build.coverage}% %td - - if defined?(controls) && current_user.can_manage_project?(@project.gitlab_id) + - if defined?(controls) && current_user.has_developer_access?(@project.gitlab_id) .pull-right - if build.active? = link_to cancel_project_build_path(build.project, build, return_to: request.original_url), title: 'Cancel build' do diff --git a/app/views/builds/show.html.haml b/app/views/builds/show.html.haml index 2a28d8d..17fc893 100644 --- a/app/views/builds/show.html.haml +++ b/app/views/builds/show.html.haml @@ -89,7 +89,7 @@ .build-widget %h4.title Build - - if current_user.can_manage_project?(@project.gitlab_id) + - if current_user.has_developer_access?(@project.gitlab_id) .pull-right - if @build.active? = link_to "Cancel", cancel_project_build_path(@project, @build), class: 'btn btn-sm btn-danger' diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb new file mode 100644 index 0000000..44b260b --- /dev/null +++ b/spec/models/user_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe User do + + describe "has_developer_access?" do + before do + @user = User.new({}) + end + + let(:project_with_owner_access) do + { + "name" => "gitlab-shell", + "permissions" => { + "project_access" => { + "access_level"=> 10, + "notification_level" => 3 + }, + "group_access" => { + "access_level" => 50, + "notification_level" => 3 + } + } + } + end + + let(:project_with_reporter_access) do + { + "name" => "gitlab-shell", + "permissions" => { + "project_access" => { + "access_level" => 20, + "notification_level" => 3 + }, + "group_access" => { + "access_level" => 10, + "notification_level" => 3 + } + } + } + end + + it "returns false for reporter" do + @user.stub(:project_info).and_return(project_with_reporter_access) + + @user.has_developer_access?(1).should be_false + end + + it "returns true for owner" do + @user.stub(:project_info).and_return(project_with_owner_access) + + @user.has_developer_access?(1).should be_true + end + end +end diff --git a/spec/support/gitlab_stubs/project_8.json b/spec/support/gitlab_stubs/project_8.json index f2758b9..f0a9fce 100644 --- a/spec/support/gitlab_stubs/project_8.json +++ b/spec/support/gitlab_stubs/project_8.json @@ -31,5 +31,15 @@ "owner_id":1, "path":"gitlab", "updated_at":"2013-03-20T13:29:13Z" + }, + "permissions":{ + "project_access": { + "access_level": 10, + "notification_level": 3 + }, + "group_access": { + "access_level": 50, + "notification_level": 3 + } } }
\ No newline at end of file |