Commit fd76d685 authored by Magdalena Frankiewicz's avatar Magdalena Frankiewicz

Disallow non-members unlocking project files

Changelog: security
MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74541
EE: true
parent f3d91f06
...@@ -1656,6 +1656,10 @@ class Project < ApplicationRecord ...@@ -1656,6 +1656,10 @@ class Project < ApplicationRecord
end end
end end
def member?(user)
project_member(user).present?
end
def membership_locked? def membership_locked?
false false
end end
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
module PathLocksHelper module PathLocksHelper
def can_unlock?(path_lock, current_user = @current_user, project = @project) def can_unlock?(path_lock, current_user = @current_user, project = @project)
can?(current_user, :admin_path_locks, project) || path_lock.user == current_user can?(current_user, :admin_path_locks, project) ||
(path_lock.user == current_user && project.member?(current_user))
end end
def text_label_for_lock(file_lock, path) def text_label_for_lock(file_lock, path)
......
...@@ -3,16 +3,45 @@ ...@@ -3,16 +3,45 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe PathLocksHelper do RSpec.describe PathLocksHelper do
let(:user) { create(:user, name: 'John') }
let(:user_2) { create(:user, name: 'Bob') }
let(:path_lock) { create(:path_lock, path: 'app', user: user) }
let(:project) { create(:project) }
describe '#can_unlock?' do
it "returns false if the user is not a project member" do
allow(self).to receive(:can?).and_return(false)
expect(can_unlock?(path_lock, user, project)).to be(false)
end
it "returns false if the user is not the lock owner" do
project.add_user(user_2, :developer)
allow(self).to receive(:can?).and_return(false)
expect(can_unlock?(path_lock, user_2, project)).to be(false)
end
it "returns true if the user has admin_path_locks permission" do
allow(self).to receive(:can?).with(user, :admin_path_locks, project).and_return(true)
expect(can_unlock?(path_lock, user, project)).to be(true)
end
it "returns true if the user is the lock owner and a project member" do
project.add_user(user, :developer)
allow(self).to receive(:can?).and_return(false)
expect(can_unlock?(path_lock, user, project)).to be(true)
end
end
describe '#text_label_for_lock' do describe '#text_label_for_lock' do
it "return correct string for non-nested locks" do it "return correct string for non-nested locks" do
user = create :user, name: 'John'
path_lock = create :path_lock, path: 'app', user: user
expect(text_label_for_lock(path_lock, 'app')).to eq('Locked by John') expect(text_label_for_lock(path_lock, 'app')).to eq('Locked by John')
end end
it "return correct string for nested locks" do it "return correct string for nested locks" do
user = create :user, name: 'John'
path_lock = create :path_lock, path: 'app', user: user
expect(text_label_for_lock(path_lock, 'app/models')).to eq('John has a lock on "app"') expect(text_label_for_lock(path_lock, 'app/models')).to eq('John has a lock on "app"')
end end
end end
......
...@@ -1589,6 +1589,19 @@ RSpec.describe Project, factory_default: :keep do ...@@ -1589,6 +1589,19 @@ RSpec.describe Project, factory_default: :keep do
it { expect(project.builds_enabled?).to be_truthy } it { expect(project.builds_enabled?).to be_truthy }
end end
describe '#member?' do
it 'returns true if the given user is a project member, false otherwise' do
project = create(:project)
user = create(:user)
expect(project.member?(user)).to be(false)
project.add_user(user, :developer)
expect(project.member?(user)).to be(true)
end
end
describe '.sort_by_attribute' do describe '.sort_by_attribute' do
it 'reorders the input relation by start count desc' do it 'reorders the input relation by start count desc' do
project1 = create(:project, star_count: 2) project1 = create(:project, star_count: 2)
......
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