Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
GitLab
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
projects.thm.de
GitLab
Commits
cadef802
Commit
cadef802
authored
Jan 30, 2017
by
Oswaldo Ferreira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remain V3 endpoint unchanged
parent
cc24682b
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1895 additions
and
3 deletions
+1895
-3
lib/api/api.rb
lib/api/api.rb
+6
-1
lib/api/v3/projects.rb
lib/api/v3/projects.rb
+458
-0
spec/requests/api/v3/projects_spec.rb
spec/requests/api/v3/projects_spec.rb
+1424
-0
spec/support/api_helpers.rb
spec/support/api_helpers.rb
+7
-2
No files found.
lib/api/api.rb
View file @
cadef802
module
API
class
API
<
Grape
::
API
include
APIGuard
version
'v3'
,
using: :path
version
%w(v3 v4)
,
using: :path
version
'v3'
,
using: :path
do
mount
::
API
::
V3
::
Projects
end
before
{
allow_access_with_scope
:api
}
...
...
lib/api/v3/projects.rb
0 → 100644
View file @
cadef802
module
API
module
V3
class
Projects
<
Grape
::
API
include
PaginationParams
before
{
authenticate_non_get!
}
helpers
do
params
:optional_params
do
optional
:description
,
type:
String
,
desc:
'The description of the project'
optional
:issues_enabled
,
type:
Boolean
,
desc:
'Flag indication if the issue tracker is enabled'
optional
:merge_requests_enabled
,
type:
Boolean
,
desc:
'Flag indication if merge requests are enabled'
optional
:wiki_enabled
,
type:
Boolean
,
desc:
'Flag indication if the wiki is enabled'
optional
:builds_enabled
,
type:
Boolean
,
desc:
'Flag indication if builds are enabled'
optional
:snippets_enabled
,
type:
Boolean
,
desc:
'Flag indication if snippets are enabled'
optional
:shared_runners_enabled
,
type:
Boolean
,
desc:
'Flag indication if shared runners are enabled for that project'
optional
:container_registry_enabled
,
type:
Boolean
,
desc:
'Flag indication if the container registry is enabled for that project'
optional
:lfs_enabled
,
type:
Boolean
,
desc:
'Flag indication if Git LFS is enabled for that project'
optional
:public
,
type:
Boolean
,
desc:
'Create a public project. The same as visibility_level = 20.'
optional
:visibility_level
,
type:
Integer
,
values:
[
Gitlab
::
VisibilityLevel
::
PRIVATE
,
Gitlab
::
VisibilityLevel
::
INTERNAL
,
Gitlab
::
VisibilityLevel
::
PUBLIC
],
desc:
'Create a public project. The same as visibility_level = 20.'
optional
:public_builds
,
type:
Boolean
,
desc:
'Perform public builds'
optional
:request_access_enabled
,
type:
Boolean
,
desc:
'Allow users to request member access'
optional
:only_allow_merge_if_build_succeeds
,
type:
Boolean
,
desc:
'Only allow to merge if builds succeed'
optional
:only_allow_merge_if_all_discussions_are_resolved
,
type:
Boolean
,
desc:
'Only allow to merge if all discussions are resolved'
end
def
map_public_to_visibility_level
(
attrs
)
publik
=
attrs
.
delete
(
:public
)
if
!
publik
.
nil?
&&
!
attrs
[
:visibility_level
].
present?
# Since setting the public attribute to private could mean either
# private or internal, use the more conservative option, private.
attrs
[
:visibility_level
]
=
(
publik
==
true
)
?
Gitlab
::
VisibilityLevel
::
PUBLIC
:
Gitlab
::
VisibilityLevel
::
PRIVATE
end
attrs
end
end
resource
:projects
do
helpers
do
params
:collection_params
do
use
:sort_params
use
:filter_params
use
:pagination
optional
:simple
,
type:
Boolean
,
default:
false
,
desc:
'Return only the ID, URL, name, and path of each project'
end
params
:sort_params
do
optional
:order_by
,
type:
String
,
values:
%w[id name path created_at updated_at last_activity_at]
,
default:
'created_at'
,
desc:
'Return projects ordered by field'
optional
:sort
,
type:
String
,
values:
%w[asc desc]
,
default:
'desc'
,
desc:
'Return projects sorted in ascending and descending order'
end
params
:filter_params
do
optional
:archived
,
type:
Boolean
,
default:
false
,
desc:
'Limit by archived status'
optional
:visibility
,
type:
String
,
values:
%w[public internal private]
,
desc:
'Limit by visibility'
optional
:search
,
type:
String
,
desc:
'Return list of authorized projects matching the search criteria'
end
params
:statistics_params
do
optional
:statistics
,
type:
Boolean
,
default:
false
,
desc:
'Include project statistics'
end
params
:create_params
do
optional
:namespace_id
,
type:
Integer
,
desc:
'Namespace ID for the new project. Default to the user namespace.'
optional
:import_url
,
type:
String
,
desc:
'URL from which the project is imported'
end
def
present_projects
(
projects
,
options
=
{})
options
=
options
.
reverse_merge
(
with:
Entities
::
Project
,
current_user:
current_user
,
simple:
params
[
:simple
],
)
projects
=
filter_projects
(
projects
)
projects
=
projects
.
with_statistics
if
options
[
:statistics
]
options
[
:with
]
=
Entities
::
BasicProjectDetails
if
options
[
:simple
]
present
paginate
(
projects
),
options
end
end
desc
'Get a list of visible projects for authenticated user'
do
success
Entities
::
BasicProjectDetails
end
params
do
use
:collection_params
end
get
'/visible'
do
entity
=
current_user
?
Entities
::
ProjectWithAccess
:
Entities
::
BasicProjectDetails
present_projects
ProjectsFinder
.
new
.
execute
(
current_user
),
with:
entity
end
desc
'Get a projects list for authenticated user'
do
success
Entities
::
BasicProjectDetails
end
params
do
use
:collection_params
end
get
do
authenticate!
present_projects
current_user
.
authorized_projects
,
with:
Entities
::
ProjectWithAccess
end
desc
'Get an owned projects list for authenticated user'
do
success
Entities
::
BasicProjectDetails
end
params
do
use
:collection_params
use
:statistics_params
end
get
'/owned'
do
authenticate!
present_projects
current_user
.
owned_projects
,
with:
Entities
::
ProjectWithAccess
,
statistics:
params
[
:statistics
]
end
desc
'Gets starred project for the authenticated user'
do
success
Entities
::
BasicProjectDetails
end
params
do
use
:collection_params
end
get
'/starred'
do
authenticate!
present_projects
current_user
.
viewable_starred_projects
end
desc
'Get all projects for admin user'
do
success
Entities
::
BasicProjectDetails
end
params
do
use
:collection_params
use
:statistics_params
end
get
'/all'
do
authenticated_as_admin!
present_projects
Project
.
all
,
with:
Entities
::
ProjectWithAccess
,
statistics:
params
[
:statistics
]
end
desc
'Search for projects the current user has access to'
do
success
Entities
::
Project
end
params
do
requires
:query
,
type:
String
,
desc:
'The project name to be searched'
use
:sort_params
use
:pagination
end
get
"/search/:query"
,
requirements:
{
query:
/[^\/]+/
}
do
search_service
=
Search
::
GlobalService
.
new
(
current_user
,
search:
params
[
:query
]).
execute
projects
=
search_service
.
objects
(
'projects'
,
params
[
:page
])
projects
=
projects
.
reorder
(
params
[
:order_by
]
=>
params
[
:sort
])
present
paginate
(
projects
),
with:
Entities
::
Project
end
desc
'Create new project'
do
success
Entities
::
Project
end
params
do
requires
:name
,
type:
String
,
desc:
'The name of the project'
optional
:path
,
type:
String
,
desc:
'The path of the repository'
use
:optional_params
use
:create_params
end
post
do
attrs
=
map_public_to_visibility_level
(
declared_params
(
include_missing:
false
))
project
=
::
Projects
::
CreateService
.
new
(
current_user
,
attrs
).
execute
if
project
.
saved?
present
project
,
with:
Entities
::
Project
,
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
project
)
else
if
project
.
errors
[
:limit_reached
].
present?
error!
(
project
.
errors
[
:limit_reached
],
403
)
end
render_validation_error!
(
project
)
end
end
desc
'Create new project for a specified user. Only available to admin users.'
do
success
Entities
::
Project
end
params
do
requires
:name
,
type:
String
,
desc:
'The name of the project'
requires
:user_id
,
type:
Integer
,
desc:
'The ID of a user'
optional
:default_branch
,
type:
String
,
desc:
'The default branch of the project'
use
:optional_params
use
:create_params
end
post
"user/:user_id"
do
authenticated_as_admin!
user
=
User
.
find_by
(
id:
params
.
delete
(
:user_id
))
not_found!
(
'User'
)
unless
user
attrs
=
map_public_to_visibility_level
(
declared_params
(
include_missing:
false
))
project
=
::
Projects
::
CreateService
.
new
(
user
,
attrs
).
execute
if
project
.
saved?
present
project
,
with:
Entities
::
Project
,
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
project
)
else
render_validation_error!
(
project
)
end
end
end
params
do
requires
:id
,
type:
String
,
desc:
'The ID of a project'
end
resource
:projects
,
requirements:
{
id:
/[^\/]+/
}
do
desc
'Get a single project'
do
success
Entities
::
ProjectWithAccess
end
get
":id"
do
entity
=
current_user
?
Entities
::
ProjectWithAccess
:
Entities
::
BasicProjectDetails
present
user_project
,
with:
entity
,
current_user:
current_user
,
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
user_project
)
end
desc
'Get events for a single project'
do
success
Entities
::
Event
end
params
do
use
:pagination
end
get
":id/events"
do
present
paginate
(
user_project
.
events
.
recent
),
with:
Entities
::
Event
end
desc
'Fork new project for the current user or provided namespace.'
do
success
Entities
::
Project
end
params
do
optional
:namespace
,
type:
String
,
desc:
'The ID or name of the namespace that the project will be forked into'
end
post
'fork/:id'
do
fork_params
=
declared_params
(
include_missing:
false
)
namespace_id
=
fork_params
[
:namespace
]
if
namespace_id
.
present?
fork_params
[
:namespace
]
=
if
namespace_id
=~
/^\d+$/
Namespace
.
find_by
(
id:
namespace_id
)
else
Namespace
.
find_by_path_or_name
(
namespace_id
)
end
unless
fork_params
[
:namespace
]
&&
can?
(
current_user
,
:create_projects
,
fork_params
[
:namespace
])
not_found!
(
'Target Namespace'
)
end
end
forked_project
=
::
Projects
::
ForkService
.
new
(
user_project
,
current_user
,
fork_params
).
execute
if
forked_project
.
errors
.
any?
conflict!
(
forked_project
.
errors
.
messages
)
else
present
forked_project
,
with:
Entities
::
Project
,
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
forked_project
)
end
end
desc
'Update an existing project'
do
success
Entities
::
Project
end
params
do
optional
:name
,
type:
String
,
desc:
'The name of the project'
optional
:default_branch
,
type:
String
,
desc:
'The default branch of the project'
optional
:path
,
type:
String
,
desc:
'The path of the repository'
use
:optional_params
at_least_one_of
:name
,
:description
,
:issues_enabled
,
:merge_requests_enabled
,
:wiki_enabled
,
:builds_enabled
,
:snippets_enabled
,
:shared_runners_enabled
,
:container_registry_enabled
,
:lfs_enabled
,
:public
,
:visibility_level
,
:public_builds
,
:request_access_enabled
,
:only_allow_merge_if_build_succeeds
,
:only_allow_merge_if_all_discussions_are_resolved
,
:path
,
:default_branch
end
put
':id'
do
authorize_admin_project
attrs
=
map_public_to_visibility_level
(
declared_params
(
include_missing:
false
))
authorize!
:rename_project
,
user_project
if
attrs
[
:name
].
present?
authorize!
:change_visibility_level
,
user_project
if
attrs
[
:visibility_level
].
present?
result
=
::
Projects
::
UpdateService
.
new
(
user_project
,
current_user
,
attrs
).
execute
if
result
[
:status
]
==
:success
present
user_project
,
with:
Entities
::
Project
,
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
user_project
)
else
render_validation_error!
(
user_project
)
end
end
desc
'Archive a project'
do
success
Entities
::
Project
end
post
':id/archive'
do
authorize!
(
:archive_project
,
user_project
)
user_project
.
archive!
present
user_project
,
with:
Entities
::
Project
end
desc
'Unarchive a project'
do
success
Entities
::
Project
end
post
':id/unarchive'
do
authorize!
(
:archive_project
,
user_project
)
user_project
.
unarchive!
present
user_project
,
with:
Entities
::
Project
end
desc
'Star a project'
do
success
Entities
::
Project
end
post
':id/star'
do
if
current_user
.
starred?
(
user_project
)
not_modified!
else
current_user
.
toggle_star
(
user_project
)
user_project
.
reload
present
user_project
,
with:
Entities
::
Project
end
end
desc
'Unstar a project'
do
success
Entities
::
Project
end
delete
':id/star'
do
if
current_user
.
starred?
(
user_project
)
current_user
.
toggle_star
(
user_project
)
user_project
.
reload
present
user_project
,
with:
Entities
::
Project
else
not_modified!
end
end
desc
'Remove a project'
delete
":id"
do
authorize!
:remove_project
,
user_project
::
Projects
::
DestroyService
.
new
(
user_project
,
current_user
,
{}).
async_execute
end
desc
'Mark this project as forked from another'
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
authenticated_as_admin!
forked_from_project
=
find_project!
(
params
[
:forked_from_id
])
not_found!
(
"Source Project"
)
unless
forked_from_project
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
end
desc
'Remove a forked_from relationship'
delete
":id/fork"
do
authorize!
:remove_fork_project
,
user_project
if
user_project
.
forked?
user_project
.
forked_project_link
.
destroy
else
not_modified!
end
end
desc
'Share the project with a group'
do
success
Entities
::
ProjectGroupLink
end
params
do
requires
:group_id
,
type:
Integer
,
desc:
'The ID of a group'
requires
:group_access
,
type:
Integer
,
values:
Gitlab
::
Access
.
values
,
desc:
'The group access level'
optional
:expires_at
,
type:
Date
,
desc:
'Share expiration date'
end
post
":id/share"
do
authorize!
:admin_project
,
user_project
group
=
Group
.
find_by_id
(
params
[
:group_id
])
unless
group
&&
can?
(
current_user
,
:read_group
,
group
)
not_found!
(
'Group'
)
end
unless
user_project
.
allowed_to_share_with_group?
return
render_api_error!
(
"The project sharing with group is disabled"
,
400
)
end
link
=
user_project
.
project_group_links
.
new
(
declared_params
(
include_missing:
false
))
if
link
.
save
present
link
,
with:
Entities
::
ProjectGroupLink
else
render_api_error!
(
link
.
errors
.
full_messages
.
first
,
409
)
end
end
params
do
requires
:group_id
,
type:
Integer
,
desc:
'The ID of the group'
end
delete
":id/share/:group_id"
do
authorize!
:admin_project
,
user_project
link
=
user_project
.
project_group_links
.
find_by
(
group_id:
params
[
:group_id
])
not_found!
(
'Group Link'
)
unless
link
link
.
destroy
no_content!
end
desc
'Upload a file'
params
do
requires
:file
,
type:
File
,
desc:
'The file to be uploaded'
end
post
":id/uploads"
do
::
Projects
::
UploadService
.
new
(
user_project
,
params
[
:file
]).
execute
end
desc
'Get the users list of a project'
do
success
Entities
::
UserBasic
end
params
do
optional
:search
,
type:
String
,
desc:
'Return list of users matching the search criteria'
use
:pagination
end
get
':id/users'
do
users
=
user_project
.
team
.
users
users
=
users
.
search
(
params
[
:search
])
if
params
[
:search
].
present?
present
paginate
(
users
),
with:
Entities
::
UserBasic
end
end
end
end
end
spec/requests/api/v3/projects_spec.rb
0 → 100644
View file @
cadef802
This diff is collapsed.
Click to expand it.
spec/support/api_helpers.rb
View file @
cadef802
...
...
@@ -17,8 +17,8 @@ module ApiHelpers
# => "/api/v2/issues?foo=bar&private_token=..."
#
# Returns the relative path to the requested API resource
def
api
(
path
,
user
=
nil
)
"/api/
#{
API
::
API
.
version
}#{
path
}
"
+
def
api
(
path
,
user
=
nil
,
version:
API
::
API
.
version
)
"/api/
#{
version
}#{
path
}
"
+
# Normalize query string
(
path
.
index
(
'?'
)
?
''
:
'?'
)
+
...
...
@@ -31,6 +31,11 @@ def api(path, user = nil)
end
end
# Temporary helper method for simplifying V3 exclusive API specs
def
v3_api
(
path
,
user
=
nil
)
api
(
path
,
user
,
version:
'v3'
)
end
def
ci_api
(
path
,
user
=
nil
)
"/ci/api/v1/
#{
path
}
"
+
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment