Newer
Older
Dmitriy Zaporozhets
committed
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
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
Dmitriy Zaporozhets
committed
# 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
# 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) - false by default
# Example Request
# POST /projects
post do
Sebastian Ziebell
committed
required_attributes! [:name]
Dmitriy Zaporozhets
committed
attrs = attributes_for_keys [:name,
:path,
:description,
:issues_enabled,
:wall_enabled,
:merge_requests_enabled,
:wiki_enabled,
:snippets_enabled,
:namespace_id,
:public]
@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
# 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)
# 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]
@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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# 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
# id (required) - The ID of a project
# 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
# id (required) - The ID of a project
# user_id (required) - The ID of a user
# 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
Sebastian Ziebell
committed
required_attributes! [:user_id, :access_level]
Sebastian Ziebell
committed
# 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
# id (required) - The ID of a project
# user_id (required) - The ID of a team member
# access_level (required) - Project access level
# PUT /projects/:id/members/:user_id
put ":id/members/:user_id" do
Sebastian Ziebell
committed
required_attributes! [:access_level]
Sebastian Ziebell
committed
team_member = user_project.users_projects.find_by_user_id(params[:user_id])
Sebastian Ziebell
committed
not_found!("User can not be found") if team_member.nil?
Sebastian Ziebell
committed
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
# id (required) - The ID of a project
# user_id (required) - The ID of a team member
# DELETE /projects/:id/members/:user_id
delete ":id/members/:user_id" do
team_member = user_project.users_projects.find_by_user_id(params[:user_id])
unless team_member.nil?
team_member.destroy
{message: "Access revoked", id: params[:user_id].to_i}
# 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)
projects = Project.where("(id in (?) OR public = true) AND (name LIKE (?))", ids, "%#{params[:query]}%")
present paginate(projects), with: Entities::Project