mirror of
https://github.com/redmine/redmine.git
synced 2026-03-05 12:01:23 +01:00
Add write control on repository from Redmine interface
* new methods to add/remove rights in app/models/role.rb * some unit tests * add write check in Redmine.pm To keep compatibility migration add write rights to non builtin roles but default clean install give write access only to manager and developer, not to reporter. git-svn-id: http://redmine.rubyforge.org/svn/branches/nbc@1791 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -36,7 +36,7 @@ class Role < ActiveRecord::Base
|
||||
has_many :members
|
||||
acts_as_list
|
||||
|
||||
serialize :permissions
|
||||
serialize :permissions, Array
|
||||
attr_protected :builtin
|
||||
|
||||
validates_presence_of :name
|
||||
@@ -49,9 +49,27 @@ class Role < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def permissions=(perms)
|
||||
perms = perms.collect {|p| p.to_sym unless p.blank? }.compact if perms
|
||||
perms = perms.collect {|p| p.to_sym unless p.blank? }.compact.uniq if perms
|
||||
write_attribute(:permissions, perms)
|
||||
end
|
||||
|
||||
def add_permission!(*perms)
|
||||
self.permissions = [] unless permissions.is_a?(Array)
|
||||
|
||||
permissions_will_change!
|
||||
perms.each do |p|
|
||||
p = p.to_sym
|
||||
permissions << p unless permissions.include?(p)
|
||||
end
|
||||
save!
|
||||
end
|
||||
|
||||
def remove_permission!(*perms)
|
||||
return unless permissions.is_a?(Array)
|
||||
permissions_will_change!
|
||||
perms.each { |p| permissions.delete(p.to_sym) }
|
||||
save!
|
||||
end
|
||||
|
||||
def <=>(role)
|
||||
position <=> role.position
|
||||
|
||||
14
db/migrate/20080827185639_add_repository_write_access.rb
Normal file
14
db/migrate/20080827185639_add_repository_write_access.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class AddRepositoryWriteAccess < ActiveRecord::Migration
|
||||
|
||||
def self.up
|
||||
Role.find(:all).select { |r| not r.builtin? }.each do |r|
|
||||
r.add_permission!(:commit_access)
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
Role.find(:all).select { |r| not r.builtin? }.each do |r|
|
||||
r.remove_permission!(:commit_access)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -148,11 +148,12 @@ sub RedmineDSN {
|
||||
my ($self, $parms, $arg) = @_;
|
||||
$self->{RedmineDSN} = $arg;
|
||||
my $query = "SELECT
|
||||
hashed_password, auth_source_id
|
||||
FROM members, projects, users
|
||||
hashed_password, auth_source_id, permissions
|
||||
FROM members, projects, users, roles
|
||||
WHERE
|
||||
projects.id=members.project_id
|
||||
AND users.id=members.user_id
|
||||
AND roles.id=members.role_id
|
||||
AND users.status=1
|
||||
AND login=?
|
||||
AND identifier=? ";
|
||||
@@ -277,9 +278,11 @@ sub is_member {
|
||||
$sth->execute($redmine_user, $project_id);
|
||||
|
||||
my $ret;
|
||||
while (my @row = $sth->fetchrow_array) {
|
||||
unless ($row[1]) {
|
||||
if ($row[0] eq $pass_digest) {
|
||||
while (my ($hashed_password, $auth_source_id, $permissions) = $sth->fetchrow_array) {
|
||||
|
||||
unless ($auth_source_id) {
|
||||
my $method = $r->method;
|
||||
if ($hashed_password eq $pass_digest && (defined $read_only_methods{$method} || $permissions =~ /:commit_access/) ) {
|
||||
$ret = 1;
|
||||
last;
|
||||
}
|
||||
@@ -287,7 +290,7 @@ sub is_member {
|
||||
my $sthldap = $dbh->prepare(
|
||||
"SELECT host,port,tls,account,account_password,base_dn,attr_login from auth_sources WHERE id = ?;"
|
||||
);
|
||||
$sthldap->execute($row[1]);
|
||||
$sthldap->execute($auth_source_id);
|
||||
while (my @rowldap = $sthldap->fetchrow_array) {
|
||||
my $ldap = Authen::Simple::LDAP->new(
|
||||
host => ($rowldap[2] == 1 || $rowldap[2] eq "t") ? "ldaps://$rowldap[0]" : $rowldap[0],
|
||||
|
||||
@@ -88,6 +88,7 @@ Redmine::AccessControl.map do |map|
|
||||
map.permission :manage_repository, {:repositories => [:edit, :destroy]}, :require => :member
|
||||
map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
|
||||
map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
|
||||
map.permission :commit_access, {}
|
||||
end
|
||||
|
||||
map.project_module :boards do |map|
|
||||
|
||||
@@ -67,7 +67,8 @@ module Redmine
|
||||
:view_files,
|
||||
:manage_files,
|
||||
:browse_repository,
|
||||
:view_changesets]
|
||||
:view_changesets,
|
||||
:commit_access]
|
||||
|
||||
reporter = Role.create! :name => l(:default_role_reporter),
|
||||
:position => 3,
|
||||
|
||||
@@ -30,4 +30,24 @@ class RoleTest < Test::Unit::TestCase
|
||||
target.reload
|
||||
assert_equal 90, target.workflows.size
|
||||
end
|
||||
|
||||
def test_add_permission
|
||||
role = Role.find(1)
|
||||
size = role.permissions.size
|
||||
role.add_permission!("apermission", "anotherpermission")
|
||||
role.reload
|
||||
assert role.permissions.include?(:anotherpermission)
|
||||
assert_equal size + 2, role.permissions.size
|
||||
end
|
||||
|
||||
def test_remove_permission
|
||||
role = Role.find(1)
|
||||
size = role.permissions.size
|
||||
perm = role.permissions[0..1]
|
||||
role.remove_permission!(*perm)
|
||||
role.reload
|
||||
assert ! role.permissions.include?(perm[0])
|
||||
assert_equal size - 2, role.permissions.size
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user