Commit 392094d3 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Add feature categories to the API

This adds a feature category to API classes from ResourceLabelEvents
-> Projects
parent 342e8cf8
......@@ -9,9 +9,11 @@ module EE
class_methods do
extend ::Gitlab::Utils::Override
override :eventable_types
def eventable_types
[::Epic, *super]
override :feature_category_per_eventable_type
def feature_category_per_eventable_type
super.merge!(
::Epic => :issue_tracking
)
end
end
end
......
......@@ -10,7 +10,7 @@ module EE
desc 'Restore a project' do
success Entities::Project
end
post ':id/restore' do
post ':id/restore', feature_category: :authentication_and_authorization do
authorize!(:remove_project, user_project)
break not_found! unless user_project.feature_available?(:adjourned_deletion_for_projects_and_groups)
......@@ -21,7 +21,7 @@ module EE
render_api_error!(result[:message], 400)
end
end
segment ':id/audit_events' do
segment ':id/audit_events', feature_category: :audit_events do
before do
authorize! :admin_project, user_project
check_audit_events_available!(user_project)
......@@ -37,7 +37,7 @@ module EE
use :pagination
end
get '/' do
get '/', feature_category: :audit_events do
level = ::Gitlab::Audit::Levels::Project.new(project: user_project)
audit_events = AuditLogFinder.new(
level: level,
......@@ -53,7 +53,7 @@ module EE
params do
requires :audit_event_id, type: Integer, desc: 'The ID of the audit event'
end
get '/:audit_event_id' do
get '/:audit_event_id', feature_category: :audit_events do
level = ::Gitlab::Audit::Levels::Project.new(project: user_project)
# rubocop: disable CodeReuse/ActiveRecord
# This is not `find_by!` from ActiveRecord
......
......@@ -9,6 +9,8 @@ module API
include ::API::Helpers::Packages::BasicAuthHelpers::Constants
include ::Gitlab::Utils::StrongMemoize
feature_category :package_registry
content_type :json, 'application/json'
default_format :json
......
......@@ -29,6 +29,8 @@ module API
CONAN_FILES = (Gitlab::Regex::Packages::CONAN_RECIPE_FILES + Gitlab::Regex::Packages::CONAN_PACKAGE_FILES).freeze
included do
feature_category :package_registry
helpers ::API::Helpers::PackagesManagerClientsHelpers
helpers ::API::Helpers::Packages::Conan::ApiHelpers
helpers ::API::Helpers::RelatedResourcesHelpers
......
......@@ -26,6 +26,8 @@ module API
}.freeze
included do
feature_category :package_registry
helpers ::API::Helpers::PackagesHelpers
helpers ::API::Helpers::Packages::BasicAuthHelpers
......
......@@ -7,6 +7,8 @@ module API
file_name: API::NO_SLASH_URL_PART_REGEX
}.freeze
feature_category :package_registry
before do
require_packages_enabled!
authenticate!
......
......@@ -4,6 +4,8 @@ module API
helpers Gitlab::Golang
helpers ::API::Helpers::PackagesHelpers
feature_category :package_registry
# basic semver, except case encoded (A => !a)
MODULE_VERSION_REGEX = /v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([-.!a-z0-9]+))?(?:\+([-.!a-z0-9]+))?/.freeze
......
......@@ -8,6 +8,8 @@ module API
authorize_packages_access!(user_group)
end
feature_category :package_registry
helpers ::API::Helpers::PackagesHelpers
params do
......
......@@ -3,10 +3,13 @@
module API
module Helpers
module ResourceLabelEventsHelpers
def self.eventable_types
def self.feature_category_per_eventable_type
# This is a method instead of a constant, allowing EE to more easily
# extend it.
[Issue, MergeRequest]
{
Issue => :issue_tracking,
MergeRequest => :code_review
}
end
end
end
......
......@@ -5,6 +5,8 @@ module API
file_name: API::NO_SLASH_URL_PART_REGEX
}.freeze
feature_category :package_registry
content_type :md5, 'text/plain'
content_type :sha1, 'text/plain'
content_type :binary, 'application/octet-stream'
......
......@@ -5,6 +5,8 @@ module API
class NotificationSettings < ::API::Base
before { authenticate! }
feature_category :users
helpers ::API::Helpers::MembersHelpers
resource :notification_settings do
......
......@@ -4,6 +4,8 @@ module API
helpers ::API::Helpers::PackagesHelpers
helpers ::API::Helpers::Packages::DependencyProxyHelpers
feature_category :package_registry
NPM_ENDPOINT_REQUIREMENTS = {
package_name: API::NO_SLASH_URL_PART_REGEX
}.freeze
......
......@@ -10,6 +10,8 @@ module API
helpers ::API::Helpers::PackagesManagerClientsHelpers
helpers ::API::Helpers::Packages::BasicAuthHelpers
feature_category :package_registry
POSITIVE_INTEGER_REGEX = %r{\A[1-9]\d*\z}.freeze
NON_NEGATIVE_INTEGER_REGEX = %r{\A0|[1-9]\d*\z}.freeze
......
......@@ -8,6 +8,8 @@ module API
authorize_packages_access!(user_project)
end
feature_category :package_registry
helpers ::API::Helpers::PackagesHelpers
params do
......
......@@ -2,6 +2,8 @@
module API
class Pages < ::API::Base
feature_category :pages
before do
require_pages_config_enabled!
authenticated_with_can_read_all_resources!
......
......@@ -4,6 +4,8 @@ module API
class PagesDomains < ::API::Base
include PaginationParams
feature_category :pages
PAGES_DOMAINS_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(domain: API::NO_SLASH_URL_PART_REGEX)
before do
......
......@@ -6,6 +6,8 @@ module API
before { authenticate! }
feature_category :kubernetes_management
params do
requires :id, type: String, desc: 'The ID of the project'
end
......
......@@ -10,6 +10,8 @@ module API
before { authorize_read_container_images! }
feature_category :package_registry
params do
requires :id, type: String, desc: 'The ID of a project'
end
......
......@@ -6,6 +6,8 @@ module API
include APIGuard
helpers ::API::Helpers::EventsHelpers
feature_category :users
params do
requires :id, type: String, desc: 'The ID of a project'
end
......
......@@ -4,6 +4,8 @@ module API
class ProjectExport < ::API::Base
helpers Helpers::RateLimiter
feature_category :importers
before do
not_found! unless Gitlab::CurrentSettings.project_export_enabled?
authorize_admin_project
......
......@@ -7,6 +7,8 @@ module API
before { authenticate! }
before { authorize_admin_project }
feature_category :integrations
helpers do
params :project_hook_properties do
requires :url, type: String, desc: "The URL to send the request to"
......
......@@ -8,6 +8,8 @@ module API
helpers Helpers::FileUploadHelpers
helpers Helpers::RateLimiter
feature_category :importers
helpers do
def import_params
declared_params(include_missing: false)
......
......@@ -7,6 +7,8 @@ module API
before { authenticate! }
feature_category :issue_tracking
params do
requires :id, type: String, desc: 'The ID of a project'
end
......
......@@ -8,6 +8,8 @@ module API
authorize_packages_access!(user_project)
end
feature_category :package_registry
helpers ::API::Helpers::PackagesHelpers
params do
......
......@@ -6,6 +6,8 @@ module API
before { authenticated_as_admin! }
feature_category :gitaly
resource :project_repository_storage_moves do
desc 'Get a list of all project repository storage moves' do
detail 'This feature was introduced in GitLab 13.0.'
......
......@@ -11,6 +11,8 @@ module API
before { authenticate_non_get! }
feature_category :projects, ['/projects/:id/custom_attributes', '/projects/:id/custom_attributes/:key']
helpers do
# EE::API::Projects would override this method
def apply_filters(projects)
......@@ -150,7 +152,7 @@ module API
use :statistics_params
use :with_custom_attributes
end
get ":user_id/projects" do
get ":user_id/projects", feature_category: :projects do
user = find_user(params[:user_id])
not_found!('User') unless user
......@@ -167,7 +169,7 @@ module API
use :collection_params
use :statistics_params
end
get ":user_id/starred_projects" do
get ":user_id/starred_projects", feature_category: :projects do
user = find_user(params[:user_id])
not_found!('User') unless user
......@@ -187,7 +189,7 @@ module API
use :statistics_params
use :with_custom_attributes
end
get do
get feature_category: :projects do
present_projects load_projects
end
......@@ -234,7 +236,7 @@ module API
use :create_params
end
# rubocop: disable CodeReuse/ActiveRecord
post "user/:user_id" do
post "user/:user_id", feature_category: :projects do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/21139')
authenticated_as_admin!
user = User.find_by(id: params.delete(:user_id))
......@@ -270,7 +272,7 @@ module API
optional :license, type: Boolean, default: false,
desc: 'Include project license data'
end
get ":id" do
get ":id", feature_category: :projects do
options = {
with: current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails,
current_user: current_user,
......@@ -294,7 +296,7 @@ module API
optional :path, type: String, desc: 'The path that will be assigned to the fork'
optional :name, type: String, desc: 'The name that will be assigned to the fork'
end
post ':id/fork' do
post ':id/fork', feature_category: :source_code_management do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42284')
not_found! unless can?(current_user, :fork_project, user_project)
......@@ -332,14 +334,14 @@ module API
use :collection_params
use :with_custom_attributes
end
get ':id/forks' do
get ':id/forks', feature_category: :source_code_management do
forks = ForkProjectsFinder.new(user_project, params: project_finder_params, current_user: current_user).execute
present_projects forks, request_scope: user_project
end
desc 'Check pages access of this project'
get ':id/pages_access' do
get ':id/pages_access', feature_category: :pages do
authorize! :read_pages_content, user_project unless user_project.public_pages?
status 200
end
......@@ -357,7 +359,7 @@ module API
at_least_one_of(*Helpers::ProjectsHelpers.update_params_at_least_one_of)
end
put ':id' do
put ':id', feature_category: :projects do
authorize_admin_project
attrs = declared_params(include_missing: false)
authorize! :rename_project, user_project if attrs[:name].present?
......@@ -381,7 +383,7 @@ module API
desc 'Archive a project' do
success Entities::Project
end
post ':id/archive' do
post ':id/archive', feature_category: :projects do
authorize!(:archive_project, user_project)
::Projects::UpdateService.new(user_project, current_user, archived: true).execute
......@@ -392,7 +394,7 @@ module API
desc 'Unarchive a project' do
success Entities::Project
end
post ':id/unarchive' do
post ':id/unarchive', feature_category: :projects do
authorize!(:archive_project, user_project)
::Projects::UpdateService.new(user_project, current_user, archived: false).execute
......@@ -403,7 +405,7 @@ module API
desc 'Star a project' do
success Entities::Project
end
post ':id/star' do
post ':id/star', feature_category: :projects do
if current_user.starred?(user_project)
not_modified!
else
......@@ -417,7 +419,7 @@ module API
desc 'Unstar a project' do
success Entities::Project
end
post ':id/unstar' do
post ':id/unstar', feature_category: :projects do
if current_user.starred?(user_project)
current_user.toggle_star(user_project)
user_project.reset
......@@ -435,21 +437,21 @@ module API
optional :search, type: String, desc: 'Return list of users matching the search criteria'
use :pagination
end
get ':id/starrers' do
get ':id/starrers', feature_category: :projects do
starrers = UsersStarProjectsFinder.new(user_project, params, current_user: current_user).execute
present paginate(starrers), with: Entities::UserStarsProject
end
desc 'Get languages in project repository'
get ':id/languages' do
get ':id/languages', feature_category: :source_code_management do
::Projects::RepositoryLanguagesService
.new(user_project, current_user)
.execute.map { |lang| [lang.name, lang.share] }.to_h
end
desc 'Delete a project'
delete ":id" do
delete ":id", feature_category: :projects do
authorize! :remove_project, user_project
delete_project(user_project)
......@@ -459,7 +461,7 @@ module API
params do
requires :forked_from_id, type: String, desc: 'The ID of the project it was forked from'
end
post ":id/fork/:forked_from_id" do
post ":id/fork/:forked_from_id", feature_category: :source_code_management do
authorize! :admin_project, user_project
fork_from_project = find_project!(params[:forked_from_id])
......@@ -478,7 +480,7 @@ module API
end
desc 'Remove a forked_from relationship'
delete ":id/fork" do
delete ":id/fork", feature_category: :source_code_management do
authorize! :remove_fork_project, user_project
result = destroy_conditionally!(user_project) do
......@@ -496,7 +498,7 @@ module API
requires :group_access, type: Integer, values: Gitlab::Access.values, as: :link_group_access, desc: 'The group access level'
optional :expires_at, type: Date, desc: 'Share expiration date'
end
post ":id/share" do
post ":id/share", feature_category: :authentication_and_authorization do
authorize! :admin_project, user_project
group = Group.find_by_id(params[:group_id])
......@@ -518,7 +520,7 @@ module API
requires :group_id, type: Integer, desc: 'The ID of the group'
end
# rubocop: disable CodeReuse/ActiveRecord
delete ":id/share/:group_id" do
delete ":id/share/:group_id", feature_category: :authentication_and_authorization do
authorize! :admin_project, user_project
link = user_project.project_group_links.find_by(group_id: params[:group_id])
......@@ -535,7 +537,7 @@ module API
# TODO: remove rubocop disable - https://gitlab.com/gitlab-org/gitlab/issues/14960
requires :file, type: File, desc: 'The file to be uploaded' # rubocop:disable Scalability/FileUploads
end
post ":id/uploads" do
post ":id/uploads", feature_category: :not_owned do
upload = UploadService.new(user_project, params[:file]).execute
present upload, with: Entities::ProjectUpload
......@@ -549,7 +551,7 @@ module API
optional :skip_users, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'Filter out users with the specified IDs'
use :pagination
end
get ':id/users' do
get ':id/users', feature_category: :authentication_and_authorization do
users = DeclarativePolicy.subject_scope { user_project.team.users }
users = users.search(params[:search]) if params[:search].present?
users = users.where_not_in(params[:skip_users]) if params[:skip_users].present?
......@@ -560,7 +562,7 @@ module API
desc 'Start the housekeeping task for a project' do
detail 'This feature was introduced in GitLab 9.0.'
end
post ':id/housekeeping' do
post ':id/housekeeping', feature_category: :source_code_management do
authorize_admin_project
begin
......@@ -574,7 +576,7 @@ module API
params do
requires :namespace, type: String, desc: 'The ID or path of the new namespace'
end
put ":id/transfer" do
put ":id/transfer", feature_category: :projects do
authorize! :change_namespace, user_project
namespace = find_namespace!(params[:namespace])
......
......@@ -12,6 +12,8 @@ module API
helpers ::API::Helpers::Packages::BasicAuthHelpers
include ::API::Helpers::Packages::BasicAuthHelpers::Constants
feature_category :package_registry
default_format :json
rescue_from ArgumentError do |e|
......
......@@ -7,7 +7,7 @@ module API
before { authenticate! }
Helpers::ResourceLabelEventsHelpers.eventable_types.each do |eventable_type|
Helpers::ResourceLabelEventsHelpers.feature_category_per_eventable_type.each do |eventable_type, feature_category|
parent_type = eventable_type.parent_class.to_s.underscore
eventables_str = eventable_type.to_s.underscore.pluralize
......@@ -24,7 +24,7 @@ module API
use :pagination
end
get ":id/#{eventables_str}/:eventable_id/resource_label_events" do
get ":id/#{eventables_str}/:eventable_id/resource_label_events", feature_category: feature_category do
eventable = find_noteable(eventable_type, params[:eventable_id])
events = eventable.resource_label_events.inc_relations
......@@ -40,7 +40,7 @@ module API
requires :event_id, type: String, desc: 'The ID of a resource label event'
requires :eventable_id, types: [Integer, String], desc: 'The ID of the eventable'
end
get ":id/#{eventables_str}/:eventable_id/resource_label_events/:event_id" do
get ":id/#{eventables_str}/:eventable_id/resource_label_events/:event_id", feature_category: feature_category do
eventable = find_noteable(eventable_type, params[:eventable_id])
event = eventable.resource_label_events.find(params[:event_id])
......
......@@ -7,7 +7,10 @@ module API
before { authenticate! }
[Issue, MergeRequest].each do |eventable_type|
{
Issue => :issue_tracking,
MergeRequest => :code_review
}.each do |eventable_type, feature_category|
parent_type = eventable_type.parent_class.to_s.underscore
eventables_str = eventable_type.to_s.underscore.pluralize
......@@ -23,7 +26,7 @@ module API
use :pagination
end
get ":id/#{eventables_str}/:eventable_id/resource_milestone_events" do
get ":id/#{eventables_str}/:eventable_id/resource_milestone_events", feature_category: feature_category do
eventable = find_noteable(eventable_type, params[:eventable_id])
events = ResourceMilestoneEventFinder.new(current_user, eventable).execute
......@@ -38,7 +41,7 @@ module API
requires :event_id, type: String, desc: 'The ID of a resource milestone event'
requires :eventable_id, types: [Integer, String], desc: 'The ID of the eventable'
end
get ":id/#{eventables_str}/:eventable_id/resource_milestone_events/:event_id" do
get ":id/#{eventables_str}/:eventable_id/resource_milestone_events/:event_id", feature_category: feature_category do
eventable = find_noteable(eventable_type, params[:eventable_id])
event = eventable.resource_milestone_events.find(params[:event_id])
......
......@@ -7,7 +7,10 @@ module API
before { authenticate! }
[Issue, MergeRequest].each do |eventable_class|
{
Issue => :issue_tracking,
MergeRequest => :code_review
}.each do |eventable_class, feature_category|
eventable_name = eventable_class.to_s.underscore
params do
......@@ -22,7 +25,7 @@ module API
use :pagination
end
get ":id/#{eventable_name.pluralize}/:eventable_iid/resource_state_events" do
get ":id/#{eventable_name.pluralize}/:eventable_iid/resource_state_events", feature_category: feature_category do
eventable = find_noteable(eventable_class, params[:eventable_iid])
events = ResourceStateEventFinder.new(current_user, eventable).execute
......@@ -37,7 +40,7 @@ module API
requires :eventable_iid, types: Integer, desc: "The IID of the #{eventable_name}"
requires :event_id, type: Integer, desc: 'The ID of a resource state event'
end
get ":id/#{eventable_name.pluralize}/:eventable_iid/resource_state_events/:event_id" do
get ":id/#{eventable_name.pluralize}/:eventable_iid/resource_state_events/:event_id", feature_category: feature_category do
eventable = find_noteable(eventable_class, params[:eventable_iid])
event = ResourceStateEventFinder.new(current_user, eventable).find(params[:event_id])
......
......@@ -37,7 +37,15 @@ RSpec.describe 'Every API endpoint' do
::API::Lint, ::API::Markdown, ::API::Members, ::API::MergeRequestDiffs,
::API::MergeRequests, ::API::MergeRequestApprovals, ::API::Metrics::Dashboard::Annotations,
::API::Metrics::UserStarredDashboards, ::API::Namespaces, ::API::Notes,
::API::Discussions
::API::Discussions, ::API::ResourceLabelEvents, ::API::ResourceMilestoneEvents,
::API::ResourceStateEvents, ::API::NotificationSettings, ::API::ProjectPackages,
::API::GroupPackages, ::API::PackageFiles, ::API::NugetPackages, ::API::PypiPackages,
::API::ComposerPackages, ::API::ConanProjectPackages, ::API::ConanInstancePackages,
::API::DebianGroupPackages, ::API::DebianProjectPackages, ::API::MavenPackages,
::API::NpmPackages, ::API::GenericPackages, ::API::GoProxy, ::API::Pages,
::API::PagesDomains, ::API::ProjectClusters, ::API::ProjectContainerRepositories,
::API::ProjectEvents, ::API::ProjectExport, ::API::ProjectImport, ::API::ProjectHooks,
::API::ProjectMilestones, ::API::ProjectRepositoryStorageMoves, ::API::Projects
]
next unless completed_classes.include?(klass)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment