Merge pull request #87 from abf/rosa-build:82-extend-abilities-of-personal-platforms

[refs #82]: Extend abilities of personal platforms
This commit is contained in:
warpc 2013-04-17 14:34:36 +04:00
commit 079d7110e0
16 changed files with 130 additions and 77 deletions

View File

@ -72,7 +72,7 @@ class Projects::ProjectsController < Projects::BaseController
redirect_to forked, :notice => t("flash.project.forked")
else
flash[:warning] = t("flash.project.fork_error")
flash[:error] = forked.errors.full_messages
flash[:error] = forked.errors.full_messages.join("\n")
redirect_to @project
end
end

View File

@ -146,7 +146,8 @@ class Ability
# Shared cannot rights for all users (registered, admin)
cannot :destroy, Platform, :platform_type => 'personal'
cannot [:create, :destroy, :edit, :update, :add_project, :remove_project], Repository, :platform => {:platform_type => 'personal'}
cannot [:create, :destroy], Repository, :platform => {:platform_type => 'personal'}, :name => 'main'
cannot [:remove_members, :remove_member, :add_member], Repository, :platform => {:platform_type => 'personal'}
cannot :clear, Platform, :platform_type => 'main'
cannot :destroy, Issue

View File

@ -33,6 +33,14 @@ class Project < ActiveRecord::Base
validates :visibility, :presence => true, :inclusion => {:in => VISIBILITIES}
validate { errors.add(:base, :can_have_less_or_equal, :count => MAX_OWN_PROJECTS) if owner.projects.size >= MAX_OWN_PROJECTS }
validate :check_default_branch
# throws validation error message from ProjectToRepository model into Project model
validate do |project|
project.project_to_repositories.each do |p_to_r|
next if p_to_r.valid?
p_to_r.errors.full_messages.each{ |msg| errors[:base] << msg }
end
errors.delete :project_to_repositories
end
attr_accessible :name, :description, :visibility, :srpm, :is_package, :default_branch, :has_issues, :has_wiki, :maintainer_id, :publish_i686_into_x86_64
attr_readonly :name, :owner_id, :owner_type
@ -250,11 +258,11 @@ class Project < ActiveRecord::Base
end
def attach_to_personal_repository
owner_rep = self.owner.personal_repository
owner_repos = self.owner.personal_platform.repositories
if is_package
repositories << owner_rep unless repositories.exists?(:id => owner_rep)
repositories << self.owner.personal_repository unless repositories.exists?(:id => owner_repos.pluck(:id))
else
repositories.delete owner_rep
repositories.delete owner_repos
end
end

View File

@ -7,12 +7,12 @@ class ProjectToRepository < ActiveRecord::Base
after_destroy lambda { project.destroy_project_from_repository(repository) }, :unless => lambda {Thread.current[:skip]}
validate :one_project_in_platform_repositories
validate :one_project_in_platform_repositories, :on => :create
protected
def one_project_in_platform_repositories
errors.add(:project, 'should be one in platform') if Project.joins(:repositories => :platform).
where('platforms.id = ?', repository.platform_id).by_name(project.name).count > 0
errors.add(:base, I18n.t('activerecord.errors.project_to_repository.project')) if Project.joins(:repositories => :platform).
where('platforms.id = ?', repository.platform_id).by_name(project.name).exists?
end
end

View File

@ -1,5 +1,3 @@
= render 'platforms/base/sidebar'
%h3= t("layout.key_pairs.header")
= form_for :key_pair, :url => platform_key_pairs_path(@platform), :method => :post, :html => { :class => :form } do |f|

View File

@ -1,2 +1,6 @@
- set_meta_tags :title => [title_object(@platform), t('layout.key_pairs.header')]
= render 'platforms/base/submenu'
= render 'platforms/base/sidebar'
= render 'new' if can? :edit, @platform
= render 'list'

View File

@ -15,7 +15,7 @@
.rightside
= link_to t('layout.repositories.regenerate_metadata').split.first, regenerate_metadata_platform_repository_path(@platform, @repository),
:method => :put, :confirm => t('layout.confirm'), :class => :button
.hr{:style => 'padding-bottom:20px;'}
.hr{:style => 'padding-bottom:20px;'}
.both
.button_block

View File

@ -8,9 +8,10 @@
= render "form", :f => f
%br
= render "shared/members_table",
:remove_members_path => remove_members_platform_repository_path(@platform, @repository),
:remove_member_path => remove_member_platform_repository_path(@platform, @repository),
:add_member_path => add_member_platform_repository_path(@platform, @repository),
:members => @members,
:editable_object => @repository
- if @platform.main?
= render "shared/members_table",
:remove_members_path => remove_members_platform_repository_path(@platform, @repository),
:remove_member_path => remove_member_platform_repository_path(@platform, @repository),
:add_member_path => add_member_platform_repository_path(@platform, @repository),
:members => @members,
:editable_object => @repository

View File

@ -14,5 +14,5 @@
- Group.can_own_project(current_user).each do |group|
=render 'choose_fork', :owner => group
%hr.bootstrap
- if can? :create, @project.build_lists.new
- if @project.is_package && can?(:create, @project.build_lists.new)
.r{:style => "display: block"}= link_to t('layout.projects.new_build_list'), new_project_build_list_path(@project), :class => 'button'

View File

@ -0,0 +1,5 @@
en:
activerecord:
errors:
project_to_repository:
project: Project already exists in platform

View File

@ -0,0 +1,5 @@
ru:
activerecord:
errors:
project_to_repository:
project: Проект уже присутствует в платформе

View File

@ -36,7 +36,7 @@ en:
update_error: Unable to update repository
destroyed: Repository deleted
project_added: Project added to repository
project_not_added: Project adding error. A project with such name already exists in this repository. Remove the old project first
project_not_added: Project adding error. A project with such name already exists in one repository of platform. Remove the old project first
project_removed: Project deleted
project_not_removed: Unable to delete project from repository
clear: Platform successfully cleared!

View File

@ -36,7 +36,7 @@ ru:
update_error: Не удалось обновить репозиторий
destroyed: Репозиторий успешно удален
project_added: Проект добавлен к репозиторию
project_not_added: Не удалось добавить проект. В этом репозитории уже есть проект с таким именем. Сначала нужно удалить старый проект
project_not_added: Не удалось добавить проект. В одном из репозиториев платформы уже есть проект с таким именем. Сначала нужно удалить старый проект
project_removed: Проект удален из репозитория
project_not_removed: Не удалось удалить проект из репозитория
clear: Платформа успешно очищена!

View File

@ -99,12 +99,24 @@ shared_examples_for 'api repository user with writer rights' do
it 'ensures that repository of main platform has been destroyed' do
lambda { delete :destroy, :id => @repository.id, :format => :json }.should change{ Repository.count }.by(-1)
end
it 'should not be able to perform destroy action for repository of personal platform' do
delete :destroy, :id => @personal_repository.id, :format => :json
response.should_not be_success
context 'repository with name "main" of personal platform' do
# hook for "ActiveRecord::ActiveRecordError: name is marked as readonly"
before { Repository.where(:id => @personal_repository.id).update_all("name = 'main'") }
it 'should not be able to perform destroy action' do
delete :destroy, :id => @personal_repository.id, :format => :json
response.should_not be_success
end
it 'ensures that repository has not been destroyed' do
lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should_not change{ Repository.count }
end
end
it 'ensures that repository of personal platform has not been destroyed' do
lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should_not change{ Repository.count }
it 'should be able to perform destroy action for repository with name not "main" of personal platform' do
delete :destroy, :id => @personal_repository.id, :format => :json
response.should be_success
end
it 'ensures that repository with name not "main" of personal platform has been destroyed' do
lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should change{ Repository.count }.by(-1)
end
end
@ -296,9 +308,11 @@ describe Api::V1::RepositoriesController do
before(:each) do
@user = FactoryGirl.create(:user)
http_login(@user)
platform = @repository.platform
platform.owner = @user; platform.save
@repository.platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
[@repository, @personal_repository].each do |repository|
platform = repository.platform
platform.owner = @user; platform.save
repository.platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end
end
it_should_behave_like 'api repository user with reader rights'

View File

@ -1,14 +1,6 @@
# -*- encoding : utf-8 -*-
require 'spec_helper'
shared_examples_for 'not destroy personal repository' do
it 'should not be able to destroy personal repository' do
lambda { delete :destroy, :id => @personal_repository.id, :platform_id =>
@personal_repository.platform.id}.should change{ Repository.count }.by(0)
response.should redirect_to(redirect_path)
end
end
shared_examples_for 'user with change projects in repository rights' do
it 'should be able to see add_project page' do
@ -90,12 +82,16 @@ shared_examples_for 'registered user or guest' do
end
it 'should not be able to destroy repository in main platform' do
delete :destroy, :id => @repository.id
delete :destroy, :id => @repository.id, :platform_id => @platform.id
response.should redirect_to(redirect_path)
lambda { delete :destroy, :id => @repository.id }.should_not change{ Repository.count }.by(-1)
end
it_should_behave_like 'not destroy personal repository'
it 'should not be able to destroy personal repository' do
lambda { delete :destroy, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id}.
should change{ Repository.count }.by(0)
response.should redirect_to(redirect_path)
end
end
shared_examples_for 'registered user' do
@ -131,7 +127,7 @@ shared_examples_for 'platform admin user' do
end
it 'should be able to destroy repository in main platform' do
lambda { delete :destroy, :id => @repository.id }.should change{ Repository.count }.by(-1)
lambda { delete :destroy, :id => @repository.id, :platform_id => @platform.id }.should change{ Repository.count }.by(-1)
response.should redirect_to(platform_repositories_path(@repository.platform))
end
@ -163,10 +159,21 @@ shared_examples_for 'platform admin user' do
@repository.members.should_not include(@another_user, another_user2)
end
it_should_behave_like 'user with change projects in repository rights'
it_should_behave_like 'not destroy personal repository' do
let(:redirect_path) { forbidden_path }
it 'should not be able to destroy personal repository with name "main"' do
# hook for "ActiveRecord::ActiveRecordError: name is marked as readonly"
Repository.where(:id => @personal_repository.id).update_all("name = 'main'")
lambda { delete :destroy, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id}.
should change{ Repository.count }.by(0)
response.should redirect_to(forbidden_path)
end
it 'should be able to destroy personal repository with name not "main"' do
lambda { delete :destroy, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id}.
should change{ Repository.count }.by(-1)
response.should redirect_to(platform_repositories_path(@personal_repository.platform))
end
it_should_behave_like 'user with change projects in repository rights'
end
describe Platforms::RepositoriesController do
@ -234,6 +241,8 @@ describe Platforms::RepositoriesController do
context 'for platform owner user' do
before(:each) do
@user = @repository.platform.owner
platform = @personal_repository.platform
platform.owner = @user; platform.save
set_session_for(@user)
end
@ -242,7 +251,9 @@ describe Platforms::RepositoriesController do
context 'for platform member user' do
before(:each) do
@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
[@repository, @personal_repository].each do |repo|
repo.platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end
end
it_should_behave_like 'platform admin user'
@ -250,7 +261,9 @@ describe Platforms::RepositoriesController do
context 'for repository member user' do
before(:each) do
@repository.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
[@repository, @personal_repository].each do |repo|
repo.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end
end
it_should_behave_like 'registered user'

View File

@ -3,12 +3,12 @@ require 'spec_helper'
require "cancan/matchers"
def admin_create
@admin = FactoryGirl.create(:admin)
@admin = FactoryGirl.create(:admin)
@ability = Ability.new(@admin)
end
def user_create
@user = FactoryGirl.create(:user)
@user = FactoryGirl.create(:user)
@ability = Ability.new(@user)
end
@ -17,47 +17,51 @@ def guest_create
end
describe CanCan do
let(:personal_platform) { FactoryGirl.create(:platform, :platform_type => 'personal') }
let(:personal_repository) { FactoryGirl.create(:personal_repository) }
let(:open_platform) { FactoryGirl.create(:platform, :visibility => 'open') }
let(:hidden_platform) { FactoryGirl.create(:platform, :visibility => 'hidden') }
let(:register_request) { FactoryGirl.create(:register_request) }
let(:open_platform) { FactoryGirl.create(:platform, :visibility => 'open') }
before(:each) do
stub_symlink_methods
end
context 'Site admin' do
before(:each) do
admin_create
end
context 'Site admin' do
let(:personal_platform) { FactoryGirl.create(:platform, :platform_type => 'personal') }
let(:personal_repository_main) { FactoryGirl.create(:personal_repository, :name => 'main') }
let(:personal_repository) { FactoryGirl.create(:personal_repository) }
before(:each) do
admin_create
end
it 'should manage all' do
#(@ability.can? :manage, :all).should be_true
@ability.should be_able_to(:manage, :all)
end
it 'should manage all' do
#(@ability.can? :manage, :all).should be_true
@ability.should be_able_to(:manage, :all)
end
it 'should not be able to destroy personal platforms' do
@ability.should_not be_able_to(:destroy, personal_platform)
end
it 'should not be able to destroy personal platforms' do
@ability.should_not be_able_to(:destroy, personal_platform)
end
it 'should not be able to destroy personal repositories' do
@ability.should_not be_able_to(:destroy, personal_repository)
end
end
it 'should not be able to destroy personal repositories with name "main"' do
@ability.should_not be_able_to(:destroy, personal_repository_main)
end
it 'should be able to destroy personal repositories with name not "main"' do
@ability.should be_able_to(:destroy, personal_repository)
end
end
context 'Site guest' do
before(:each) do
guest_create
end
context 'Site guest' do
let(:hidden_platform) { FactoryGirl.create(:platform, :visibility => 'hidden') }
let(:register_request) { FactoryGirl.create(:register_request) }
before(:each) do
guest_create
end
it 'should not be able to read open platform' do
@ability.should_not be_able_to(:read, open_platform)
@ability.should_not be_able_to(:read, open_platform)
end
it 'should not be able to read hidden platform' do
@ability.should_not be_able_to(:read, hidden_platform)
@ability.should_not be_able_to(:read, hidden_platform)
end
[:publish, :cancel, :reject_publish, :create_container].each do |action|
@ -78,10 +82,10 @@ describe CanCan do
@ability.should_not be_able_to(:destroy, register_request)
end
pending 'should be able to register new user' do # while self registration is closed
@ability.should be_able_to(:create, User)
end
end
pending 'should be able to register new user' do # while self registration is closed
@ability.should be_able_to(:create, User)
end
end
context 'Site user' do
before(:each) do