2014-02-19 17:50:53 +08: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.
2014-05-01 21:21:46 -04:00
package cmd
2014-02-19 17:50:53 +08:00
import (
2014-12-11 11:14:41 +01:00
"crypto/tls"
2014-02-19 17:50:53 +08:00
"fmt"
2014-05-28 00:06:31 -04:00
"io/ioutil"
2014-02-19 17:50:53 +08:00
"net/http"
2014-11-03 20:46:53 -05:00
"net/http/fcgi"
2014-04-15 20:01:20 -04:00
"os"
2014-05-25 20:11:25 -04:00
"path"
2014-09-29 05:38:46 -04:00
"strings"
2014-02-19 17:50:53 +08:00
"github.com/codegangsta/cli"
2015-10-15 21:28:12 -04:00
"github.com/go-macaron/binding"
"github.com/go-macaron/cache"
"github.com/go-macaron/captcha"
"github.com/go-macaron/csrf"
"github.com/go-macaron/gzip"
"github.com/go-macaron/i18n"
"github.com/go-macaron/session"
"github.com/go-macaron/toolbox"
2015-08-06 23:03:04 +08:00
"github.com/go-xorm/xorm"
"github.com/mcuadros/go-version"
2015-01-02 20:14:43 +08:00
"gopkg.in/ini.v1"
2015-10-15 21:28:12 -04:00
"gopkg.in/macaron.v1"
2014-02-19 17:50:53 +08:00
2015-12-15 17:25:45 -05:00
"github.com/gogits/git-module"
2016-01-06 13:34:34 +08:00
"github.com/gogits/go-gogs-client"
2015-12-09 20:46:05 -05:00
2014-08-06 17:21:24 -04:00
"github.com/gogits/gogs/models"
2014-03-06 02:21:44 -05:00
"github.com/gogits/gogs/modules/auth"
2015-03-18 06:37:44 -04:00
"github.com/gogits/gogs/modules/bindata"
2016-03-11 11:56:52 -05:00
"github.com/gogits/gogs/modules/context"
2014-03-07 17:22:15 -05:00
"github.com/gogits/gogs/modules/log"
2014-05-25 20:11:25 -04:00
"github.com/gogits/gogs/modules/setting"
2015-11-13 17:10:25 -05:00
"github.com/gogits/gogs/modules/template"
2014-02-19 17:50:53 +08:00
"github.com/gogits/gogs/routers"
2014-03-20 07:50:26 -04:00
"github.com/gogits/gogs/routers/admin"
2015-12-04 17:16:42 -05:00
apiv1 "github.com/gogits/gogs/routers/api/v1"
2014-03-19 12:50:44 -04:00
"github.com/gogits/gogs/routers/dev"
2014-07-26 02:28:04 -04:00
"github.com/gogits/gogs/routers/org"
2014-02-19 21:45:43 -05:00
"github.com/gogits/gogs/routers/repo"
2014-02-19 17:50:53 +08:00
"github.com/gogits/gogs/routers/user"
)
var CmdWeb = cli . Command {
Name : "web" ,
2014-05-01 21:21:46 -04:00
Usage : "Start Gogs web server" ,
2014-08-30 15:12:53 +02:00
Description : ` Gogs web server is the only thing you need to run ,
2014-03-24 07:36:38 -04:00
and it takes care of all the other things for you ` ,
2014-02-19 17:50:53 +08:00
Action : runWeb ,
2015-02-01 12:41:03 -05:00
Flags : [ ] cli . Flag {
2015-11-15 17:07:44 -05:00
stringFlag ( "port, p" , "3000" , "Temporary port number to prevent conflict" ) ,
stringFlag ( "config, c" , "custom/conf/app.ini" , "Custom configuration file path" ) ,
2015-02-01 12:41:03 -05:00
} ,
2014-02-19 17:50:53 +08:00
}
2014-12-15 01:49:59 -05:00
type VerChecker struct {
ImportPath string
Version func ( ) string
Expected string
}
2014-08-24 21:09:05 +08:00
// checkVersion checks if binary matches the version of templates files.
2014-05-25 20:57:01 -04:00
func checkVersion ( ) {
2014-09-28 01:38:25 -04:00
// Templates.
2015-08-02 11:36:18 +08:00
data , err := ioutil . ReadFile ( setting . StaticRootPath + "/templates/.VERSION" )
2014-05-25 20:57:01 -04:00
if err != nil {
2014-07-26 00:24:27 -04:00
log . Fatal ( 4 , "Fail to read 'templates/.VERSION': %v" , err )
2014-05-25 20:57:01 -04:00
}
if string ( data ) != setting . AppVer {
2014-07-26 00:24:27 -04:00
log . Fatal ( 4 , "Binary and template file version does not match, did you forget to recompile?" )
2014-05-25 20:57:01 -04:00
}
2014-09-28 01:38:25 -04:00
2014-10-06 19:12:52 -04:00
// Check dependency version.
2014-12-15 01:49:59 -05:00
checkers := [ ] VerChecker {
2016-07-16 00:36:39 +08:00
{ "github.com/go-xorm/xorm" , func ( ) string { return xorm . Version } , "0.5.5" } ,
2016-07-12 07:07:57 +08:00
{ "github.com/go-macaron/binding" , binding . Version , "0.3.2" } ,
2015-11-03 12:16:43 -05:00
{ "github.com/go-macaron/cache" , cache . Version , "0.1.2" } ,
2016-03-12 20:56:03 -05:00
{ "github.com/go-macaron/csrf" , csrf . Version , "0.1.0" } ,
2016-06-12 17:54:22 +08:00
{ "github.com/go-macaron/i18n" , i18n . Version , "0.3.0" } ,
2015-11-03 12:16:43 -05:00
{ "github.com/go-macaron/session" , session . Version , "0.1.6" } ,
2015-11-14 13:21:31 -05:00
{ "github.com/go-macaron/toolbox" , toolbox . Version , "0.1.0" } ,
2015-12-11 18:52:28 -05:00
{ "gopkg.in/ini.v1" , ini . Version , "1.8.4" } ,
2016-08-05 18:34:13 -07:00
{ "gopkg.in/macaron.v1" , macaron . Version , "1.1.7" } ,
2016-08-11 10:53:51 -07:00
{ "github.com/gogits/git-module" , git . Version , "0.3.5" } ,
2016-08-09 18:28:06 -07:00
{ "github.com/gogits/go-gogs-client" , gogs . Version , "0.10.3" } ,
2014-10-10 06:15:27 -04:00
}
2014-12-15 01:49:59 -05:00
for _ , c := range checkers {
2015-08-06 23:03:04 +08:00
if ! version . Compare ( c . Version ( ) , c . Expected , ">=" ) {
2016-07-11 07:57:15 +08:00
log . Fatal ( 4 , ` Dependency outdated !
Package ' % s ' current version ( % s ) is below requirement ( % s ) ,
please use following command to update this package and recompile Gogs :
go get - u % [ 1 ] s ` , c . ImportPath , c . Version ( ) , c . Expected )
2014-12-15 01:49:59 -05:00
}
2014-09-28 01:38:25 -04:00
}
2014-05-25 20:57:01 -04:00
}
2014-07-26 00:24:27 -04:00
// newMacaron initializes Macaron instance.
func newMacaron ( ) * macaron . Macaron {
m := macaron . New ( )
2015-07-31 15:03:30 +08:00
if ! setting . DisableRouterLog {
m . Use ( macaron . Logger ( ) )
}
2014-07-26 00:24:27 -04:00
m . Use ( macaron . Recovery ( ) )
2014-10-13 18:04:07 -04:00
if setting . EnableGzip {
2015-10-15 21:28:12 -04:00
m . Use ( gzip . Gziper ( ) )
2014-10-13 18:04:07 -04:00
}
2014-11-16 00:06:09 -05:00
if setting . Protocol == setting . FCGI {
m . SetURLPrefix ( setting . AppSubUrl )
}
2014-09-15 17:23:58 -04:00
m . Use ( macaron . Static (
path . Join ( setting . StaticRootPath , "public" ) ,
2014-07-26 00:24:27 -04:00
macaron . StaticOptions {
2015-07-31 15:03:30 +08:00
SkipLogging : setting . DisableRouterLog ,
2014-07-26 00:24:27 -04:00
} ,
) )
2014-11-21 10:58:08 -05:00
m . Use ( macaron . Static (
setting . AvatarUploadPath ,
macaron . StaticOptions {
Prefix : "avatars" ,
2015-07-31 15:03:30 +08:00
SkipLogging : setting . DisableRouterLog ,
2014-11-21 10:58:08 -05:00
} ,
) )
2016-07-16 00:36:39 +08:00
funcMap := template . NewFuncMap ( )
2014-07-26 00:24:27 -04:00
m . Use ( macaron . Renderer ( macaron . RenderOptions {
2016-03-12 13:48:34 -05:00
Directory : path . Join ( setting . StaticRootPath , "templates" ) ,
AppendDirectories : [ ] string { path . Join ( setting . CustomPath , "templates" ) } ,
2016-07-16 00:36:39 +08:00
Funcs : funcMap ,
2016-03-12 13:48:34 -05:00
IndentJSON : macaron . Env != macaron . PROD ,
2014-07-26 00:24:27 -04:00
} ) )
2016-07-16 00:36:39 +08:00
models . InitMailRender ( path . Join ( setting . StaticRootPath , "templates/mail" ) ,
path . Join ( setting . CustomPath , "templates/mail" ) , funcMap )
2015-03-18 06:37:44 -04:00
localeNames , err := bindata . AssetDir ( "conf/locale" )
if err != nil {
log . Fatal ( 4 , "Fail to list locale files: %v" , err )
}
localFiles := make ( map [ string ] [ ] byte )
for _ , name := range localeNames {
localFiles [ name ] = bindata . MustAsset ( "conf/locale/" + name )
}
2014-08-06 17:21:24 -04:00
m . Use ( i18n . I18n ( i18n . Options {
2014-10-09 18:35:09 -04:00
SubURL : setting . AppSubUrl ,
2015-03-18 06:37:44 -04:00
Files : localFiles ,
2014-10-09 18:35:09 -04:00
CustomDirectory : path . Join ( setting . CustomPath , "conf/locale" ) ,
Langs : setting . Langs ,
Names : setting . Names ,
2015-12-05 01:20:11 -05:00
DefaultLang : "en-US" ,
2014-10-09 18:35:09 -04:00
Redirect : true ,
2014-07-26 00:24:27 -04:00
} ) )
2014-07-31 17:25:34 -04:00
m . Use ( cache . Cacher ( cache . Options {
2014-12-31 17:08:57 +08:00
Adapter : setting . CacheAdapter ,
AdapterConfig : setting . CacheConn ,
2016-08-11 14:59:11 +02:00
Interval : setting . CacheInterval ,
2014-07-31 17:25:34 -04:00
} ) )
2014-09-19 20:11:34 -04:00
m . Use ( captcha . Captchaer ( captcha . Options {
SubURL : setting . AppSubUrl ,
} ) )
2014-12-28 20:40:35 +08:00
m . Use ( session . Sessioner ( setting . SessionConfig ) )
2014-12-20 22:51:16 -05:00
m . Use ( csrf . Csrfer ( csrf . Options {
2014-09-21 12:22:50 -04:00
Secret : setting . SecretKey ,
2016-03-12 20:56:03 -05:00
Cookie : setting . CSRFCookieName ,
2014-09-21 12:22:50 -04:00
SetCookie : true ,
Header : "X-Csrf-Token" ,
CookiePath : setting . AppSubUrl ,
2014-07-31 17:25:34 -04:00
} ) )
2014-08-06 17:21:24 -04:00
m . Use ( toolbox . Toolboxer ( m , toolbox . Options {
HealthCheckFuncs : [ ] * toolbox . HealthCheckFuncDesc {
& toolbox . HealthCheckFuncDesc {
Desc : "Database connection" ,
Func : models . Ping ,
} ,
} ,
} ) )
2016-03-11 11:56:52 -05:00
m . Use ( context . Contexter ( ) )
2014-07-26 00:24:27 -04:00
return m
2014-03-19 05:31:38 -04:00
}
2016-05-12 14:32:28 -04:00
func runWeb ( ctx * cli . Context ) error {
2015-02-05 12:12:37 +02:00
if ctx . IsSet ( "config" ) {
setting . CustomConf = ctx . String ( "config" )
}
2014-03-29 17:50:51 -04:00
routers . GlobalInit ( )
2015-02-14 17:01:33 -05:00
checkVersion ( )
2014-02-19 17:50:53 +08:00
2014-07-26 00:24:27 -04:00
m := newMacaron ( )
2014-03-15 19:01:50 +08:00
2016-03-11 11:56:52 -05:00
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 } )
2014-03-23 01:44:02 +08:00
2014-05-05 02:42:52 -04:00
bindIgnErr := binding . BindIgnErr
2014-04-10 14:37:43 -04:00
2016-03-05 18:08:42 -05:00
// FIXME: not all routes need go through same middlewares.
// Especially some AJAX requests, we can reduce middleware number to improve performance.
2014-02-19 17:50:53 +08:00
// Routers.
2014-03-24 11:58:46 -04:00
m . Get ( "/" , ignSignIn , routers . Home )
2016-03-11 15:33:12 -05:00
m . Group ( "/explore" , func ( ) {
2016-03-11 17:12:37 -05:00
m . Get ( "" , func ( ctx * context . Context ) {
ctx . Redirect ( setting . AppSubUrl + "/explore/repos" )
} )
2016-03-11 15:33:12 -05:00
m . Get ( "/repos" , routers . ExploreRepos )
m . Get ( "/users" , routers . ExploreUsers )
} , ignSignIn )
2015-09-02 16:18:09 -04:00
m . Combo ( "/install" , routers . InstallInit ) . Get ( routers . Install ) .
2015-02-01 12:41:03 -05:00
Post ( bindIgnErr ( auth . InstallForm { } ) , routers . InstallPost )
2015-09-24 14:20:07 -04:00
m . Get ( "/^:type(issues|pulls)$" , reqSignIn , user . Issues )
2014-03-29 10:01:52 -04:00
2015-08-19 02:49:44 +08:00
// ***** START: User *****
2014-10-24 18:43:17 -04:00
m . Group ( "/user" , func ( ) {
m . Get ( "/login" , user . SignIn )
m . Post ( "/login" , bindIgnErr ( auth . SignInForm { } ) , user . SignInPost )
m . Get ( "/sign_up" , user . SignUp )
m . Post ( "/sign_up" , bindIgnErr ( auth . RegisterForm { } ) , user . SignUpPost )
m . Get ( "/reset_password" , user . ResetPasswd )
m . Post ( "/reset_password" , user . ResetPasswdPost )
2014-03-22 16:00:46 -04:00
} , reqSignOut )
2015-08-19 02:49:44 +08:00
2014-10-24 18:43:17 -04:00
m . Group ( "/user/settings" , func ( ) {
m . Get ( "" , user . Settings )
m . Post ( "" , bindIgnErr ( auth . UpdateProfileForm { } ) , user . SettingsPost )
2016-08-07 19:27:38 +02:00
m . Combo ( "/avatar" ) . Get ( user . SettingsAvatar ) .
Post ( binding . MultipartForm ( auth . AvatarForm { } ) , user . SettingsAvatarPost )
2016-03-05 00:51:51 -05:00
m . Post ( "/avatar/delete" , user . SettingsDeleteAvatar )
2015-09-10 11:40:34 -04:00
m . Combo ( "/email" ) . Get ( user . SettingsEmails ) .
Post ( bindIgnErr ( auth . AddEmailForm { } ) , user . SettingsEmailPost )
m . Post ( "/email/delete" , user . DeleteEmail )
2014-10-24 18:43:17 -04:00
m . Get ( "/password" , user . SettingsPassword )
m . Post ( "/password" , bindIgnErr ( auth . ChangePasswordForm { } ) , user . SettingsPasswordPost )
2015-08-20 17:11:29 +08:00
m . Combo ( "/ssh" ) . Get ( user . SettingsSSHKeys ) .
Post ( bindIgnErr ( auth . AddSSHKeyForm { } ) , user . SettingsSSHKeysPost )
m . Post ( "/ssh/delete" , user . DeleteSSHKey )
2015-08-19 03:36:16 +08:00
m . Combo ( "/applications" ) . Get ( user . SettingsApplications ) .
Post ( bindIgnErr ( auth . NewAccessTokenForm { } ) , user . SettingsApplicationsPost )
m . Post ( "/applications/delete" , user . SettingsDeleteApplication )
2014-10-24 18:43:17 -04:00
m . Route ( "/delete" , "GET,POST" , user . SettingsDelete )
2016-03-11 11:56:52 -05:00
} , reqSignIn , func ( ctx * context . Context ) {
2015-08-19 02:49:44 +08:00
ctx . Data [ "PageIsUserSettings" ] = true
} )
2014-10-24 18:43:17 -04:00
m . Group ( "/user" , func ( ) {
2014-07-26 00:24:27 -04:00
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
2014-10-24 18:43:17 -04:00
m . Any ( "/activate" , user . Activate )
2014-12-17 17:42:54 +02:00
m . Any ( "/activate_email" , user . ActivateEmail )
2014-10-24 18:43:17 -04:00
m . Get ( "/email2user" , user . Email2User )
m . Get ( "/forget_password" , user . ForgotPasswd )
m . Post ( "/forget_password" , user . ForgotPasswdPost )
m . Get ( "/logout" , user . SignOut )
2014-03-22 16:00:46 -04:00
} )
2015-08-19 02:49:44 +08:00
// ***** END: User *****
2014-03-10 16:54:52 +08:00
2016-03-11 11:56:52 -05:00
adminReq := context . Toggle ( & context . ToggleOptions { SignInRequired : true , AdminRequired : true } )
2014-03-23 01:44:02 +08:00
2015-08-26 21:45:51 +08:00
// ***** START: Admin *****
2014-10-24 18:43:17 -04:00
m . Group ( "/admin" , func ( ) {
2014-08-29 20:50:43 +08:00
m . Get ( "" , adminReq , admin . Dashboard )
2014-10-24 18:43:17 -04:00
m . Get ( "/config" , admin . Config )
2016-02-24 23:59:17 -05:00
m . Post ( "/config/test_mail" , admin . SendTestMail )
2014-10-24 18:43:17 -04:00
m . Get ( "/monitor" , admin . Monitor )
m . Group ( "/users" , func ( ) {
m . Get ( "" , admin . Users )
2015-12-11 19:24:57 -05:00
m . Combo ( "/new" ) . Get ( admin . NewUser ) . Post ( bindIgnErr ( auth . AdminCrateUserForm { } ) , admin . NewUserPost )
m . Combo ( "/:userid" ) . Get ( admin . EditUser ) . Post ( bindIgnErr ( auth . AdminEditUserForm { } ) , admin . EditUserPost )
2014-10-24 18:43:17 -04:00
m . Post ( "/:userid/delete" , admin . DeleteUser )
2014-08-29 20:50:43 +08:00
} )
2014-10-24 18:43:17 -04:00
m . Group ( "/orgs" , func ( ) {
m . Get ( "" , admin . Organizations )
2014-08-29 20:50:43 +08:00
} )
2014-10-24 18:43:17 -04:00
m . Group ( "/repos" , func ( ) {
2015-12-05 17:39:29 -05:00
m . Get ( "" , admin . Repos )
m . Post ( "/delete" , admin . DeleteRepo )
2014-08-29 20:50:43 +08:00
} )
2014-10-24 18:43:17 -04:00
m . Group ( "/auths" , func ( ) {
m . Get ( "" , admin . Authentications )
2015-12-11 19:24:57 -05:00
m . Combo ( "/new" ) . Get ( admin . NewAuthSource ) . Post ( bindIgnErr ( auth . AuthenticationForm { } ) , admin . NewAuthSourcePost )
2015-09-11 12:03:08 -04:00
m . Combo ( "/:authid" ) . Get ( admin . EditAuthSource ) .
Post ( bindIgnErr ( auth . AuthenticationForm { } ) , admin . EditAuthSourcePost )
2014-10-24 18:43:17 -04:00
m . Post ( "/:authid/delete" , admin . DeleteAuthSource )
2014-08-29 20:50:43 +08:00
} )
2014-10-08 18:29:18 -04:00
2014-10-24 18:43:17 -04:00
m . Group ( "/notices" , func ( ) {
m . Get ( "" , admin . Notices )
2015-12-05 01:09:14 -05:00
m . Post ( "/delete" , admin . DeleteNotices )
2015-12-01 23:33:08 -05:00
m . Get ( "/empty" , admin . EmptyNotices )
2014-10-08 18:29:18 -04:00
} )
2014-05-03 10:48:14 +08:00
} , adminReq )
2015-08-26 21:45:51 +08:00
// ***** END: Admin *****
2014-05-03 10:48:14 +08:00
2015-08-11 17:54:00 +08:00
m . Group ( "" , func ( ) {
2015-12-21 04:24:11 -08:00
m . Group ( "/:username" , func ( ) {
m . Get ( "" , user . Profile )
m . Get ( "/followers" , user . Followers )
m . Get ( "/following" , user . Following )
m . Get ( "/stars" , user . Stars )
} )
2016-03-11 11:56:52 -05:00
m . Get ( "/attachments/:uuid" , func ( ctx * context . Context ) {
2015-08-11 23:24:40 +08:00
attach , err := models . GetAttachmentByUUID ( ctx . Params ( ":uuid" ) )
if err != nil {
if models . IsErrAttachmentNotExist ( err ) {
ctx . Error ( 404 )
} else {
ctx . Handle ( 500 , "GetAttachmentByUUID" , err )
}
return
}
2015-08-12 04:49:51 +08:00
fr , err := os . Open ( attach . LocalPath ( ) )
if err != nil {
ctx . Handle ( 500 , "Open" , err )
return
}
defer fr . Close ( )
2015-08-12 04:58:39 +08:00
ctx . Header ( ) . Set ( "Cache-Control" , "public,max-age=86400" )
2015-08-11 23:24:40 +08:00
// Fix #312. Attachments with , in their name are not handled correctly by Google Chrome.
// We must put the name in " manually.
2015-08-12 04:49:51 +08:00
if err = repo . ServeData ( ctx , "\"" + attach . Name + "\"" , fr ) ; err != nil {
ctx . Handle ( 500 , "ServeData" , err )
return
}
2015-08-11 23:24:40 +08:00
} )
m . Post ( "/issues/attachments" , repo . UploadIssueAttachment )
2015-08-11 17:54:00 +08:00
} , ignSignIn )
2014-07-12 00:55:19 -04:00
2015-12-21 04:24:11 -08:00
m . Group ( "/:username" , func ( ) {
m . Get ( "/action/:action" , user . Action )
} , reqSignIn )
2014-07-26 00:24:27 -04:00
if macaron . Env == macaron . DEV {
2014-07-31 17:25:34 -04:00
m . Get ( "/template/*" , dev . TemplatePreview )
2014-03-27 11:37:33 -04:00
}
2016-03-11 11:56:52 -05:00
reqRepoAdmin := context . RequireRepoAdmin ( )
reqRepoWriter := context . RequireRepoWriter ( )
2014-07-26 02:28:04 -04:00
2015-08-26 21:45:51 +08:00
// ***** START: Organization *****
2014-10-24 18:43:17 -04:00
m . Group ( "/org" , func ( ) {
m . Get ( "/create" , org . Create )
m . Post ( "/create" , bindIgnErr ( auth . CreateOrgForm { } ) , org . CreatePost )
m . Group ( "/:org" , func ( ) {
m . Get ( "/dashboard" , user . Dashboard )
2015-09-24 14:20:07 -04:00
m . Get ( "/^:type(issues|pulls)$" , user . Issues )
2014-10-24 18:43:17 -04:00
m . Get ( "/members" , org . Members )
m . Get ( "/members/action/:action" , org . MembersAction )
m . Get ( "/teams" , org . Teams )
2016-03-11 11:56:52 -05:00
} , context . OrgAssignment ( true ) )
2016-01-31 13:28:42 +00:00
m . Group ( "/:org" , func ( ) {
2014-10-24 18:43:17 -04:00
m . Get ( "/teams/:team" , org . TeamMembers )
m . Get ( "/teams/:team/repositories" , org . TeamRepositories )
2015-11-22 01:32:09 -05:00
m . Route ( "/teams/:team/action/:action" , "GET,POST" , org . TeamsAction )
m . Route ( "/teams/:team/action/repo/:action" , "GET,POST" , org . TeamsRepoAction )
2016-03-11 11:56:52 -05:00
} , context . OrgAssignment ( true , false , true ) )
2014-07-26 02:28:04 -04:00
2014-10-24 18:43:17 -04:00
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 ( ) {
2015-08-26 21:45:51 +08:00
m . Combo ( "" ) . Get ( org . Settings ) .
Post ( bindIgnErr ( auth . UpdateOrgSettingForm { } ) , org . SettingsPost )
2016-08-07 19:27:38 +02:00
m . Post ( "/avatar" , binding . MultipartForm ( auth . AvatarForm { } ) , org . SettingsAvatar )
2016-03-06 17:36:30 +01:00
m . Post ( "/avatar/delete" , org . SettingsDeleteAvatar )
2015-08-26 21:45:51 +08:00
m . Group ( "/hooks" , func ( ) {
m . Get ( "" , org . Webhooks )
m . Post ( "/delete" , org . DeleteWebhook )
2015-08-27 00:30:06 +08:00
m . Get ( "/:type/new" , repo . WebhooksNew )
m . Post ( "/gogs/new" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksNewPost )
m . Post ( "/slack/new" , bindIgnErr ( auth . NewSlackHookForm { } ) , repo . SlackHooksNewPost )
2015-08-27 01:04:23 +08:00
m . Get ( "/:id" , repo . WebHooksEdit )
m . Post ( "/gogs/:id" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksEditPost )
m . Post ( "/slack/:id" , bindIgnErr ( auth . NewSlackHookForm { } ) , repo . SlackHooksEditPost )
2015-08-26 21:45:51 +08:00
} )
2014-10-24 18:43:17 -04:00
m . Route ( "/delete" , "GET,POST" , org . SettingsDelete )
2014-08-14 14:12:21 +08:00
} )
2014-08-15 18:29:41 +08:00
2014-10-24 18:43:17 -04:00
m . Route ( "/invitations/new" , "GET,POST" , org . Invitation )
2016-03-11 11:56:52 -05:00
} , context . OrgAssignment ( true , true ) )
2014-07-26 02:28:04 -04:00
} , reqSignIn )
2015-08-26 21:45:51 +08:00
// ***** END: Organization *****
2014-07-26 02:28:04 -04:00
2015-08-26 21:45:51 +08:00
// ***** START: Repository *****
2014-10-24 18:43:17 -04:00
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 )
2015-08-08 17:10:34 +08:00
m . Combo ( "/fork/:repoid" ) . Get ( repo . Fork ) .
Post ( bindIgnErr ( auth . CreateRepoForm { } ) , repo . ForkPost )
2014-07-26 23:53:16 -04:00
} , reqSignIn )
2014-10-24 18:43:17 -04:00
m . Group ( "/:username/:reponame" , func ( ) {
m . Group ( "/settings" , func ( ) {
2015-08-26 21:45:51 +08:00
m . Combo ( "" ) . Get ( repo . Settings ) .
Post ( bindIgnErr ( auth . RepoSettingForm { } ) , repo . SettingsPost )
2016-03-05 18:08:42 -05:00
m . Group ( "/collaboration" , func ( ) {
m . Combo ( "" ) . Get ( repo . Collaboration ) . Post ( repo . CollaborationPost )
m . Post ( "/access_mode" , repo . ChangeCollaborationAccessMode )
m . Post ( "/delete" , repo . DeleteCollaboration )
} )
2015-08-26 21:45:51 +08:00
m . Group ( "/hooks" , func ( ) {
m . Get ( "" , repo . Webhooks )
m . Post ( "/delete" , repo . DeleteWebhook )
2015-08-27 00:30:06 +08:00
m . Get ( "/:type/new" , repo . WebhooksNew )
m . Post ( "/gogs/new" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksNewPost )
m . Post ( "/slack/new" , bindIgnErr ( auth . NewSlackHookForm { } ) , repo . SlackHooksNewPost )
2015-08-27 01:04:23 +08:00
m . Get ( "/:id" , repo . WebHooksEdit )
2015-12-05 13:24:13 -05:00
m . Post ( "/:id/test" , repo . TestWebhook )
2015-08-27 01:04:23 +08:00
m . Post ( "/gogs/:id" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksEditPost )
m . Post ( "/slack/:id" , bindIgnErr ( auth . NewSlackHookForm { } ) , repo . SlackHooksEditPost )
m . Group ( "/git" , func ( ) {
m . Get ( "" , repo . GitHooks )
m . Combo ( "/:name" ) . Get ( repo . GitHooksEdit ) .
Post ( repo . GitHooksEditPost )
2016-03-11 11:56:52 -05:00
} , context . GitHookService ( ) )
2015-08-26 21:45:51 +08:00
} )
2015-08-27 00:30:06 +08:00
2015-08-06 22:48:11 +08:00
m . Group ( "/keys" , func ( ) {
2015-08-26 21:45:51 +08:00
m . Combo ( "" ) . Get ( repo . DeployKeys ) .
Post ( bindIgnErr ( auth . AddSSHKeyForm { } ) , repo . DeployKeysPost )
2015-08-06 22:48:11 +08:00
m . Post ( "/delete" , repo . DeleteDeployKey )
} )
2016-03-11 11:56:52 -05:00
} , func ( ctx * context . Context ) {
2015-11-16 11:16:52 -05:00
ctx . Data [ "PageIsSettings" ] = true
2014-07-26 02:28:04 -04:00
} )
2016-03-11 11:56:52 -05:00
} , reqSignIn , context . RepoAssignment ( ) , reqRepoAdmin , context . RepoRef ( ) )
2014-07-26 02:28:04 -04:00
2016-03-11 11:56:52 -05:00
m . Get ( "/:username/:reponame/action/:action" , reqSignIn , context . RepoAssignment ( ) , repo . Action )
2014-10-24 18:43:17 -04:00
m . Group ( "/:username/:reponame" , func ( ) {
2016-08-09 09:39:55 -07: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.
2014-10-24 18:43:17 -04:00
m . Group ( "/issues" , func ( ) {
2016-08-09 09:39:55 -07:00
m . Combo ( "/new" , repo . MustEnableIssues ) . Get ( context . RepoRef ( ) , repo . NewIssue ) .
2015-08-09 15:23:02 +08:00
Post ( bindIgnErr ( auth . CreateIssueForm { } ) , repo . NewIssuePost )
2015-08-13 16:07:11 +08:00
m . Group ( "/:index" , func ( ) {
m . Post ( "/label" , repo . UpdateIssueLabel )
m . Post ( "/milestone" , repo . UpdateIssueMilestone )
2015-08-15 00:42:43 +08:00
m . Post ( "/assignee" , repo . UpdateIssueAssignee )
2016-03-05 20:45:23 -05:00
} , reqRepoWriter )
2015-08-20 04:31:28 +08:00
m . Group ( "/:index" , func ( ) {
m . Post ( "/title" , repo . UpdateIssueTitle )
m . Post ( "/content" , repo . UpdateIssueContent )
2016-08-11 06:22:56 -07:00
m . Combo ( "/comments" ) . Post ( bindIgnErr ( auth . CreateCommentForm { } ) , repo . NewComment )
2015-08-20 04:31:28 +08:00
} )
2016-08-09 09:39:55 -07:00
} )
2016-07-26 02:48:17 +08:00
m . Group ( "/comments/:id" , func ( ) {
m . Post ( "" , repo . UpdateCommentContent )
m . Post ( "/delete" , repo . DeleteComment )
} )
2015-07-24 16:42:47 +08: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 )
2016-08-04 16:32:02 -07:00
} , repo . MustEnableIssues , reqRepoWriter , context . RepoRef ( ) )
2015-07-24 16:42:47 +08:00
m . Group ( "/milestones" , func ( ) {
2015-12-02 20:56:26 -05:00
m . Combo ( "/new" ) . Get ( repo . NewMilestone ) .
Post ( bindIgnErr ( auth . CreateMilestoneForm { } ) , repo . NewMilestonePost )
2015-08-06 23:25:35 +08:00
m . Get ( "/:id/edit" , repo . EditMilestone )
m . Post ( "/:id/edit" , bindIgnErr ( auth . CreateMilestoneForm { } ) , repo . EditMilestonePost )
m . Get ( "/:id/:action" , repo . ChangeMilestonStatus )
2015-08-05 20:23:08 +08:00
m . Post ( "/delete" , repo . DeleteMilestone )
2016-08-04 16:32:02 -07:00
} , repo . MustEnableIssues , reqRepoWriter , context . RepoRef ( ) )
2014-07-26 02:28:04 -04:00
2014-12-10 16:37:54 -05:00
m . Group ( "/releases" , func ( ) {
m . Get ( "/new" , repo . NewRelease )
m . Post ( "/new" , bindIgnErr ( auth . NewReleaseForm { } ) , repo . NewReleasePost )
m . Get ( "/edit/:tagname" , repo . EditRelease )
m . Post ( "/edit/:tagname" , bindIgnErr ( auth . EditReleaseForm { } ) , repo . EditReleasePost )
2015-11-20 02:38:41 -05:00
m . Post ( "/delete" , repo . DeleteRelease )
2016-03-11 11:56:52 -05:00
} , reqRepoWriter , context . RepoRef ( ) )
2015-08-08 22:43:14 +08:00
2016-02-19 20:48:32 +01:00
m . Combo ( "/compare/*" , repo . MustAllowPulls ) . Get ( repo . CompareAndPullRequest ) .
2015-09-01 19:07:02 -04:00
Post ( bindIgnErr ( auth . CreateIssueForm { } ) , repo . CompareAndPullRequestPost )
2016-03-11 11:56:52 -05:00
} , reqSignIn , context . RepoAssignment ( ) , repo . MustBeNotBare )
2014-07-26 02:28:04 -04:00
2014-10-24 18:43:17 -04:00
m . Group ( "/:username/:reponame" , func ( ) {
2015-11-16 10:14:12 -05:00
m . Group ( "" , func ( ) {
m . Get ( "/releases" , repo . Releases )
m . Get ( "/^:type(issues|pulls)$" , repo . RetrieveLabels , repo . Issues )
2015-12-03 14:31:31 -05:00
m . Get ( "/^:type(issues|pulls)$/:index" , repo . ViewIssue )
2015-11-16 10:14:12 -05:00
m . Get ( "/labels/" , repo . RetrieveLabels , repo . Labels )
m . Get ( "/milestones" , repo . Milestones )
2016-03-11 11:56:52 -05:00
} , context . RepoRef ( ) )
2015-11-16 10:14:12 -05:00
2015-11-25 20:10:25 -05:00
// m.Get("/branches", repo.Branches)
m . Group ( "/wiki" , func ( ) {
m . Get ( "/?:page" , repo . Wiki )
2015-11-27 01:50:38 -05:00
m . Get ( "/_pages" , repo . WikiPages )
2015-11-25 20:10:25 -05:00
m . Group ( "" , func ( ) {
2015-11-26 17:33:45 -05:00
m . Combo ( "/_new" ) . Get ( repo . NewWiki ) .
Post ( bindIgnErr ( auth . NewWikiForm { } ) , repo . NewWikiPost )
2015-11-27 01:50:38 -05:00
m . Combo ( "/:page/_edit" ) . Get ( repo . EditWiki ) .
Post ( bindIgnErr ( auth . NewWikiForm { } ) , repo . EditWikiPost )
2016-03-04 13:32:17 -05:00
m . Post ( "/:page/delete" , repo . DeleteWikiPagePost )
2016-03-05 20:45:23 -05:00
} , reqSignIn , reqRepoWriter )
2016-03-11 11:56:52 -05:00
} , repo . MustEnableWiki , context . RepoRef ( ) )
2015-11-25 20:10:25 -05:00
2014-10-24 18:43:17 -04:00
m . Get ( "/archive/*" , repo . Download )
2014-07-26 00:24:27 -04:00
2015-09-02 04:08:05 -04:00
m . Group ( "/pulls/:index" , func ( ) {
2016-03-11 11:56:52 -05:00
m . Get ( "/commits" , context . RepoRef ( ) , repo . ViewPullCommits )
m . Get ( "/files" , context . RepoRef ( ) , repo . ViewPullFiles )
2016-03-05 20:45:23 -05:00
m . Post ( "/merge" , reqRepoWriter , repo . MergePullRequest )
2016-02-19 20:48:32 +01:00
} , repo . MustAllowPulls )
2015-09-02 04:08:05 -04:00
2014-11-06 22:06:41 -05:00
m . Group ( "" , func ( ) {
m . Get ( "/src/*" , repo . Home )
m . Get ( "/raw/*" , repo . SingleDownload )
m . Get ( "/commits/*" , repo . RefCommits )
2016-03-21 10:49:46 -04:00
m . Get ( "/commit/:sha([a-z0-9]{40})$" , repo . Diff )
2015-10-02 10:48:31 +02:00
m . Get ( "/forks" , repo . Forks )
2016-03-11 11:56:52 -05:00
} , context . RepoRef ( ) )
2016-03-21 10:49:46 -04:00
m . Get ( "/commit/:sha([a-z0-9]{40})\\.:ext(patch|diff)" , repo . RawDiff )
2014-11-07 14:46:13 -05:00
2016-02-02 17:34:06 +00:00
m . Get ( "/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})" , repo . CompareDiff )
2016-03-11 11:56:52 -05:00
} , ignSignIn , context . RepoAssignment ( ) , repo . MustBeNotBare )
2016-01-07 11:07:17 +08:00
m . Group ( "/:username/:reponame" , func ( ) {
m . Get ( "/stars" , repo . Stars )
m . Get ( "/watchers" , repo . Watchers )
2016-03-11 11:56:52 -05:00
} , ignSignIn , context . RepoAssignment ( ) , context . RepoRef ( ) )
2014-03-22 16:00:46 -04:00
2014-10-24 18:43:17 -04:00
m . Group ( "/:username" , func ( ) {
2015-07-31 14:25:12 +08:00
m . Group ( "/:reponame" , func ( ) {
m . Get ( "" , repo . Home )
2015-09-07 11:56:06 -04:00
m . Get ( "\\.git$" , repo . Home )
2016-03-11 11:56:52 -05:00
} , ignSignIn , context . RepoAssignment ( true ) , context . RepoRef ( ) )
2015-07-31 14:25:12 +08:00
2015-08-08 01:04:12 +08:00
m . Group ( "/:reponame" , func ( ) {
2015-10-24 03:36:47 -04:00
m . Any ( "/*" , ignSignInAndCsrf , repo . HTTP )
m . Head ( "/tasks/trigger" , repo . TriggerTask )
2015-08-08 01:04:12 +08:00
} )
2014-09-15 10:09:17 -04:00
} )
2015-08-26 21:45:51 +08:00
// ***** END: Repository *****
2014-03-22 00:48:26 +08:00
2016-03-13 18:49:16 -04:00
m . Group ( "/api" , func ( ) {
apiv1 . RegisterRoutes ( m )
} , ignSignIn )
2014-09-21 19:39:10 -04:00
// robots.txt
2016-03-11 11:56:52 -05:00
m . Get ( "/robots.txt" , func ( ctx * context . Context ) {
2014-09-21 19:39:10 -04:00
if setting . HasRobotsTxt {
2015-03-18 01:29:54 -04:00
ctx . ServeFileContent ( path . Join ( setting . CustomPath , "robots.txt" ) )
2014-09-21 19:39:10 -04:00
} else {
ctx . Error ( 404 )
}
} )
2014-03-23 06:27:01 -04:00
// Not found handler.
2014-03-23 13:48:01 +08:00
m . NotFound ( routers . NotFound )
2015-02-01 12:41:03 -05:00
// Flag for port number in case first time run conflict.
if ctx . IsSet ( "port" ) {
setting . AppUrl = strings . Replace ( setting . AppUrl , setting . HttpPort , ctx . String ( "port" ) , 1 )
setting . HttpPort = ctx . String ( "port" )
}
2014-05-25 20:11:25 -04:00
var err error
listenAddr := fmt . Sprintf ( "%s:%s" , setting . HttpAddr , setting . HttpPort )
2014-09-19 20:11:34 -04:00
log . Info ( "Listen: %v://%s%s" , setting . Protocol , listenAddr , setting . AppSubUrl )
2014-05-25 20:11:25 -04:00
switch setting . Protocol {
case setting . HTTP :
err = http . ListenAndServe ( listenAddr , m )
case setting . HTTPS :
2014-12-11 18:55:09 -05:00
server := & http . Server { Addr : listenAddr , TLSConfig : & tls . Config { MinVersion : tls . VersionTLS10 } , Handler : m }
2014-12-11 11:14:41 +01:00
err = server . ListenAndServeTLS ( setting . CertFile , setting . KeyFile )
2014-11-03 20:46:53 -05:00
case setting . FCGI :
err = fcgi . Serve ( nil , m )
2014-05-25 20:11:25 -04:00
default :
2014-07-26 00:24:27 -04:00
log . Fatal ( 4 , "Invalid protocol: %s" , setting . Protocol )
2014-05-25 20:11:25 -04:00
}
if err != nil {
2014-07-26 00:24:27 -04:00
log . Fatal ( 4 , "Fail to start server: %v" , err )
2014-03-18 21:58:58 +08:00
}
2016-05-12 14:32:28 -04:00
return nil
2014-02-19 17:50:53 +08:00
}