2017-04-25 03:24:51 -04: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 routes
import (
2019-04-02 08:48:31 +01:00
"bytes"
2018-05-19 16:12:37 +02:00
"encoding/gob"
"net/http"
2017-04-25 03:24:51 -04:00
"os"
"path"
2019-04-02 08:48:31 +01:00
"text/template"
2018-02-03 23:37:05 +01:00
"time"
2017-04-25 03:24:51 -04:00
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/context"
2019-01-23 08:56:51 +00:00
"code.gitea.io/gitea/modules/gzip"
2017-04-25 03:24:51 -04:00
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log"
2018-11-05 06:20:00 +03:00
"code.gitea.io/gitea/modules/metrics"
2017-04-25 03:24:51 -04:00
"code.gitea.io/gitea/modules/options"
"code.gitea.io/gitea/modules/public"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/validation"
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/routers/admin"
apiv1 "code.gitea.io/gitea/routers/api/v1"
"code.gitea.io/gitea/routers/dev"
"code.gitea.io/gitea/routers/org"
"code.gitea.io/gitea/routers/private"
"code.gitea.io/gitea/routers/repo"
"code.gitea.io/gitea/routers/user"
2018-05-17 06:05:00 +02:00
userSetting "code.gitea.io/gitea/routers/user/setting"
2017-04-25 03:24:51 -04:00
2019-07-17 09:04:37 +08:00
// to registers all internal adapters
_ "code.gitea.io/gitea/modules/session"
2019-08-23 09:40:30 -07:00
"gitea.com/macaron/binding"
"gitea.com/macaron/cache"
"gitea.com/macaron/captcha"
2019-08-26 04:33:06 -07:00
"gitea.com/macaron/cors"
2019-08-23 09:40:30 -07:00
"gitea.com/macaron/csrf"
"gitea.com/macaron/i18n"
"gitea.com/macaron/macaron"
"gitea.com/macaron/session"
"gitea.com/macaron/toolbox"
2018-11-05 06:20:00 +03:00
"github.com/prometheus/client_golang/prometheus"
2018-05-19 16:12:37 +02:00
"github.com/tstranex/u2f"
2017-04-25 03:24:51 -04:00
)
2019-04-02 08:48:31 +01:00
type routerLoggerOptions struct {
Ctx * macaron . Context
Identity * string
Start * time . Time
ResponseWriter * macaron . ResponseWriter
}
func setupAccessLogger ( m * macaron . Macaron ) {
logger := log . GetLogger ( "access" )
logTemplate , _ := template . New ( "log" ) . Parse ( setting . AccessLogTemplate )
m . Use ( func ( ctx * macaron . Context ) {
start := time . Now ( )
ctx . Next ( )
identity := "-"
if val , ok := ctx . Data [ "SignedUserName" ] ; ok {
if stringVal , ok := val . ( string ) ; ok && stringVal != "" {
identity = stringVal
}
}
rw := ctx . Resp . ( macaron . ResponseWriter )
buf := bytes . NewBuffer ( [ ] byte { } )
2019-06-12 21:41:28 +02:00
err := logTemplate . Execute ( buf , routerLoggerOptions {
2019-04-02 08:48:31 +01:00
Ctx : ctx ,
Identity : & identity ,
Start : & start ,
ResponseWriter : & rw ,
} )
2019-06-12 21:41:28 +02:00
if err != nil {
log . Error ( "Could not set up macaron access logger: %v" , err . Error ( ) )
}
2019-04-02 08:48:31 +01:00
2019-06-12 21:41:28 +02:00
err = logger . SendLog ( log . INFO , "" , "" , 0 , buf . String ( ) , "" )
if err != nil {
log . Error ( "Could not set up macaron access logger: %v" , err . Error ( ) )
}
2019-04-02 08:48:31 +01:00
} )
2019-02-06 03:06:41 +00:00
}
2019-05-14 10:55:52 +08:00
// RouterHandler is a macaron handler that will log the routing to the default gitea log
func RouterHandler ( level log . Level ) func ( ctx * macaron . Context ) {
return func ( ctx * macaron . Context ) {
start := time . Now ( )
2019-06-12 21:41:28 +02:00
_ = log . GetLogger ( "router" ) . Log ( 0 , level , "Started %s %s for %s" , log . ColoredMethod ( ctx . Req . Method ) , ctx . Req . RequestURI , ctx . RemoteAddr ( ) )
2019-05-14 10:55:52 +08:00
rw := ctx . Resp . ( macaron . ResponseWriter )
ctx . Next ( )
status := rw . Status ( )
2019-06-12 21:41:28 +02:00
_ = log . GetLogger ( "router" ) . Log ( 0 , level , "Completed %s %s %v %s in %v" , log . ColoredMethod ( ctx . Req . Method ) , ctx . Req . RequestURI , log . ColoredStatus ( status ) , log . ColoredStatus ( status , http . StatusText ( rw . Status ( ) ) ) , log . ColoredTime ( time . Since ( start ) ) )
2019-05-14 10:55:52 +08:00
}
}
2017-04-25 03:24:51 -04:00
// NewMacaron initializes Macaron instance.
func NewMacaron ( ) * macaron . Macaron {
2018-05-19 16:12:37 +02:00
gob . Register ( & u2f . Challenge { } )
2019-02-06 03:06:41 +00:00
var m * macaron . Macaron
if setting . RedirectMacaronLog {
2019-04-02 08:48:31 +01:00
loggerAsWriter := log . NewLoggerAsWriter ( "INFO" , log . GetLogger ( "macaron" ) )
2019-02-06 03:06:41 +00:00
m = macaron . NewWithLogger ( loggerAsWriter )
2019-04-02 08:48:31 +01:00
if ! setting . DisableRouterLog && setting . RouterLogLevel != log . NONE {
2019-05-14 10:55:52 +08:00
if log . GetLogger ( "router" ) . GetLevel ( ) <= setting . RouterLogLevel {
m . Use ( RouterHandler ( setting . RouterLogLevel ) )
}
2019-02-06 03:06:41 +00:00
}
} else {
m = macaron . New ( )
if ! setting . DisableRouterLog {
m . Use ( macaron . Logger ( ) )
}
2017-04-25 03:24:51 -04:00
}
2019-04-02 08:48:31 +01:00
// Access Logger is similar to Router Log but more configurable and by default is more like the NCSA Common Log format
if setting . EnableAccessLog {
setupAccessLogger ( m )
}
2017-04-25 03:24:51 -04:00
m . Use ( macaron . Recovery ( ) )
if setting . EnableGzip {
2019-01-23 08:56:51 +00:00
m . Use ( gzip . Middleware ( ) )
2017-04-25 03:24:51 -04:00
}
if setting . Protocol == setting . FCGI {
m . SetURLPrefix ( setting . AppSubURL )
}
m . Use ( public . Custom (
& public . Options {
2018-02-03 23:37:05 +01:00
SkipLogging : setting . DisableRouterLog ,
ExpiresAfter : time . Hour * 6 ,
2017-04-25 03:24:51 -04:00
} ,
) )
m . Use ( public . Static (
& public . Options {
2018-02-03 23:37:05 +01:00
Directory : path . Join ( setting . StaticRootPath , "public" ) ,
SkipLogging : setting . DisableRouterLog ,
ExpiresAfter : time . Hour * 6 ,
2017-04-25 03:24:51 -04:00
} ,
) )
2018-02-03 23:37:05 +01:00
m . Use ( public . StaticHandler (
2017-04-25 03:24:51 -04:00
setting . AvatarUploadPath ,
2018-02-03 23:37:05 +01:00
& public . Options {
Prefix : "avatars" ,
SkipLogging : setting . DisableRouterLog ,
ExpiresAfter : time . Hour * 6 ,
2017-04-25 03:24:51 -04:00
} ,
) )
2019-05-30 05:22:26 +03:00
m . Use ( public . StaticHandler (
setting . RepositoryAvatarUploadPath ,
& public . Options {
Prefix : "repo-avatars" ,
SkipLogging : setting . DisableRouterLog ,
ExpiresAfter : time . Hour * 6 ,
} ,
) )
2017-04-25 03:24:51 -04:00
2018-07-28 02:19:01 +02:00
m . Use ( templates . HTMLRenderer ( ) )
2017-04-25 03:24:51 -04:00
models . InitMailRender ( templates . Mailer ( ) )
localeNames , err := options . Dir ( "locale" )
if err != nil {
2019-04-02 08:48:31 +01:00
log . Fatal ( "Failed to list locale files: %v" , err )
2017-04-25 03:24:51 -04:00
}
localFiles := make ( map [ string ] [ ] byte )
for _ , name := range localeNames {
localFiles [ name ] , err = options . Locale ( name )
if err != nil {
2019-04-02 08:48:31 +01:00
log . Fatal ( "Failed to load %s locale file. %v" , name , err )
2017-04-25 03:24:51 -04:00
}
}
m . Use ( i18n . I18n ( i18n . Options {
2019-07-12 06:57:31 -07:00
SubURL : setting . AppSubURL ,
Files : localFiles ,
Langs : setting . Langs ,
Names : setting . Names ,
DefaultLang : "en-US" ,
Redirect : false ,
CookieDomain : setting . SessionConfig . Domain ,
2017-04-25 03:24:51 -04:00
} ) )
m . Use ( cache . Cacher ( cache . Options {
2017-10-26 04:37:33 +03:00
Adapter : setting . CacheService . Adapter ,
AdapterConfig : setting . CacheService . Conn ,
Interval : setting . CacheService . Interval ,
2017-04-25 03:24:51 -04:00
} ) )
m . Use ( captcha . Captchaer ( captcha . Options {
SubURL : setting . AppSubURL ,
} ) )
m . Use ( session . Sessioner ( setting . SessionConfig ) )
m . Use ( csrf . Csrfer ( csrf . Options {
2018-08-14 22:16:37 +02:00
Secret : setting . SecretKey ,
Cookie : setting . CSRFCookieName ,
SetCookie : true ,
Secure : setting . SessionConfig . Secure ,
2019-07-12 06:57:31 -07:00
CookieHttpOnly : setting . CSRFCookieHTTPOnly ,
2018-08-14 22:16:37 +02:00
Header : "X-Csrf-Token" ,
2019-07-12 06:57:31 -07:00
CookieDomain : setting . SessionConfig . Domain ,
2018-08-14 22:16:37 +02:00
CookiePath : setting . AppSubURL ,
2017-04-25 03:24:51 -04:00
} ) )
m . Use ( toolbox . Toolboxer ( m , toolbox . Options {
HealthCheckFuncs : [ ] * toolbox . HealthCheckFuncDesc {
{
Desc : "Database connection" ,
Func : models . Ping ,
} ,
} ,
2018-09-30 01:44:06 +03:00
DisableDebug : ! setting . EnablePprof ,
2017-04-25 03:24:51 -04:00
} ) )
m . Use ( context . Contexter ( ) )
2019-01-30 22:00:00 +00:00
// OK we are now set-up enough to allow us to create a nicer recovery than
// the default macaron recovery
m . Use ( context . Recovery ( ) )
2018-10-30 15:08:49 +00:00
m . SetAutoHead ( true )
2017-04-25 03:24:51 -04:00
return m
}
// RegisterRoutes routes routes to Macaron
func RegisterRoutes ( m * macaron . Macaron ) {
reqSignIn := context . Toggle ( & context . ToggleOptions { SignInRequired : true } )
ignSignIn := context . Toggle ( & context . ToggleOptions { SignInRequired : setting . Service . RequireSignInView } )
ignSignInAndCsrf := context . Toggle ( & context . ToggleOptions { DisableCSRF : true } )
reqSignOut := context . Toggle ( & context . ToggleOptions { SignOutRequired : true } )
bindIgnErr := binding . BindIgnErr
validation . AddBindingRules ( )
2017-08-19 17:34:49 +02:00
openIDSignInEnabled := func ( ctx * context . Context ) {
if ! setting . Service . EnableOpenIDSignIn {
ctx . Error ( 403 )
return
}
}
openIDSignUpEnabled := func ( ctx * context . Context ) {
if ! setting . Service . EnableOpenIDSignUp {
ctx . Error ( 403 )
return
}
}
2017-04-25 03:24:51 -04:00
m . Use ( user . GetNotificationCount )
// FIXME: not all routes need go through same middlewares.
// Especially some AJAX requests, we can reduce middleware number to improve performance.
// Routers.
// for health check
m . Head ( "/" , func ( ) string {
return ""
} )
2018-05-24 15:51:28 -04:00
m . Get ( "/" , routers . Home )
2017-04-25 03:24:51 -04:00
m . Group ( "/explore" , func ( ) {
m . Get ( "" , func ( ctx * context . Context ) {
ctx . Redirect ( setting . AppSubURL + "/explore/repos" )
} )
m . Get ( "/repos" , routers . ExploreRepos )
m . Get ( "/users" , routers . ExploreUsers )
m . Get ( "/organizations" , routers . ExploreOrganizations )
2018-03-16 22:04:33 +08:00
m . Get ( "/code" , routers . ExploreCode )
2017-04-25 03:24:51 -04:00
} , ignSignIn )
m . Combo ( "/install" , routers . InstallInit ) . Get ( routers . Install ) .
Post ( bindIgnErr ( auth . InstallForm { } ) , routers . InstallPost )
m . Get ( "/^:type(issues|pulls)$" , reqSignIn , user . Issues )
// ***** START: User *****
m . Group ( "/user" , func ( ) {
m . Get ( "/login" , user . SignIn )
m . Post ( "/login" , bindIgnErr ( auth . SignInForm { } ) , user . SignInPost )
2017-08-19 17:34:49 +02:00
m . Group ( "" , func ( ) {
2017-04-25 03:24:51 -04:00
m . Combo ( "/login/openid" ) .
Get ( user . SignInOpenID ) .
Post ( bindIgnErr ( auth . SignInOpenIDForm { } ) , user . SignInOpenIDPost )
2017-08-19 17:34:49 +02:00
} , openIDSignInEnabled )
m . Group ( "/openid" , func ( ) {
m . Combo ( "/connect" ) .
Get ( user . ConnectOpenID ) .
Post ( bindIgnErr ( auth . ConnectOpenIDForm { } ) , user . ConnectOpenIDPost )
m . Group ( "/register" , func ( ) {
m . Combo ( "" ) .
Get ( user . RegisterOpenID , openIDSignUpEnabled ) .
2017-04-25 03:24:51 -04:00
Post ( bindIgnErr ( auth . SignUpOpenIDForm { } ) , user . RegisterOpenIDPost )
2017-08-19 17:34:49 +02:00
} , openIDSignUpEnabled )
} , openIDSignInEnabled )
2017-04-25 03:24:51 -04:00
m . Get ( "/sign_up" , user . SignUp )
m . Post ( "/sign_up" , bindIgnErr ( auth . RegisterForm { } ) , user . SignUpPost )
m . Group ( "/oauth2" , func ( ) {
m . Get ( "/:provider" , user . SignInOAuth )
m . Get ( "/:provider/callback" , user . SignInOAuthCallback )
} )
m . Get ( "/link_account" , user . LinkAccount )
m . Post ( "/link_account_signin" , bindIgnErr ( auth . SignInForm { } ) , user . LinkAccountPostSignIn )
m . Post ( "/link_account_signup" , bindIgnErr ( auth . RegisterForm { } ) , user . LinkAccountPostRegister )
m . Group ( "/two_factor" , func ( ) {
m . Get ( "" , user . TwoFactor )
m . Post ( "" , bindIgnErr ( auth . TwoFactorAuthForm { } ) , user . TwoFactorPost )
m . Get ( "/scratch" , user . TwoFactorScratch )
m . Post ( "/scratch" , bindIgnErr ( auth . TwoFactorScratchAuthForm { } ) , user . TwoFactorScratchPost )
} )
2018-05-19 16:12:37 +02:00
m . Group ( "/u2f" , func ( ) {
m . Get ( "" , user . U2F )
m . Get ( "/challenge" , user . U2FChallenge )
m . Post ( "/sign" , bindIgnErr ( u2f . SignResponse { } ) , user . U2FSign )
} )
2017-04-25 03:24:51 -04:00
} , reqSignOut )
2019-03-08 17:42:50 +01:00
m . Group ( "/login/oauth" , func ( ) {
m . Get ( "/authorize" , bindIgnErr ( auth . AuthorizationForm { } ) , user . AuthorizeOAuth )
m . Post ( "/grant" , bindIgnErr ( auth . GrantApplicationForm { } ) , user . GrantApplicationOAuth )
// TODO manage redirection
m . Post ( "/authorize" , bindIgnErr ( auth . AuthorizationForm { } ) , user . AuthorizeOAuth )
} , ignSignInAndCsrf , reqSignIn )
m . Post ( "/login/oauth/access_token" , bindIgnErr ( auth . AccessTokenForm { } ) , ignSignInAndCsrf , user . AccessTokenOAuth )
2017-04-25 03:24:51 -04:00
m . Group ( "/user/settings" , func ( ) {
2018-05-17 06:05:00 +02:00
m . Get ( "" , userSetting . Profile )
m . Post ( "" , bindIgnErr ( auth . UpdateProfileForm { } ) , userSetting . ProfilePost )
2018-09-13 13:04:25 +01:00
m . Get ( "/change_password" , user . MustChangePassword )
m . Post ( "/change_password" , bindIgnErr ( auth . MustChangePasswordForm { } ) , user . MustChangePasswordPost )
2018-05-17 06:05:00 +02:00
m . Post ( "/avatar" , binding . MultipartForm ( auth . AvatarForm { } ) , userSetting . AvatarPost )
m . Post ( "/avatar/delete" , userSetting . DeleteAvatar )
2018-05-15 12:07:32 +02:00
m . Group ( "/account" , func ( ) {
2018-05-17 06:05:00 +02:00
m . Combo ( "" ) . Get ( userSetting . Account ) . Post ( bindIgnErr ( auth . ChangePasswordForm { } ) , userSetting . AccountPost )
m . Post ( "/email" , bindIgnErr ( auth . AddEmailForm { } ) , userSetting . EmailPost )
m . Post ( "/email/delete" , userSetting . DeleteEmail )
m . Post ( "/delete" , userSetting . DeleteAccount )
2019-01-09 18:22:57 +01:00
m . Post ( "/theme" , bindIgnErr ( auth . UpdateThemeForm { } ) , userSetting . UpdateUIThemePost )
2018-05-15 12:07:32 +02:00
} )
m . Group ( "/security" , func ( ) {
2018-05-17 06:05:00 +02:00
m . Get ( "" , userSetting . Security )
2018-05-15 12:07:32 +02:00
m . Group ( "/two_factor" , func ( ) {
2018-05-17 06:05:00 +02:00
m . Post ( "/regenerate_scratch" , userSetting . RegenerateScratchTwoFactor )
m . Post ( "/disable" , userSetting . DisableTwoFactor )
m . Get ( "/enroll" , userSetting . EnrollTwoFactor )
m . Post ( "/enroll" , bindIgnErr ( auth . TwoFactorAuthForm { } ) , userSetting . EnrollTwoFactorPost )
2018-05-15 12:07:32 +02:00
} )
2018-05-19 16:12:37 +02:00
m . Group ( "/u2f" , func ( ) {
m . Post ( "/request_register" , bindIgnErr ( auth . U2FRegistrationForm { } ) , userSetting . U2FRegister )
m . Post ( "/register" , bindIgnErr ( u2f . RegisterResponse { } ) , userSetting . U2FRegisterPost )
m . Post ( "/delete" , bindIgnErr ( auth . U2FDeleteForm { } ) , userSetting . U2FDelete )
} )
2018-05-15 12:07:32 +02:00
m . Group ( "/openid" , func ( ) {
2018-05-17 06:05:00 +02:00
m . Post ( "" , bindIgnErr ( auth . AddOpenIDForm { } ) , userSetting . OpenIDPost )
m . Post ( "/delete" , userSetting . DeleteOpenID )
m . Post ( "/toggle_visibility" , userSetting . ToggleOpenIDVisibility )
2018-05-15 12:07:32 +02:00
} , openIDSignInEnabled )
2018-05-17 06:05:00 +02:00
m . Post ( "/account_link" , userSetting . DeleteAccountLink )
2018-05-15 12:07:32 +02:00
} )
2019-03-08 17:42:50 +01:00
m . Group ( "/applications/oauth2" , func ( ) {
m . Get ( "/:id" , userSetting . OAuth2ApplicationShow )
m . Post ( "/:id" , bindIgnErr ( auth . EditOAuth2ApplicationForm { } ) , userSetting . OAuthApplicationsEdit )
2019-03-09 17:29:58 +01:00
m . Post ( "/:id/regenerate_secret" , userSetting . OAuthApplicationsRegenerateSecret )
2019-03-08 17:42:50 +01:00
m . Post ( "" , bindIgnErr ( auth . EditOAuth2ApplicationForm { } ) , userSetting . OAuthApplicationsPost )
m . Post ( "/delete" , userSetting . DeleteOAuth2Application )
2019-04-17 10:18:16 +02:00
m . Post ( "/revoke" , userSetting . RevokeOAuth2Grant )
2019-03-08 17:42:50 +01:00
} )
2018-05-17 06:05:00 +02:00
m . Combo ( "/applications" ) . Get ( userSetting . Applications ) .
Post ( bindIgnErr ( auth . NewAccessTokenForm { } ) , userSetting . ApplicationsPost )
m . Post ( "/applications/delete" , userSetting . DeleteApplication )
m . Combo ( "/keys" ) . Get ( userSetting . Keys ) .
Post ( bindIgnErr ( auth . AddKeyForm { } ) , userSetting . KeysPost )
m . Post ( "/keys/delete" , userSetting . DeleteKey )
m . Get ( "/organization" , userSetting . Organization )
m . Get ( "/repos" , userSetting . Repos )
2018-05-15 12:07:32 +02:00
// redirects from old settings urls to new ones
// TODO: can be removed on next major version
m . Get ( "/avatar" , func ( ctx * context . Context ) {
ctx . Redirect ( setting . AppSubURL + "/user/settings" , http . StatusMovedPermanently )
} )
m . Get ( "/email" , func ( ctx * context . Context ) {
ctx . Redirect ( setting . AppSubURL + "/user/settings/account" , http . StatusMovedPermanently )
} )
m . Get ( "/delete" , func ( ctx * context . Context ) {
ctx . Redirect ( setting . AppSubURL + "/user/settings/account" , http . StatusMovedPermanently )
} )
m . Get ( "/openid" , func ( ctx * context . Context ) {
ctx . Redirect ( setting . AppSubURL + "/user/settings/security" , http . StatusMovedPermanently )
} )
m . Get ( "/account_link" , func ( ctx * context . Context ) {
ctx . Redirect ( setting . AppSubURL + "/user/settings/security" , http . StatusMovedPermanently )
2017-04-25 03:24:51 -04:00
} )
} , reqSignIn , func ( ctx * context . Context ) {
ctx . Data [ "PageIsUserSettings" ] = true
2019-01-09 18:22:57 +01:00
ctx . Data [ "AllThemes" ] = setting . UI . Themes
2017-04-25 03:24:51 -04:00
} )
m . Group ( "/user" , func ( ) {
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
2019-04-02 13:44:33 +08:00
m . Any ( "/activate" , user . Activate , reqSignIn )
2017-04-25 03:24:51 -04:00
m . Any ( "/activate_email" , user . ActivateEmail )
m . Get ( "/email2user" , user . Email2User )
2019-04-18 01:23:59 -06:00
m . Get ( "/recover_account" , user . ResetPasswd )
m . Post ( "/recover_account" , user . ResetPasswdPost )
2017-04-25 03:24:51 -04:00
m . Get ( "/forgot_password" , user . ForgotPasswd )
m . Post ( "/forgot_password" , user . ForgotPasswdPost )
m . Get ( "/logout" , user . SignOut )
} )
// ***** END: User *****
adminReq := context . Toggle ( & context . ToggleOptions { SignInRequired : true , AdminRequired : true } )
// ***** START: Admin *****
m . Group ( "/admin" , func ( ) {
m . Get ( "" , adminReq , admin . Dashboard )
m . Get ( "/config" , admin . Config )
m . Post ( "/config/test_mail" , admin . SendTestMail )
m . Get ( "/monitor" , admin . Monitor )
m . Group ( "/users" , func ( ) {
m . Get ( "" , admin . Users )
m . Combo ( "/new" ) . Get ( admin . NewUser ) . Post ( bindIgnErr ( auth . AdminCreateUserForm { } ) , admin . NewUserPost )
m . Combo ( "/:userid" ) . Get ( admin . EditUser ) . Post ( bindIgnErr ( auth . AdminEditUserForm { } ) , admin . EditUserPost )
m . Post ( "/:userid/delete" , admin . DeleteUser )
} )
m . Group ( "/orgs" , func ( ) {
m . Get ( "" , admin . Organizations )
} )
m . Group ( "/repos" , func ( ) {
m . Get ( "" , admin . Repos )
m . Post ( "/delete" , admin . DeleteRepo )
} )
2019-03-18 22:33:20 -04:00
m . Group ( "/hooks" , func ( ) {
m . Get ( "" , admin . DefaultWebhooks )
m . Post ( "/delete" , admin . DeleteDefaultWebhook )
m . Get ( "/:type/new" , repo . WebhooksNew )
m . Post ( "/gitea/new" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksNewPost )
2019-06-12 21:41:28 +02:00
m . Post ( "/gogs/new" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . GogsHooksNewPost )
2019-03-18 22:33:20 -04:00
m . Post ( "/slack/new" , bindIgnErr ( auth . NewSlackHookForm { } ) , repo . SlackHooksNewPost )
m . Post ( "/discord/new" , bindIgnErr ( auth . NewDiscordHookForm { } ) , repo . DiscordHooksNewPost )
m . Post ( "/dingtalk/new" , bindIgnErr ( auth . NewDingtalkHookForm { } ) , repo . DingtalkHooksNewPost )
2019-08-26 22:59:10 +00:00
m . Post ( "/telegram/new" , bindIgnErr ( auth . NewTelegramHookForm { } ) , repo . TelegramHooksNewPost )
2019-04-20 00:18:06 +10:00
m . Post ( "/msteams/new" , bindIgnErr ( auth . NewMSTeamsHookForm { } ) , repo . MSTeamsHooksNewPost )
2019-03-18 22:33:20 -04:00
m . Get ( "/:id" , repo . WebHooksEdit )
m . Post ( "/gitea/:id" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksEditPost )
2019-06-12 21:41:28 +02:00
m . Post ( "/gogs/:id" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . GogsHooksEditPost )
2019-03-18 22:33:20 -04:00
m . Post ( "/slack/:id" , bindIgnErr ( auth . NewSlackHookForm { } ) , repo . SlackHooksEditPost )
m . Post ( "/discord/:id" , bindIgnErr ( auth . NewDiscordHookForm { } ) , repo . DiscordHooksEditPost )
m . Post ( "/dingtalk/:id" , bindIgnErr ( auth . NewDingtalkHookForm { } ) , repo . DingtalkHooksEditPost )
2019-08-26 22:59:10 +00:00
m . Post ( "/telegram/:id" , bindIgnErr ( auth . NewTelegramHookForm { } ) , repo . TelegramHooksEditPost )
2019-04-20 00:18:06 +10:00
m . Post ( "/msteams/:id" , bindIgnErr ( auth . NewMSTeamsHookForm { } ) , repo . MSTeamsHooksNewPost )
2019-03-18 22:33:20 -04:00
} )
2017-04-25 03:24:51 -04:00
m . Group ( "/auths" , func ( ) {
m . Get ( "" , admin . Authentications )
m . Combo ( "/new" ) . Get ( admin . NewAuthSource ) . Post ( bindIgnErr ( auth . AuthenticationForm { } ) , admin . NewAuthSourcePost )
m . Combo ( "/:authid" ) . Get ( admin . EditAuthSource ) .
Post ( bindIgnErr ( auth . AuthenticationForm { } ) , admin . EditAuthSourcePost )
m . Post ( "/:authid/delete" , admin . DeleteAuthSource )
} )
m . Group ( "/notices" , func ( ) {
m . Get ( "" , admin . Notices )
m . Post ( "/delete" , admin . DeleteNotices )
m . Get ( "/empty" , admin . EmptyNotices )
} )
} , adminReq )
// ***** END: Admin *****
m . Group ( "" , func ( ) {
m . Group ( "/:username" , func ( ) {
m . Get ( "" , user . Profile )
m . Get ( "/followers" , user . Followers )
m . Get ( "/following" , user . Following )
} )
m . Get ( "/attachments/:uuid" , func ( ctx * context . Context ) {
attach , err := models . GetAttachmentByUUID ( ctx . Params ( ":uuid" ) )
if err != nil {
if models . IsErrAttachmentNotExist ( err ) {
ctx . Error ( 404 )
} else {
2018-01-10 22:34:17 +01:00
ctx . ServerError ( "GetAttachmentByUUID" , err )
2017-04-25 03:24:51 -04:00
}
return
}
fr , err := os . Open ( attach . LocalPath ( ) )
if err != nil {
2018-01-10 22:34:17 +01:00
ctx . ServerError ( "Open" , err )
2017-04-25 03:24:51 -04:00
return
}
defer fr . Close ( )
if err := attach . IncreaseDownloadCount ( ) ; err != nil {
2018-01-10 22:34:17 +01:00
ctx . ServerError ( "Update" , err )
2017-04-25 03:24:51 -04:00
return
}
if err = repo . ServeData ( ctx , attach . Name , fr ) ; err != nil {
2018-01-10 22:34:17 +01:00
ctx . ServerError ( "ServeData" , err )
2017-04-25 03:24:51 -04:00
return
}
} )
} , ignSignIn )
2019-04-03 03:25:05 +08:00
m . Group ( "" , func ( ) {
m . Post ( "/attachments" , repo . UploadAttachment )
} , reqSignIn )
2017-04-25 03:24:51 -04:00
m . Group ( "/:username" , func ( ) {
m . Get ( "/action/:action" , user . Action )
} , reqSignIn )
if macaron . Env == macaron . DEV {
m . Get ( "/template/*" , dev . TemplatePreview )
}
reqRepoAdmin := context . RequireRepoAdmin ( )
2018-11-28 19:26:14 +08:00
reqRepoCodeWriter := context . RequireRepoWriter ( models . UnitTypeCode )
reqRepoCodeReader := context . RequireRepoReader ( models . UnitTypeCode )
reqRepoReleaseWriter := context . RequireRepoWriter ( models . UnitTypeReleases )
reqRepoReleaseReader := context . RequireRepoReader ( models . UnitTypeReleases )
reqRepoWikiWriter := context . RequireRepoWriter ( models . UnitTypeWiki )
reqRepoIssueReader := context . RequireRepoReader ( models . UnitTypeIssues )
reqRepoPullsWriter := context . RequireRepoWriter ( models . UnitTypePullRequests )
reqRepoPullsReader := context . RequireRepoReader ( models . UnitTypePullRequests )
reqRepoIssuesOrPullsWriter := context . RequireRepoWriterOr ( models . UnitTypeIssues , models . UnitTypePullRequests )
reqRepoIssuesOrPullsReader := context . RequireRepoReaderOr ( models . UnitTypeIssues , models . UnitTypePullRequests )
2017-04-25 03:24:51 -04:00
2019-02-18 21:55:04 +01:00
reqRepoIssueWriter := func ( ctx * context . Context ) {
if ! ctx . Repo . CanWrite ( models . UnitTypeIssues ) {
ctx . Error ( 403 )
return
}
}
2017-04-25 03:24:51 -04:00
// ***** START: Organization *****
m . Group ( "/org" , func ( ) {
m . Group ( "" , func ( ) {
m . Get ( "/create" , org . Create )
m . Post ( "/create" , bindIgnErr ( auth . CreateOrgForm { } ) , org . CreatePost )
} )
m . Group ( "/:org" , func ( ) {
m . Get ( "/dashboard" , user . Dashboard )
m . Get ( "/^:type(issues|pulls)$" , user . Issues )
m . Get ( "/members" , org . Members )
m . Get ( "/members/action/:action" , org . MembersAction )
m . Get ( "/teams" , org . Teams )
} , context . OrgAssignment ( true ) )
m . Group ( "/:org" , func ( ) {
m . Get ( "/teams/:team" , org . TeamMembers )
m . Get ( "/teams/:team/repositories" , org . TeamRepositories )
m . Route ( "/teams/:team/action/:action" , "GET,POST" , org . TeamsAction )
m . Route ( "/teams/:team/action/repo/:action" , "GET,POST" , org . TeamsRepoAction )
} , context . OrgAssignment ( true , false , true ) )
m . Group ( "/:org" , func ( ) {
m . Get ( "/teams/new" , org . NewTeam )
m . Post ( "/teams/new" , bindIgnErr ( auth . CreateTeamForm { } ) , org . NewTeamPost )
m . Get ( "/teams/:team/edit" , org . EditTeam )
m . Post ( "/teams/:team/edit" , bindIgnErr ( auth . CreateTeamForm { } ) , org . EditTeamPost )
m . Post ( "/teams/:team/delete" , org . DeleteTeam )
m . Group ( "/settings" , func ( ) {
m . Combo ( "" ) . Get ( org . Settings ) .
Post ( bindIgnErr ( auth . UpdateOrgSettingForm { } ) , org . SettingsPost )
m . Post ( "/avatar" , binding . MultipartForm ( auth . AvatarForm { } ) , org . SettingsAvatar )
m . Post ( "/avatar/delete" , org . SettingsDeleteAvatar )
m . Group ( "/hooks" , func ( ) {
m . Get ( "" , org . Webhooks )
m . Post ( "/delete" , org . DeleteWebhook )
m . Get ( "/:type/new" , repo . WebhooksNew )
2017-05-29 09:17:15 +02:00
m . Post ( "/gitea/new" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksNewPost )
2019-06-12 21:41:28 +02:00
m . Post ( "/gogs/new" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . GogsHooksNewPost )
2017-04-25 03:24:51 -04:00
m . Post ( "/slack/new" , bindIgnErr ( auth . NewSlackHookForm { } ) , repo . SlackHooksNewPost )
2017-08-30 13:36:52 +08:00
m . Post ( "/discord/new" , bindIgnErr ( auth . NewDiscordHookForm { } ) , repo . DiscordHooksNewPost )
2017-11-21 12:26:43 +08:00
m . Post ( "/dingtalk/new" , bindIgnErr ( auth . NewDingtalkHookForm { } ) , repo . DingtalkHooksNewPost )
2019-04-18 22:45:02 -04:00
m . Post ( "/telegram/new" , bindIgnErr ( auth . NewTelegramHookForm { } ) , repo . TelegramHooksNewPost )
2017-04-25 03:24:51 -04:00
m . Get ( "/:id" , repo . WebHooksEdit )
2017-05-29 09:17:15 +02:00
m . Post ( "/gitea/:id" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksEditPost )
m . Post ( "/gogs/:id" , bindIgnErr ( auth . NewGogshookForm { } ) , repo . GogsHooksEditPost )
2017-04-25 03:24:51 -04:00
m . Post ( "/slack/:id" , bindIgnErr ( auth . NewSlackHookForm { } ) , repo . SlackHooksEditPost )
2017-08-29 09:20:35 +08:00
m . Post ( "/discord/:id" , bindIgnErr ( auth . NewDiscordHookForm { } ) , repo . DiscordHooksEditPost )
2017-11-21 12:26:43 +08:00
m . Post ( "/dingtalk/:id" , bindIgnErr ( auth . NewDingtalkHookForm { } ) , repo . DingtalkHooksEditPost )
2019-04-18 22:45:02 -04:00
m . Post ( "/telegram/:id" , bindIgnErr ( auth . NewTelegramHookForm { } ) , repo . TelegramHooksEditPost )
2017-04-25 03:24:51 -04:00
} )
m . Route ( "/delete" , "GET,POST" , org . SettingsDelete )
} )
} , context . OrgAssignment ( true , true ) )
} , reqSignIn )
// ***** END: Organization *****
// ***** START: Repository *****
m . Group ( "/repo" , func ( ) {
m . Get ( "/create" , repo . Create )
m . Post ( "/create" , bindIgnErr ( auth . CreateRepoForm { } ) , repo . CreatePost )
m . Get ( "/migrate" , repo . Migrate )
m . Post ( "/migrate" , bindIgnErr ( auth . MigrateRepoForm { } ) , repo . MigratePost )
2017-09-18 16:52:20 +02:00
m . Group ( "/fork" , func ( ) {
m . Combo ( "/:repoid" ) . Get ( repo . Fork ) .
Post ( bindIgnErr ( auth . CreateRepoForm { } ) , repo . ForkPost )
2018-11-28 19:26:14 +08:00
} , context . RepoIDAssignment ( ) , context . UnitTypes ( ) , reqRepoCodeReader )
2017-04-25 03:24:51 -04:00
} , reqSignIn )
2019-01-06 23:37:30 +01:00
// ***** Release Attachment Download without Signin
2019-01-18 00:01:04 +00:00
m . Get ( "/:username/:reponame/releases/download/:vTag/:fileName" , ignSignIn , context . RepoAssignment ( ) , repo . MustBeNotEmpty , repo . RedirectDownload )
2019-01-06 23:37:30 +01:00
2017-04-25 03:24:51 -04:00
m . Group ( "/:username/:reponame" , func ( ) {
m . Group ( "/settings" , func ( ) {
m . Combo ( "" ) . Get ( repo . Settings ) .
Post ( bindIgnErr ( auth . RepoSettingForm { } ) , repo . SettingsPost )
2019-05-30 05:22:26 +03:00
m . Post ( "/avatar" , binding . MultipartForm ( auth . AvatarForm { } ) , repo . SettingsAvatar )
m . Post ( "/avatar/delete" , repo . SettingsDeleteAvatar )
2017-04-25 03:24:51 -04:00
m . Group ( "/collaboration" , func ( ) {
m . Combo ( "" ) . Get ( repo . Collaboration ) . Post ( repo . CollaborationPost )
m . Post ( "/access_mode" , repo . ChangeCollaborationAccessMode )
m . Post ( "/delete" , repo . DeleteCollaboration )
2019-09-23 22:08:03 +02:00
m . Group ( "/team" , func ( ) {
m . Post ( "" , repo . AddTeamPost )
m . Post ( "/delete" , repo . DeleteTeam )
} )
2017-04-25 03:24:51 -04:00
} )
m . Group ( "/branches" , func ( ) {
m . Combo ( "" ) . Get ( repo . ProtectedBranch ) . Post ( repo . ProtectedBranchPost )
2017-09-14 16:16:22 +08:00
m . Combo ( "/*" ) . Get ( repo . SettingsProtectedBranch ) .
2019-01-23 19:58:38 +01:00
Post ( bindIgnErr ( auth . ProtectBranchForm { } ) , context . RepoMustNotBeArchived ( ) , repo . SettingsProtectedBranchPost )
2019-01-18 00:01:04 +00:00
} , repo . MustBeNotEmpty )
2017-04-25 03:24:51 -04:00
m . Group ( "/hooks" , func ( ) {
m . Get ( "" , repo . Webhooks )
m . Post ( "/delete" , repo . DeleteWebhook )
m . Get ( "/:type/new" , repo . WebhooksNew )
2017-05-29 09:17:15 +02:00
m . Post ( "/gitea/new" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksNewPost )
2019-06-12 21:41:28 +02:00
m . Post ( "/gogs/new" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . GogsHooksNewPost )
2017-04-25 03:24:51 -04:00
m . Post ( "/slack/new" , bindIgnErr ( auth . NewSlackHookForm { } ) , repo . SlackHooksNewPost )
2017-08-28 13:06:45 +08:00
m . Post ( "/discord/new" , bindIgnErr ( auth . NewDiscordHookForm { } ) , repo . DiscordHooksNewPost )
2017-11-21 12:26:43 +08:00
m . Post ( "/dingtalk/new" , bindIgnErr ( auth . NewDingtalkHookForm { } ) , repo . DingtalkHooksNewPost )
2019-04-18 22:45:02 -04:00
m . Post ( "/telegram/new" , bindIgnErr ( auth . NewTelegramHookForm { } ) , repo . TelegramHooksNewPost )
2019-04-20 00:18:06 +10:00
m . Post ( "/msteams/new" , bindIgnErr ( auth . NewMSTeamsHookForm { } ) , repo . MSTeamsHooksNewPost )
2017-04-25 03:24:51 -04:00
m . Get ( "/:id" , repo . WebHooksEdit )
m . Post ( "/:id/test" , repo . TestWebhook )
2017-05-29 09:17:15 +02:00
m . Post ( "/gitea/:id" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksEditPost )
2018-06-21 01:22:03 -04:00
m . Post ( "/gogs/:id" , bindIgnErr ( auth . NewGogshookForm { } ) , repo . GogsHooksEditPost )
2017-04-25 03:24:51 -04:00
m . Post ( "/slack/:id" , bindIgnErr ( auth . NewSlackHookForm { } ) , repo . SlackHooksEditPost )
2017-08-28 13:06:45 +08:00
m . Post ( "/discord/:id" , bindIgnErr ( auth . NewDiscordHookForm { } ) , repo . DiscordHooksEditPost )
2017-11-21 12:26:43 +08:00
m . Post ( "/dingtalk/:id" , bindIgnErr ( auth . NewDingtalkHookForm { } ) , repo . DingtalkHooksEditPost )
2019-04-18 22:45:02 -04:00
m . Post ( "/telegram/:id" , bindIgnErr ( auth . NewTelegramHookForm { } ) , repo . TelegramHooksEditPost )
2019-04-20 00:18:06 +10:00
m . Post ( "/msteams/:id" , bindIgnErr ( auth . NewMSTeamsHookForm { } ) , repo . MSTeamsHooksEditPost )
2017-04-25 03:24:51 -04:00
m . Group ( "/git" , func ( ) {
m . Get ( "" , repo . GitHooks )
m . Combo ( "/:name" ) . Get ( repo . GitHooksEdit ) .
Post ( repo . GitHooksEditPost )
} , context . GitHookService ( ) )
} )
m . Group ( "/keys" , func ( ) {
m . Combo ( "" ) . Get ( repo . DeployKeys ) .
2017-04-26 15:10:43 +02:00
Post ( bindIgnErr ( auth . AddKeyForm { } ) , repo . DeployKeysPost )
2017-04-25 03:24:51 -04:00
m . Post ( "/delete" , repo . DeleteDeployKey )
} )
} , func ( ctx * context . Context ) {
ctx . Data [ "PageIsSettings" ] = true
2017-07-17 05:04:43 +03:00
} )
2019-07-15 23:43:30 -04:00
} , reqSignIn , context . RepoAssignment ( ) , context . UnitTypes ( ) , reqRepoAdmin , context . RepoRef ( ) )
2017-04-25 03:24:51 -04:00
2019-06-10 02:02:42 +01:00
m . Get ( "/:username/:reponame/action/:action" , reqSignIn , context . RepoAssignment ( ) , context . UnitTypes ( ) , repo . Action )
2017-05-18 22:54:24 +08:00
2017-04-25 03:24:51 -04:00
m . Group ( "/:username/:reponame" , func ( ) {
m . Group ( "/issues" , func ( ) {
2017-09-30 06:04:16 +02:00
m . Combo ( "/new" ) . Get ( context . RepoRef ( ) , repo . NewIssue ) .
2017-04-25 03:24:51 -04:00
Post ( bindIgnErr ( auth . CreateIssueForm { } ) , repo . NewIssuePost )
2019-01-23 19:58:38 +01:00
} , context . RepoMustNotBeArchived ( ) , reqRepoIssueReader )
2017-10-16 10:55:43 +03:00
// FIXME: should use different URLs but mostly same logic for comments of issue and pull reuqest.
// So they can apply their own enable/disable logic on routers.
m . Group ( "/issues" , func ( ) {
2017-04-25 03:24:51 -04:00
m . Group ( "/:index" , func ( ) {
m . Post ( "/title" , repo . UpdateIssueTitle )
m . Post ( "/content" , repo . UpdateIssueContent )
m . Post ( "/watch" , repo . IssueWatch )
2018-07-17 23:23:58 +02:00
m . Group ( "/dependency" , func ( ) {
m . Post ( "/add" , repo . AddDependency )
m . Post ( "/delete" , repo . RemoveDependency )
} )
2019-02-18 21:55:04 +01:00
m . Combo ( "/comments" ) . Post ( repo . MustAllowUserComment , bindIgnErr ( auth . CreateCommentForm { } ) , repo . NewComment )
2017-09-12 08:48:13 +02:00
m . Group ( "/times" , func ( ) {
m . Post ( "/add" , bindIgnErr ( auth . AddTimeManuallyForm { } ) , repo . AddTimeManually )
m . Group ( "/stopwatch" , func ( ) {
m . Post ( "/toggle" , repo . IssueStopwatch )
m . Post ( "/cancel" , repo . CancelStopwatch )
} )
} )
2017-12-04 01:14:26 +02:00
m . Post ( "/reactions/:action" , bindIgnErr ( auth . ReactionForm { } ) , repo . ChangeIssueReaction )
2019-02-18 21:55:04 +01:00
m . Post ( "/lock" , reqRepoIssueWriter , bindIgnErr ( auth . IssueLockForm { } ) , repo . LockIssue )
m . Post ( "/unlock" , reqRepoIssueWriter , repo . UnlockIssue )
2019-01-23 19:58:38 +01:00
} , context . RepoMustNotBeArchived ( ) )
2017-04-25 03:24:51 -04:00
2018-11-28 19:26:14 +08:00
m . Post ( "/labels" , reqRepoIssuesOrPullsWriter , repo . UpdateIssueLabel )
m . Post ( "/milestone" , reqRepoIssuesOrPullsWriter , repo . UpdateIssueMilestone )
m . Post ( "/assignee" , reqRepoIssuesOrPullsWriter , repo . UpdateIssueAssignee )
m . Post ( "/status" , reqRepoIssuesOrPullsWriter , repo . UpdateIssueStatus )
2019-01-23 19:58:38 +01:00
} , context . RepoMustNotBeArchived ( ) )
2017-04-25 03:24:51 -04:00
m . Group ( "/comments/:id" , func ( ) {
m . Post ( "" , repo . UpdateCommentContent )
m . Post ( "/delete" , repo . DeleteComment )
2017-12-04 01:14:26 +02:00
m . Post ( "/reactions/:action" , bindIgnErr ( auth . ReactionForm { } ) , repo . ChangeCommentReaction )
2019-01-23 19:58:38 +01:00
} , context . RepoMustNotBeArchived ( ) )
2017-04-25 03:24:51 -04:00
m . Group ( "/labels" , func ( ) {
m . Post ( "/new" , bindIgnErr ( auth . CreateLabelForm { } ) , repo . NewLabel )
m . Post ( "/edit" , bindIgnErr ( auth . CreateLabelForm { } ) , repo . UpdateLabel )
m . Post ( "/delete" , repo . DeleteLabel )
m . Post ( "/initialize" , bindIgnErr ( auth . InitializeLabelsForm { } ) , repo . InitializeLabels )
2019-01-23 19:58:38 +01:00
} , context . RepoMustNotBeArchived ( ) , reqRepoIssuesOrPullsWriter , context . RepoRef ( ) )
2017-04-25 03:24:51 -04:00
m . Group ( "/milestones" , func ( ) {
m . Combo ( "/new" ) . Get ( repo . NewMilestone ) .
Post ( bindIgnErr ( auth . CreateMilestoneForm { } ) , repo . NewMilestonePost )
m . Get ( "/:id/edit" , repo . EditMilestone )
m . Post ( "/:id/edit" , bindIgnErr ( auth . CreateMilestoneForm { } ) , repo . EditMilestonePost )
m . Get ( "/:id/:action" , repo . ChangeMilestonStatus )
m . Post ( "/delete" , repo . DeleteMilestone )
2019-01-23 19:58:38 +01:00
} , context . RepoMustNotBeArchived ( ) , reqRepoIssuesOrPullsWriter , context . RepoRef ( ) )
2018-11-29 09:46:30 +08:00
m . Group ( "/milestone" , func ( ) {
m . Get ( "/:id" , repo . MilestoneIssuesAndPulls )
2019-03-15 10:50:27 -05:00
} , reqRepoIssuesOrPullsReader , context . RepoRef ( ) )
2019-06-07 22:29:29 +02:00
m . Combo ( "/compare/*" , repo . MustBeNotEmpty , reqRepoCodeReader , repo . SetEditorconfigIfExists ) .
Get ( repo . SetDiffViewStyle , repo . CompareDiff ) .
Post ( context . RepoMustNotBeArchived ( ) , reqRepoPullsReader , repo . MustAllowPulls , bindIgnErr ( auth . CreateIssueForm { } ) , repo . CompareAndPullRequestPost )
2017-04-25 03:24:51 -04:00
m . Group ( "" , func ( ) {
m . Group ( "" , func ( ) {
2017-10-29 19:04:25 -07:00
m . Combo ( "/_edit/*" ) . Get ( repo . EditFile ) .
Post ( bindIgnErr ( auth . EditRepoFileForm { } ) , repo . EditFilePost )
m . Combo ( "/_new/*" ) . Get ( repo . NewFile ) .
Post ( bindIgnErr ( auth . EditRepoFileForm { } ) , repo . NewFilePost )
m . Post ( "/_preview/*" , bindIgnErr ( auth . EditPreviewDiffForm { } ) , repo . DiffPreviewPost )
m . Combo ( "/_delete/*" ) . Get ( repo . DeleteFile ) .
Post ( bindIgnErr ( auth . DeleteRepoFileForm { } ) , repo . DeleteFilePost )
m . Combo ( "/_upload/*" , repo . MustBeAbleToUpload ) .
Get ( repo . UploadFile ) .
2017-04-25 03:24:51 -04:00
Post ( bindIgnErr ( auth . UploadRepoFileForm { } ) , repo . UploadFilePost )
2017-10-29 19:04:25 -07:00
} , context . RepoRefByType ( context . RepoRefBranch ) , repo . MustBeEditable )
m . Group ( "" , func ( ) {
2017-04-25 03:24:51 -04:00
m . Post ( "/upload-file" , repo . UploadFileToServer )
m . Post ( "/upload-remove" , bindIgnErr ( auth . RemoveUploadFileForm { } ) , repo . RemoveUploadFileFromServer )
2017-10-29 19:04:25 -07:00
} , context . RepoRef ( ) , repo . MustBeEditable , repo . MustBeAbleToUpload )
2019-01-23 19:58:38 +01:00
} , context . RepoMustNotBeArchived ( ) , reqRepoCodeWriter , repo . MustBeNotEmpty )
2017-10-15 22:59:24 +03:00
m . Group ( "/branches" , func ( ) {
2017-10-29 19:04:25 -07:00
m . Group ( "/_new/" , func ( ) {
m . Post ( "/branch/*" , context . RepoRefByType ( context . RepoRefBranch ) , repo . CreateBranch )
m . Post ( "/tag/*" , context . RepoRefByType ( context . RepoRefTag ) , repo . CreateBranch )
m . Post ( "/commit/*" , context . RepoRefByType ( context . RepoRefCommit ) , repo . CreateBranch )
} , bindIgnErr ( auth . NewBranchForm { } ) )
2017-10-26 02:49:16 +02:00
m . Post ( "/delete" , repo . DeleteBranchPost )
m . Post ( "/restore" , repo . RestoreBranchPost )
2019-01-23 19:58:38 +01:00
} , context . RepoMustNotBeArchived ( ) , reqRepoCodeWriter , repo . MustBeNotEmpty )
2017-10-26 02:49:16 +02:00
2018-11-28 19:26:14 +08:00
} , reqSignIn , context . RepoAssignment ( ) , context . UnitTypes ( ) )
2017-05-18 22:54:24 +08:00
// Releases
m . Group ( "/:username/:reponame" , func ( ) {
m . Group ( "/releases" , func ( ) {
2019-01-18 00:01:04 +00:00
m . Get ( "/" , repo . MustBeNotEmpty , repo . Releases )
} , repo . MustBeNotEmpty , context . RepoRef ( ) )
2017-06-17 23:38:24 -04:00
m . Group ( "/releases" , func ( ) {
2017-05-18 22:54:24 +08:00
m . Get ( "/new" , repo . NewRelease )
m . Post ( "/new" , bindIgnErr ( auth . NewReleaseForm { } ) , repo . NewReleasePost )
m . Post ( "/delete" , repo . DeleteRelease )
2019-01-23 19:58:38 +01:00
} , reqSignIn , repo . MustBeNotEmpty , context . RepoMustNotBeArchived ( ) , reqRepoReleaseWriter , context . RepoRef ( ) )
2017-05-18 22:54:24 +08:00
m . Group ( "/releases" , func ( ) {
m . Get ( "/edit/*" , repo . EditRelease )
m . Post ( "/edit/*" , bindIgnErr ( auth . EditReleaseForm { } ) , repo . EditReleasePost )
2019-01-23 19:58:38 +01:00
} , reqSignIn , repo . MustBeNotEmpty , context . RepoMustNotBeArchived ( ) , reqRepoReleaseWriter , func ( ctx * context . Context ) {
2017-05-18 22:54:24 +08:00
var err error
ctx . Repo . Commit , err = ctx . Repo . GitRepo . GetBranchCommit ( ctx . Repo . Repository . DefaultBranch )
if err != nil {
2018-01-10 22:34:17 +01:00
ctx . ServerError ( "GetBranchCommit" , err )
2017-05-18 22:54:24 +08:00
return
}
2017-10-26 04:37:33 +03:00
ctx . Repo . CommitsCount , err = ctx . Repo . GetCommitsCount ( )
2017-05-18 22:54:24 +08:00
if err != nil {
2018-01-10 22:34:17 +01:00
ctx . ServerError ( "GetCommitsCount" , err )
2017-05-18 22:54:24 +08:00
return
}
ctx . Data [ "CommitsCount" ] = ctx . Repo . CommitsCount
} )
2019-01-30 17:45:48 +01:00
} , ignSignIn , context . RepoAssignment ( ) , context . UnitTypes ( ) , reqRepoReleaseReader )
2017-04-25 03:24:51 -04:00
2018-04-11 10:51:44 +08:00
m . Group ( "/:username/:reponame" , func ( ) {
2018-06-21 12:09:46 +03:00
m . Post ( "/topics" , repo . TopicsPost )
2019-01-24 12:22:27 +02:00
} , context . RepoAssignment ( ) , context . RepoMustNotBeArchived ( ) , reqRepoAdmin )
2018-04-11 10:51:44 +08:00
2017-04-25 03:24:51 -04:00
m . Group ( "/:username/:reponame" , func ( ) {
m . Group ( "" , func ( ) {
2019-01-23 06:10:38 +02:00
m . Get ( "/^:type(issues|pulls)$" , repo . Issues )
2017-04-25 03:24:51 -04:00
m . Get ( "/^:type(issues|pulls)$/:index" , repo . ViewIssue )
2018-11-28 19:26:14 +08:00
m . Get ( "/labels/" , reqRepoIssuesOrPullsReader , repo . RetrieveLabels , repo . Labels )
m . Get ( "/milestones" , reqRepoIssuesOrPullsReader , repo . Milestones )
2017-06-03 01:56:36 -04:00
} , context . RepoRef ( ) )
2017-04-25 03:24:51 -04:00
m . Group ( "/wiki" , func ( ) {
m . Get ( "/?:page" , repo . Wiki )
m . Get ( "/_pages" , repo . WikiPages )
2019-07-08 10:20:22 +02:00
m . Get ( "/:page/_revision" , repo . WikiRevision )
2017-04-25 03:24:51 -04:00
m . Group ( "" , func ( ) {
m . Combo ( "/_new" ) . Get ( repo . NewWiki ) .
Post ( bindIgnErr ( auth . NewWikiForm { } ) , repo . NewWikiPost )
m . Combo ( "/:page/_edit" ) . Get ( repo . EditWiki ) .
Post ( bindIgnErr ( auth . NewWikiForm { } ) , repo . EditWikiPost )
m . Post ( "/:page/delete" , repo . DeleteWikiPagePost )
2019-01-23 19:58:38 +01:00
} , context . RepoMustNotBeArchived ( ) , reqSignIn , reqRepoWikiWriter )
2017-09-30 06:04:16 +02:00
} , repo . MustEnableWiki , context . RepoRef ( ) )
2017-04-25 03:24:51 -04:00
m . Group ( "/wiki" , func ( ) {
m . Get ( "/raw/*" , repo . WikiRaw )
2017-09-30 06:04:16 +02:00
} , repo . MustEnableWiki )
2017-04-25 03:24:51 -04:00
2017-10-15 02:17:39 +03:00
m . Group ( "/activity" , func ( ) {
m . Get ( "" , repo . Activity )
m . Get ( "/:period" , repo . Activity )
2019-01-18 00:01:04 +00:00
} , context . RepoRef ( ) , repo . MustBeNotEmpty , context . RequireRepoReaderOr ( models . UnitTypePullRequests , models . UnitTypeIssues , models . UnitTypeReleases ) )
2017-10-15 02:17:39 +03:00
2019-05-04 15:39:03 +03:00
m . Group ( "/activity_author_data" , func ( ) {
m . Get ( "" , repo . ActivityAuthors )
m . Get ( "/:period" , repo . ActivityAuthors )
} , context . RepoRef ( ) , repo . MustBeNotEmpty , context . RequireRepoReaderOr ( models . UnitTypeCode ) )
2019-01-18 00:01:04 +00:00
m . Get ( "/archive/*" , repo . MustBeNotEmpty , reqRepoCodeReader , repo . Download )
2017-04-25 03:24:51 -04:00
2017-10-26 02:49:16 +02:00
m . Group ( "/branches" , func ( ) {
m . Get ( "" , repo . Branches )
2019-01-18 00:01:04 +00:00
} , repo . MustBeNotEmpty , context . RepoRef ( ) , reqRepoCodeReader )
2017-10-26 02:49:16 +02:00
2017-04-25 03:24:51 -04:00
m . Group ( "/pulls/:index" , func ( ) {
2018-01-05 11:56:52 +01:00
m . Get ( ".diff" , repo . DownloadPullDiff )
2018-01-07 14:10:20 +01:00
m . Get ( ".patch" , repo . DownloadPullPatch )
2017-04-25 03:24:51 -04:00
m . Get ( "/commits" , context . RepoRef ( ) , repo . ViewPullCommits )
2019-01-23 19:58:38 +01:00
m . Post ( "/merge" , context . RepoMustNotBeArchived ( ) , reqRepoPullsWriter , bindIgnErr ( auth . MergePullRequestForm { } ) , repo . MergePullRequest )
m . Post ( "/cleanup" , context . RepoMustNotBeArchived ( ) , context . RepoRef ( ) , repo . CleanUpPullRequest )
2018-08-06 07:43:22 +03:00
m . Group ( "/files" , func ( ) {
2018-08-14 19:49:33 +02:00
m . Get ( "" , context . RepoRef ( ) , repo . SetEditorconfigIfExists , repo . SetDiffViewStyle , repo . SetWhitespaceBehavior , repo . ViewPullFiles )
2018-08-06 07:43:22 +03:00
m . Group ( "/reviews" , func ( ) {
m . Post ( "/comments" , bindIgnErr ( auth . CodeCommentForm { } ) , repo . CreateCodeComment )
m . Post ( "/submit" , bindIgnErr ( auth . SubmitReviewForm { } ) , repo . SubmitReview )
2019-01-23 19:58:38 +01:00
} , context . RepoMustNotBeArchived ( ) )
2018-08-06 07:43:22 +03:00
} )
2017-09-30 06:04:16 +02:00
} , repo . MustAllowPulls )
2017-04-25 03:24:51 -04:00
2019-02-12 15:09:43 +00:00
m . Group ( "/media" , func ( ) {
m . Get ( "/branch/*" , context . RepoRefByType ( context . RepoRefBranch ) , repo . SingleDownloadOrLFS )
m . Get ( "/tag/*" , context . RepoRefByType ( context . RepoRefTag ) , repo . SingleDownloadOrLFS )
m . Get ( "/commit/*" , context . RepoRefByType ( context . RepoRefCommit ) , repo . SingleDownloadOrLFS )
m . Get ( "/blob/:sha" , context . RepoRefByType ( context . RepoRefBlob ) , repo . DownloadByIDOrLFS )
// "/*" route is deprecated, and kept for backward compatibility
m . Get ( "/*" , context . RepoRefByType ( context . RepoRefLegacy ) , repo . SingleDownloadOrLFS )
} , repo . MustBeNotEmpty , reqRepoCodeReader )
2017-10-29 19:04:25 -07:00
m . Group ( "/raw" , func ( ) {
m . Get ( "/branch/*" , context . RepoRefByType ( context . RepoRefBranch ) , repo . SingleDownload )
m . Get ( "/tag/*" , context . RepoRefByType ( context . RepoRefTag ) , repo . SingleDownload )
m . Get ( "/commit/*" , context . RepoRefByType ( context . RepoRefCommit ) , repo . SingleDownload )
2018-11-18 19:45:40 +01:00
m . Get ( "/blob/:sha" , context . RepoRefByType ( context . RepoRefBlob ) , repo . DownloadByID )
2017-10-29 19:04:25 -07:00
// "/*" route is deprecated, and kept for backward compatibility
m . Get ( "/*" , context . RepoRefByType ( context . RepoRefLegacy ) , repo . SingleDownload )
2019-01-18 00:01:04 +00:00
} , repo . MustBeNotEmpty , reqRepoCodeReader )
2017-10-29 19:04:25 -07:00
m . Group ( "/commits" , func ( ) {
m . Get ( "/branch/*" , context . RepoRefByType ( context . RepoRefBranch ) , repo . RefCommits )
m . Get ( "/tag/*" , context . RepoRefByType ( context . RepoRefTag ) , repo . RefCommits )
m . Get ( "/commit/*" , context . RepoRefByType ( context . RepoRefCommit ) , repo . RefCommits )
// "/*" route is deprecated, and kept for backward compatibility
m . Get ( "/*" , context . RepoRefByType ( context . RepoRefLegacy ) , repo . RefCommits )
2019-01-18 00:01:04 +00:00
} , repo . MustBeNotEmpty , reqRepoCodeReader )
2017-10-29 19:04:25 -07:00
2019-04-20 04:47:00 +02:00
m . Group ( "/blame" , func ( ) {
m . Get ( "/branch/*" , context . RepoRefByType ( context . RepoRefBranch ) , repo . RefBlame )
m . Get ( "/tag/*" , context . RepoRefByType ( context . RepoRefTag ) , repo . RefBlame )
m . Get ( "/commit/*" , context . RepoRefByType ( context . RepoRefCommit ) , repo . RefBlame )
} , repo . MustBeNotEmpty , reqRepoCodeReader )
2017-04-25 03:24:51 -04:00
m . Group ( "" , func ( ) {
m . Get ( "/graph" , repo . Graph )
m . Get ( "/commit/:sha([a-f0-9]{7,40})$" , repo . SetEditorconfigIfExists , repo . SetDiffViewStyle , repo . Diff )
2019-01-18 00:01:04 +00:00
} , repo . MustBeNotEmpty , context . RepoRef ( ) , reqRepoCodeReader )
2017-07-27 02:23:38 -07:00
2017-10-29 19:04:25 -07:00
m . Group ( "/src" , func ( ) {
m . Get ( "/branch/*" , context . RepoRefByType ( context . RepoRefBranch ) , repo . Home )
m . Get ( "/tag/*" , context . RepoRefByType ( context . RepoRefTag ) , repo . Home )
m . Get ( "/commit/*" , context . RepoRefByType ( context . RepoRefCommit ) , repo . Home )
// "/*" route is deprecated, and kept for backward compatibility
m . Get ( "/*" , context . RepoRefByType ( context . RepoRefLegacy ) , repo . Home )
} , repo . SetEditorconfigIfExists )
2017-07-27 02:23:38 -07:00
m . Group ( "" , func ( ) {
2017-04-25 03:24:51 -04:00
m . Get ( "/forks" , repo . Forks )
2018-11-28 19:26:14 +08:00
} , context . RepoRef ( ) , reqRepoCodeReader )
2017-08-28 23:53:51 -07:00
m . Get ( "/commit/:sha([a-f0-9]{7,40})\\.:ext(patch|diff)" ,
2019-01-18 00:01:04 +00:00
repo . MustBeNotEmpty , reqRepoCodeReader , repo . RawDiff )
2018-11-28 19:26:14 +08:00
} , ignSignIn , context . RepoAssignment ( ) , context . UnitTypes ( ) )
2017-04-25 03:24:51 -04:00
m . Group ( "/:username/:reponame" , func ( ) {
m . Get ( "/stars" , repo . Stars )
m . Get ( "/watchers" , repo . Watchers )
2018-11-28 19:26:14 +08:00
m . Get ( "/search" , reqRepoCodeReader , repo . Search )
} , ignSignIn , context . RepoAssignment ( ) , context . RepoRef ( ) , context . UnitTypes ( ) )
2017-04-25 03:24:51 -04:00
m . Group ( "/:username" , func ( ) {
m . Group ( "/:reponame" , func ( ) {
m . Get ( "" , repo . SetEditorconfigIfExists , repo . Home )
m . Get ( "\\.git$" , repo . SetEditorconfigIfExists , repo . Home )
2018-11-28 19:26:14 +08:00
} , ignSignIn , context . RepoAssignment ( ) , context . RepoRef ( ) , context . UnitTypes ( ) )
2017-04-25 03:24:51 -04:00
m . Group ( "/:reponame" , func ( ) {
2017-11-29 00:35:23 +01:00
m . Group ( "\\.git/info/lfs" , func ( ) {
2017-04-25 03:24:51 -04:00
m . Post ( "/objects/batch" , lfs . BatchHandler )
m . Get ( "/objects/:oid/:filename" , lfs . ObjectOidHandler )
m . Any ( "/objects/:oid" , lfs . ObjectOidHandler )
m . Post ( "/objects" , lfs . PostHandler )
2017-11-08 15:04:19 +02:00
m . Post ( "/verify" , lfs . VerifyHandler )
2017-11-28 21:58:37 +01:00
m . Group ( "/locks" , func ( ) {
m . Get ( "/" , lfs . GetListLockHandler )
m . Post ( "/" , lfs . PostLockHandler )
m . Post ( "/verify" , lfs . VerifyLockHandler )
m . Post ( "/:lid/unlock" , lfs . UnLockHandler )
2019-05-28 11:32:41 +01:00
} )
2017-04-25 03:24:51 -04:00
m . Any ( "/*" , func ( ctx * context . Context ) {
2018-01-10 22:34:17 +01:00
ctx . NotFound ( "" , nil )
2017-04-25 03:24:51 -04:00
} )
} , ignSignInAndCsrf )
m . Any ( "/*" , ignSignInAndCsrf , repo . HTTP )
m . Head ( "/tasks/trigger" , repo . TriggerTask )
} )
} )
// ***** END: Repository *****
m . Group ( "/notifications" , func ( ) {
m . Get ( "" , user . Notifications )
m . Post ( "/status" , user . NotificationStatusPost )
2017-12-07 12:52:57 +07:00
m . Post ( "/purge" , user . NotificationPurgePost )
2017-04-25 03:24:51 -04:00
} , reqSignIn )
2018-07-28 02:19:01 +02:00
if setting . API . EnableSwagger {
m . Get ( "/swagger.v1.json" , templates . JSONRenderer ( ) , routers . SwaggerV1Json )
}
2019-08-26 04:33:06 -07:00
var handlers [ ] macaron . Handler
if setting . EnableCORS {
handlers = append ( handlers , cors . CORS ( setting . CORSConfig ) )
}
handlers = append ( handlers , ignSignIn )
2017-04-25 03:24:51 -04:00
m . Group ( "/api" , func ( ) {
apiv1 . RegisterRoutes ( m )
2019-08-26 04:33:06 -07:00
} , handlers ... )
2017-04-25 03:24:51 -04:00
m . Group ( "/api/internal" , func ( ) {
// package name internal is ideal but Golang is not allowed, so we use private as package name.
private . RegisterRoutes ( m )
} )
// robots.txt
m . Get ( "/robots.txt" , func ( ctx * context . Context ) {
if setting . HasRobotsTxt {
ctx . ServeFileContent ( path . Join ( setting . CustomPath , "robots.txt" ) )
} else {
2018-01-10 22:34:17 +01:00
ctx . NotFound ( "" , nil )
2017-04-25 03:24:51 -04:00
}
} )
2018-11-27 16:18:26 +01:00
// Progressive Web App
m . Get ( "/manifest.json" , templates . JSONRenderer ( ) , func ( ctx * context . Context ) {
ctx . HTML ( 200 , "pwa/manifest_json" )
} )
m . Get ( "/serviceworker.js" , templates . JSRenderer ( ) , func ( ctx * context . Context ) {
ctx . HTML ( 200 , "pwa/serviceworker_js" )
} )
2018-11-05 06:20:00 +03:00
// prometheus metrics endpoint
if setting . Metrics . Enabled {
c := metrics . NewCollector ( )
prometheus . MustRegister ( c )
m . Get ( "/metrics" , routers . Metrics )
}
2017-04-25 03:24:51 -04:00
// Not found handler.
m . NotFound ( routers . NotFound )
}