2019-06-01 18:00:21 +03:00
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package private
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
2019-12-26 14:29:45 +03:00
"time"
2019-06-01 18:00:21 +03:00
"code.gitea.io/gitea/modules/setting"
)
// Git environment variables
const (
GitAlternativeObjectDirectories = "GIT_ALTERNATE_OBJECT_DIRECTORIES"
GitObjectDirectory = "GIT_OBJECT_DIRECTORY"
GitQuarantinePath = "GIT_QUARANTINE_PATH"
)
// HookOptions represents the options for the Hook calls
type HookOptions struct {
2019-12-26 14:29:45 +03:00
OldCommitIDs [ ] string
NewCommitIDs [ ] string
RefFullNames [ ] string
2019-06-01 18:00:21 +03:00
UserID int64
UserName string
GitObjectDirectory string
GitAlternativeObjectDirectories string
2019-08-14 12:25:05 +03:00
GitQuarantinePath string
2019-07-01 04:18:13 +03:00
ProtectedBranchID int64
2019-10-21 11:21:45 +03:00
IsDeployKey bool
2019-06-01 18:00:21 +03:00
}
2019-12-26 14:29:45 +03:00
// HookPostReceiveResult represents an individual result from PostReceive
type HookPostReceiveResult struct {
Results [ ] HookPostReceiveBranchResult
RepoWasEmpty bool
Err string
}
// HookPostReceiveBranchResult represents an individual branch result from PostReceive
type HookPostReceiveBranchResult struct {
Message bool
Create bool
Branch string
URL string
}
2019-06-01 18:00:21 +03:00
// HookPreReceive check whether the provided commits are allowed
func HookPreReceive ( ownerName , repoName string , opts HookOptions ) ( int , string ) {
2019-12-26 14:29:45 +03:00
reqURL := setting . LocalURL + fmt . Sprintf ( "api/internal/hook/pre-receive/%s/%s" ,
2019-06-01 18:00:21 +03:00
url . PathEscape ( ownerName ) ,
url . PathEscape ( repoName ) ,
)
2019-12-26 14:29:45 +03:00
req := newInternalRequest ( reqURL , "POST" )
req = req . Header ( "Content-Type" , "application/json" )
jsonBytes , _ := json . Marshal ( opts )
req . Body ( jsonBytes )
req . SetTimeout ( 60 * time . Second , time . Duration ( 60 + len ( opts . OldCommitIDs ) ) * time . Second )
resp , err := req . Response ( )
2019-06-01 18:00:21 +03:00
if err != nil {
return http . StatusInternalServerError , fmt . Sprintf ( "Unable to contact gitea: %v" , err . Error ( ) )
}
defer resp . Body . Close ( )
if resp . StatusCode != http . StatusOK {
return resp . StatusCode , decodeJSONError ( resp ) . Err
}
return http . StatusOK , ""
}
// HookPostReceive updates services and users
2019-12-26 14:29:45 +03:00
func HookPostReceive ( ownerName , repoName string , opts HookOptions ) ( * HookPostReceiveResult , string ) {
reqURL := setting . LocalURL + fmt . Sprintf ( "api/internal/hook/post-receive/%s/%s" ,
2019-06-01 18:00:21 +03:00
url . PathEscape ( ownerName ) ,
url . PathEscape ( repoName ) ,
2019-12-26 14:29:45 +03:00
)
2019-06-01 18:00:21 +03:00
2019-12-26 14:29:45 +03:00
req := newInternalRequest ( reqURL , "POST" )
req = req . Header ( "Content-Type" , "application/json" )
req . SetTimeout ( 60 * time . Second , time . Duration ( 60 + len ( opts . OldCommitIDs ) ) * time . Second )
jsonBytes , _ := json . Marshal ( opts )
req . Body ( jsonBytes )
resp , err := req . Response ( )
2019-06-01 18:00:21 +03:00
if err != nil {
return nil , fmt . Sprintf ( "Unable to contact gitea: %v" , err . Error ( ) )
}
defer resp . Body . Close ( )
if resp . StatusCode != http . StatusOK {
return nil , decodeJSONError ( resp ) . Err
}
2019-12-26 14:29:45 +03:00
res := & HookPostReceiveResult { }
_ = json . NewDecoder ( resp . Body ) . Decode ( res )
2019-06-01 18:00:21 +03:00
return res , ""
}
2019-12-26 14:29:45 +03:00
// SetDefaultBranch will set the default branch to the provided branch for the provided repository
func SetDefaultBranch ( ownerName , repoName , branch string ) error {
reqURL := setting . LocalURL + fmt . Sprintf ( "api/internal/hook/set-default-branch/%s/%s/%s" ,
url . PathEscape ( ownerName ) ,
url . PathEscape ( repoName ) ,
url . PathEscape ( branch ) ,
)
req := newInternalRequest ( reqURL , "POST" )
req = req . Header ( "Content-Type" , "application/json" )
req . SetTimeout ( 60 * time . Second , 60 * time . Second )
resp , err := req . Response ( )
if err != nil {
return fmt . Errorf ( "Unable to contact gitea: %v" , err )
}
defer resp . Body . Close ( )
if resp . StatusCode != http . StatusOK {
return fmt . Errorf ( "Error returned from gitea: %v" , decodeJSONError ( resp ) . Err )
}
return nil
}