2017-04-19 11:45:01 +08:00
// Copyright 2017 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 includes all internal routes. The package name internal is ideal but Golang is not allowed, so we use private as package name instead.
package private
import (
2021-01-26 23:36:53 +08:00
"net/http"
"reflect"
2017-04-19 11:45:01 +08:00
"strings"
2021-01-26 23:36:53 +08:00
"code.gitea.io/gitea/modules/context"
2019-12-24 08:11:12 +08:00
"code.gitea.io/gitea/modules/log"
2019-12-26 19:29:45 +08:00
"code.gitea.io/gitea/modules/private"
2017-04-19 11:45:01 +08:00
"code.gitea.io/gitea/modules/setting"
2021-01-26 23:36:53 +08:00
"code.gitea.io/gitea/modules/web"
2017-05-04 13:42:02 +08:00
2021-01-26 23:36:53 +08:00
"gitea.com/go-chi/binding"
2022-10-11 16:57:37 +08:00
chi_middleware "github.com/go-chi/chi/v5/middleware"
2017-04-19 11:45:01 +08:00
)
// CheckInternalToken check internal token is set
2021-01-26 23:36:53 +08:00
func CheckInternalToken ( next http . Handler ) http . Handler {
return http . HandlerFunc ( func ( w http . ResponseWriter , req * http . Request ) {
tokens := req . Header . Get ( "Authorization" )
2021-05-15 23:32:09 +08:00
fields := strings . SplitN ( tokens , " " , 2 )
2022-10-02 01:26:33 +08:00
if setting . InternalToken == "" {
log . Warn ( ` The INTERNAL_TOKEN setting is missing from the configuration file: %q, internal API can't work. ` , setting . CustomConf )
http . Error ( w , http . StatusText ( http . StatusForbidden ) , http . StatusForbidden )
return
}
2021-01-26 23:36:53 +08:00
if len ( fields ) != 2 || fields [ 0 ] != "Bearer" || fields [ 1 ] != setting . InternalToken {
log . Debug ( "Forbidden attempt to access internal url: Authorization header: %s" , tokens )
http . Error ( w , http . StatusText ( http . StatusForbidden ) , http . StatusForbidden )
} else {
next . ServeHTTP ( w , req )
}
} )
}
// bind binding an obj to a handler
func bind ( obj interface { } ) http . HandlerFunc {
2022-01-21 01:46:10 +08:00
tp := reflect . TypeOf ( obj )
2021-01-26 23:36:53 +08:00
for tp . Kind ( ) == reflect . Ptr {
tp = tp . Elem ( )
2017-04-19 11:45:01 +08:00
}
2021-01-26 23:36:53 +08:00
return web . Wrap ( func ( ctx * context . PrivateContext ) {
2022-01-21 01:46:10 +08:00
theObj := reflect . New ( tp ) . Interface ( ) // create a new form obj for every request but not use obj directly
2021-01-26 23:36:53 +08:00
binding . Bind ( ctx . Req , theObj )
web . SetForm ( ctx , theObj )
} )
2017-04-19 11:45:01 +08:00
}
2021-01-26 23:36:53 +08:00
// Routes registers all internal APIs routes to web application.
2017-04-19 11:45:01 +08:00
// These APIs will be invoked by internal commands for example `gitea serv` and etc.
2021-01-26 23:36:53 +08:00
func Routes ( ) * web . Route {
2022-01-21 01:46:10 +08:00
r := web . NewRoute ( )
2021-01-26 23:36:53 +08:00
r . Use ( context . PrivateContexter ( ) )
r . Use ( CheckInternalToken )
2022-10-11 16:57:37 +08:00
// Log the real ip address of the request from SSH is really helpful for diagnosing sometimes.
// Since internal API will be sent only from Gitea sub commands and it's under control (checked by InternalToken), we can trust the headers.
r . Use ( chi_middleware . RealIP )
2021-01-26 23:36:53 +08:00
r . Post ( "/ssh/authorized_keys" , AuthorizedPublicKeyByContent )
r . Post ( "/ssh/{id}/update/{repoid}" , UpdatePublicKeyInRepo )
2021-05-22 05:37:16 +08:00
r . Post ( "/ssh/log" , bind ( private . SSHLogOption { } ) , SSHLog )
2021-09-16 21:34:54 +08:00
r . Post ( "/hook/pre-receive/{owner}/{repo}" , RepoAssignment , bind ( private . HookOptions { } ) , HookPreReceive )
2022-01-20 07:26:57 +08:00
r . Post ( "/hook/post-receive/{owner}/{repo}" , context . OverrideContext , bind ( private . HookOptions { } ) , HookPostReceive )
r . Post ( "/hook/proc-receive/{owner}/{repo}" , context . OverrideContext , RepoAssignment , bind ( private . HookOptions { } ) , HookProcReceive )
2021-09-16 21:34:54 +08:00
r . Post ( "/hook/set-default-branch/{owner}/{repo}/{branch}" , RepoAssignment , SetDefaultBranch )
2021-01-26 23:36:53 +08:00
r . Get ( "/serv/none/{keyid}" , ServNoCommand )
r . Get ( "/serv/command/{keyid}/{owner}/{repo}" , ServCommand )
r . Post ( "/manager/shutdown" , Shutdown )
r . Post ( "/manager/restart" , Restart )
r . Post ( "/manager/flush-queues" , bind ( private . FlushOptions { } ) , FlushQueues )
r . Post ( "/manager/pause-logging" , PauseLogging )
r . Post ( "/manager/resume-logging" , ResumeLogging )
r . Post ( "/manager/release-and-reopen-logging" , ReleaseReopenLogging )
2022-06-24 18:49:47 +08:00
r . Post ( "/manager/set-log-sql" , SetLogSQL )
2021-01-26 23:36:53 +08:00
r . Post ( "/manager/add-logger" , bind ( private . LoggerOptions { } ) , AddLogger )
r . Post ( "/manager/remove-logger/{group}/{name}" , RemoveLogger )
2022-04-01 01:01:43 +08:00
r . Get ( "/manager/processes" , Processes )
2021-01-26 23:36:53 +08:00
r . Post ( "/mail/send" , SendEmail )
2021-05-10 15:57:45 +08:00
r . Post ( "/restore_repo" , RestoreRepo )
2021-01-26 23:36:53 +08:00
return r
2017-04-19 11:45:01 +08:00
}