@ -9,12 +9,12 @@ import (
"errors"
"errors"
"fmt"
"fmt"
"net/http"
"net/http"
"net/url"
"strings"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/migrations"
"code.gitea.io/gitea/modules/migrations"
@ -26,7 +26,7 @@ import (
)
)
// Migrate migrate remote git repository to gitea
// Migrate migrate remote git repository to gitea
func Migrate ( ctx * context . APIContext , form auth . MigrateRepoForm ) {
func Migrate ( ctx * context . APIContext , form api . MigrateRepoOptions ) {
// swagger:operation POST /repos/migrate repository repoMigrate
// swagger:operation POST /repos/migrate repository repoMigrate
// ---
// ---
// summary: Migrate a remote git repository
// summary: Migrate a remote git repository
@ -38,7 +38,7 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
// - name: body
// - name: body
// in: body
// in: body
// schema:
// schema:
// "$ref": "#/definitions/MigrateRepoForm "
// "$ref": "#/definitions/MigrateRepoOptions "
// responses:
// responses:
// "201":
// "201":
// "$ref": "#/responses/Repository"
// "$ref": "#/responses/Repository"
@ -47,21 +47,26 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
// "422":
// "422":
// "$ref": "#/responses/validationError"
// "$ref": "#/responses/validationError"
ctxUser := ctx . User
//get repoOwner
// Not equal means context user is an organization,
var (
// or is another user/organization if current user is admin.
repoOwner * models . User
if form . UID != ctxUser . ID {
err error
org , err := models . GetUserByID ( form . UID )
)
if len ( form . RepoOwner ) != 0 {
repoOwner , err = models . GetUserByName ( form . RepoOwner )
} else if form . RepoOwnerID != 0 {
repoOwner , err = models . GetUserByID ( form . RepoOwnerID )
} else {
repoOwner = ctx . User
}
if err != nil {
if err != nil {
if models . IsErrUserNotExist ( err ) {
if models . IsErrUserNotExist ( err ) {
ctx . Error ( http . StatusUnprocessableEntity , "" , err )
ctx . Error ( http . StatusUnprocessableEntity , "" , err )
} else {
} else {
ctx . Error ( http . StatusInternalServerError , "GetUserByID" , err )
ctx . Error ( http . StatusInternalServerError , "GetUser" , err )
}
}
return
return
}
}
ctxUser = org
}
if ctx . HasError ( ) {
if ctx . HasError ( ) {
ctx . Error ( http . StatusUnprocessableEntity , "" , ctx . GetErrMsg ( ) )
ctx . Error ( http . StatusUnprocessableEntity , "" , ctx . GetErrMsg ( ) )
@ -69,14 +74,14 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
}
}
if ! ctx . User . IsAdmin {
if ! ctx . User . IsAdmin {
if ! ctxUs er. IsOrganization ( ) && ctx . User . ID != ctxUs er. ID {
if ! repoOwn er. IsOrganization ( ) && ctx . User . ID != repoOwn er. ID {
ctx . Error ( http . StatusForbidden , "" , "Given user is not an organization." )
ctx . Error ( http . StatusForbidden , "" , "Given user is not an organization." )
return
return
}
}
if ctxUs er. IsOrganization ( ) {
if repoOwn er. IsOrganization ( ) {
// Check ownership of organization.
// Check ownership of organization.
isOwner , err := ctxUs er. IsOwnedBy ( ctx . User . ID )
isOwner , err := repoOwn er. IsOwnedBy ( ctx . User . ID )
if err != nil {
if err != nil {
ctx . Error ( http . StatusInternalServerError , "IsOwnedBy" , err )
ctx . Error ( http . StatusInternalServerError , "IsOwnedBy" , err )
return
return
@ -87,7 +92,7 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
}
}
}
}
remoteAddr , err := form . ParseRemoteAddr ( ctx . User )
remoteAddr , err := auth . ParseRemoteAddr ( form . CloneAddr , form . AuthUsername , form . AuthPassword , ctx . User )
if err != nil {
if err != nil {
if models . IsErrInvalidCloneAddr ( err ) {
if models . IsErrInvalidCloneAddr ( err ) {
addrErr := err . ( models . ErrInvalidCloneAddr )
addrErr := err . ( models . ErrInvalidCloneAddr )
@ -107,11 +112,7 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
return
return
}
}
var gitServiceType = api . PlainGitService
gitServiceType := convert . ToGitServiceType ( form . Service )
u , err := url . Parse ( remoteAddr )
if err == nil && strings . EqualFold ( u . Host , "github.com" ) {
gitServiceType = api . GithubService
}
if form . Mirror && setting . Repository . DisableMirrors {
if form . Mirror && setting . Repository . DisableMirrors {
ctx . Error ( http . StatusForbidden , "MirrorsGlobalDisabled" , fmt . Errorf ( "the site administrator has disabled mirrors" ) )
ctx . Error ( http . StatusForbidden , "MirrorsGlobalDisabled" , fmt . Errorf ( "the site administrator has disabled mirrors" ) )
@ -126,6 +127,7 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
Mirror : form . Mirror ,
Mirror : form . Mirror ,
AuthUsername : form . AuthUsername ,
AuthUsername : form . AuthUsername ,
AuthPassword : form . AuthPassword ,
AuthPassword : form . AuthPassword ,
AuthToken : form . AuthToken ,
Wiki : form . Wiki ,
Wiki : form . Wiki ,
Issues : form . Issues ,
Issues : form . Issues ,
Milestones : form . Milestones ,
Milestones : form . Milestones ,
@ -144,7 +146,7 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
opts . Releases = false
opts . Releases = false
}
}
repo , err := repo_module . CreateRepository ( ctx . User , ctxUs er, models . CreateRepoOptions {
repo , err := repo_module . CreateRepository ( ctx . User , repoOwn er, models . CreateRepoOptions {
Name : opts . RepoName ,
Name : opts . RepoName ,
Description : opts . Description ,
Description : opts . Description ,
OriginalURL : form . CloneAddr ,
OriginalURL : form . CloneAddr ,
@ -154,7 +156,7 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
Status : models . RepositoryBeingMigrated ,
Status : models . RepositoryBeingMigrated ,
} )
} )
if err != nil {
if err != nil {
handleMigrateError ( ctx , ctxUs er, remoteAddr , err )
handleMigrateError ( ctx , repoOwn er, remoteAddr , err )
return
return
}
}
@ -171,24 +173,24 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
if err == nil {
if err == nil {
repo . Status = models . RepositoryReady
repo . Status = models . RepositoryReady
if err := models . UpdateRepositoryCols ( repo , "status" ) ; err == nil {
if err := models . UpdateRepositoryCols ( repo , "status" ) ; err == nil {
notification . NotifyMigrateRepository ( ctx . User , ctxUs er, repo )
notification . NotifyMigrateRepository ( ctx . User , repoOwn er, repo )
return
return
}
}
}
}
if repo != nil {
if repo != nil {
if errDelete := models . DeleteRepository ( ctx . User , ctxUs er. ID , repo . ID ) ; errDelete != nil {
if errDelete := models . DeleteRepository ( ctx . User , repoOwn er. ID , repo . ID ) ; errDelete != nil {
log . Error ( "DeleteRepository: %v" , errDelete )
log . Error ( "DeleteRepository: %v" , errDelete )
}
}
}
}
} ( )
} ( )
if _ , err = migrations . MigrateRepository ( graceful . GetManager ( ) . HammerContext ( ) , ctx . User , ctxUs er. Name , opts ) ; err != nil {
if _ , err = migrations . MigrateRepository ( graceful . GetManager ( ) . HammerContext ( ) , ctx . User , repoOwn er. Name , opts ) ; err != nil {
handleMigrateError ( ctx , ctxUs er, remoteAddr , err )
handleMigrateError ( ctx , repoOwn er, remoteAddr , err )
return
return
}
}
log . Trace ( "Repository migrated: %s/%s" , ctxUs er. Name , form . RepoName )
log . Trace ( "Repository migrated: %s/%s" , repoOwn er. Name , form . RepoName )
ctx . JSON ( http . StatusCreated , repo . APIFormat ( models . AccessModeAdmin ) )
ctx . JSON ( http . StatusCreated , repo . APIFormat ( models . AccessModeAdmin ) )
}
}