2014-08-26 14:11:15 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2015-12-05 01:16:42 +03:00
package repo
2014-08-26 14:11:15 +04:00
import (
"path"
2016-11-11 12:39:44 +03:00
api "code.gitea.io/sdk/gitea"
2014-11-15 01:11:30 +03:00
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers/api/v1/convert"
2014-08-26 14:11:15 +04:00
)
2016-11-24 10:04:31 +03:00
// Search repositories via options
// see https://github.com/gogits/go-gogs-client/wiki/Repositories#search-repositories
2016-03-14 01:49:16 +03:00
func Search ( ctx * context . APIContext ) {
2016-03-11 23:33:12 +03:00
opts := & models . SearchRepoOptions {
Keyword : path . Base ( ctx . Query ( "q" ) ) ,
2016-07-04 12:27:06 +03:00
OwnerID : ctx . QueryInt64 ( "uid" ) ,
PageSize : convert . ToCorrectPageSize ( ctx . QueryInt ( "limit" ) ) ,
2014-08-26 14:11:15 +04:00
}
2014-10-25 15:50:19 +04:00
// Check visibility.
2016-03-11 23:33:12 +03:00
if ctx . IsSigned && opts . OwnerID > 0 {
2016-07-23 20:08:22 +03:00
if ctx . User . ID == opts . OwnerID {
2016-03-11 23:33:12 +03:00
opts . Private = true
2014-10-25 15:50:19 +04:00
} else {
2016-03-11 23:33:12 +03:00
u , err := models . GetUserByID ( opts . OwnerID )
2014-10-25 15:50:19 +04:00
if err != nil {
ctx . JSON ( 500 , map [ string ] interface { } {
"ok" : false ,
"error" : err . Error ( ) ,
} )
return
}
2016-07-23 20:08:22 +03:00
if u . IsOrganization ( ) && u . IsOwnedBy ( ctx . User . ID ) {
2016-03-11 23:33:12 +03:00
opts . Private = true
2014-10-25 15:50:19 +04:00
}
// FIXME: how about collaborators?
}
}
2016-07-04 12:27:06 +03:00
repos , count , err := models . SearchRepositoryByName ( opts )
2014-08-26 14:11:15 +04:00
if err != nil {
ctx . JSON ( 500 , map [ string ] interface { } {
"ok" : false ,
"error" : err . Error ( ) ,
} )
return
}
2014-11-15 01:11:30 +03:00
results := make ( [ ] * api . Repository , len ( repos ) )
2014-08-26 14:11:15 +04:00
for i := range repos {
if err = repos [ i ] . GetOwner ( ) ; err != nil {
ctx . JSON ( 500 , map [ string ] interface { } {
"ok" : false ,
"error" : err . Error ( ) ,
} )
return
}
2014-11-15 01:11:30 +03:00
results [ i ] = & api . Repository {
2016-03-14 06:20:22 +03:00
ID : repos [ i ] . ID ,
2014-11-13 10:32:18 +03:00
FullName : path . Join ( repos [ i ] . Owner . Name , repos [ i ] . Name ) ,
2014-08-26 14:11:15 +04:00
}
}
2016-07-04 12:27:06 +03:00
ctx . SetLinkHeader ( int ( count ) , setting . API . MaxResponseItems )
2014-12-13 04:30:32 +03:00
ctx . JSON ( 200 , map [ string ] interface { } {
2014-08-26 14:11:15 +04:00
"ok" : true ,
"data" : results ,
} )
}
2014-08-29 07:24:37 +04:00
2016-11-24 10:04:31 +03:00
// ListMyRepos list all my repositories
// see https://github.com/gogits/go-gogs-client/wiki/Repositories#list-your-repositories
2016-03-14 01:49:16 +03:00
func ListMyRepos ( ctx * context . APIContext ) {
2016-07-24 09:32:46 +03:00
ownRepos , err := models . GetUserRepositories ( ctx . User . ID , true , 1 , ctx . User . NumRepos )
2015-08-28 14:06:18 +03:00
if err != nil {
2016-03-14 01:49:16 +03:00
ctx . Error ( 500 , "GetRepositories" , err )
2015-08-28 14:06:18 +03:00
return
}
numOwnRepos := len ( ownRepos )
2015-11-14 01:37:02 +03:00
accessibleRepos , err := ctx . User . GetRepositoryAccesses ( )
2015-08-28 14:06:18 +03:00
if err != nil {
2016-03-14 01:49:16 +03:00
ctx . Error ( 500 , "GetRepositoryAccesses" , err )
2015-08-28 14:06:18 +03:00
return
}
repos := make ( [ ] * api . Repository , numOwnRepos + len ( accessibleRepos ) )
for i := range ownRepos {
2016-08-14 14:17:26 +03:00
repos [ i ] = ownRepos [ i ] . APIFormat ( & api . Permission { true , true , true } )
2015-08-28 14:06:18 +03:00
}
i := numOwnRepos
for repo , access := range accessibleRepos {
2016-08-14 14:17:26 +03:00
repos [ i ] = repo . APIFormat ( & api . Permission {
2016-11-07 19:20:37 +03:00
Admin : access >= models . AccessModeAdmin ,
Push : access >= models . AccessModeWrite ,
2015-08-28 14:06:18 +03:00
Pull : true ,
} )
i ++
}
ctx . JSON ( 200 , & repos )
}
2016-11-24 10:04:31 +03:00
// CreateUserRepo create a repository for a user
2016-03-14 01:49:16 +03:00
func CreateUserRepo ( ctx * context . APIContext , owner * models . User , opt api . CreateRepoOption ) {
2015-08-28 13:33:09 +03:00
repo , err := models . CreateRepository ( owner , models . CreateRepoOptions {
Name : opt . Name ,
Description : opt . Description ,
2015-08-28 14:06:18 +03:00
Gitignores : opt . Gitignores ,
2015-08-28 13:33:09 +03:00
License : opt . License ,
2015-08-28 14:06:18 +03:00
Readme : opt . Readme ,
IsPrivate : opt . Private ,
AutoInit : opt . AutoInit ,
2015-08-28 13:33:09 +03:00
} )
2014-12-13 04:30:32 +03:00
if err != nil {
2015-08-08 12:10:34 +03:00
if models . IsErrRepoAlreadyExist ( err ) ||
2015-03-27 00:11:47 +03:00
models . IsErrNameReserved ( err ) ||
models . IsErrNamePatternNotAllowed ( err ) {
2016-03-14 01:49:16 +03:00
ctx . Error ( 422 , "" , err )
2014-12-13 04:30:32 +03:00
} else {
if repo != nil {
2016-07-23 20:08:22 +03:00
if err = models . DeleteRepository ( ctx . User . ID , repo . ID ) ; err != nil {
2014-12-13 04:30:32 +03:00
log . Error ( 4 , "DeleteRepository: %v" , err )
}
}
2016-03-14 01:49:16 +03:00
ctx . Error ( 500 , "CreateRepository" , err )
2014-12-13 04:30:32 +03:00
}
return
}
2016-08-14 14:17:26 +03:00
ctx . JSON ( 201 , repo . APIFormat ( & api . Permission { true , true , true } ) )
2014-12-13 04:30:32 +03:00
}
2016-11-24 10:04:31 +03:00
// Create create one repository of mine
// see https://github.com/gogits/go-gogs-client/wiki/Repositories#create
2016-03-14 01:49:16 +03:00
func Create ( ctx * context . APIContext , opt api . CreateRepoOption ) {
2014-12-13 04:30:32 +03:00
// Shouldn't reach this condition, but just in case.
if ctx . User . IsOrganization ( ) {
2016-03-14 01:49:16 +03:00
ctx . Error ( 422 , "" , "not allowed creating repository for organization" )
2014-12-13 04:30:32 +03:00
return
}
2015-12-18 06:57:41 +03:00
CreateUserRepo ( ctx , ctx . User , opt )
2014-12-13 04:30:32 +03:00
}
2016-11-24 10:04:31 +03:00
// CreateOrgRepo create one repository of the organization
2016-03-14 01:49:16 +03:00
func CreateOrgRepo ( ctx * context . APIContext , opt api . CreateRepoOption ) {
2014-12-13 04:30:32 +03:00
org , err := models . GetOrgByName ( ctx . Params ( ":org" ) )
if err != nil {
2015-08-05 06:14:17 +03:00
if models . IsErrUserNotExist ( err ) {
2016-03-14 01:49:16 +03:00
ctx . Error ( 422 , "" , err )
2014-12-13 04:30:32 +03:00
} else {
2016-03-14 01:49:16 +03:00
ctx . Error ( 500 , "GetOrgByName" , err )
2014-12-13 04:30:32 +03:00
}
return
}
2016-07-23 20:08:22 +03:00
if ! org . IsOwnedBy ( ctx . User . ID ) {
2016-03-14 01:49:16 +03:00
ctx . Error ( 403 , "" , "Given user is not owner of organization." )
2014-12-13 04:30:32 +03:00
return
}
2015-12-18 06:57:41 +03:00
CreateUserRepo ( ctx , org , opt )
2014-12-13 04:30:32 +03:00
}
2016-11-24 10:04:31 +03:00
// Migrate migrate remote git repository to gitea
// see https://github.com/gogits/go-gogs-client/wiki/Repositories#migrate
2016-03-14 01:49:16 +03:00
func Migrate ( ctx * context . APIContext , form auth . MigrateRepoForm ) {
2015-09-03 13:17:33 +03:00
ctxUser := ctx . User
2015-11-25 08:55:37 +03:00
// Not equal means context user is an organization,
// or is another user/organization if current user is admin.
2016-11-27 09:03:59 +03:00
if form . UID != ctxUser . ID {
org , err := models . GetUserByID ( form . UID )
2014-08-29 13:31:53 +04:00
if err != nil {
2015-08-05 06:14:17 +03:00
if models . IsErrUserNotExist ( err ) {
2016-03-14 01:49:16 +03:00
ctx . Error ( 422 , "" , err )
2015-02-22 17:49:25 +03:00
} else {
2016-03-14 01:49:16 +03:00
ctx . Error ( 500 , "GetUserByID" , err )
2015-02-22 17:49:25 +03:00
}
2014-08-29 07:24:37 +04:00
return
}
ctxUser = org
}
if ctx . HasError ( ) {
2016-03-14 01:49:16 +03:00
ctx . Error ( 422 , "" , ctx . GetErrMsg ( ) )
2014-08-29 07:24:37 +04:00
return
}
2015-11-25 08:55:37 +03:00
if ctxUser . IsOrganization ( ) && ! ctx . User . IsAdmin {
2014-08-29 07:24:37 +04:00
// Check ownership of organization.
2016-07-23 20:08:22 +03:00
if ! ctxUser . IsOwnedBy ( ctx . User . ID ) {
2016-03-14 01:49:16 +03:00
ctx . Error ( 403 , "" , "Given user is not owner of organization." )
2014-08-29 07:24:37 +04:00
return
}
}
2015-11-04 02:40:52 +03:00
remoteAddr , err := form . ParseRemoteAddr ( ctx . User )
if err != nil {
if models . IsErrInvalidCloneAddr ( err ) {
addrErr := err . ( models . ErrInvalidCloneAddr )
switch {
case addrErr . IsURLError :
2016-03-14 01:49:16 +03:00
ctx . Error ( 422 , "" , err )
2015-11-04 02:40:52 +03:00
case addrErr . IsPermissionDenied :
2016-03-14 01:49:16 +03:00
ctx . Error ( 422 , "" , "You are not allowed to import local repositories." )
2015-11-04 02:40:52 +03:00
case addrErr . IsInvalidPath :
2016-03-14 01:49:16 +03:00
ctx . Error ( 422 , "" , "Invalid local path, it does not exist or not a directory." )
2015-11-04 02:40:52 +03:00
default :
2016-03-14 01:49:16 +03:00
ctx . Error ( 500 , "ParseRemoteAddr" , "Unknown error type (ErrInvalidCloneAddr): " + err . Error ( ) )
2015-11-04 02:40:52 +03:00
}
} else {
2016-03-14 01:49:16 +03:00
ctx . Error ( 500 , "ParseRemoteAddr" , err )
2015-02-22 17:49:25 +03:00
}
2014-08-29 07:24:37 +04:00
return
}
2015-10-25 11:26:26 +03:00
repo , err := models . MigrateRepository ( ctxUser , models . MigrateRepoOptions {
Name : form . RepoName ,
Description : form . Description ,
IsPrivate : form . Private || setting . Repository . ForcePrivate ,
IsMirror : form . Mirror ,
RemoteAddr : remoteAddr ,
} )
2015-02-22 17:49:25 +03:00
if err != nil {
if repo != nil {
2016-07-23 20:08:22 +03:00
if errDelete := models . DeleteRepository ( ctxUser . ID , repo . ID ) ; errDelete != nil {
2015-02-22 17:49:25 +03:00
log . Error ( 4 , "DeleteRepository: %v" , errDelete )
}
2014-08-29 07:24:37 +04:00
}
2016-03-14 01:49:16 +03:00
ctx . Error ( 500 , "MigrateRepository" , models . HandleCloneUserCredentials ( err . Error ( ) , true ) )
2015-02-22 17:49:25 +03:00
return
2014-08-29 07:24:37 +04:00
}
2015-02-22 17:49:25 +03:00
log . Trace ( "Repository migrated: %s/%s" , ctxUser . Name , form . RepoName )
2016-08-14 14:17:26 +03:00
ctx . JSON ( 201 , repo . APIFormat ( & api . Permission { true , true , true } ) )
2014-08-29 07:24:37 +04:00
}
2015-10-04 18:09:16 +03:00
2016-11-24 10:04:31 +03:00
// Get get one repository
// see https://github.com/gogits/go-gogs-client/wiki/Repositories#get
2016-03-14 01:49:16 +03:00
func Get ( ctx * context . APIContext ) {
2016-11-15 01:33:58 +03:00
repo := ctx . Repo . Repository
2016-08-14 14:17:26 +03:00
ctx . JSON ( 200 , repo . APIFormat ( & api . Permission { true , true , true } ) )
2015-10-23 00:46:07 +03:00
}
2016-10-03 13:35:42 +03:00
// GetByID returns a single Repository
func GetByID ( ctx * context . APIContext ) {
repo , err := models . GetRepositoryByID ( ctx . ParamsInt64 ( ":id" ) )
if err != nil {
if models . IsErrRepoNotExist ( err ) {
ctx . Status ( 404 )
} else {
ctx . Error ( 500 , "GetRepositoryByID" , err )
}
return
}
ctx . JSON ( 200 , repo . APIFormat ( & api . Permission { true , true , true } ) )
}
2016-11-24 10:04:31 +03:00
// Delete delete one repository
// see https://github.com/gogits/go-gogs-client/wiki/Repositories#delete
2016-03-14 01:49:16 +03:00
func Delete ( ctx * context . APIContext ) {
2016-11-15 01:33:58 +03:00
owner := ctx . Repo . Owner
repo := ctx . Repo . Repository
2015-10-04 18:09:16 +03:00
2016-07-23 20:08:22 +03:00
if owner . IsOrganization ( ) && ! owner . IsOwnedBy ( ctx . User . ID ) {
2016-03-14 01:49:16 +03:00
ctx . Error ( 403 , "" , "Given user is not owner of organization." )
2015-10-04 18:09:16 +03:00
return
}
2016-07-23 20:08:22 +03:00
if err := models . DeleteRepository ( owner . ID , repo . ID ) ; err != nil {
2016-03-14 01:49:16 +03:00
ctx . Error ( 500 , "DeleteRepository" , err )
2015-10-04 18:09:16 +03:00
return
}
2015-10-23 00:46:07 +03:00
log . Trace ( "Repository deleted: %s/%s" , owner . Name , repo . Name )
2015-10-04 18:09:16 +03:00
ctx . Status ( 204 )
}