diff options
author | http://jneen.net/ <jneen@jneen.net> | 2016-08-11 15:12:52 -0700 |
---|---|---|
committer | http://jneen.net/ <jneen@jneen.net> | 2016-08-30 11:35:06 -0700 |
commit | e208765a92748086cacbc56225e827c8463750a5 (patch) | |
tree | be9bb5c39c1b88cb3bab21d05c7a6a07398b4f7e /app/policies | |
parent | 5853c96b49010aaf33b85caeb94dfc18873d5656 (diff) | |
download | gitlab-ce-e208765a92748086cacbc56225e827c8463750a5.tar.gz |
add policies, and factor out ProjectPolicy
Diffstat (limited to 'app/policies')
-rw-r--r-- | app/policies/base_policy.rb | 25 | ||||
-rw-r--r-- | app/policies/project_policy.rb | 202 |
2 files changed, 227 insertions, 0 deletions
diff --git a/app/policies/base_policy.rb b/app/policies/base_policy.rb new file mode 100644 index 00000000000..3f52b0b005a --- /dev/null +++ b/app/policies/base_policy.rb @@ -0,0 +1,25 @@ +class BasePolicy + def initialize(user, subject) + @user = user + @subject = subject + end + + def abilities + @can = Set.new + @cannot = Set.new + generate! + @can - @cannot + end + + def generate! + raise 'abstract' + end + + def can!(*rules) + @can.merge(rules) + end + + def cannot!(*rules) + @cannot.merge(rules) + end +end diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb new file mode 100644 index 00000000000..1e82070e62a --- /dev/null +++ b/app/policies/project_policy.rb @@ -0,0 +1,202 @@ +class ProjectPolicy < BasePolicy + def project + @subject + end + + def guest_access! + can! :read_project + can! :read_board + can! :read_list + can! :read_wiki + can! :read_issue + can! :read_label + can! :read_milestone + can! :read_project_snippet + can! :read_project_member + can! :read_merge_request + can! :read_note + can! :create_project + can! :create_issue + can! :create_note + can! :upload_file + end + + def reporter_access! + can! :download_code + can! :fork_project + can! :create_project_snippet + can! :update_issue + can! :admin_issue + can! :admin_label + can! :read_commit_status + can! :read_build + can! :read_container_image + can! :read_pipeline + can! :read_environment + can! :read_deployment + end + + def developer_access! + can! :admin_merge_request + can! :update_merge_request + can! :create_commit_status + can! :update_commit_status + can! :create_build + can! :update_build + can! :create_pipeline + can! :update_pipeline + can! :create_merge_request + can! :create_wiki + can! :push_code + can! :create_container_image + can! :update_container_image + can! :create_environment + can! :create_deployment + end + + def master_access! + can! :push_code_to_protected_branches + can! :update_project_snippet + can! :update_environment + can! :update_deployment + can! :admin_milestone + can! :admin_project_snippet + can! :admin_project_member + can! :admin_merge_request + can! :admin_note + can! :admin_wiki + can! :admin_project + can! :admin_commit_status + can! :admin_build + can! :admin_container_image + can! :admin_pipeline + can! :admin_environment + can! :admin_deployment + end + + def public_access! + can! :download_code + can! :fork_project + can! :read_commit_status + can! :read_pipeline + can! :read_container_image + end + + def owner_access! + guest_access! + reporter_access! + developer_access! + master_access! + can! :change_namespace + can! :change_visibility_level + can! :rename_project + can! :remove_project + can! :archive_project + can! :remove_fork_project + can! :destroy_merge_request + can! :destroy_issue + end + + # Push abilities on the users team role + def team_access! + access = project.team.max_member_access(@user.id) + + return if access < Gitlab::Access::GUEST + guest_access! + + return if access < Gitlab::Access::REPORTER + reporter_access! + + return if access < Gitlab::Access::DEVELOPER + developer_access! + + return if access < Gitlab::Access::MASTER + master_access! + end + + def archived_access! + cannot! :create_merge_request + cannot! :push_code + cannot! :push_code_to_protected_branches + cannot! :update_merge_request + cannot! :admin_merge_request + end + + def disabled_features! + unless project.issues_enabled + cannot!(*named_abilities(:issue)) + end + + unless project.merge_requests_enabled + cannot!(*named_abilities(:merge_request)) + end + + unless project.issues_enabled or project.merge_requests_enabled + cannot!(*named_abilities(:label)) + cannot!(*named_abilities(:milestone)) + end + + unless project.snippets_enabled + cannot!(*named_abilities(:project_snippet)) + end + + unless project.wiki_enabled + cannot!(*named_abilities(:wiki)) + end + + unless project.builds_enabled + cannot!(*named_abilities(:build)) + cannot!(*named_abilities(:pipeline)) + cannot!(*named_abilities(:environment)) + cannot!(*named_abilities(:deployment)) + end + + unless project.container_registry_enabled + cannot!(*named_abilities(:container_image)) + end + end + + def generate! + team_access! + + owner = @user.admin? || + project.owner == @user || + (project.group && project.group.has_owner?(@user)) + + owner_access! if owner + + if project.public? || (project.internal? && !@user.external?) + guest_access! + public_access! + + # Allow to read builds for internal projects + can! :read_build if project.public_builds? + + if project.request_access_enabled && + !(owner || project.team.member?(@user) || project_group_member?) + can! :request_access + end + end + + archived_access! if project.archived? + + disabled_features! + end + + def project_group_member? + project.group && + ( + project.group.members.exists?(user_id: @user.id) || + project.group.requesters.exists?(user_id: @user.id) + ) + end + + def named_abilities(name) + [ + :"read_#{name}", + :"create_#{name}", + :"update_#{name}", + :"admin_#{name}" + ] + end +end |