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 (
"fmt"
2014-02-19 14:49:08 -05:00
"html/template"
2014-05-28 00:06:31 -04:00
"io/ioutil"
2014-02-19 17:50:53 +08:00
"net/http"
2014-04-15 20:01:20 -04:00
"os"
2014-05-25 20:11:25 -04:00
"path"
2014-02-19 17:50:53 +08:00
2014-07-26 00:24:27 -04:00
"github.com/Unknwon/macaron"
2014-02-19 17:50:53 +08:00
"github.com/codegangsta/cli"
2014-07-31 17:25:34 -04:00
"github.com/macaron-contrib/cache"
"github.com/macaron-contrib/captcha"
"github.com/macaron-contrib/csrf"
2014-07-26 00:24:27 -04:00
"github.com/macaron-contrib/i18n"
"github.com/macaron-contrib/session"
2014-08-06 17:21:24 -04:00
"github.com/macaron-contrib/toolbox"
2014-02-19 17:50:53 +08: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"
2014-05-05 13:08:01 -04:00
"github.com/gogits/gogs/modules/auth/apiv1"
2014-03-23 18:13:23 +08:00
"github.com/gogits/gogs/modules/avatar"
2014-03-06 02:21:44 -05:00
"github.com/gogits/gogs/modules/base"
2014-03-07 17:22:15 -05:00
"github.com/gogits/gogs/modules/log"
2014-03-15 19:01:50 +08:00
"github.com/gogits/gogs/modules/middleware"
2014-05-05 02:42:52 -04:00
"github.com/gogits/gogs/modules/middleware/binding"
2014-05-25 20:11:25 -04:00
"github.com/gogits/gogs/modules/setting"
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"
2014-03-29 10:01:52 -04:00
"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-05-05 00:55:17 -04: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 ,
2014-03-13 02:09:36 -04:00
Flags : [ ] cli . Flag { } ,
2014-02-19 17:50:53 +08:00
}
2014-05-28 00:06:31 -04:00
// checkVersion checks if binary matches the version of temolate files.
2014-05-25 20:57:01 -04:00
func checkVersion ( ) {
2014-07-26 00:24:27 -04:00
data , err := ioutil . ReadFile ( path . Join ( 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-07-26 00:24:27 -04:00
// newMacaron initializes Macaron instance.
func newMacaron ( ) * macaron . Macaron {
m := macaron . New ( )
m . Use ( macaron . Logger ( ) )
m . Use ( macaron . Recovery ( ) )
m . Use ( macaron . Static ( "public" ,
macaron . StaticOptions {
SkipLogging : ! setting . DisableRouterLog ,
} ,
) )
2014-08-06 17:21:24 -04:00
if setting . EnableGzip {
m . Use ( macaron . Gzip ( ) )
}
2014-07-26 00:24:27 -04:00
m . Use ( macaron . Renderer ( macaron . RenderOptions {
Directory : path . Join ( setting . StaticRootPath , "templates" ) ,
Funcs : [ ] template . FuncMap { base . TemplateFuncs } ,
IndentJSON : macaron . Env != macaron . PROD ,
} ) )
2014-08-06 17:21:24 -04:00
m . Use ( i18n . I18n ( i18n . Options {
2014-07-26 00:24:27 -04:00
Langs : setting . Langs ,
Names : setting . Names ,
Redirect : true ,
} ) )
2014-07-31 17:25:34 -04:00
m . Use ( cache . Cacher ( cache . Options {
Adapter : setting . CacheAdapter ,
Interval : setting . CacheInternal ,
Conn : setting . CacheConn ,
} ) )
m . Use ( captcha . Captchaer ( ) )
2014-07-26 00:24:27 -04:00
m . Use ( session . Sessioner ( session . Options {
Provider : setting . SessionProvider ,
Config : * setting . SessionConfig ,
} ) )
2014-07-31 17:25:34 -04:00
m . Use ( csrf . Generate ( csrf . Options {
Secret : setting . SecretKey ,
SetCookie : true ,
} ) )
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 ,
} ,
} ,
} ) )
2014-08-07 06:40:05 -04:00
m . Use ( middleware . Contexter ( ) )
2014-07-26 00:24:27 -04:00
return m
2014-03-19 05:31:38 -04:00
}
2014-02-19 17:50:53 +08:00
func runWeb ( * cli . Context ) {
2014-03-29 17:50:51 -04:00
routers . GlobalInit ( )
2014-05-30 06:34:24 -04: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
2014-03-23 01:44:02 +08:00
reqSignIn := middleware . Toggle ( & middleware . ToggleOptions { SignInRequire : true } )
2014-05-25 20:11:25 -04:00
ignSignIn := middleware . Toggle ( & middleware . ToggleOptions { SignInRequire : setting . Service . RequireSignInView } )
2014-04-16 04:12:31 -04:00
ignSignInAndCsrf := middleware . Toggle ( & middleware . ToggleOptions { DisableCsrf : true } )
2014-03-23 01:44:02 +08:00
reqSignOut := middleware . Toggle ( & middleware . ToggleOptions { SignOutRequire : true } )
2014-05-05 02:42:52 -04:00
bindIgnErr := binding . BindIgnErr
2014-04-10 14:37:43 -04:00
2014-02-19 17:50:53 +08:00
// Routers.
2014-03-24 11:58:46 -04:00
m . Get ( "/" , ignSignIn , routers . Home )
2014-07-26 02:28:04 -04:00
m . Get ( "/install" , bindIgnErr ( auth . InstallForm { } ) , routers . Install )
m . Post ( "/install" , bindIgnErr ( auth . InstallForm { } ) , routers . InstallPost )
2014-07-26 00:24:27 -04:00
m . Group ( "" , func ( r * macaron . Router ) {
2014-06-05 22:07:35 -04:00
r . Get ( "/pulls" , user . Pulls )
2014-07-26 23:53:16 -04:00
r . Get ( "/issues" , user . Issues )
2014-06-05 22:07:35 -04:00
} , reqSignIn )
2014-03-29 10:01:52 -04:00
2014-07-26 00:24:27 -04:00
// API routers.
m . Group ( "/api" , func ( _ * macaron . Router ) {
m . Group ( "/v1" , func ( r * macaron . Router ) {
2014-05-21 21:37:13 -04:00
// Miscellaneous.
r . Post ( "/markdown" , bindIgnErr ( apiv1 . MarkdownForm { } ) , v1 . Markdown )
r . Post ( "/markdown/raw" , v1 . MarkdownRaw )
// Users.
2014-07-12 00:55:19 -04:00
r . Get ( "/users/search" , v1 . SearchUsers )
// Repositories.
r . Get ( "/orgs/:org/repos/search" , v1 . SearchOrgRepositoreis )
2014-05-21 21:37:13 -04:00
2014-07-31 17:25:34 -04:00
r . Any ( "/*" , func ( ctx * middleware . Context ) {
2014-05-21 21:37:13 -04:00
ctx . JSON ( 404 , & base . ApiJsonErr { "Not Found" , v1 . DOC_URL } )
} )
2014-05-05 13:08:01 -04:00
} )
2014-03-29 10:01:52 -04:00
} )
2014-03-22 16:00:46 -04:00
2014-07-26 00:24:27 -04:00
// User routers.
m . Group ( "/user" , func ( r * macaron . Router ) {
2014-05-05 16:21:43 -04:00
r . Get ( "/login" , user . SignIn )
2014-07-26 00:24:27 -04:00
r . Post ( "/login" , bindIgnErr ( auth . SignInForm { } ) , user . SignInPost )
2014-04-12 23:19:17 +08:00
r . Get ( "/login/:name" , user . SocialSignIn )
2014-04-10 16:36:50 -04:00
r . Get ( "/sign_up" , user . SignUp )
r . Post ( "/sign_up" , bindIgnErr ( auth . RegisterForm { } ) , user . SignUpPost )
r . Get ( "/reset_password" , user . ResetPasswd )
r . Post ( "/reset_password" , user . ResetPasswdPost )
2014-03-22 16:00:46 -04:00
} , reqSignOut )
2014-07-26 00:24:27 -04:00
m . Group ( "/user" , func ( r * macaron . Router ) {
r . Get ( "/settings" , user . Settings )
r . Post ( "/settings" , bindIgnErr ( auth . UpdateProfileForm { } ) , user . SettingsPost )
m . Group ( "/settings" , func ( r * macaron . Router ) {
r . Get ( "/password" , user . SettingsPassword )
r . Post ( "/password" , bindIgnErr ( auth . ChangePasswordForm { } ) , user . SettingsPasswordPost )
r . Get ( "/ssh" , user . SettingsSSHKeys )
r . Post ( "/ssh" , bindIgnErr ( auth . AddSSHKeyForm { } ) , user . SettingsSSHKeysPost )
r . Get ( "/social" , user . SettingsSocial )
2014-07-26 02:28:04 -04:00
r . Get ( "/orgs" , user . SettingsOrgs )
2014-07-26 00:24:27 -04:00
r . Route ( "/delete" , "GET,POST" , user . SettingsDelete )
} )
2014-03-22 16:00:46 -04:00
} , reqSignIn )
2014-07-26 00:24:27 -04:00
m . Group ( "/user" , func ( r * macaron . Router ) {
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
2014-04-18 12:12:10 -04:00
r . Any ( "/activate" , user . Activate )
2014-04-12 20:35:35 -04:00
r . Get ( "/email2user" , user . Email2User )
2014-04-10 18:09:57 -04:00
r . Get ( "/forget_password" , user . ForgotPasswd )
r . Post ( "/forget_password" , user . ForgotPasswdPost )
2014-04-18 21:14:35 -04:00
r . Get ( "/logout" , user . SignOut )
2014-03-22 16:00:46 -04:00
} )
2014-03-10 16:54:52 +08:00
2014-07-26 00:24:27 -04:00
m . Get ( "/user/:username" , ignSignIn , user . Profile ) // TODO: Legacy
2014-07-31 17:25:34 -04:00
// Gravatar service.
avt := avatar . CacheServer ( "public/img/avatar/" , "public/img/avatar_default.jpg" )
os . MkdirAll ( "public/img/avatar/" , os . ModePerm )
m . Get ( "/avatar/:hash" , avt . ServeHTTP )
2014-03-07 17:08:21 -05:00
2014-03-23 01:44:02 +08:00
adminReq := middleware . Toggle ( & middleware . ToggleOptions { SignInRequire : true , AdminRequire : true } )
m . Get ( "/admin" , adminReq , admin . Dashboard )
2014-07-26 00:24:27 -04:00
m . Group ( "/admin" , func ( r * macaron . Router ) {
2014-03-22 16:00:46 -04:00
r . Get ( "/users" , admin . Users )
r . Get ( "/repos" , admin . Repositories )
2014-05-03 10:48:14 +08:00
r . Get ( "/auths" , admin . Auths )
2014-06-13 13:01:52 -04:00
r . Get ( "/config" , admin . Config )
r . Get ( "/monitor" , admin . Monitor )
2014-03-22 16:00:46 -04:00
} , adminReq )
2014-07-26 00:24:27 -04:00
m . Group ( "/admin/users" , func ( r * macaron . Router ) {
2014-04-10 18:09:57 -04:00
r . Get ( "/new" , admin . NewUser )
r . Post ( "/new" , bindIgnErr ( auth . RegisterForm { } ) , admin . NewUserPost )
r . Get ( "/:userid" , admin . EditUser )
r . Post ( "/:userid" , bindIgnErr ( auth . AdminEditUserForm { } ) , admin . EditUserPost )
r . Get ( "/:userid/delete" , admin . DeleteUser )
2014-03-22 16:00:46 -04:00
} , adminReq )
2014-07-26 00:24:27 -04:00
m . Group ( "/admin/auths" , func ( r * macaron . Router ) {
2014-05-03 10:48:14 +08:00
r . Get ( "/new" , admin . NewAuthSource )
r . Post ( "/new" , bindIgnErr ( auth . AuthenticationForm { } ) , admin . NewAuthSourcePost )
r . Get ( "/:authid" , admin . EditAuthSource )
2014-05-05 16:40:25 +08:00
r . Post ( "/:authid" , bindIgnErr ( auth . AuthenticationForm { } ) , admin . EditAuthSourcePost )
2014-05-03 10:48:14 +08:00
r . Get ( "/:authid/delete" , admin . DeleteAuthSource )
} , adminReq )
2014-07-12 00:55:19 -04:00
m . Get ( "/:username" , ignSignIn , user . Profile )
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
}
2014-07-26 02:28:04 -04:00
reqTrueOwner := middleware . RequireTrueOwner ( )
// Organization routers.
m . Group ( "/org" , func ( r * macaron . Router ) {
2014-07-26 23:53:16 -04:00
r . Get ( "/create" , org . Create )
r . Post ( "/create" , bindIgnErr ( auth . CreateOrgForm { } ) , org . CreatePost )
2014-07-26 02:28:04 -04:00
r . Get ( "/:org" , org . Home )
2014-07-26 23:53:16 -04:00
r . Get ( "/:org/dashboard" , user . Dashboard )
2014-07-26 02:28:04 -04:00
r . Get ( "/:org/members" , org . Members )
r . Get ( "/:org/teams" , org . Teams )
r . Get ( "/:org/teams/new" , org . NewTeam )
r . Post ( "/:org/teams/new" , bindIgnErr ( auth . CreateTeamForm { } ) , org . NewTeamPost )
r . Get ( "/:org/teams/:team/edit" , org . EditTeam )
r . Get ( "/:org/team/:team" , org . SingleTeam )
r . Get ( "/:org/settings" , org . Settings )
r . Post ( "/:org/settings" , bindIgnErr ( auth . OrgSettingForm { } ) , org . SettingsPost )
r . Post ( "/:org/settings/delete" , org . DeletePost )
} , reqSignIn )
2014-07-26 23:53:16 -04:00
// Repository routers.
m . Group ( "/repo" , func ( r * macaron . Router ) {
r . Get ( "/create" , repo . Create )
r . Post ( "/create" , bindIgnErr ( auth . CreateRepoForm { } ) , repo . CreatePost )
r . Get ( "/migrate" , repo . Migrate )
r . Post ( "/migrate" , bindIgnErr ( auth . MigrateRepoForm { } ) , repo . MigratePost )
} , reqSignIn )
2014-07-26 02:28:04 -04:00
m . Group ( "/:username/:reponame" , func ( r * macaron . Router ) {
2014-08-02 13:47:33 -04:00
r . Get ( "/settings" , repo . Settings )
r . Post ( "/settings" , bindIgnErr ( auth . RepoSettingForm { } ) , repo . SettingsPost )
2014-07-26 02:28:04 -04:00
m . Group ( "/settings" , func ( r * macaron . Router ) {
2014-08-07 06:40:05 -04:00
r . Route ( "/collaboration" , "GET,POST" , repo . SettingsCollaboration )
2014-07-26 02:28:04 -04:00
r . Get ( "/hooks" , repo . WebHooks )
r . Get ( "/hooks/add" , repo . WebHooksAdd )
r . Post ( "/hooks/add" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksAddPost )
r . Get ( "/hooks/:id" , repo . WebHooksEdit )
r . Post ( "/hooks/:id" , bindIgnErr ( auth . NewWebhookForm { } ) , repo . WebHooksEditPost )
} )
} , reqSignIn , middleware . RepoAssignment ( true ) , reqTrueOwner )
m . Group ( "/:username/:reponame" , func ( r * macaron . Router ) {
// r.Get("/action/:action", repo.Action)
m . Group ( "/issues" , func ( r * macaron . Router ) {
r . Get ( "/new" , repo . CreateIssue )
r . Post ( "/new" , bindIgnErr ( auth . CreateIssueForm { } ) , repo . CreateIssuePost )
r . Post ( "/:index" , bindIgnErr ( auth . CreateIssueForm { } ) , repo . UpdateIssue )
r . Post ( "/:index/label" , repo . UpdateIssueLabel )
r . Post ( "/:index/milestone" , repo . UpdateIssueMilestone )
r . Post ( "/:index/assignee" , repo . UpdateAssignee )
r . Get ( "/:index/attachment/:id" , repo . IssueGetAttachment )
r . Post ( "/labels/new" , bindIgnErr ( auth . CreateLabelForm { } ) , repo . NewLabel )
r . Post ( "/labels/edit" , bindIgnErr ( auth . CreateLabelForm { } ) , repo . UpdateLabel )
r . Post ( "/labels/delete" , repo . DeleteLabel )
r . Get ( "/milestones" , repo . Milestones )
r . Get ( "/milestones/new" , repo . NewMilestone )
r . Post ( "/milestones/new" , bindIgnErr ( auth . CreateMilestoneForm { } ) , repo . NewMilestonePost )
r . Get ( "/milestones/:index/edit" , repo . UpdateMilestone )
r . Post ( "/milestones/:index/edit" , bindIgnErr ( auth . CreateMilestoneForm { } ) , repo . UpdateMilestonePost )
r . Get ( "/milestones/:index/:action" , repo . UpdateMilestone )
} )
r . Post ( "/comment/:action" , repo . Comment )
r . Get ( "/releases/new" , repo . NewRelease )
r . Get ( "/releases/edit/:tagname" , repo . EditRelease )
} , reqSignIn , middleware . RepoAssignment ( true ) )
m . Group ( "/:username/:reponame" , func ( r * macaron . Router ) {
r . Post ( "/releases/new" , bindIgnErr ( auth . NewReleaseForm { } ) , repo . NewReleasePost )
r . Post ( "/releases/edit/:tagname" , bindIgnErr ( auth . EditReleaseForm { } ) , repo . EditReleasePost )
} , reqSignIn , middleware . RepoAssignment ( true , true ) )
m . Group ( "/:username/:reponame" , func ( r * macaron . Router ) {
r . Get ( "/issues" , repo . Issues )
r . Get ( "/issues/:index" , repo . ViewIssue )
r . Get ( "/pulls" , repo . Pulls )
r . Get ( "/branches" , repo . Branches )
} , ignSignIn , middleware . RepoAssignment ( true ) )
2014-07-26 00:24:27 -04:00
m . Group ( "/:username/:reponame" , func ( r * macaron . Router ) {
r . Get ( "/src/:branchname" , repo . Home )
r . Get ( "/src/:branchname/*" , repo . Home )
2014-07-26 02:28:04 -04:00
r . Get ( "/raw/:branchname/*" , repo . SingleDownload )
r . Get ( "/commits/:branchname" , repo . Commits )
r . Get ( "/commits/:branchname/search" , repo . SearchCommits )
r . Get ( "/commits/:branchname/*" , repo . FileHistory )
r . Get ( "/commit/:branchname" , repo . Diff )
r . Get ( "/commit/:branchname/*" , repo . Diff )
r . Get ( "/releases" , repo . Releases )
2014-07-26 00:24:27 -04:00
r . Get ( "/archive/*.*" , repo . Download )
2014-03-30 13:30:17 +08:00
} , ignSignIn , middleware . RepoAssignment ( true , true ) )
2014-03-22 16:00:46 -04:00
2014-07-26 00:24:27 -04:00
m . Group ( "/:username" , func ( r * macaron . Router ) {
r . Get ( "/:reponame" , middleware . RepoAssignment ( true , true , true ) , repo . Home )
m . Group ( "/:reponame" , func ( r * macaron . Router ) {
r . Any ( "/*" , repo . Http )
} )
2014-04-10 22:12:32 +08:00
} , ignSignInAndCsrf )
2014-03-22 00:48:26 +08:00
2014-03-23 06:27:01 -04:00
// Not found handler.
2014-03-23 13:48:01 +08:00
m . NotFound ( routers . NotFound )
2014-05-25 20:11:25 -04:00
var err error
listenAddr := fmt . Sprintf ( "%s:%s" , setting . HttpAddr , setting . HttpPort )
log . Info ( "Listen: %v://%s" , setting . Protocol , listenAddr )
switch setting . Protocol {
case setting . HTTP :
err = http . ListenAndServe ( listenAddr , m )
case setting . HTTPS :
err = http . ListenAndServeTLS ( listenAddr , setting . CertFile , setting . KeyFile , m )
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
}
2014-02-19 17:50:53 +08:00
}