d9bb4230cc
Added visibility_level icons to project view (rather than just text). Added public projects to search results. Added ability to restrict visibility levels standard users can set.
312 lines
11 KiB
Ruby
312 lines
11 KiB
Ruby
module API
|
|
# Projects API
|
|
class Projects < Grape::API
|
|
before { authenticate! }
|
|
|
|
resource :projects do
|
|
helpers do
|
|
def handle_project_member_errors(errors)
|
|
if errors[:project_access].any?
|
|
error!(errors[:project_access], 422)
|
|
end
|
|
not_found!
|
|
end
|
|
|
|
def map_public_to_visibility_level(attrs)
|
|
publik = attrs.delete(:public)
|
|
publik = [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(publik)
|
|
attrs[:visibility_level] = Gitlab::VisibilityLevel::PUBLIC if !attrs[:visibility_level].present? && publik == true
|
|
attrs
|
|
end
|
|
end
|
|
|
|
# Get a projects list for authenticated user
|
|
#
|
|
# Example Request:
|
|
# GET /projects
|
|
get do
|
|
@projects = paginate current_user.authorized_projects
|
|
present @projects, with: Entities::Project
|
|
end
|
|
|
|
# Get an owned projects list for authenticated user
|
|
#
|
|
# Example Request:
|
|
# GET /projects/owned
|
|
get '/owned' do
|
|
@projects = paginate current_user.owned_projects
|
|
present @projects, with: Entities::Project
|
|
end
|
|
|
|
# Get all projects for admin user
|
|
#
|
|
# Example Request:
|
|
# GET /projects/all
|
|
get '/all' do
|
|
authenticated_as_admin!
|
|
@projects = paginate Project
|
|
present @projects, with: Entities::Project
|
|
end
|
|
|
|
# Get a single project
|
|
#
|
|
# Parameters:
|
|
# id (required) - The ID of a project
|
|
# Example Request:
|
|
# GET /projects/:id
|
|
get ":id" do
|
|
present user_project, with: Entities::Project
|
|
end
|
|
|
|
# Get a single project events
|
|
#
|
|
# Parameters:
|
|
# id (required) - The ID of a project
|
|
# Example Request:
|
|
# GET /projects/:id
|
|
get ":id/events" do
|
|
limit = (params[:per_page] || 20).to_i
|
|
offset = (params[:page] || 0).to_i * limit
|
|
events = user_project.events.recent.limit(limit).offset(offset)
|
|
|
|
present events, with: Entities::Event
|
|
end
|
|
|
|
# Create new project
|
|
#
|
|
# Parameters:
|
|
# name (required) - name for new project
|
|
# description (optional) - short project description
|
|
# issues_enabled (optional)
|
|
# wall_enabled (optional)
|
|
# merge_requests_enabled (optional)
|
|
# wiki_enabled (optional)
|
|
# snippets_enabled (optional)
|
|
# namespace_id (optional) - defaults to user namespace
|
|
# public (optional) - if true same as setting visibility_level = 20
|
|
# visibility_level (optional) - 0 by default
|
|
# Example Request
|
|
# POST /projects
|
|
post do
|
|
required_attributes! [:name]
|
|
attrs = attributes_for_keys [:name,
|
|
:path,
|
|
:description,
|
|
:issues_enabled,
|
|
:wall_enabled,
|
|
:merge_requests_enabled,
|
|
:wiki_enabled,
|
|
:snippets_enabled,
|
|
:namespace_id,
|
|
:public,
|
|
:visibility_level]
|
|
attrs = map_public_to_visibility_level(attrs)
|
|
@project = ::Projects::CreateContext.new(current_user, attrs).execute
|
|
if @project.saved?
|
|
present @project, with: Entities::Project
|
|
else
|
|
if @project.errors[:limit_reached].present?
|
|
error!(@project.errors[:limit_reached], 403)
|
|
end
|
|
not_found!
|
|
end
|
|
end
|
|
|
|
# Create new project for a specified user. Only available to admin users.
|
|
#
|
|
# Parameters:
|
|
# user_id (required) - The ID of a user
|
|
# name (required) - name for new project
|
|
# description (optional) - short project description
|
|
# default_branch (optional) - 'master' by default
|
|
# issues_enabled (optional)
|
|
# wall_enabled (optional)
|
|
# merge_requests_enabled (optional)
|
|
# wiki_enabled (optional)
|
|
# snippets_enabled (optional)
|
|
# public (optional) - if true same as setting visibility_level = 20
|
|
# visibility_level (optional)
|
|
# Example Request
|
|
# POST /projects/user/:user_id
|
|
post "user/:user_id" do
|
|
authenticated_as_admin!
|
|
user = User.find(params[:user_id])
|
|
attrs = attributes_for_keys [:name,
|
|
:description,
|
|
:default_branch,
|
|
:issues_enabled,
|
|
:wall_enabled,
|
|
:merge_requests_enabled,
|
|
:wiki_enabled,
|
|
:snippets_enabled,
|
|
:public,
|
|
:visibility_level]
|
|
attrs = map_public_to_visibility_level(attrs)
|
|
@project = ::Projects::CreateContext.new(user, attrs).execute
|
|
if @project.saved?
|
|
present @project, with: Entities::Project
|
|
else
|
|
not_found!
|
|
end
|
|
end
|
|
|
|
# Remove project
|
|
#
|
|
# Parameters:
|
|
# id (required) - The ID of a project
|
|
# Example Request:
|
|
# DELETE /projects/:id
|
|
delete ":id" do
|
|
authorize! :remove_project, user_project
|
|
user_project.destroy
|
|
end
|
|
|
|
# Mark this project as forked from another
|
|
#
|
|
# Parameters:
|
|
# id: (required) - The ID of the project being marked as a fork
|
|
# forked_from_id: (required) - The ID of the project it was forked from
|
|
# Example Request:
|
|
# POST /projects/:id/fork/:forked_from_id
|
|
post ":id/fork/:forked_from_id" do
|
|
authenticated_as_admin!
|
|
forked_from_project = find_project(params[:forked_from_id])
|
|
unless forked_from_project.nil?
|
|
if user_project.forked_from_project.nil?
|
|
user_project.create_forked_project_link(forked_to_project_id: user_project.id, forked_from_project_id: forked_from_project.id)
|
|
else
|
|
render_api_error!("Project already forked", 409)
|
|
end
|
|
else
|
|
not_found!
|
|
end
|
|
|
|
end
|
|
|
|
# Remove a forked_from relationship
|
|
#
|
|
# Parameters:
|
|
# id: (required) - The ID of the project being marked as a fork
|
|
# Example Request:
|
|
# DELETE /projects/:id/fork
|
|
delete ":id/fork" do
|
|
authenticated_as_admin!
|
|
unless user_project.forked_project_link.nil?
|
|
user_project.forked_project_link.destroy
|
|
end
|
|
end
|
|
|
|
# Get a project team members
|
|
#
|
|
# Parameters:
|
|
# id (required) - The ID of a project
|
|
# query - Query string
|
|
# Example Request:
|
|
# GET /projects/:id/members
|
|
get ":id/members" do
|
|
if params[:query].present?
|
|
@members = paginate user_project.users.where("username LIKE ?", "%#{params[:query]}%")
|
|
else
|
|
@members = paginate user_project.users
|
|
end
|
|
present @members, with: Entities::ProjectMember, project: user_project
|
|
end
|
|
|
|
# Get a project team members
|
|
#
|
|
# Parameters:
|
|
# id (required) - The ID of a project
|
|
# user_id (required) - The ID of a user
|
|
# Example Request:
|
|
# GET /projects/:id/members/:user_id
|
|
get ":id/members/:user_id" do
|
|
@member = user_project.users.find params[:user_id]
|
|
present @member, with: Entities::ProjectMember, project: user_project
|
|
end
|
|
|
|
# Add a new project team member
|
|
#
|
|
# Parameters:
|
|
# id (required) - The ID of a project
|
|
# user_id (required) - The ID of a user
|
|
# access_level (required) - Project access level
|
|
# Example Request:
|
|
# POST /projects/:id/members
|
|
post ":id/members" do
|
|
authorize! :admin_project, user_project
|
|
required_attributes! [:user_id, :access_level]
|
|
|
|
# either the user is already a team member or a new one
|
|
team_member = user_project.team_member_by_id(params[:user_id])
|
|
if team_member.nil?
|
|
team_member = user_project.users_projects.new(
|
|
user_id: params[:user_id],
|
|
project_access: params[:access_level]
|
|
)
|
|
end
|
|
|
|
if team_member.save
|
|
@member = team_member.user
|
|
present @member, with: Entities::ProjectMember, project: user_project
|
|
else
|
|
handle_project_member_errors team_member.errors
|
|
end
|
|
end
|
|
|
|
# Update project team member
|
|
#
|
|
# Parameters:
|
|
# id (required) - The ID of a project
|
|
# user_id (required) - The ID of a team member
|
|
# access_level (required) - Project access level
|
|
# Example Request:
|
|
# PUT /projects/:id/members/:user_id
|
|
put ":id/members/:user_id" do
|
|
authorize! :admin_project, user_project
|
|
required_attributes! [:access_level]
|
|
|
|
team_member = user_project.users_projects.find_by_user_id(params[:user_id])
|
|
not_found!("User can not be found") if team_member.nil?
|
|
|
|
if team_member.update_attributes(project_access: params[:access_level])
|
|
@member = team_member.user
|
|
present @member, with: Entities::ProjectMember, project: user_project
|
|
else
|
|
handle_project_member_errors team_member.errors
|
|
end
|
|
end
|
|
|
|
# Remove a team member from project
|
|
#
|
|
# Parameters:
|
|
# id (required) - The ID of a project
|
|
# user_id (required) - The ID of a team member
|
|
# Example Request:
|
|
# DELETE /projects/:id/members/:user_id
|
|
delete ":id/members/:user_id" do
|
|
authorize! :admin_project, user_project
|
|
team_member = user_project.users_projects.find_by_user_id(params[:user_id])
|
|
unless team_member.nil?
|
|
team_member.destroy
|
|
else
|
|
{message: "Access revoked", id: params[:user_id].to_i}
|
|
end
|
|
end
|
|
|
|
# search for projects current_user has access to
|
|
#
|
|
# Parameters:
|
|
# query (required) - A string contained in the project name
|
|
# per_page (optional) - number of projects to return per page
|
|
# page (optional) - the page to retrieve
|
|
# Example Request:
|
|
# GET /projects/search/:query
|
|
get "/search/:query" do
|
|
ids = current_user.authorized_projects.map(&:id)
|
|
visibility_levels = [ Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::PUBLIC ]
|
|
projects = Project.where("(id in (?) OR visibility_level in (?)) AND (name LIKE (?))", ids, visibility_levels, "%#{params[:query]}%")
|
|
present paginate(projects), with: Entities::Project
|
|
end
|
|
end
|
|
end
|
|
end
|