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-21 14:48:16 +00:00
|
|
|
|
2011-11-15 20:05:08 +00:00
|
|
|
if user.admin?
|
|
|
|
can :manage, :all
|
|
|
|
else
|
2011-11-17 19:34:02 +00:00
|
|
|
#WARNING:
|
|
|
|
# - put cannot rules _after_ can rules and not before!
|
|
|
|
# - beware inner joins. Use sub queries against them!
|
2011-11-15 20:05:08 +00:00
|
|
|
# Shared rights between guests and registered users
|
2011-11-16 18:45:01 +00:00
|
|
|
can :forbidden, Platform
|
2011-11-17 19:34:02 +00:00
|
|
|
|
2011-11-22 19:21:09 +00:00
|
|
|
can :read, [Repository, Platform], :visibility => 'open'
|
2011-11-30 00:56:57 +00:00
|
|
|
# TODO remove because auth callbacks skipped
|
|
|
|
can :auto_build, Project
|
2011-11-19 11:41:11 +00:00
|
|
|
can [:status_build, :pre_build, :post_build, :circle_build, :new_bbdt], BuildList
|
2011-11-17 19:34:02 +00:00
|
|
|
|
2011-11-15 20:05:08 +00:00
|
|
|
# Guest rights
|
|
|
|
if user.guest?
|
2011-11-17 19:34:02 +00:00
|
|
|
can :create, User
|
2011-11-15 20:05:08 +00:00
|
|
|
# Registered user rights
|
|
|
|
else
|
2011-11-24 21:46:19 +00:00
|
|
|
can [:read, :platforms], Category
|
|
|
|
|
|
|
|
can :create, AutoBuildList
|
|
|
|
can [:index, :destroy], AutoBuildList, :project_id => user.own_project_ids
|
2011-11-15 20:05:08 +00:00
|
|
|
# If rules goes one by one CanCan joins them by 'OR' sql operator
|
|
|
|
can :read, Project, :visibility => 'open'
|
2011-12-05 12:32:18 +00:00
|
|
|
can :read, Group
|
2011-11-21 19:06:34 +00:00
|
|
|
can :read, User
|
2011-12-16 07:32:34 +00:00
|
|
|
cannot :index, User
|
2011-11-18 18:26:22 +00:00
|
|
|
can :manage_collaborators, Project do |project|
|
|
|
|
project.relations.exists? :object_id => user.id, :object_type => 'User', :role => 'admin'
|
|
|
|
end
|
2011-12-05 12:32:18 +00:00
|
|
|
can :manage_members, Group do |group|
|
|
|
|
group.objects.exists? :object_id => user.id, :object_type => 'User', :role => 'admin'
|
|
|
|
end
|
|
|
|
|
2011-11-19 11:41:11 +00:00
|
|
|
# Put here model names which objects can user create
|
|
|
|
can :create, Project
|
2011-12-05 12:32:18 +00:00
|
|
|
can :create, Group
|
2011-11-19 11:41:11 +00:00
|
|
|
can :publish, BuildList do |build_list|
|
2011-12-21 21:42:06 +00:00
|
|
|
build_list.can_publish? && build_list.project.relations.exists?(:object_type => 'User', :object_id => user.id)
|
2011-11-19 11:41:11 +00:00
|
|
|
end
|
2011-12-21 01:30:34 +00:00
|
|
|
can [:index, :read], BuildList, ["build_lists.project_id IN (SELECT id FROM projects WHERE visibility = ?)", 'open'] do |build_list|
|
2011-12-15 21:58:20 +00:00
|
|
|
build_list.project.public?
|
2011-12-13 14:21:25 +00:00
|
|
|
end
|
2011-12-21 01:30:34 +00:00
|
|
|
can [:index, :read], BuildList, build_lists_in_relations_with(:object_type => 'User', :object_id => user.id) do |build_list|
|
2011-12-15 21:58:20 +00:00
|
|
|
build_list.project.relations.exists?(:object_type => 'User', :object_id => user.id)
|
|
|
|
end
|
|
|
|
|
2011-11-19 11:41:11 +00:00
|
|
|
can [:read, :create], PrivateUser, :platform => {:owner_type => 'User', :owner_id => user.id}
|
2011-11-17 19:34:02 +00:00
|
|
|
|
|
|
|
# If rule has multiple conditions CanCan joins them by 'AND' sql operator
|
2011-12-21 14:01:50 +00:00
|
|
|
can [:read, :update, :destroy], Project, :owner_type => 'User', :owner_id => user.id
|
2011-11-24 19:22:37 +00:00
|
|
|
#can :read, Project, :relations => {:role => 'reader'}
|
|
|
|
can :read, Project, projects_in_relations_with(:role => 'reader', :object_type => 'User', :object_id => user.id) do |project|
|
2011-11-18 18:26:22 +00:00
|
|
|
#The can? and cannot? call cannot be used with a raw sql 'can' definition.
|
2011-11-24 19:22:37 +00:00
|
|
|
project.relations.exists?(:role => 'reader', :object_type => 'User', :object_id => user.id)
|
2011-11-18 18:26:22 +00:00
|
|
|
end
|
2011-12-21 14:01:50 +00:00
|
|
|
#can [:update], Project, :relations => {:role => 'writer'}
|
|
|
|
can [:read, :update], Project, projects_in_relations_with(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id) do |project|
|
2011-11-24 19:22:37 +00:00
|
|
|
project.relations.exists?(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id)
|
2011-11-18 18:26:22 +00:00
|
|
|
end
|
2011-12-01 14:20:24 +00:00
|
|
|
|
2011-12-02 06:57:58 +00:00
|
|
|
can [:read, :update, :destroy], Product, products_in_relations_with(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id) do |product|
|
|
|
|
product.relations.exists?(:role => 'admin', :object_type => 'User', :object_id => user.id)
|
|
|
|
end
|
|
|
|
# Small CanCan hack by Product.new(:platform_id => ...)
|
|
|
|
can [:new, :create], Product do |product|
|
|
|
|
product.platform.relations.exists?(:role => 'admin', :object_type => 'User', :object_id => user.id)
|
2011-12-01 14:20:24 +00:00
|
|
|
end
|
|
|
|
|
2011-12-05 12:32:18 +00:00
|
|
|
can [:read, :update], Group, groups_in_relations_with(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id) do |group|
|
|
|
|
group.objects.exists?(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id)
|
|
|
|
end
|
2011-12-21 14:48:16 +00:00
|
|
|
|
2011-11-19 11:41:11 +00:00
|
|
|
can :manage, Platform, :owner_type => 'User', :owner_id => user.id
|
2011-12-01 14:20:24 +00:00
|
|
|
can :manage, Platform, platforms_in_relations_with(:role => 'admin', :object_type => 'User', :object_id => user.id) do |platform|
|
|
|
|
platform.relations.exists?(:role => 'admin', :object_type => 'User', :object_id => user.id)
|
|
|
|
end
|
2011-11-17 19:34:02 +00:00
|
|
|
#can :read, Platform, :members => {:id => user.id}
|
2011-11-24 19:22:37 +00:00
|
|
|
can :read, Platform, platforms_in_relations_with(:role => 'reader', :object_type => 'User', :object_id => user.id) do |platform|
|
|
|
|
platform.relations.exists?(:role => 'reader', :object_type => 'User', :object_id => user.id)
|
2011-11-18 18:26:22 +00:00
|
|
|
end
|
2011-11-19 11:41:11 +00:00
|
|
|
|
|
|
|
can [:manage, :add_project, :remove_project, :change_visibility, :settings], Repository, :owner_type => 'User', :owner_id => user.id
|
2011-12-01 14:20:24 +00:00
|
|
|
can :manage, Repository, repositories_in_relations_with(:role => 'admin', :object_type => 'User', :object_id => user.id) do |repository|
|
|
|
|
repository.relations.exists?(:role => 'admin', :object_type => 'User', :object_id => user.id)
|
|
|
|
end
|
2011-11-28 13:28:29 +00:00
|
|
|
#can :read, Repository, :members => {:id => user.id}
|
2011-11-24 19:22:37 +00:00
|
|
|
can :read, Repository, repositories_in_relations_with(:role => 'reader', :object_type => 'User', :object_id => user.id) do |repository|
|
|
|
|
repository.relations.exists?(:role => 'reader', :object_type => 'User', :object_id => user.id)
|
2011-11-19 11:41:11 +00:00
|
|
|
end
|
2011-12-02 06:57:58 +00:00
|
|
|
# Small CanCan hack by Repository.new(:platform_id => ...)
|
2011-12-02 15:25:59 +00:00
|
|
|
can [:new, :create], Repository do |repository|
|
|
|
|
repository.platform.relations.exists?(:role => 'admin', :object_type => 'User', :object_id => user.id)
|
|
|
|
end
|
2011-12-21 14:48:16 +00:00
|
|
|
|
2011-12-22 07:41:37 +00:00
|
|
|
can [:read, :index], Issue do |issue|
|
2011-12-21 14:48:16 +00:00
|
|
|
issue.status == 'open'
|
|
|
|
end
|
2011-12-22 07:41:37 +00:00
|
|
|
#can [:read], Issue, :status => 'open'
|
|
|
|
#can [:show], Issue, with_project_id_in_relations_with(:object_type => 'User', :object_id => user.id)
|
|
|
|
can [:read, :index], Issue do |issue|
|
2011-12-21 14:48:16 +00:00
|
|
|
issue.project.relations.exists?(:object_type => 'User', :object_id => user.id)
|
|
|
|
end
|
|
|
|
can [:create, :new], Issue do |issue|
|
|
|
|
issue.project.relations.exists?(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id)
|
|
|
|
end
|
|
|
|
can [:edit, :update], Issue do |issue|
|
|
|
|
issue.user_id == user.id || (user.id == issue.project.owner_id && issue.project.owner_type == 'User') ||
|
|
|
|
issue.project.relations.exists?(:role => 'admin', :object_type => 'User', :object_id => user.id)
|
|
|
|
end
|
|
|
|
can [:create, :new], Comment do |comment|
|
|
|
|
comment.commentable.project.relations.exists?(:object_type => 'User', :object_id => user.id)
|
|
|
|
end
|
|
|
|
can [:edit, :update], Comment do |comment|
|
|
|
|
comment.user_id == user.id || (user.id == comment.commentable.project.owner_id && comment.commentable.project.owner_type == 'User') ||
|
|
|
|
comment.commentable.project.relations.exists?(:role => 'admin', :object_type => 'User', :object_id => user.id)
|
|
|
|
end
|
|
|
|
#
|
2011-12-23 10:56:46 +00:00
|
|
|
cannot [:index, :edit, :update, :create, :new, :read, :show], Issue do |issue|
|
2011-12-21 14:48:16 +00:00
|
|
|
!issue.project.has_issues
|
|
|
|
end
|
|
|
|
cannot [:edit, :update, :create, :new, :destroy], Comment do |comment|
|
|
|
|
!comment.commentable.project.has_issues
|
|
|
|
end
|
|
|
|
|
2011-11-16 18:45:01 +00:00
|
|
|
#can :read, Repository
|
|
|
|
# TODO: Add personal repos rules
|
2011-12-21 14:48:16 +00:00
|
|
|
|
2011-11-16 18:45:01 +00:00
|
|
|
# Same rights for groups:
|
2011-11-19 11:41:11 +00:00
|
|
|
can [:read, :create], PrivateUser, :platform => {:owner_type => 'Group', :owner_id => user.group_ids}
|
|
|
|
can :publish, BuildList do |build_list|
|
2011-12-21 21:42:06 +00:00
|
|
|
build_list.can_publish? && build_list.project.relations.exists?(:object_type => 'Group', :object_id => user.group_ids)
|
2011-11-19 11:41:11 +00:00
|
|
|
end
|
2011-12-21 01:30:34 +00:00
|
|
|
can [:index, :read], BuildList, build_lists_in_relations_with(:object_type => 'Group', :object_id => user.group_ids) do |build_list|
|
2011-12-15 21:58:20 +00:00
|
|
|
build_list.project.relations.exists?(:object_type => 'Group', :object_id => user.group_ids)
|
2011-12-13 14:21:25 +00:00
|
|
|
end
|
2011-11-19 11:41:11 +00:00
|
|
|
|
2011-12-06 23:45:09 +00:00
|
|
|
can :manage_collaborators, Project, projects_in_relations_with(:role => 'admin', :object_type => 'Group', :object_id => user.group_ids) do |project|
|
|
|
|
project.relations.exists? :object_id => user.group_ids, :object_type => 'Group', :role => 'admin'
|
|
|
|
end
|
|
|
|
|
2011-12-21 14:01:50 +00:00
|
|
|
can [:read, :update, :destroy], Project, :owner_type => 'Group', :owner_id => user.group_ids
|
2011-11-24 19:22:37 +00:00
|
|
|
#can :read, Project, :relations => {:role => 'reader', :object_type => 'Group', :object_id => user.group_ids}
|
|
|
|
can :read, Project, projects_in_relations_with(:role => 'reader', :object_type => 'Group', :object_id => user.group_ids) do |project|
|
|
|
|
project.relations.exists?(:role => 'reader', :object_type => 'Group', :object_id => user.group_ids)
|
2011-11-18 18:26:22 +00:00
|
|
|
end
|
2011-12-21 14:01:50 +00:00
|
|
|
#can [:update], Project, :relations => {:role => 'writer', :object_type => 'Group', :object_id => user.group_ids}
|
|
|
|
can [:read, :update], Project, projects_in_relations_with(:role => ['writer', 'admin'], :object_type => 'Group', :object_id => user.group_ids) do |project|
|
2011-11-24 19:22:37 +00:00
|
|
|
project.relations.exists?(:role => ['writer', 'admin'], :object_type => 'Group', :object_id => user.group_ids)
|
2011-11-18 18:26:22 +00:00
|
|
|
end
|
2011-12-21 14:48:16 +00:00
|
|
|
|
2011-11-16 18:45:01 +00:00
|
|
|
can :manage, Platform, :owner_type => 'Group', :owner_id => user.group_ids
|
2011-11-17 19:34:02 +00:00
|
|
|
#can :read, Platform, :groups => {:id => user.group_ids}
|
2011-11-24 19:22:37 +00:00
|
|
|
can :read, Platform, platforms_in_relations_with(:role => 'reader', :object_type => 'Group', :object_id => user.group_ids) do |platform|
|
|
|
|
platform.relations.exists?(:role => 'reader', :object_type => 'Group', :object_id => user.group_ids)
|
2011-11-18 18:26:22 +00:00
|
|
|
end
|
2011-11-19 11:41:11 +00:00
|
|
|
|
|
|
|
can [:manage, :add_project, :remove_project], Repository, :owner_type => 'Group', :owner_id => user.group_ids
|
|
|
|
#can :read, Platform, :groups => {:id => user.group_ids}
|
2011-11-24 19:22:37 +00:00
|
|
|
can :read, Repository, repositories_in_relations_with(:role => 'reader', :object_type => 'Group', :object_id => user.group_ids) do |repository|
|
|
|
|
repository.relations.exists?(:role => 'reader', :object_type => 'Group', :object_id => user.group_ids)
|
2011-11-19 11:41:11 +00:00
|
|
|
end
|
2011-11-22 13:20:35 +00:00
|
|
|
|
2011-11-23 15:52:33 +00:00
|
|
|
can(:fork, Project) {|p| can? :read, p}
|
2011-12-21 14:01:50 +00:00
|
|
|
can(:create, BuildList) {|bl| can? :update, bl.project}
|
2011-11-23 15:52:33 +00:00
|
|
|
|
2011-11-22 13:20:35 +00:00
|
|
|
# Things that can not do simple user
|
2011-12-02 15:25:59 +00:00
|
|
|
cannot :create, [Platform, User]
|
2011-11-15 20:05:08 +00:00
|
|
|
end
|
|
|
|
end
|
2011-12-21 14:48:16 +00:00
|
|
|
|
2011-11-19 11:41:11 +00:00
|
|
|
# Shared cannot rights for all users (guests, registered, admin)
|
2011-11-16 18:45:01 +00:00
|
|
|
cannot :destroy, Platform, :platform_type => 'personal'
|
2011-11-19 11:41:11 +00:00
|
|
|
cannot :destroy, Repository, :platform => {:platform_type => 'personal'}
|
2011-11-23 15:52:33 +00:00
|
|
|
cannot :fork, Project, :owner_id => user.id, :owner_type => user.class.to_s
|
2011-12-21 14:48:16 +00:00
|
|
|
cannot :destroy, Issue
|
2011-11-15 20:05:08 +00:00
|
|
|
end
|
2011-11-17 19:34:02 +00:00
|
|
|
|
|
|
|
# Sub query for platforms, projects relations
|
2011-11-19 11:41:11 +00:00
|
|
|
# TODO: Replace table names list by method_missing way
|
2011-12-05 13:16:32 +00:00
|
|
|
%w[platforms projects products repositories groups].each do |table_name|
|
2011-11-17 19:34:02 +00:00
|
|
|
define_method table_name + "_in_relations_with" do |opts|
|
|
|
|
query = "#{ table_name }.id IN (SELECT target_id FROM relations WHERE relations.target_type = '#{ table_name.singularize.camelize }'"
|
|
|
|
opts.each do |key, value|
|
|
|
|
query = query + " AND relations.#{ key } #{ value.class == Array ? 'IN (?)' : '= ?' } "
|
|
|
|
end
|
|
|
|
query = query + ")"
|
|
|
|
|
|
|
|
return opts.values.unshift query
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-12-21 14:48:16 +00:00
|
|
|
def with_project_id_in_relations_with(opts = {})
|
|
|
|
query = "issues.project_id IN (SELECT target_id FROM relations WHERE relations.target_type = 'issues'"
|
|
|
|
opts.each do |key, value|
|
|
|
|
query = query + " AND relations.#{ key } #{ value.class == Array ? 'IN (?)' : '= ?' } "
|
|
|
|
end
|
|
|
|
query = query + ")"
|
|
|
|
|
|
|
|
return opts.values.unshift query
|
|
|
|
end
|
|
|
|
|
2011-12-15 21:58:20 +00:00
|
|
|
def build_lists_in_relations_with(opts)
|
|
|
|
query = "build_lists.project_id IN (SELECT target_id FROM relations WHERE relations.target_type = 'Project'"
|
|
|
|
opts.each do |key, value|
|
|
|
|
query = query + " AND relations.#{ key } #{ value.class == Array ? 'IN (?)' : '= ?' } "
|
|
|
|
end
|
|
|
|
query = query + ")"
|
|
|
|
|
|
|
|
return opts.values.unshift query
|
|
|
|
end
|
|
|
|
|
2011-11-17 19:34:02 +00:00
|
|
|
## Sub query for project relations
|
|
|
|
#def projects_in_relations_with(opts={})
|
|
|
|
# ["projects.id IN (SELECT target_id FROM relations WHERE relations.object_id #{ opts[:object_id].class == Array ? 'IN (?)' : '= ?' } AND relations.object_type = '#{ opts[:object_type] }' AND relations.target_type = 'Platform') AND relations.role", opts[:object_id]]
|
|
|
|
#end
|
2011-12-01 14:20:24 +00:00
|
|
|
end
|