Files
gitlabhq/lib/gitlab/access.rb
2025-03-04 09:11:37 +00:00

238 lines
7.7 KiB
Ruby

# frozen_string_literal: true
# Gitlab::Access module
#
# Define allowed roles that can be used
# in GitLab code to determine authorization level
#
module Gitlab
module Access
AccessDeniedError = Class.new(StandardError)
NO_ACCESS = 0
MINIMAL_ACCESS = 5
GUEST = 10
PLANNER = 15
REPORTER = 20
DEVELOPER = 30
MAINTAINER = 40
OWNER = 50
ADMIN = 60
# Branch protection settings
PROTECTION_NONE = 0
PROTECTION_DEV_CAN_PUSH = 1
PROTECTION_FULL = 2
PROTECTION_DEV_CAN_MERGE = 3
PROTECTION_DEV_CAN_INITIAL_PUSH = 4
# Default project creation level
NO_ONE_PROJECT_ACCESS = 0
MAINTAINER_PROJECT_ACCESS = 1
DEVELOPER_PROJECT_ACCESS = 2
ADMINISTRATOR_PROJECT_ACCESS = 3
OWNER_PROJECT_ACCESS = 4
# Default subgroup creation level
OWNER_SUBGROUP_ACCESS = 0
MAINTAINER_SUBGROUP_ACCESS = 1
class << self
delegate :values, to: :options
def all_values
options_with_owner.values
end
def options
{
"Guest" => GUEST,
"Planner" => PLANNER,
"Reporter" => REPORTER,
"Developer" => DEVELOPER,
"Maintainer" => MAINTAINER
}
end
def options_with_owner
options.merge(
"Owner" => OWNER
)
end
def options_with_none
options_with_owner.merge(
"None" => NO_ACCESS
)
end
def option_descriptions
{
NO_ACCESS => s_('MemberRole|The None role is assigned to the invited group users of a shared project when project sharing is disabled in group setting.'),
GUEST => s_('MemberRole|The Guest role is for users who need visibility into a project or group but should not have the ability to make changes, such as external stakeholders.'),
PLANNER => s_('The Planner role is suitable for team members who need to manage projects and track work items but do not need to contribute code.'),
REPORTER => s_('MemberRole|The Reporter role is suitable for team members who need to stay informed about a project or group but do not actively contribute code.'),
DEVELOPER => s_('MemberRole|The Developer role gives users access to contribute code while restricting sensitive administrative actions.'),
MAINTAINER => s_('MemberRole|The Maintainer role is primarily used for managing code reviews, approvals, and administrative settings for projects. This role can also manage project memberships.'),
OWNER => s_('MemberRole|The Owner role is typically assigned to the individual or team responsible for managing and maintaining the group or creating the project. This role has the highest level of administrative control, and can manage all aspects of the group or project, including managing other Owners.')
}
end
def sym_options
{
guest: GUEST,
planner: PLANNER,
reporter: REPORTER,
developer: DEVELOPER,
maintainer: MAINTAINER
}
end
def sym_options_with_owner
sym_options.merge(owner: OWNER)
end
def sym_options_with_admin
sym_options_with_owner.merge(admin: ADMIN)
end
def protection_options
[
{
label: s_('DefaultBranchProtection|Not protected'),
help_text: s_('DefaultBranchProtection|Both developers and maintainers can push new commits, force push, or delete the branch.'),
value: PROTECTION_NONE
},
{
label: s_('DefaultBranchProtection|Protected against pushes'),
help_text: s_('DefaultBranchProtection|Developers cannot push new commits, but are allowed to accept merge requests to the branch. Maintainers can push to the branch.'),
value: PROTECTION_DEV_CAN_MERGE
},
{
label: s_('DefaultBranchProtection|Partially protected'),
help_text: s_('DefaultBranchProtection|Both developers and maintainers can push new commits, but cannot force push.'),
value: PROTECTION_DEV_CAN_PUSH
},
{
label: s_('DefaultBranchProtection|Fully protected'),
help_text: s_('DefaultBranchProtection|Developers cannot push new commits, but maintainers can. No one can force push.'),
value: PROTECTION_FULL
},
{
label: s_('DefaultBranchProtection|Fully protected after initial push'),
help_text: s_('DefaultBranchProtection|Developers can push the initial commit to a repository, but none afterward. Maintainers can always push. No one can force push.'),
value: PROTECTION_DEV_CAN_INITIAL_PUSH
}
]
end
def global_protection_levels
[
{
label: s_('DefaultBranchProtection|Not protected'),
help_text: s_('DefaultBranchProtection|Both developers and maintainers can push new commits, force push, or delete the branch.'),
value: false
},
{
label: s_('DefaultBranchProtection|Protected'),
help_text: s_('DefaultBranchProtection|Once a repository is created this branch will be protected.'),
value: true
}
]
end
def protection_values
protection_options.map { |option| option[:value] }
end
def human_access(access, _member_role = nil)
options_with_owner.key(access)
end
def role_description(access)
option_descriptions[access]
end
def human_access_with_none(access, _member_role = nil)
options_with_none.key(access)
end
def project_creation_options
{
s_('ProjectCreationLevel|No one') => NO_ONE_PROJECT_ACCESS,
s_('ProjectCreationLevel|Administrators') => ADMINISTRATOR_PROJECT_ACCESS,
s_('ProjectCreationLevel|Owners') => OWNER_PROJECT_ACCESS,
s_('ProjectCreationLevel|Maintainers') => MAINTAINER_PROJECT_ACCESS,
s_('ProjectCreationLevel|Developers') => DEVELOPER_PROJECT_ACCESS
}
end
def project_creation_string_options
{
'noone' => NO_ONE_PROJECT_ACCESS,
'owner' => OWNER_PROJECT_ACCESS,
'maintainer' => MAINTAINER_PROJECT_ACCESS,
'developer' => DEVELOPER_PROJECT_ACCESS,
'administrator' => ADMINISTRATOR_PROJECT_ACCESS
}
end
def project_creation_values
project_creation_options.values
end
def project_creation_string_values
project_creation_string_options.keys
end
def project_creation_level_name(name)
project_creation_options.key(name)
end
def subgroup_creation_options
{
s_('SubgroupCreationlevel|Owners') => OWNER_SUBGROUP_ACCESS,
s_('SubgroupCreationlevel|Maintainers') => MAINTAINER_SUBGROUP_ACCESS
}
end
def subgroup_creation_string_options
{
'owner' => OWNER_SUBGROUP_ACCESS,
'maintainer' => MAINTAINER_SUBGROUP_ACCESS
}
end
def subgroup_creation_values
subgroup_creation_options.values
end
def subgroup_creation_string_values
subgroup_creation_string_options.keys
end
end
def human_access
Gitlab::Access.human_access(access_field)
end
def role_description
Gitlab::Access.role_description(access_field)
end
def human_access_with_none
Gitlab::Access.human_access_with_none(access_field)
end
def human_access_labeled
"#{s_('Default role')}: #{human_access}"
end
def owner?
access_field == OWNER
end
end
end
Gitlab::Access.prepend_mod_with('Gitlab::Access')