2014-04-10 22:20:58 +04: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-26 04:11:25 +04:00
package setting
2014-04-10 22:20:58 +04:00
import (
"fmt"
2014-09-14 21:35:22 +04:00
"net/url"
2014-04-10 22:20:58 +04:00
"os"
"os/exec"
"path"
"path/filepath"
2014-09-16 21:34:09 +04:00
"runtime"
2014-04-10 22:20:58 +04:00
"strings"
2014-07-25 00:31:59 +04:00
"time"
2014-04-10 22:20:58 +04:00
2015-08-10 03:44:43 +03:00
"gopkg.in/ini.v1"
2014-04-10 22:20:58 +04:00
"github.com/Unknwon/com"
2015-10-16 04:28:12 +03:00
"github.com/go-macaron/session"
2014-04-10 22:20:58 +04:00
2015-03-18 13:37:44 +03:00
"github.com/gogits/gogs/modules/bindata"
2014-04-10 22:20:58 +04:00
"github.com/gogits/gogs/modules/log"
2014-11-21 20:51:36 +03:00
// "github.com/gogits/gogs/modules/ssh"
2015-07-31 09:50:11 +03:00
"github.com/gogits/gogs/modules/user"
2014-04-10 22:20:58 +04:00
)
2014-05-26 04:11:25 +04:00
type Scheme string
2014-04-14 02:12:07 +04:00
2014-05-26 04:11:25 +04:00
const (
HTTP Scheme = "http"
HTTPS Scheme = "https"
2014-11-04 04:46:53 +03:00
FCGI Scheme = "fcgi"
2014-05-26 04:11:25 +04:00
)
2014-04-10 22:20:58 +04:00
2014-11-25 02:47:59 +03:00
type LandingPage string
const (
LANDING_PAGE_HOME LandingPage = "/"
LANDING_PAGE_EXPLORE LandingPage = "/explore"
)
2014-04-10 22:20:58 +04:00
var (
2015-11-03 20:16:43 +03:00
// Build information.
BuildTime string
BuildGitHash string
2014-05-26 04:11:25 +04:00
// App settings.
2015-10-30 03:40:57 +03:00
AppVer string
AppName string
AppUrl string
AppSubUrl string
AppDataPath = "data"
2014-05-26 04:11:25 +04:00
// Server settings.
Protocol Scheme
Domain string
HttpAddr , HttpPort string
2015-02-07 18:46:57 +03:00
DisableSSH bool
SSHPort int
2015-04-18 13:21:07 +03:00
SSHDomain string
2014-05-26 04:11:25 +04:00
OfflineMode bool
DisableRouterLog bool
CertFile , KeyFile string
StaticRootPath string
2014-07-26 08:24:27 +04:00
EnableGzip bool
2014-11-25 02:47:59 +03:00
LandingPageUrl LandingPage
2014-05-26 04:11:25 +04:00
// Security settings.
2014-06-24 21:55:47 +04:00
InstallLock bool
SecretKey string
LogInRememberDays int
CookieUserName string
CookieRememberName string
ReverseProxyAuthUser string
2014-04-10 22:20:58 +04:00
2015-02-12 05:58:37 +03:00
// Database settings.
UseSQLite3 bool
UseMySQL bool
UsePostgreSQL bool
2015-09-12 22:31:36 +03:00
UseTiDB bool
2015-02-12 05:58:37 +03:00
2014-06-08 12:45:34 +04:00
// Webhook settings.
2015-02-11 05:06:59 +03:00
Webhook struct {
2015-07-25 16:32:04 +03:00
QueueLength int
2015-02-11 20:04:01 +03:00
DeliverTimeout int
SkipTLSVerify bool
2015-08-26 19:30:06 +03:00
Types [ ] string
2015-08-27 18:06:14 +03:00
PagingNum int
2015-02-11 05:06:59 +03:00
}
2014-06-08 12:45:34 +04:00
2014-05-26 04:11:25 +04:00
// Repository settings.
2015-10-24 10:36:47 +03:00
Repository struct {
2015-10-25 11:26:26 +03:00
AnsiCharset string
ForcePrivate bool
2015-10-24 10:36:47 +03:00
PullRequestQueueLength int
}
2015-07-24 21:52:25 +03:00
RepoRootPath string
ScriptType string
// UI settings.
2015-09-26 03:35:56 +03:00
ExplorePagingNum int
IssuePagingNum int
FeedMaxCommitNum int
AdminUserPagingNum int
AdminRepoPagingNum int
2015-09-25 19:13:38 +03:00
AdminNoticePagingNum int
2015-09-26 03:35:56 +03:00
AdminOrgPagingNum int
2014-04-10 22:20:58 +04:00
2015-09-01 15:32:02 +03:00
// Markdown sttings.
Markdown struct {
EnableHardLineBreak bool
}
2014-05-26 04:11:25 +04:00
// Picture settings.
2014-11-21 18:58:08 +03:00
PictureService string
AvatarUploadPath string
GravatarSource string
DisableGravatar bool
2014-05-26 04:11:25 +04:00
// Log settings.
2014-05-28 09:53:06 +04:00
LogRootPath string
LogModes [ ] string
LogConfigs [ ] string
2014-04-10 22:20:58 +04:00
2014-07-23 23:15:47 +04:00
// Attachment settings.
AttachmentPath string
AttachmentAllowedTypes string
2014-07-24 17:19:59 +04:00
AttachmentMaxSize int64
AttachmentMaxFiles int
2014-07-24 17:51:40 +04:00
AttachmentEnabled bool
2014-07-23 23:15:47 +04:00
2014-07-25 00:31:59 +04:00
// Time settings.
TimeFormat string
2014-05-26 04:11:25 +04:00
// Cache settings.
2014-08-01 01:25:34 +04:00
CacheAdapter string
CacheInternal int
CacheConn string
2014-04-10 22:20:58 +04:00
2014-05-26 04:11:25 +04:00
EnableRedis bool
EnableMemcache bool
// Session settings.
2014-12-28 15:40:35 +03:00
SessionConfig session . Options
2014-04-10 22:20:58 +04:00
2014-09-17 22:22:51 +04:00
// Git settings.
2015-01-02 15:14:43 +03:00
Git struct {
MaxGitDiffLines int
GcArgs [ ] string ` delim:" " `
2015-08-17 21:19:29 +03:00
}
// Cron tasks.
Cron struct {
UpdateMirror struct {
Enabled bool
RunAtStart bool
Schedule string
} ` ini:"cron.update_mirrors" `
RepoHealthCheck struct {
Enabled bool
RunAtStart bool
Schedule string
Args [ ] string ` delim:" " `
} ` ini:"cron.repo_health_check" `
CheckRepoStats struct {
Enabled bool
RunAtStart bool
Schedule string
} ` ini:"cron.check_repo_stats" `
2015-01-02 15:14:43 +03:00
}
2014-09-17 22:22:51 +04:00
// I18n settings.
Langs , Names [ ] string
2015-08-05 10:24:26 +03:00
dateLangs map [ string ] string
2014-09-17 22:22:51 +04:00
2015-03-23 17:19:19 +03:00
// Other settings.
ShowFooterBranding bool
2014-05-26 04:11:25 +04:00
// Global setting objects.
2014-12-31 13:37:29 +03:00
Cfg * ini . File
2014-07-26 08:24:27 +04:00
CustomPath string // Custom directory path.
2015-02-05 13:12:37 +03:00
CustomConf string
2014-07-26 08:24:27 +04:00
ProdMode bool
RunUser string
2014-09-16 21:34:09 +04:00
IsWindows bool
2014-09-22 03:39:10 +04:00
HasRobotsTxt bool
2014-04-10 22:20:58 +04:00
)
2015-08-05 10:24:26 +03:00
func DateLang ( lang string ) string {
name , ok := dateLangs [ lang ]
if ok {
return name
}
return "en"
}
2014-07-26 08:24:27 +04:00
func init ( ) {
2014-09-16 21:34:09 +04:00
IsWindows = runtime . GOOS == "windows"
2014-07-26 08:24:27 +04:00
log . NewLogger ( 0 , "console" , ` { "level": 0} ` )
}
2014-06-11 03:11:53 +04:00
func ExecPath ( ) ( string , error ) {
2014-05-26 04:11:25 +04:00
file , err := exec . LookPath ( os . Args [ 0 ] )
if err != nil {
return "" , err
}
p , err := filepath . Abs ( file )
if err != nil {
return "" , err
}
2014-06-11 03:11:53 +04:00
return p , nil
}
// WorkDir returns absolute path of work directory.
func WorkDir ( ) ( string , error ) {
2015-09-07 21:06:05 +03:00
wd := os . Getenv ( "GOGS_WORK_DIR" )
if len ( wd ) > 0 {
return wd , nil
}
2014-06-11 03:11:53 +04:00
execPath , err := ExecPath ( )
2015-08-02 06:41:28 +03:00
if err != nil {
return execPath , err
}
// Note: we don't use path.Dir here because it does not handle case
// which path starts with two "/" in Windows: "//psf/Home/..."
execPath = strings . Replace ( execPath , "\\" , "/" , - 1 )
i := strings . LastIndex ( execPath , "/" )
if i == - 1 {
return execPath , nil
}
return execPath [ : i ] , nil
2014-05-26 04:11:25 +04:00
}
2015-03-18 11:25:55 +03:00
func forcePathSeparator ( path string ) {
if strings . Contains ( path , "\\" ) {
2015-03-18 13:37:44 +03:00
log . Fatal ( 4 , "Do not use '\\' or '\\\\' in paths, instead, please use '/' in all places" )
2015-03-18 11:25:55 +03:00
}
}
2015-09-17 06:08:46 +03:00
// NewContext initializes configuration context.
2014-05-26 04:57:01 +04:00
// NOTE: do not print any log except error.
2015-09-17 06:08:46 +03:00
func NewContext ( ) {
2014-05-26 04:11:25 +04:00
workDir , err := WorkDir ( )
if err != nil {
2014-07-26 08:24:27 +04:00
log . Fatal ( 4 , "Fail to get work directory: %v" , err )
2014-05-26 04:11:25 +04:00
}
2015-03-18 13:37:44 +03:00
Cfg , err = ini . Load ( bindata . MustAsset ( "conf/app.ini" ) )
2014-05-26 04:11:25 +04:00
if err != nil {
2014-07-26 08:24:27 +04:00
log . Fatal ( 4 , "Fail to parse 'conf/app.ini': %v" , err )
2014-05-26 04:11:25 +04:00
}
CustomPath = os . Getenv ( "GOGS_CUSTOM" )
if len ( CustomPath ) == 0 {
2015-08-02 06:52:48 +03:00
CustomPath = workDir + "/custom"
2014-05-26 04:11:25 +04:00
}
2015-02-05 13:12:37 +03:00
if len ( CustomConf ) == 0 {
2015-08-02 06:52:48 +03:00
CustomConf = CustomPath + "/conf/app.ini"
2015-02-05 13:12:37 +03:00
}
if com . IsFile ( CustomConf ) {
if err = Cfg . Append ( CustomConf ) ; err != nil {
log . Fatal ( 4 , "Fail to load custom conf '%s': %v" , CustomConf , err )
2014-05-26 04:11:25 +04:00
}
} else {
2015-02-05 13:12:37 +03:00
log . Warn ( "Custom config (%s) not found, ignore this if you're running first time" , CustomConf )
2014-05-26 04:11:25 +04:00
}
2015-01-02 15:14:43 +03:00
Cfg . NameMapper = ini . AllCapsUnderscore
2014-05-26 04:11:25 +04:00
2014-12-31 13:37:29 +03:00
LogRootPath = Cfg . Section ( "log" ) . Key ( "ROOT_PATH" ) . MustString ( path . Join ( workDir , "log" ) )
2015-03-18 11:25:55 +03:00
forcePathSeparator ( LogRootPath )
2014-12-31 13:37:29 +03:00
sec := Cfg . Section ( "server" )
AppName = Cfg . Section ( "" ) . Key ( "APP_NAME" ) . MustString ( "Gogs: Go Git Service" )
AppUrl = sec . Key ( "ROOT_URL" ) . MustString ( "http://localhost:3000/" )
2014-08-25 05:45:39 +04:00
if AppUrl [ len ( AppUrl ) - 1 ] != '/' {
AppUrl += "/"
}
2014-05-26 04:11:25 +04:00
2014-09-20 04:11:34 +04:00
// Check if has app suburl.
2014-09-14 21:35:22 +04:00
url , err := url . Parse ( AppUrl )
if err != nil {
2014-09-20 04:11:34 +04:00
log . Fatal ( 4 , "Invalid ROOT_URL(%s): %s" , AppUrl , err )
2014-09-14 21:35:22 +04:00
}
2014-09-20 04:11:34 +04:00
AppSubUrl = strings . TrimSuffix ( url . Path , "/" )
2014-09-14 21:35:22 +04:00
2014-05-26 04:11:25 +04:00
Protocol = HTTP
2014-12-31 13:37:29 +03:00
if sec . Key ( "PROTOCOL" ) . String ( ) == "https" {
2014-05-26 04:11:25 +04:00
Protocol = HTTPS
2014-12-31 13:37:29 +03:00
CertFile = sec . Key ( "CERT_FILE" ) . String ( )
KeyFile = sec . Key ( "KEY_FILE" ) . String ( )
} else if sec . Key ( "PROTOCOL" ) . String ( ) == "fcgi" {
2014-11-04 04:46:53 +03:00
Protocol = FCGI
}
2014-12-31 13:37:29 +03:00
Domain = sec . Key ( "DOMAIN" ) . MustString ( "localhost" )
HttpAddr = sec . Key ( "HTTP_ADDR" ) . MustString ( "0.0.0.0" )
HttpPort = sec . Key ( "HTTP_PORT" ) . MustString ( "3000" )
2015-02-07 18:46:57 +03:00
DisableSSH = sec . Key ( "DISABLE_SSH" ) . MustBool ( )
2015-04-18 13:21:07 +03:00
SSHDomain = sec . Key ( "SSH_DOMAIN" ) . MustString ( Domain )
2015-02-07 18:46:57 +03:00
SSHPort = sec . Key ( "SSH_PORT" ) . MustInt ( 22 )
2014-12-31 13:37:29 +03:00
OfflineMode = sec . Key ( "OFFLINE_MODE" ) . MustBool ( )
DisableRouterLog = sec . Key ( "DISABLE_ROUTER_LOG" ) . MustBool ( )
StaticRootPath = sec . Key ( "STATIC_ROOT_PATH" ) . MustString ( workDir )
EnableGzip = sec . Key ( "ENABLE_GZIP" ) . MustBool ( )
switch sec . Key ( "LANDING_PAGE" ) . MustString ( "home" ) {
2014-11-25 02:47:59 +03:00
case "explore" :
LandingPageUrl = LANDING_PAGE_EXPLORE
default :
LandingPageUrl = LANDING_PAGE_HOME
}
2014-12-31 13:37:29 +03:00
sec = Cfg . Section ( "security" )
InstallLock = sec . Key ( "INSTALL_LOCK" ) . MustBool ( )
SecretKey = sec . Key ( "SECRET_KEY" ) . String ( )
LogInRememberDays = sec . Key ( "LOGIN_REMEMBER_DAYS" ) . MustInt ( )
CookieUserName = sec . Key ( "COOKIE_USERNAME" ) . String ( )
CookieRememberName = sec . Key ( "COOKIE_REMEMBER_NAME" ) . String ( )
ReverseProxyAuthUser = sec . Key ( "REVERSE_PROXY_AUTHENTICATION_USER" ) . MustString ( "X-WEBAUTH-USER" )
sec = Cfg . Section ( "attachment" )
2015-10-30 03:40:57 +03:00
AttachmentPath = sec . Key ( "PATH" ) . MustString ( path . Join ( AppDataPath , "attachments" ) )
2015-02-15 01:49:33 +03:00
if ! filepath . IsAbs ( AttachmentPath ) {
AttachmentPath = path . Join ( workDir , AttachmentPath )
}
2015-08-11 18:24:40 +03:00
AttachmentAllowedTypes = strings . Replace ( sec . Key ( "ALLOWED_TYPES" ) . MustString ( "image/jpeg,image/png" ) , "|" , "," , - 1 )
2015-09-02 23:18:09 +03:00
AttachmentMaxSize = sec . Key ( "MAX_SIZE" ) . MustInt64 ( 4 )
2015-08-11 18:24:40 +03:00
AttachmentMaxFiles = sec . Key ( "MAX_FILES" ) . MustInt ( 5 )
2014-12-31 13:37:29 +03:00
AttachmentEnabled = sec . Key ( "ENABLE" ) . MustBool ( true )
2014-07-23 23:15:47 +04:00
2014-08-01 08:24:29 +04:00
TimeFormat = map [ string ] string {
"ANSIC" : time . ANSIC ,
"UnixDate" : time . UnixDate ,
"RubyDate" : time . RubyDate ,
"RFC822" : time . RFC822 ,
"RFC822Z" : time . RFC822Z ,
"RFC850" : time . RFC850 ,
"RFC1123" : time . RFC1123 ,
"RFC1123Z" : time . RFC1123Z ,
"RFC3339" : time . RFC3339 ,
"RFC3339Nano" : time . RFC3339Nano ,
"Kitchen" : time . Kitchen ,
"Stamp" : time . Stamp ,
"StampMilli" : time . StampMilli ,
"StampMicro" : time . StampMicro ,
"StampNano" : time . StampNano ,
2014-12-31 13:37:29 +03:00
} [ Cfg . Section ( "time" ) . Key ( "FORMAT" ) . MustString ( "RFC1123" ) ]
2014-07-25 00:31:59 +04:00
2014-12-31 13:37:29 +03:00
RunUser = Cfg . Section ( "" ) . Key ( "RUN_USER" ) . String ( )
2015-07-31 09:50:11 +03:00
curUser := user . CurrentUsername ( )
2014-05-26 04:11:25 +04:00
// Does not check run user when the install lock is off.
if InstallLock && RunUser != curUser {
2014-07-26 08:24:27 +04:00
log . Fatal ( 4 , "Expect user(%s) but current user is: %s" , RunUser , curUser )
2014-05-26 04:11:25 +04:00
}
2014-12-07 04:22:48 +03:00
// Determine and create root git repository path.
2014-05-26 04:11:25 +04:00
homeDir , err := com . HomeDir ( )
if err != nil {
2014-07-26 08:24:27 +04:00
log . Fatal ( 4 , "Fail to get home directory: %v" , err )
2014-05-26 04:11:25 +04:00
}
2015-03-18 11:25:55 +03:00
homeDir = strings . Replace ( homeDir , "\\" , "/" , - 1 )
2014-12-31 13:37:29 +03:00
sec = Cfg . Section ( "repository" )
2015-03-18 11:25:55 +03:00
RepoRootPath = sec . Key ( "ROOT" ) . MustString ( path . Join ( homeDir , "gogs-repositories" ) )
forcePathSeparator ( RepoRootPath )
2014-06-24 10:28:47 +04:00
if ! filepath . IsAbs ( RepoRootPath ) {
2015-03-18 11:25:55 +03:00
RepoRootPath = path . Join ( workDir , RepoRootPath )
2014-06-24 10:28:47 +04:00
} else {
2015-03-18 11:25:55 +03:00
RepoRootPath = path . Clean ( RepoRootPath )
2014-06-24 10:28:47 +04:00
}
2014-12-31 13:37:29 +03:00
ScriptType = sec . Key ( "SCRIPT_TYPE" ) . MustString ( "bash" )
2015-10-25 11:26:26 +03:00
Repository . AnsiCharset = sec . Key ( "ANSI_CHARSET" ) . String ( )
Repository . ForcePrivate = sec . Key ( "FORCE_PRIVATE" ) . MustBool ( )
Repository . PullRequestQueueLength = sec . Key ( "PULL_REQUEST_QUEUE_LENGTH" ) . MustInt ( 10000 )
2014-05-26 04:11:25 +04:00
2015-07-24 21:52:25 +03:00
// UI settings.
2015-09-01 15:32:02 +03:00
sec = Cfg . Section ( "ui" )
ExplorePagingNum = sec . Key ( "EXPLORE_PAGING_NUM" ) . MustInt ( 20 )
IssuePagingNum = sec . Key ( "ISSUE_PAGING_NUM" ) . MustInt ( 10 )
2015-09-26 03:35:56 +03:00
FeedMaxCommitNum = sec . Key ( "FEED_MAX_COMMIT_NUM" ) . MustInt ( 5 )
2015-07-24 21:52:25 +03:00
2015-09-12 03:42:26 +03:00
sec = Cfg . Section ( "ui.admin" )
AdminUserPagingNum = sec . Key ( "USER_PAGING_NUM" ) . MustInt ( 50 )
2015-09-26 01:38:43 +03:00
AdminRepoPagingNum = sec . Key ( "REPO_PAGING_NUM" ) . MustInt ( 50 )
2015-09-25 19:13:38 +03:00
AdminNoticePagingNum = sec . Key ( "NOTICE_PAGING_NUM" ) . MustInt ( 50 )
2015-09-25 20:54:52 +03:00
AdminOrgPagingNum = sec . Key ( "ORG_PAGING_NUM" ) . MustInt ( 50 )
2015-09-12 03:42:26 +03:00
2014-12-31 13:37:29 +03:00
sec = Cfg . Section ( "picture" )
PictureService = sec . Key ( "SERVICE" ) . In ( "server" , [ ] string { "server" } )
2015-10-30 03:40:57 +03:00
AvatarUploadPath = sec . Key ( "AVATAR_UPLOAD_PATH" ) . MustString ( path . Join ( AppDataPath , "avatars" ) )
2015-03-18 11:25:55 +03:00
forcePathSeparator ( AvatarUploadPath )
2015-02-15 01:49:33 +03:00
if ! filepath . IsAbs ( AvatarUploadPath ) {
AvatarUploadPath = path . Join ( workDir , AvatarUploadPath )
}
2015-08-10 03:44:43 +03:00
switch source := sec . Key ( "GRAVATAR_SOURCE" ) . MustString ( "gravatar" ) ; source {
2014-11-17 04:27:04 +03:00
case "duoshuo" :
GravatarSource = "http://gravatar.duoshuo.com/avatar/"
2015-08-10 03:44:43 +03:00
case "gravatar" :
2014-11-17 04:27:04 +03:00
GravatarSource = "//1.gravatar.com/avatar/"
2015-08-10 03:44:43 +03:00
default :
GravatarSource = source
2014-11-17 04:27:04 +03:00
}
2014-12-31 13:37:29 +03:00
DisableGravatar = sec . Key ( "DISABLE_GRAVATAR" ) . MustBool ( )
2015-03-25 01:38:12 +03:00
if OfflineMode {
DisableGravatar = true
}
2014-07-26 08:24:27 +04:00
2015-09-01 15:32:02 +03:00
if err = Cfg . Section ( "markdown" ) . MapTo ( & Markdown ) ; err != nil {
log . Fatal ( 4 , "Fail to map Markdown settings: %v" , err )
} else if err = Cfg . Section ( "git" ) . MapTo ( & Git ) ; err != nil {
2015-01-02 15:14:43 +03:00
log . Fatal ( 4 , "Fail to map Git settings: %v" , err )
2015-08-17 21:19:29 +03:00
} else if Cfg . Section ( "cron" ) . MapTo ( & Cron ) ; err != nil {
log . Fatal ( 4 , "Fail to map Cron settings: %v" , err )
2015-01-02 15:14:43 +03:00
}
2014-09-17 08:03:03 +04:00
2014-12-31 13:37:29 +03:00
Langs = Cfg . Section ( "i18n" ) . Key ( "LANGS" ) . Strings ( "," )
Names = Cfg . Section ( "i18n" ) . Key ( "NAMES" ) . Strings ( "," )
2015-08-05 10:24:26 +03:00
dateLangs = Cfg . Section ( "i18n.datelang" ) . KeysHash ( )
2014-09-22 03:39:10 +04:00
2015-03-23 17:19:19 +03:00
ShowFooterBranding = Cfg . Section ( "other" ) . Key ( "SHOW_FOOTER_BRANDING" ) . MustBool ( )
2014-09-22 03:39:10 +04:00
HasRobotsTxt = com . IsFile ( path . Join ( CustomPath , "robots.txt" ) )
2014-05-26 04:11:25 +04:00
}
2014-04-10 22:20:58 +04:00
var Service struct {
2015-03-25 15:59:48 +03:00
ActiveCodeLives int
ResetPwdCodeLives int
2014-12-06 01:54:57 +03:00
RegisterEmailConfirm bool
DisableRegistration bool
2015-02-05 19:09:26 +03:00
ShowRegistrationButton bool
2014-12-06 01:54:57 +03:00
RequireSignInView bool
EnableCacheAvatar bool
EnableNotifyMail bool
EnableReverseProxyAuth bool
EnableReverseProxyAutoRegister bool
2015-03-25 15:59:48 +03:00
DisableMinimumKeySizeCheck bool
2015-10-30 15:53:06 +03:00
MinimumKeySizes map [ string ] int
2015-09-13 18:07:21 +03:00
EnableCaptcha bool
2014-04-10 22:20:58 +04:00
}
2014-05-26 04:11:25 +04:00
func newService ( ) {
2015-03-25 15:59:48 +03:00
sec := Cfg . Section ( "service" )
Service . ActiveCodeLives = sec . Key ( "ACTIVE_CODE_LIVE_MINUTES" ) . MustInt ( 180 )
Service . ResetPwdCodeLives = sec . Key ( "RESET_PASSWD_CODE_LIVE_MINUTES" ) . MustInt ( 180 )
Service . DisableRegistration = sec . Key ( "DISABLE_REGISTRATION" ) . MustBool ( )
Service . ShowRegistrationButton = sec . Key ( "SHOW_REGISTRATION_BUTTON" ) . MustBool ( ! Service . DisableRegistration )
Service . RequireSignInView = sec . Key ( "REQUIRE_SIGNIN_VIEW" ) . MustBool ( )
Service . EnableCacheAvatar = sec . Key ( "ENABLE_CACHE_AVATAR" ) . MustBool ( )
Service . EnableReverseProxyAuth = sec . Key ( "ENABLE_REVERSE_PROXY_AUTHENTICATION" ) . MustBool ( )
Service . EnableReverseProxyAutoRegister = sec . Key ( "ENABLE_REVERSE_PROXY_AUTO_REGISTRATION" ) . MustBool ( )
2015-03-25 16:44:57 +03:00
Service . DisableMinimumKeySizeCheck = sec . Key ( "DISABLE_MINIMUM_KEY_SIZE_CHECK" ) . MustBool ( )
2015-09-13 18:07:21 +03:00
Service . EnableCaptcha = sec . Key ( "ENABLE_CAPTCHA" ) . MustBool ( )
2015-10-30 15:53:06 +03:00
minimumKeySizes := Cfg . Section ( "service.minimum_key_sizes" ) . Keys ( )
2015-11-02 22:01:19 +03:00
Service . MinimumKeySizes = make ( map [ string ] int )
2015-10-30 15:53:06 +03:00
for _ , key := range minimumKeySizes {
Service . MinimumKeySizes [ key . Name ( ) ] = key . MustInt ( )
}
2014-04-10 22:20:58 +04:00
}
var logLevels = map [ string ] string {
"Trace" : "0" ,
"Debug" : "1" ,
"Info" : "2" ,
"Warn" : "3" ,
"Error" : "4" ,
"Critical" : "5" ,
}
func newLogService ( ) {
2014-05-11 22:37:12 +04:00
log . Info ( "%s %s" , AppName , AppVer )
2014-04-10 22:20:58 +04:00
2015-11-03 20:16:43 +03:00
if len ( BuildTime ) > 0 {
log . Info ( "Build Time: %s" , BuildTime )
log . Info ( "Build Git Hash: %s" , BuildGitHash )
}
2014-05-11 22:37:12 +04:00
// Get and check log mode.
2014-12-31 13:37:29 +03:00
LogModes = strings . Split ( Cfg . Section ( "log" ) . Key ( "MODE" ) . MustString ( "console" ) , "," )
2014-05-11 22:37:12 +04:00
LogConfigs = make ( [ ] string , len ( LogModes ) )
for i , mode := range LogModes {
mode = strings . TrimSpace ( mode )
2014-12-31 13:37:29 +03:00
sec , err := Cfg . GetSection ( "log." + mode )
if err != nil {
2014-07-26 08:24:27 +04:00
log . Fatal ( 4 , "Unknown log mode: %s" , mode )
2014-05-11 22:37:12 +04:00
}
2015-02-27 03:45:38 +03:00
validLevels := [ ] string { "Trace" , "Debug" , "Info" , "Warn" , "Error" , "Critical" }
2014-05-11 22:37:12 +04:00
// Log level.
2015-02-27 03:45:38 +03:00
levelName := Cfg . Section ( "log." + mode ) . Key ( "LEVEL" ) . In (
Cfg . Section ( "log" ) . Key ( "LEVEL" ) . In ( "Trace" , validLevels ) ,
validLevels )
2014-05-11 22:37:12 +04:00
level , ok := logLevels [ levelName ]
if ! ok {
2014-07-26 08:24:27 +04:00
log . Fatal ( 4 , "Unknown log level: %s" , levelName )
2014-05-11 22:37:12 +04:00
}
// Generate log configuration.
switch mode {
case "console" :
LogConfigs [ i ] = fmt . Sprintf ( ` { "level":%s} ` , level )
case "file" :
2014-12-31 13:37:29 +03:00
logPath := sec . Key ( "FILE_NAME" ) . MustString ( path . Join ( LogRootPath , "gogs.log" ) )
2014-05-11 22:37:12 +04:00
os . MkdirAll ( path . Dir ( logPath ) , os . ModePerm )
LogConfigs [ i ] = fmt . Sprintf (
` { "level":%s,"filename":"%s","rotate":%v,"maxlines":%d,"maxsize":%d,"daily":%v,"maxdays":%d} ` , level ,
logPath ,
2014-12-31 13:37:29 +03:00
sec . Key ( "LOG_ROTATE" ) . MustBool ( true ) ,
sec . Key ( "MAX_LINES" ) . MustInt ( 1000000 ) ,
1 << uint ( sec . Key ( "MAX_SIZE_SHIFT" ) . MustInt ( 28 ) ) ,
sec . Key ( "DAILY_ROTATE" ) . MustBool ( true ) ,
sec . Key ( "MAX_DAYS" ) . MustInt ( 7 ) )
2014-05-11 22:37:12 +04:00
case "conn" :
2014-06-20 08:25:23 +04:00
LogConfigs [ i ] = fmt . Sprintf ( ` { "level":%s,"reconnectOnMsg":%v,"reconnect":%v,"net":"%s","addr":"%s"} ` , level ,
2014-12-31 13:37:29 +03:00
sec . Key ( "RECONNECT_ON_MSG" ) . MustBool ( ) ,
sec . Key ( "RECONNECT" ) . MustBool ( ) ,
sec . Key ( "PROTOCOL" ) . In ( "tcp" , [ ] string { "tcp" , "unix" , "udp" } ) ,
sec . Key ( "ADDR" ) . MustString ( ":7020" ) )
2014-05-11 22:37:12 +04:00
case "smtp" :
2014-06-20 08:25:23 +04:00
LogConfigs [ i ] = fmt . Sprintf ( ` { "level":%s,"username":"%s","password":"%s","host":"%s","sendTos":"%s","subject":"%s"} ` , level ,
2014-12-31 13:37:29 +03:00
sec . Key ( "USER" ) . MustString ( "example@example.com" ) ,
sec . Key ( "PASSWD" ) . MustString ( "******" ) ,
sec . Key ( "HOST" ) . MustString ( "127.0.0.1:25" ) ,
sec . Key ( "RECEIVERS" ) . MustString ( "[]" ) ,
sec . Key ( "SUBJECT" ) . MustString ( "Diagnostic message from serve" ) )
2014-05-11 22:37:12 +04:00
case "database" :
2014-06-20 08:25:23 +04:00
LogConfigs [ i ] = fmt . Sprintf ( ` { "level":%s,"driver":"%s","conn":"%s"} ` , level ,
2014-12-31 13:37:29 +03:00
sec . Key ( "DRIVER" ) . String ( ) ,
sec . Key ( "CONN" ) . String ( ) )
2014-05-11 22:37:12 +04:00
}
2014-12-31 13:37:29 +03:00
log . NewLogger ( Cfg . Section ( "log" ) . Key ( "BUFFER_LEN" ) . MustInt64 ( 10000 ) , mode , LogConfigs [ i ] )
2014-05-11 22:37:12 +04:00
log . Info ( "Log Mode: %s(%s)" , strings . Title ( mode ) , levelName )
2014-04-10 22:20:58 +04:00
}
}
func newCacheService ( ) {
2014-12-31 13:37:29 +03:00
CacheAdapter = Cfg . Section ( "cache" ) . Key ( "ADAPTER" ) . In ( "memory" , [ ] string { "memory" , "redis" , "memcache" } )
2014-04-21 14:54:07 +04:00
if EnableRedis {
2015-08-02 07:36:35 +03:00
log . Info ( "Redis Supported" )
2014-04-20 06:13:22 +04:00
}
2014-04-21 14:54:07 +04:00
if EnableMemcache {
2015-08-02 07:36:35 +03:00
log . Info ( "Memcache Supported" )
2014-04-20 06:13:22 +04:00
}
2014-04-10 22:20:58 +04:00
switch CacheAdapter {
case "memory" :
2014-12-31 13:37:29 +03:00
CacheInternal = Cfg . Section ( "cache" ) . Key ( "INTERVAL" ) . MustInt ( 60 )
2014-04-10 22:20:58 +04:00
case "redis" , "memcache" :
2014-12-31 13:37:29 +03:00
CacheConn = strings . Trim ( Cfg . Section ( "cache" ) . Key ( "HOST" ) . String ( ) , "\" " )
2014-04-10 22:20:58 +04:00
default :
2014-07-26 08:24:27 +04:00
log . Fatal ( 4 , "Unknown cache adapter: %s" , CacheAdapter )
2014-04-10 22:20:58 +04:00
}
log . Info ( "Cache Service Enabled" )
}
func newSessionService ( ) {
2014-12-31 13:37:29 +03:00
SessionConfig . Provider = Cfg . Section ( "session" ) . Key ( "PROVIDER" ) . In ( "memory" ,
2014-05-19 06:05:35 +04:00
[ ] string { "memory" , "file" , "redis" , "mysql" } )
2014-12-31 13:37:29 +03:00
SessionConfig . ProviderConfig = strings . Trim ( Cfg . Section ( "session" ) . Key ( "PROVIDER_CONFIG" ) . String ( ) , "\" " )
SessionConfig . CookieName = Cfg . Section ( "session" ) . Key ( "COOKIE_NAME" ) . MustString ( "i_like_gogits" )
2014-09-21 20:22:50 +04:00
SessionConfig . CookiePath = AppSubUrl
2014-12-31 13:37:29 +03:00
SessionConfig . Secure = Cfg . Section ( "session" ) . Key ( "COOKIE_SECURE" ) . MustBool ( )
SessionConfig . Gclifetime = Cfg . Section ( "session" ) . Key ( "GC_INTERVAL_TIME" ) . MustInt64 ( 86400 )
SessionConfig . Maxlifetime = Cfg . Section ( "session" ) . Key ( "SESSION_LIFE_TIME" ) . MustInt64 ( 86400 )
2014-04-10 22:20:58 +04:00
log . Info ( "Session Service Enabled" )
}
2014-05-26 04:11:25 +04:00
// Mailer represents mail service.
type Mailer struct {
2015-09-17 06:08:46 +03:00
QueueLength int
2015-02-12 18:54:51 +03:00
Name string
Host string
From string
User , Passwd string
2015-07-03 09:08:18 +03:00
DisableHelo bool
HeloHostname string
2015-02-12 18:54:51 +03:00
SkipVerify bool
2015-02-13 10:33:55 +03:00
UseCertificate bool
2015-02-12 18:54:51 +03:00
CertFile , KeyFile string
2014-05-26 04:11:25 +04:00
}
var (
2015-09-17 23:11:44 +03:00
MailService * Mailer
2014-05-26 04:11:25 +04:00
)
2014-04-10 22:20:58 +04:00
func newMailService ( ) {
2014-12-31 13:37:29 +03:00
sec := Cfg . Section ( "mailer" )
2014-04-10 22:20:58 +04:00
// Check mailer setting.
2014-12-31 13:37:29 +03:00
if ! sec . Key ( "ENABLED" ) . MustBool ( ) {
2014-04-10 22:20:58 +04:00
return
}
MailService = & Mailer {
2015-09-17 06:08:46 +03:00
QueueLength : sec . Key ( "SEND_BUFFER_LEN" ) . MustInt ( 100 ) ,
2015-02-13 10:33:55 +03:00
Name : sec . Key ( "NAME" ) . MustString ( AppName ) ,
Host : sec . Key ( "HOST" ) . String ( ) ,
User : sec . Key ( "USER" ) . String ( ) ,
Passwd : sec . Key ( "PASSWD" ) . String ( ) ,
2015-07-03 09:08:18 +03:00
DisableHelo : sec . Key ( "DISABLE_HELO" ) . MustBool ( ) ,
HeloHostname : sec . Key ( "HELO_HOSTNAME" ) . String ( ) ,
2015-02-13 10:33:55 +03:00
SkipVerify : sec . Key ( "SKIP_VERIFY" ) . MustBool ( ) ,
UseCertificate : sec . Key ( "USE_CERTIFICATE" ) . MustBool ( ) ,
CertFile : sec . Key ( "CERT_FILE" ) . String ( ) ,
KeyFile : sec . Key ( "KEY_FILE" ) . String ( ) ,
2014-04-10 22:20:58 +04:00
}
2014-12-31 13:37:29 +03:00
MailService . From = sec . Key ( "FROM" ) . MustString ( MailService . User )
2014-04-10 22:20:58 +04:00
log . Info ( "Mail Service Enabled" )
}
func newRegisterMailService ( ) {
2014-12-31 13:37:29 +03:00
if ! Cfg . Section ( "service" ) . Key ( "REGISTER_EMAIL_CONFIRM" ) . MustBool ( ) {
2014-04-10 22:20:58 +04:00
return
} else if MailService == nil {
log . Warn ( "Register Mail Service: Mail Service is not enabled" )
return
}
Service . RegisterEmailConfirm = true
log . Info ( "Register Mail Service Enabled" )
}
func newNotifyMailService ( ) {
2014-12-31 13:37:29 +03:00
if ! Cfg . Section ( "service" ) . Key ( "ENABLE_NOTIFY_MAIL" ) . MustBool ( ) {
2014-04-10 22:20:58 +04:00
return
} else if MailService == nil {
log . Warn ( "Notify Mail Service: Mail Service is not enabled" )
return
}
2014-06-21 08:51:41 +04:00
Service . EnableNotifyMail = true
2014-04-10 22:20:58 +04:00
log . Info ( "Notify Mail Service Enabled" )
}
2014-06-08 12:45:34 +04:00
func newWebhookService ( ) {
2015-02-11 05:06:59 +03:00
sec := Cfg . Section ( "webhook" )
2015-07-25 16:32:04 +03:00
Webhook . QueueLength = sec . Key ( "QUEUE_LENGTH" ) . MustInt ( 1000 )
2015-02-11 05:06:59 +03:00
Webhook . DeliverTimeout = sec . Key ( "DELIVER_TIMEOUT" ) . MustInt ( 5 )
2015-02-11 20:04:01 +03:00
Webhook . SkipTLSVerify = sec . Key ( "SKIP_TLS_VERIFY" ) . MustBool ( )
2015-08-26 19:30:06 +03:00
Webhook . Types = [ ] string { "gogs" , "slack" }
2015-08-27 18:06:14 +03:00
Webhook . PagingNum = sec . Key ( "PAGING_NUM" ) . MustInt ( 10 )
2014-06-08 12:45:34 +04:00
}
2014-05-26 04:11:25 +04:00
func NewServices ( ) {
2014-04-10 22:20:58 +04:00
newService ( )
newLogService ( )
newCacheService ( )
newSessionService ( )
newMailService ( )
newRegisterMailService ( )
newNotifyMailService ( )
2014-06-08 12:45:34 +04:00
newWebhookService ( )
2014-11-21 20:51:36 +03:00
// ssh.Listen("2222")
2014-04-10 22:20:58 +04:00
}