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.
package base
import (
"fmt"
"os"
"os/exec"
"path"
"path/filepath"
2014-04-22 20:55:27 +04:00
"regexp"
2014-04-10 22:20:58 +04:00
"strings"
"github.com/Unknwon/com"
"github.com/Unknwon/goconfig"
qlog "github.com/qiniu/log"
"github.com/gogits/cache"
"github.com/gogits/session"
2014-04-22 20:55:27 +04:00
"github.com/gogits/gogs/modules/auth/ldap"
2014-04-10 22:20:58 +04:00
"github.com/gogits/gogs/modules/log"
)
// Mailer represents mail service.
type Mailer struct {
Name string
Host string
User , Passwd string
}
2014-04-14 02:12:07 +04:00
type OauthInfo struct {
ClientId , ClientSecret string
Scopes string
AuthUrl , TokenUrl string
}
2014-04-10 22:20:58 +04:00
// Oauther represents oauth service.
type Oauther struct {
2014-04-14 12:11:33 +04:00
GitHub , Google , Tencent ,
Twitter , Weibo bool
OauthInfos map [ string ] * OauthInfo
2014-04-10 22:20:58 +04:00
}
var (
2014-05-06 21:47:47 +04:00
AppVer string
AppName string
AppLogo string
AppUrl string
2014-05-11 19:18:10 +04:00
SshPort int
2014-05-06 21:47:47 +04:00
OfflineMode bool
DisableRouterLog bool
ProdMode bool
Domain string
SecretKey string
RunUser string
2014-04-19 14:00:08 +04:00
2014-04-10 22:20:58 +04:00
RepoRootPath string
2014-04-19 14:00:08 +04:00
ScriptType string
2014-04-10 22:20:58 +04:00
InstallLock bool
LogInRememberDays int
CookieUserName string
CookieRememberName string
Cfg * goconfig . ConfigFile
MailService * Mailer
OauthService * Oauther
LogMode string
LogConfig string
Cache cache . Cache
CacheAdapter string
CacheConfig string
SessionProvider string
SessionConfig * session . Config
SessionManager * session . Manager
2014-05-02 05:30:04 +04:00
PictureService string
DisableGravatar bool
2014-04-21 14:54:07 +04:00
EnableRedis bool
EnableMemcache bool
2014-04-10 22:20:58 +04:00
)
var Service struct {
2014-04-22 20:55:27 +04:00
RegisterEmailConfirm bool
DisableRegistration bool
RequireSignInView bool
EnableCacheAvatar bool
NotifyMail bool
ActiveCodeLives int
ResetPwdCodeLives int
2014-04-27 08:34:48 +04:00
LdapAuth bool
2014-04-10 22:20:58 +04:00
}
2014-05-07 00:28:52 +04:00
// ExecDir returns absolute path execution(binary) path.
2014-04-10 22:20:58 +04:00
func ExecDir ( ) ( string , error ) {
file , err := exec . LookPath ( os . Args [ 0 ] )
if err != nil {
return "" , err
}
p , err := filepath . Abs ( file )
if err != nil {
return "" , err
}
return path . Dir ( strings . Replace ( p , "\\" , "/" , - 1 ) ) , nil
}
var logLevels = map [ string ] string {
"Trace" : "0" ,
"Debug" : "1" ,
"Info" : "2" ,
"Warn" : "3" ,
"Error" : "4" ,
"Critical" : "5" ,
}
func newService ( ) {
Service . ActiveCodeLives = Cfg . MustInt ( "service" , "ACTIVE_CODE_LIVE_MINUTES" , 180 )
Service . ResetPwdCodeLives = Cfg . MustInt ( "service" , "RESET_PASSWD_CODE_LIVE_MINUTES" , 180 )
2014-04-22 02:03:04 +04:00
Service . DisableRegistration = Cfg . MustBool ( "service" , "DISABLE_REGISTRATION" , false )
2014-04-10 22:20:58 +04:00
Service . RequireSignInView = Cfg . MustBool ( "service" , "REQUIRE_SIGNIN_VIEW" , false )
Service . EnableCacheAvatar = Cfg . MustBool ( "service" , "ENABLE_CACHE_AVATAR" , false )
}
func newLogService ( ) {
// Get and check log mode.
LogMode = Cfg . MustValue ( "log" , "MODE" , "console" )
modeSec := "log." + LogMode
if _ , err := Cfg . GetSection ( modeSec ) ; err != nil {
qlog . Fatalf ( "Unknown log mode: %s\n" , LogMode )
}
// Log level.
levelName := Cfg . MustValue ( "log." + LogMode , "LEVEL" , "Trace" )
level , ok := logLevels [ levelName ]
if ! ok {
qlog . Fatalf ( "Unknown log level: %s\n" , levelName )
}
// Generate log configuration.
switch LogMode {
case "console" :
LogConfig = fmt . Sprintf ( ` { "level":%s} ` , level )
case "file" :
logPath := Cfg . MustValue ( modeSec , "FILE_NAME" , "log/gogs.log" )
os . MkdirAll ( path . Dir ( logPath ) , os . ModePerm )
LogConfig = fmt . Sprintf (
` { "level":%s,"filename":"%s","rotate":%v,"maxlines":%d,"maxsize":%d,"daily":%v,"maxdays":%d} ` , level ,
logPath ,
Cfg . MustBool ( modeSec , "LOG_ROTATE" , true ) ,
Cfg . MustInt ( modeSec , "MAX_LINES" , 1000000 ) ,
1 << uint ( Cfg . MustInt ( modeSec , "MAX_SIZE_SHIFT" , 28 ) ) ,
Cfg . MustBool ( modeSec , "DAILY_ROTATE" , true ) ,
Cfg . MustInt ( modeSec , "MAX_DAYS" , 7 ) )
case "conn" :
LogConfig = fmt . Sprintf ( ` { "level":"%s","reconnectOnMsg":%v,"reconnect":%v,"net":"%s","addr":"%s"} ` , level ,
Cfg . MustBool ( modeSec , "RECONNECT_ON_MSG" , false ) ,
Cfg . MustBool ( modeSec , "RECONNECT" , false ) ,
Cfg . MustValue ( modeSec , "PROTOCOL" , "tcp" ) ,
Cfg . MustValue ( modeSec , "ADDR" , ":7020" ) )
case "smtp" :
LogConfig = fmt . Sprintf ( ` { "level":"%s","username":"%s","password":"%s","host":"%s","sendTos":"%s","subject":"%s"} ` , level ,
Cfg . MustValue ( modeSec , "USER" , "example@example.com" ) ,
Cfg . MustValue ( modeSec , "PASSWD" , "******" ) ,
Cfg . MustValue ( modeSec , "HOST" , "127.0.0.1:25" ) ,
Cfg . MustValue ( modeSec , "RECEIVERS" , "[]" ) ,
Cfg . MustValue ( modeSec , "SUBJECT" , "Diagnostic message from serve" ) )
case "database" :
LogConfig = fmt . Sprintf ( ` { "level":"%s","driver":"%s","conn":"%s"} ` , level ,
Cfg . MustValue ( modeSec , "Driver" ) ,
Cfg . MustValue ( modeSec , "CONN" ) )
}
log . Info ( "%s %s" , AppName , AppVer )
log . NewLogger ( Cfg . MustInt64 ( "log" , "BUFFER_LEN" , 10000 ) , LogMode , LogConfig )
log . Info ( "Log Mode: %s(%s)" , strings . Title ( LogMode ) , levelName )
}
2014-04-26 11:22:22 +04:00
func newLdapService ( ) {
2014-04-27 08:34:48 +04:00
Service . LdapAuth = Cfg . MustBool ( "security" , "LDAP_AUTH" , false )
if ! Service . LdapAuth {
2014-04-26 11:22:22 +04:00
return
}
nbsrc := 0
for _ , v := range Cfg . GetSectionList ( ) {
if matched , _ := regexp . MatchString ( "(?i)^LDAPSOURCE.*" , v ) ; matched {
ldapname := Cfg . MustValue ( v , "name" , v )
ldaphost := Cfg . MustValue ( v , "host" )
ldapport := Cfg . MustInt ( v , "port" , 389 )
ldapbasedn := Cfg . MustValue ( v , "basedn" , "dc=*,dc=*" )
ldapattribute := Cfg . MustValue ( v , "attribute" , "mail" )
ldapfilter := Cfg . MustValue ( v , "filter" , "(*)" )
ldapmsadsaformat := Cfg . MustValue ( v , "MSADSAFORMAT" , "%s" )
ldap . AddSource ( ldapname , ldaphost , ldapport , ldapbasedn , ldapattribute , ldapfilter , ldapmsadsaformat )
nbsrc ++
log . Debug ( "%s added as LDAP source" , ldapname )
}
}
if nbsrc == 0 {
log . Warn ( "No valide LDAP found, LDAP Authentication NOT enabled" )
2014-04-27 08:34:48 +04:00
Service . LdapAuth = false
2014-04-26 11:22:22 +04:00
return
}
log . Info ( "LDAP Authentication Enabled" )
}
2014-04-10 22:20:58 +04:00
func newCacheService ( ) {
CacheAdapter = Cfg . MustValue ( "cache" , "ADAPTER" , "memory" )
2014-04-21 14:54:07 +04:00
if EnableRedis {
2014-04-20 06:13:22 +04:00
log . Info ( "Redis Enabled" )
}
2014-04-21 14:54:07 +04:00
if EnableMemcache {
2014-04-20 06:13:22 +04:00
log . Info ( "Memcache Enabled" )
}
2014-04-10 22:20:58 +04:00
switch CacheAdapter {
case "memory" :
CacheConfig = fmt . Sprintf ( ` { "interval":%d} ` , Cfg . MustInt ( "cache" , "INTERVAL" , 60 ) )
case "redis" , "memcache" :
CacheConfig = fmt . Sprintf ( ` { "conn":"%s"} ` , Cfg . MustValue ( "cache" , "HOST" ) )
default :
qlog . Fatalf ( "Unknown cache adapter: %s\n" , CacheAdapter )
}
var err error
Cache , err = cache . NewCache ( CacheAdapter , CacheConfig )
if err != nil {
qlog . Fatalf ( "Init cache system failed, adapter: %s, config: %s, %v\n" ,
CacheAdapter , CacheConfig , err )
}
log . Info ( "Cache Service Enabled" )
}
func newSessionService ( ) {
SessionProvider = Cfg . MustValue ( "session" , "PROVIDER" , "memory" )
SessionConfig = new ( session . Config )
SessionConfig . ProviderConfig = Cfg . MustValue ( "session" , "PROVIDER_CONFIG" )
SessionConfig . CookieName = Cfg . MustValue ( "session" , "COOKIE_NAME" , "i_like_gogits" )
SessionConfig . CookieSecure = Cfg . MustBool ( "session" , "COOKIE_SECURE" )
SessionConfig . EnableSetCookie = Cfg . MustBool ( "session" , "ENABLE_SET_COOKIE" , true )
SessionConfig . GcIntervalTime = Cfg . MustInt64 ( "session" , "GC_INTERVAL_TIME" , 86400 )
SessionConfig . SessionLifeTime = Cfg . MustInt64 ( "session" , "SESSION_LIFE_TIME" , 86400 )
SessionConfig . SessionIDHashFunc = Cfg . MustValue ( "session" , "SESSION_ID_HASHFUNC" , "sha1" )
SessionConfig . SessionIDHashKey = Cfg . MustValue ( "session" , "SESSION_ID_HASHKEY" )
if SessionProvider == "file" {
os . MkdirAll ( path . Dir ( SessionConfig . ProviderConfig ) , os . ModePerm )
}
var err error
SessionManager , err = session . NewManager ( SessionProvider , * SessionConfig )
if err != nil {
qlog . Fatalf ( "Init session system failed, provider: %s, %v\n" ,
SessionProvider , err )
}
log . Info ( "Session Service Enabled" )
}
func newMailService ( ) {
// Check mailer setting.
if ! Cfg . MustBool ( "mailer" , "ENABLED" ) {
return
}
MailService = & Mailer {
Name : Cfg . MustValue ( "mailer" , "NAME" , AppName ) ,
Host : Cfg . MustValue ( "mailer" , "HOST" ) ,
User : Cfg . MustValue ( "mailer" , "USER" ) ,
Passwd : Cfg . MustValue ( "mailer" , "PASSWD" ) ,
}
log . Info ( "Mail Service Enabled" )
}
func newRegisterMailService ( ) {
if ! Cfg . MustBool ( "service" , "REGISTER_EMAIL_CONFIRM" ) {
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 ( ) {
if ! Cfg . MustBool ( "service" , "ENABLE_NOTIFY_MAIL" ) {
return
} else if MailService == nil {
log . Warn ( "Notify Mail Service: Mail Service is not enabled" )
return
}
Service . NotifyMail = true
log . Info ( "Notify Mail Service Enabled" )
}
func NewConfigContext ( ) {
workDir , err := ExecDir ( )
if err != nil {
qlog . Fatalf ( "Fail to get work directory: %s\n" , err )
}
cfgPath := filepath . Join ( workDir , "conf/app.ini" )
Cfg , err = goconfig . LoadConfigFile ( cfgPath )
if err != nil {
qlog . Fatalf ( "Cannot load config file(%s): %v\n" , cfgPath , err )
}
Cfg . BlockMode = false
2014-05-05 10:49:33 +04:00
cfgPaths := [ ] string { os . Getenv ( "GOGS_CONFIG" ) , filepath . Join ( workDir , "custom/conf/app.ini" ) }
for _ , cfgPath := range cfgPaths {
if com . IsFile ( cfgPath ) {
if err = Cfg . AppendFiles ( cfgPath ) ; err != nil {
qlog . Fatalf ( "Cannot load config file(%s): %v\n" , cfgPath , err )
}
2014-04-10 22:20:58 +04:00
}
}
AppName = Cfg . MustValue ( "" , "APP_NAME" , "Gogs: Go Git Service" )
AppLogo = Cfg . MustValue ( "" , "APP_LOGO" , "img/favicon.png" )
AppUrl = Cfg . MustValue ( "server" , "ROOT_URL" )
Domain = Cfg . MustValue ( "server" , "DOMAIN" )
2014-05-11 19:18:10 +04:00
SshPort = Cfg . MustInt ( "server" , "SSH_PORT" , 22 )
2014-04-27 11:05:13 +04:00
OfflineMode = Cfg . MustBool ( "server" , "OFFLINE_MODE" , false )
2014-05-06 21:47:47 +04:00
DisableRouterLog = Cfg . MustBool ( "server" , "DISABLE_ROUTER_LOG" , false )
2014-04-10 22:20:58 +04:00
SecretKey = Cfg . MustValue ( "security" , "SECRET_KEY" )
InstallLock = Cfg . MustBool ( "security" , "INSTALL_LOCK" , false )
RunUser = Cfg . MustValue ( "" , "RUN_USER" )
2014-04-12 07:52:08 +04:00
curUser := os . Getenv ( "USER" )
2014-04-10 22:20:58 +04:00
if len ( curUser ) == 0 {
2014-04-12 07:52:08 +04:00
curUser = os . Getenv ( "USERNAME" )
2014-04-10 22:20:58 +04:00
}
// Does not check run user when the install lock is off.
if InstallLock && RunUser != curUser {
qlog . Fatalf ( "Expect user(%s) but current user is: %s\n" , RunUser , curUser )
}
LogInRememberDays = Cfg . MustInt ( "security" , "LOGIN_REMEMBER_DAYS" )
CookieUserName = Cfg . MustValue ( "security" , "COOKIE_USERNAME" )
CookieRememberName = Cfg . MustValue ( "security" , "COOKIE_REMEMBER_NAME" )
2014-05-02 05:30:04 +04:00
2014-04-10 22:20:58 +04:00
PictureService = Cfg . MustValue ( "picture" , "SERVICE" )
2014-05-02 05:30:04 +04:00
DisableGravatar = Cfg . MustBool ( "picture" , "DISABLE_GRAVATAR" , false )
2014-04-10 22:20:58 +04:00
// Determine and create root git reposiroty path.
homeDir , err := com . HomeDir ( )
if err != nil {
qlog . Fatalf ( "Fail to get home directory): %v\n" , err )
}
RepoRootPath = Cfg . MustValue ( "repository" , "ROOT" , filepath . Join ( homeDir , "gogs-repositories" ) )
if err = os . MkdirAll ( RepoRootPath , os . ModePerm ) ; err != nil {
qlog . Fatalf ( "Fail to create RepoRootPath(%s): %v\n" , RepoRootPath , err )
}
2014-04-19 14:00:08 +04:00
ScriptType = Cfg . MustValue ( "repository" , "SCRIPT_TYPE" , "bash" )
2014-04-10 22:20:58 +04:00
}
2014-04-14 02:12:07 +04:00
func NewBaseServices ( ) {
2014-04-10 22:20:58 +04:00
newService ( )
newLogService ( )
2014-04-26 11:22:22 +04:00
newLdapService ( )
2014-04-10 22:20:58 +04:00
newCacheService ( )
newSessionService ( )
newMailService ( )
newRegisterMailService ( )
newNotifyMailService ( )
}