[refs #531] fixed user roles

This commit is contained in:
Alexander Machehin 2012-06-20 00:24:35 +06:00
parent ecf4666a31
commit 4d91ea1d6e
6 changed files with 156 additions and 17 deletions

View File

@ -147,8 +147,13 @@ class Ability
end
def relation_exists_for(target, roles)
target.relations.exists?(:actor_id => @user.id, :actor_type => 'User', :role => roles) or
target.relations.exists?(:actor_id => @user.group_ids, :actor_type => 'Group', :role => roles)
rel = target.relations
is_owner_group = target.owner.class == Group
groups = @user.groups
groups = groups.where('groups.id != ?', target.owner.id) if is_owner_group
rel.exists?(:actor_id => @user.id, :actor_type => 'User', :role => roles) or # user is member
(@user.groups.exists?(:id => target.owner.id, :relations =>{:role => roles}) and is_owner_group) or # user group is owner
rel.exists?(:actor_id => groups, :actor_type => 'Group', :role => roles) # user group is member
end
def local_reader?(target)

View File

@ -129,4 +129,23 @@ class User < ActiveRecord::Base
false
end
end
def best_role target
rel = target.relations
is_owner_group = target.owner.class == Group
gr = self.groups
gr = gr.where('groups.id != ?', target.owner.id) if is_owner_group
roles = []
if is_owner_group
owner_group = self.groups.where(:id => target.owner.id).first
roles += owner_group.actors.where(:actor_id => self) if owner_group # user group is owner
end
roles += rel.where(:actor_id => self.id, :actor_type => 'User') # user is member
roles += rel.where(:actor_id => gr, :actor_type => 'Group') # user group is member
roles = roles.map(&:role).uniq
return 'admin' if roles.include? 'admin'
return 'writer' if roles.include? 'writer'
return 'reader' if roles.include? 'reader'
raise "unknown user #{self.uname} roles #{roles}"
end
end

View File

@ -11,7 +11,7 @@
%td
- c = participant_class(alone_member, project)
%span{:class => c, :title => t("layout.relations.#{c}")}
= t("layout.collaborators.role_names.#{project.relations.by_user_through_groups(current_user).first.role}")
= t("layout.collaborators.role_names.#{current_user.best_role project}")
%td.td5
- unless project.owner == current_user or !alone_member
= link_to remove_user_project_path(project), :method => :delete, :confirm => t("layout.confirm") do

View File

@ -5,7 +5,7 @@ json.project do |proj|
proj.description project.description
proj.link project_path(project)
proj.role t("layout.collaborators.role_names.#{project.relations.by_user_through_groups(current_user).first.role}").force_encoding(Encoding::UTF_8)
proj.role t("layout.collaborators.role_names.#{current_user.best_role project}").force_encoding(Encoding::UTF_8)
proj.leave_link remove_user_project_path(project) unless project.owner == current_user or !alone_member? project
proj.rights_class participant_class(alone_member?(project), project)

View File

@ -79,6 +79,7 @@ describe Projects::ProjectsController do
end
it_should_behave_like 'projects user with reader rights'
it_should_behave_like 'user without update rights'
end
context 'for writer user' do
@ -136,20 +137,115 @@ describe Projects::ProjectsController do
response.should redirect_to(forbidden_path)
end
it 'should not be able to edit project' do
description = @project.description
put :update, :project=>{:description =>"hack"}, :owner_name => @project.owner.uname, :project_name => @project.name
response.should redirect_to(forbidden_path)
Project.find(@project.id).description.should == description
it_should_behave_like 'user without update rights'
end
context 'for group' do
before(:each) do
@group = FactoryGirl.create(:group)
@group_user = FactoryGirl.create(:user)
@project.relations.destroy_all
set_session_for(@group_user)
end
it 'should not be able to edit project sections' do
has_wiki, has_issues = @project.has_wiki, @project.has_issues
post :sections, :project =>{:has_wiki => !has_wiki, :has_issues => !has_issues}, :owner_name => @project.owner.uname, :project_name => @project.name
response.should redirect_to(forbidden_path)
project = Project.find(@project.id)
project.has_wiki.should == has_wiki
project.has_issues.should == has_issues
context 'owner of the project' do
before(:each) do
@project.update_attribute :owner, @group
@project.relations.create :actor_id => @project.owner.id, :actor_type => @project.owner.class.to_s, :role => 'admin'
end
context 'reader user' do
before(:each) do
@group.actors.create(:actor_id => @group_user.id, :actor_type => 'User', :role => 'reader')
end
it_should_behave_like 'projects user with reader rights'
it_should_behave_like 'user without update rights'
it 'should has reader role to group project' do
@group_user.best_role(@project).should eql('reader') # Need this?
end
context 'user should has best role' do
before(:each) do
@project.relations.create :actor_id => @group_user.id, :actor_type => @group_user.class.to_s, :role => 'admin'
end
it_should_behave_like 'projects user with admin rights'
end
end
context 'admin user' do
before(:each) do
@group.actors.create(:actor_id => @group_user.id, :actor_type => 'User', :role => 'admin')
end
it_should_behave_like 'projects user with admin rights'
it_should_behave_like 'projects user with reader rights'
end
end
context 'member of the project' do
context 'with admin rights' do
before(:each) do
@project.relations.create :actor_id => @group.id, :actor_type => @group.class.to_s, :role => 'admin'
end
context 'reader user' do
before(:each) do
@group.actors.create(:actor_id => @group_user.id, :actor_type => 'User', :role => 'reader')
end
it_should_behave_like 'projects user with reader rights'
it_should_behave_like 'projects user with admin rights'
context 'user should has best role' do
before(:each) do
@project.relations.create :actor_id => @group_user.id, :actor_type => @group_user.class.to_s, :role => 'reader'
end
it_should_behave_like 'projects user with admin rights'
end
end
context 'admin user' do
before(:each) do
@group.actors.create(:actor_id => @group_user.id, :actor_type => 'User', :role => 'admin')
end
it_should_behave_like 'projects user with admin rights'
it_should_behave_like 'projects user with reader rights'
end
end
context 'with reader rights' do
before(:each) do
@project.relations.create :actor_id => @group.id, :actor_type => @group.class.to_s, :role => 'reader'
end
context 'reader user' do
before(:each) do
@group.actors.create(:actor_id => @group_user.id, :actor_type => 'User', :role => 'reader')
end
it_should_behave_like 'projects user with reader rights'
it_should_behave_like 'user without update rights'
context 'user should has best role' do
before(:each) do
@project.relations.create :actor_id => @group_user.id, :actor_type => @group_user.class.to_s, :role => 'admin'
end
it_should_behave_like 'projects user with admin rights'
end
end
context 'admin user' do
before(:each) do
@group.actors.create(:actor_id => @group_user.id, :actor_type => 'User', :role => 'admin')
end
it_should_behave_like 'projects user with reader rights'
it_should_behave_like 'user without update rights'
end
end
end
end
end

View File

@ -1,11 +1,12 @@
# -*- encoding : utf-8 -*-
shared_examples_for 'projects user with reader rights' do
it_should_behave_like 'user with rights to view projects'
include_examples 'user with rights to view projects' # nested shared_examples_for dont work
it 'should be able to fork project' do
post :fork, :owner_name => @project.owner.uname, :project_name => @project.name
response.should redirect_to(project_path(Project.last))
end
end
shared_examples_for 'projects user with admin rights' do
@ -21,3 +22,21 @@ shared_examples_for 'user with rights to view projects' do
response.should render_template(:index)
end
end
shared_examples_for 'user without update rights' do
it 'should not be able to edit project' do
description = @project.description
put :update, :project=>{:description =>"hack"}, :owner_name => @project.owner.uname, :project_name => @project.name
Project.find(@project.id).description.should == description
response.should redirect_to(forbidden_path)
end
it 'should not be able to edit project sections' do
has_wiki, has_issues = @project.has_wiki, @project.has_issues
post :sections, :project =>{:has_wiki => !has_wiki, :has_issues => !has_issues}, :owner_name => @project.owner.uname, :project_name => @project.name
project = Project.find(@project.id)
project.has_wiki.should == has_wiki
project.has_issues.should == has_issues
response.should redirect_to(forbidden_path)
end
end