2012-01-30 20:39:34 +00:00
|
|
|
# -*- encoding : utf-8 -*-
|
2011-12-28 02:57:42 +00:00
|
|
|
# If rules goes one by one CanCan joins them by 'OR' sql operator
|
|
|
|
# If rule has multiple conditions CanCan joins them by 'AND' sql operator
|
2012-01-12 11:22:12 +00:00
|
|
|
# WARNING:
|
2011-12-28 02:57:42 +00:00
|
|
|
# - put cannot rules _after_ can rules and not before!
|
2012-01-12 11:22:12 +00:00
|
|
|
# - beware inner joins. Use sub queries against them!
|
2011-12-28 02:57:42 +00:00
|
|
|
|
2011-11-15 20:05:08 +00:00
|
|
|
class Ability
|
|
|
|
include CanCan::Ability
|
|
|
|
|
|
|
|
def initialize(user)
|
|
|
|
user ||= User.new # guest user (not logged in)
|
2011-12-28 02:57:42 +00:00
|
|
|
@user = user
|
2011-12-21 14:48:16 +00:00
|
|
|
|
2012-03-01 17:33:46 +00:00
|
|
|
# Shared rights between guests and registered users
|
2012-03-31 00:37:54 +01:00
|
|
|
can :show, Project, :visibility => 'open'
|
2012-04-17 11:18:03 +01:00
|
|
|
can :archive, Project, :visibility => 'open'
|
2012-03-31 00:37:54 +01:00
|
|
|
can :read, Issue, :project => {:visibility => 'open'}
|
|
|
|
can :search, BuildList
|
|
|
|
can :read, BuildList, :project => {:visibility => 'open'}
|
|
|
|
can :read, ProductBuildList, :product => {:platform => {:visibility => 'open'}}
|
|
|
|
# Core callbacks
|
2012-03-01 17:33:46 +00:00
|
|
|
can [:publish_build, :status_build, :pre_build, :post_build, :circle_build, :new_bbdt], BuildList
|
|
|
|
|
|
|
|
if user.guest? # Guest rights
|
2012-05-02 10:18:07 +01:00
|
|
|
# can [:new, :create], RegisterRequest
|
2012-03-01 17:33:46 +00:00
|
|
|
else # Registered user rights
|
|
|
|
if user.admin?
|
|
|
|
can :manage, :all
|
2012-03-27 22:28:50 +01:00
|
|
|
# Protection
|
2012-03-01 17:33:46 +00:00
|
|
|
cannot :approve, RegisterRequest, :approved => true
|
|
|
|
cannot :reject, RegisterRequest, :rejected => true
|
2012-03-27 22:28:50 +01:00
|
|
|
cannot [:destroy, :create], Subscribe
|
|
|
|
# Act admin as simple user
|
|
|
|
cannot :read, Product, :platform => {:platform_type => 'personal'}
|
2012-03-23 20:37:17 +00:00
|
|
|
cannot [:owned, :related], [BuildList, Platform]
|
2012-03-27 22:28:50 +01:00
|
|
|
cannot :membered, Project # list products which user members
|
2012-03-01 17:33:46 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
if user.user?
|
2011-12-28 02:57:42 +00:00
|
|
|
can [:show, :autocomplete_user_uname], User
|
2012-01-11 13:58:13 +00:00
|
|
|
|
2012-02-01 20:42:23 +00:00
|
|
|
can [:read, :create, :autocomplete_group_uname], Group
|
2011-12-28 02:57:42 +00:00
|
|
|
can [:update, :manage_members], Group do |group|
|
2012-04-26 02:38:33 +01:00
|
|
|
group.actors.exists?(:actor_type => 'User', :actor_id => user.id, :role => 'admin') # or group.owner_id = user.id
|
2011-12-05 12:32:18 +00:00
|
|
|
end
|
2011-12-28 02:57:42 +00:00
|
|
|
can :destroy, Group, :owner_id => user.id
|
2012-05-02 10:18:07 +01:00
|
|
|
can :remove_user, Group
|
2011-12-05 12:32:18 +00:00
|
|
|
|
2011-11-19 11:41:11 +00:00
|
|
|
can :create, Project
|
2012-04-17 14:52:52 +01:00
|
|
|
can :read, Project, :visibility => 'open'
|
2012-04-17 11:18:03 +01:00
|
|
|
can [:read, :archive], Project, :owner_type => 'User', :owner_id => user.id
|
|
|
|
can [:read, :archive], Project, :owner_type => 'Group', :owner_id => user.group_ids
|
2012-03-27 22:28:50 +01:00
|
|
|
can([:read, :membered], Project, read_relations_for('projects')) {|project| local_reader? project}
|
2011-12-28 02:57:42 +00:00
|
|
|
can(:write, Project) {|project| local_writer? project} # for grack
|
2012-02-28 15:44:16 +00:00
|
|
|
can([:update, :sections, :manage_collaborators], Project) {|project| local_admin? project}
|
2011-12-28 02:57:42 +00:00
|
|
|
can(:fork, Project) {|project| can? :read, project}
|
2012-04-19 20:45:50 +01:00
|
|
|
can(:fork, Project) {|project| project.owner_type == 'Group' and can? :update, project.owner}
|
2011-12-28 02:57:42 +00:00
|
|
|
can(:destroy, Project) {|project| owner? project}
|
2012-04-26 02:38:33 +01:00
|
|
|
can(:destroy, Project) {|project| project.owner_type == 'Group' and project.owner.actors.exists?(:actor_type => 'User', :actor_id => user.id, :role => 'admin')}
|
2012-03-07 21:34:49 +00:00
|
|
|
can :remove_user, Project
|
2011-11-19 11:41:11 +00:00
|
|
|
|
2012-02-29 14:04:04 +00:00
|
|
|
can [:read, :owned], BuildList, :user_id => user.id
|
|
|
|
can [:read, :related], BuildList, :project => {:owner_type => 'User', :owner_id => user.id}
|
|
|
|
can [:read, :related], BuildList, :project => {:owner_type => 'Group', :owner_id => user.group_ids}
|
2011-12-28 02:57:42 +00:00
|
|
|
can(:read, BuildList, read_relations_for('build_lists', 'projects')) {|build_list| can? :read, build_list.project}
|
2012-05-17 22:07:04 +01:00
|
|
|
can([:create, :update], BuildList) {|build_list| build_list.project.is_package && can?(:write, build_list.project)}
|
2012-05-14 11:51:08 +01:00
|
|
|
|
2012-04-17 19:18:39 +01:00
|
|
|
can(:publish, BuildList) do |build_list|
|
2012-05-04 18:12:51 +01:00
|
|
|
build_list.can_publish? and build_list.save_to_platform.released ? local_admin?(build_list.save_to_platform) : can?(:write, build_list.project)
|
2012-04-17 19:18:39 +01:00
|
|
|
end
|
|
|
|
can(:reject_publish, BuildList) do |build_list|
|
2012-05-04 18:12:51 +01:00
|
|
|
build_list.can_reject_publish? and build_list.save_to_platform.released and local_admin?(build_list.save_to_platform)
|
2012-04-17 19:18:39 +01:00
|
|
|
end
|
2012-02-29 14:04:04 +00:00
|
|
|
can(:cancel, BuildList) {|build_list| build_list.can_cancel? && can?(:write, build_list.project)}
|
2011-12-28 02:57:42 +00:00
|
|
|
|
2012-05-05 18:18:29 +01:00
|
|
|
can [:read], Advisory
|
|
|
|
|
2012-03-20 16:24:18 +00:00
|
|
|
can [:read, :members], Platform, :visibility => 'open'
|
|
|
|
can [:read, :owned, :related, :members], Platform, :owner_type => 'User', :owner_id => user.id
|
|
|
|
can [:read, :related, :members], Platform, :owner_type => 'Group', :owner_id => user.group_ids
|
|
|
|
can([:read, :related, :members], Platform, read_relations_for('platforms')) {|platform| local_reader? platform}
|
|
|
|
can([:update, :members], Platform) {|platform| local_admin? platform}
|
2012-05-23 17:27:06 +01:00
|
|
|
can([:destroy, :members, :add_member, :remove_member, :remove_members, :build_all, :mass_builds] , Platform) {|platform| owner? platform}
|
2011-12-28 02:57:42 +00:00
|
|
|
can :autocomplete_user_uname, Platform
|
|
|
|
|
2012-03-15 22:56:12 +00:00
|
|
|
can [:read, :projects_list], Repository, :platform => {:visibility => 'open'}
|
|
|
|
can [:read, :projects_list], Repository, :platform => {:owner_type => 'User', :owner_id => user.id}
|
|
|
|
can [:read, :projects_list], Repository, :platform => {:owner_type => 'Group', :owner_id => user.group_ids}
|
|
|
|
can([:read, :projects_list], Repository, read_relations_for('repositories', 'platforms')) {|repository| local_reader? repository.platform}
|
2012-02-20 23:13:05 +00:00
|
|
|
can([:create, :update, :projects_list, :add_project, :remove_project], Repository) {|repository| local_admin? repository.platform}
|
|
|
|
can([:change_visibility, :settings, :destroy], Repository) {|repository| owner? repository.platform}
|
2011-12-28 02:57:42 +00:00
|
|
|
|
2012-03-31 00:37:54 +01:00
|
|
|
can :read, Product, :platform => {:visibility => 'open'}
|
2012-03-16 13:25:34 +00:00
|
|
|
can :read, Product, :platform => {:owner_type => 'User', :owner_id => user.id, :platform_type => 'main'}
|
|
|
|
can :read, Product, :platform => {:owner_type => 'Group', :owner_id => user.group_ids, :platform_type => 'main'}
|
2012-03-15 00:07:53 +00:00
|
|
|
can(:read, Product, read_relations_for('products', 'platforms')) {|product| product.platform.platform_type == 'main'}
|
2012-03-16 13:25:34 +00:00
|
|
|
can([:create, :update, :destroy, :clone], Product) {|product| local_admin? product.platform and product.platform.platform_type == 'main'}
|
2012-03-15 00:07:53 +00:00
|
|
|
|
2012-03-15 21:10:24 +00:00
|
|
|
can(:create, ProductBuildList) {|pbl| can?(:update, pbl.product)}
|
2012-02-27 20:00:33 +00:00
|
|
|
can(:destroy, ProductBuildList) {|pbl| can?(:destroy, pbl.product)}
|
2012-03-15 00:07:53 +00:00
|
|
|
|
2011-12-28 02:57:42 +00:00
|
|
|
can [:read, :create], PrivateUser, :platform => {:owner_type => 'User', :owner_id => user.id}
|
2011-11-19 11:41:11 +00:00
|
|
|
can [:read, :create], PrivateUser, :platform => {:owner_type => 'Group', :owner_id => user.group_ids}
|
|
|
|
|
2011-12-28 02:57:42 +00:00
|
|
|
can :read, Issue, :project => {:owner_type => 'User', :owner_id => user.id}
|
|
|
|
can :read, Issue, :project => {:owner_type => 'Group', :owner_id => user.group_ids}
|
|
|
|
can(:read, Issue, read_relations_for('issues', 'projects')) {|issue| can? :read, issue.project rescue nil}
|
|
|
|
can(:create, Issue) {|issue| can? :write, issue.project}
|
|
|
|
can([:update, :destroy], Issue) {|issue| issue.user_id == user.id or local_admin?(issue.project)}
|
|
|
|
cannot :manage, Issue, :project => {:has_issues => false} # switch off issues
|
|
|
|
|
2012-03-06 21:49:29 +00:00
|
|
|
can(:create, Comment) {|comment| can? :read, comment.project}
|
2012-01-14 12:16:42 +00:00
|
|
|
can(:update, Comment) {|comment| comment.user_id == user.id or local_admin?(comment.project || comment.commentable.project)}
|
2012-03-06 20:51:51 +00:00
|
|
|
cannot :manage, Comment, :commentable_type => 'Issue', :commentable => {:project => {:has_issues => false}} # switch off issues
|
2011-11-15 20:05:08 +00:00
|
|
|
end
|
2011-12-21 14:48:16 +00:00
|
|
|
|
2012-03-01 17:33:46 +00:00
|
|
|
# Shared cannot rights for all users (registered, admin)
|
|
|
|
cannot :destroy, Platform, :platform_type => 'personal'
|
2012-03-14 23:25:58 +00:00
|
|
|
cannot [:create, :destroy, :add_project, :remove_project], Repository, :platform => {:platform_type => 'personal'}
|
2012-03-01 17:33:46 +00:00
|
|
|
cannot :destroy, Issue
|
2011-12-29 11:16:54 +00:00
|
|
|
|
2012-03-20 18:41:14 +00:00
|
|
|
cannot [:members, :add_member, :remove_member, :remove_members], Platform, :platform_type => 'personal'
|
|
|
|
|
2012-03-15 00:07:53 +00:00
|
|
|
cannot [:create, :update, :destroy, :clone], Product, :platform => {:platform_type => 'personal'}
|
2012-05-23 17:27:06 +01:00
|
|
|
cannot [:clone, :build_all, :mass_builds], Platform, :platform_type => 'personal'
|
2012-03-14 23:25:58 +00:00
|
|
|
|
2012-03-01 17:33:46 +00:00
|
|
|
can :create, Subscribe do |subscribe|
|
|
|
|
!subscribe.subscribeable.subscribes.exists?(:user_id => user.id)
|
|
|
|
end
|
|
|
|
can :destroy, Subscribe do |subscribe|
|
|
|
|
subscribe.subscribeable.subscribes.exists?(:user_id => user.id) && user.id == subscribe.user_id
|
|
|
|
end
|
2011-12-29 11:16:54 +00:00
|
|
|
end
|
2011-11-15 20:05:08 +00:00
|
|
|
end
|
2011-11-17 19:34:02 +00:00
|
|
|
|
2011-12-28 02:57:42 +00:00
|
|
|
# TODO group_ids ??
|
|
|
|
def read_relations_for(table, parent = nil)
|
|
|
|
key = parent ? "#{parent.singularize}_id" : 'id'
|
|
|
|
parent ||= table
|
|
|
|
["#{table}.#{key} IN (
|
|
|
|
SELECT target_id FROM relations WHERE relations.target_type = ? AND
|
2012-04-26 02:38:33 +01:00
|
|
|
(relations.actor_type = 'User' AND relations.actor_id = ? OR
|
|
|
|
relations.actor_type = 'Group' AND relations.actor_id IN (?)))", parent.classify, @user, @user.group_ids]
|
2011-11-17 19:34:02 +00:00
|
|
|
end
|
|
|
|
|
2012-04-26 02:38:33 +01:00
|
|
|
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)
|
2011-12-28 02:57:42 +00:00
|
|
|
end
|
2011-12-21 14:48:16 +00:00
|
|
|
|
2012-04-26 02:38:33 +01:00
|
|
|
def local_reader?(target)
|
|
|
|
relation_exists_for(target, %w{reader writer admin}) or owner?(target)
|
2011-12-21 14:48:16 +00:00
|
|
|
end
|
|
|
|
|
2012-04-26 02:38:33 +01:00
|
|
|
def local_writer?(target)
|
|
|
|
relation_exists_for(target, %w{writer admin}) or owner?(target)
|
2011-12-28 02:57:42 +00:00
|
|
|
end
|
2011-12-15 21:58:20 +00:00
|
|
|
|
2012-04-26 02:38:33 +01:00
|
|
|
def local_admin?(target)
|
|
|
|
relation_exists_for(target, 'admin') or owner?(target)
|
2011-12-15 21:58:20 +00:00
|
|
|
end
|
|
|
|
|
2012-04-26 02:38:33 +01:00
|
|
|
def owner?(target)
|
|
|
|
target.owner == @user or @user.own_groups.include?(target.owner)
|
2011-12-28 02:57:42 +00:00
|
|
|
end
|
2011-12-01 14:20:24 +00:00
|
|
|
end
|