* split setting.go as multiple files * fix commentstags/v1.21.12.1
| @@ -0,0 +1,43 @@ | |||
| // Copyright 2019 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 setting | |||
| import ( | |||
| "strings" | |||
| "time" | |||
| "code.gitea.io/gitea/modules/log" | |||
| ) | |||
| // Cache represents cache settings | |||
| type Cache struct { | |||
| Adapter string | |||
| Interval int | |||
| Conn string | |||
| TTL time.Duration | |||
| } | |||
| var ( | |||
| // CacheService the global cache | |||
| CacheService *Cache | |||
| ) | |||
| func newCacheService() { | |||
| sec := Cfg.Section("cache") | |||
| CacheService = &Cache{ | |||
| Adapter: sec.Key("ADAPTER").In("memory", []string{"memory", "redis", "memcache"}), | |||
| } | |||
| switch CacheService.Adapter { | |||
| case "memory": | |||
| CacheService.Interval = sec.Key("INTERVAL").MustInt(60) | |||
| case "redis", "memcache": | |||
| CacheService.Conn = strings.Trim(sec.Key("HOST").String(), "\" ") | |||
| default: | |||
| log.Fatal(4, "Unknown cache adapter: %s", CacheService.Adapter) | |||
| } | |||
| CacheService.TTL = sec.Key("ITEM_TTL").MustDuration(16 * time.Hour) | |||
| log.Info("Cache Service Enabled") | |||
| } | |||
| @@ -0,0 +1,186 @@ | |||
| // Copyright 2019 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 setting | |||
| import ( | |||
| "fmt" | |||
| "os" | |||
| "path" | |||
| "path/filepath" | |||
| "strings" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "github.com/go-xorm/core" | |||
| ) | |||
| var logLevels = map[string]string{ | |||
| "Trace": "0", | |||
| "Debug": "1", | |||
| "Info": "2", | |||
| "Warn": "3", | |||
| "Error": "4", | |||
| "Critical": "5", | |||
| } | |||
| func getLogLevel(section string, key string, defaultValue string) string { | |||
| validLevels := []string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"} | |||
| return Cfg.Section(section).Key(key).In(defaultValue, validLevels) | |||
| } | |||
| func newLogService() { | |||
| log.Info("Gitea v%s%s", AppVer, AppBuiltWith) | |||
| LogModes = strings.Split(Cfg.Section("log").Key("MODE").MustString("console"), ",") | |||
| LogConfigs = make([]string, len(LogModes)) | |||
| useConsole := false | |||
| for i := 0; i < len(LogModes); i++ { | |||
| LogModes[i] = strings.TrimSpace(LogModes[i]) | |||
| if LogModes[i] == "console" { | |||
| useConsole = true | |||
| } | |||
| } | |||
| if !useConsole { | |||
| log.DelLogger("console") | |||
| } | |||
| for i, mode := range LogModes { | |||
| sec, err := Cfg.GetSection("log." + mode) | |||
| if err != nil { | |||
| sec, _ = Cfg.NewSection("log." + mode) | |||
| } | |||
| // Log level. | |||
| levelName := getLogLevel("log."+mode, "LEVEL", LogLevel) | |||
| level, ok := logLevels[levelName] | |||
| if !ok { | |||
| log.Fatal(4, "Unknown log level: %s", levelName) | |||
| } | |||
| // Generate log configuration. | |||
| switch mode { | |||
| case "console": | |||
| LogConfigs[i] = fmt.Sprintf(`{"level":%s}`, level) | |||
| case "file": | |||
| logPath := sec.Key("FILE_NAME").MustString(path.Join(LogRootPath, "gitea.log")) | |||
| if err = os.MkdirAll(path.Dir(logPath), os.ModePerm); err != nil { | |||
| panic(err.Error()) | |||
| } | |||
| LogConfigs[i] = fmt.Sprintf( | |||
| `{"level":%s,"filename":"%s","rotate":%v,"maxsize":%d,"daily":%v,"maxdays":%d}`, level, | |||
| logPath, | |||
| sec.Key("LOG_ROTATE").MustBool(true), | |||
| 1<<uint(sec.Key("MAX_SIZE_SHIFT").MustInt(28)), | |||
| sec.Key("DAILY_ROTATE").MustBool(true), | |||
| sec.Key("MAX_DAYS").MustInt(7)) | |||
| case "conn": | |||
| LogConfigs[i] = fmt.Sprintf(`{"level":%s,"reconnectOnMsg":%v,"reconnect":%v,"net":"%s","addr":"%s"}`, level, | |||
| sec.Key("RECONNECT_ON_MSG").MustBool(), | |||
| sec.Key("RECONNECT").MustBool(), | |||
| sec.Key("PROTOCOL").In("tcp", []string{"tcp", "unix", "udp"}), | |||
| sec.Key("ADDR").MustString(":7020")) | |||
| case "smtp": | |||
| LogConfigs[i] = fmt.Sprintf(`{"level":%s,"username":"%s","password":"%s","host":"%s","sendTos":["%s"],"subject":"%s"}`, level, | |||
| sec.Key("USER").MustString("example@example.com"), | |||
| sec.Key("PASSWD").MustString("******"), | |||
| sec.Key("HOST").MustString("127.0.0.1:25"), | |||
| strings.Replace(sec.Key("RECEIVERS").MustString("example@example.com"), ",", "\",\"", -1), | |||
| sec.Key("SUBJECT").MustString("Diagnostic message from serve")) | |||
| case "database": | |||
| LogConfigs[i] = fmt.Sprintf(`{"level":%s,"driver":"%s","conn":"%s"}`, level, | |||
| sec.Key("DRIVER").String(), | |||
| sec.Key("CONN").String()) | |||
| } | |||
| log.NewLogger(Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000), mode, LogConfigs[i]) | |||
| log.Info("Log Mode: %s(%s)", strings.Title(mode), levelName) | |||
| } | |||
| } | |||
| // NewXORMLogService initializes xorm logger service | |||
| func NewXORMLogService(disableConsole bool) { | |||
| logModes := strings.Split(Cfg.Section("log").Key("MODE").MustString("console"), ",") | |||
| var logConfigs string | |||
| for _, mode := range logModes { | |||
| mode = strings.TrimSpace(mode) | |||
| if disableConsole && mode == "console" { | |||
| continue | |||
| } | |||
| sec, err := Cfg.GetSection("log." + mode) | |||
| if err != nil { | |||
| sec, _ = Cfg.NewSection("log." + mode) | |||
| } | |||
| // Log level. | |||
| levelName := getLogLevel("log."+mode, "LEVEL", LogLevel) | |||
| level, ok := logLevels[levelName] | |||
| if !ok { | |||
| log.Fatal(4, "Unknown log level: %s", levelName) | |||
| } | |||
| // Generate log configuration. | |||
| switch mode { | |||
| case "console": | |||
| logConfigs = fmt.Sprintf(`{"level":%s}`, level) | |||
| case "file": | |||
| logPath := sec.Key("FILE_NAME").MustString(path.Join(LogRootPath, "xorm.log")) | |||
| if err = os.MkdirAll(path.Dir(logPath), os.ModePerm); err != nil { | |||
| panic(err.Error()) | |||
| } | |||
| logPath = path.Join(filepath.Dir(logPath), "xorm.log") | |||
| logConfigs = fmt.Sprintf( | |||
| `{"level":%s,"filename":"%s","rotate":%v,"maxsize":%d,"daily":%v,"maxdays":%d}`, level, | |||
| logPath, | |||
| sec.Key("LOG_ROTATE").MustBool(true), | |||
| 1<<uint(sec.Key("MAX_SIZE_SHIFT").MustInt(28)), | |||
| sec.Key("DAILY_ROTATE").MustBool(true), | |||
| sec.Key("MAX_DAYS").MustInt(7)) | |||
| case "conn": | |||
| logConfigs = fmt.Sprintf(`{"level":%s,"reconnectOnMsg":%v,"reconnect":%v,"net":"%s","addr":"%s"}`, level, | |||
| sec.Key("RECONNECT_ON_MSG").MustBool(), | |||
| sec.Key("RECONNECT").MustBool(), | |||
| sec.Key("PROTOCOL").In("tcp", []string{"tcp", "unix", "udp"}), | |||
| sec.Key("ADDR").MustString(":7020")) | |||
| case "smtp": | |||
| logConfigs = fmt.Sprintf(`{"level":%s,"username":"%s","password":"%s","host":"%s","sendTos":"%s","subject":"%s"}`, level, | |||
| 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")) | |||
| case "database": | |||
| logConfigs = fmt.Sprintf(`{"level":%s,"driver":"%s","conn":"%s"}`, level, | |||
| sec.Key("DRIVER").String(), | |||
| sec.Key("CONN").String()) | |||
| } | |||
| log.NewXORMLogger(Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000), mode, logConfigs) | |||
| if !disableConsole { | |||
| log.Info("XORM Log Mode: %s(%s)", strings.Title(mode), levelName) | |||
| } | |||
| var lvl core.LogLevel | |||
| switch levelName { | |||
| case "Trace", "Debug": | |||
| lvl = core.LOG_DEBUG | |||
| case "Info": | |||
| lvl = core.LOG_INFO | |||
| case "Warn": | |||
| lvl = core.LOG_WARNING | |||
| case "Error", "Critical": | |||
| lvl = core.LOG_ERR | |||
| } | |||
| log.XORMLogger.SetLevel(lvl) | |||
| } | |||
| if len(logConfigs) == 0 { | |||
| log.DiscardXORMLogger() | |||
| } | |||
| } | |||
| @@ -0,0 +1,126 @@ | |||
| // Copyright 2019 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 setting | |||
| import ( | |||
| "net/mail" | |||
| "code.gitea.io/gitea/modules/log" | |||
| shellquote "github.com/kballard/go-shellquote" | |||
| ) | |||
| // Mailer represents mail service. | |||
| type Mailer struct { | |||
| // Mailer | |||
| QueueLength int | |||
| Name string | |||
| From string | |||
| FromName string | |||
| FromEmail string | |||
| SendAsPlainText bool | |||
| MailerType string | |||
| // SMTP sender | |||
| Host string | |||
| User, Passwd string | |||
| DisableHelo bool | |||
| HeloHostname string | |||
| SkipVerify bool | |||
| UseCertificate bool | |||
| CertFile, KeyFile string | |||
| IsTLSEnabled bool | |||
| // Sendmail sender | |||
| SendmailPath string | |||
| SendmailArgs []string | |||
| } | |||
| var ( | |||
| // MailService the global mailer | |||
| MailService *Mailer | |||
| ) | |||
| func newMailService() { | |||
| sec := Cfg.Section("mailer") | |||
| // Check mailer setting. | |||
| if !sec.Key("ENABLED").MustBool() { | |||
| return | |||
| } | |||
| MailService = &Mailer{ | |||
| QueueLength: sec.Key("SEND_BUFFER_LEN").MustInt(100), | |||
| Name: sec.Key("NAME").MustString(AppName), | |||
| SendAsPlainText: sec.Key("SEND_AS_PLAIN_TEXT").MustBool(false), | |||
| MailerType: sec.Key("MAILER_TYPE").In("", []string{"smtp", "sendmail", "dummy"}), | |||
| Host: sec.Key("HOST").String(), | |||
| User: sec.Key("USER").String(), | |||
| Passwd: sec.Key("PASSWD").String(), | |||
| DisableHelo: sec.Key("DISABLE_HELO").MustBool(), | |||
| HeloHostname: sec.Key("HELO_HOSTNAME").String(), | |||
| SkipVerify: sec.Key("SKIP_VERIFY").MustBool(), | |||
| UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(), | |||
| CertFile: sec.Key("CERT_FILE").String(), | |||
| KeyFile: sec.Key("KEY_FILE").String(), | |||
| IsTLSEnabled: sec.Key("IS_TLS_ENABLED").MustBool(), | |||
| SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"), | |||
| } | |||
| MailService.From = sec.Key("FROM").MustString(MailService.User) | |||
| if sec.HasKey("ENABLE_HTML_ALTERNATIVE") { | |||
| log.Warn("ENABLE_HTML_ALTERNATIVE is deprecated, use SEND_AS_PLAIN_TEXT") | |||
| MailService.SendAsPlainText = !sec.Key("ENABLE_HTML_ALTERNATIVE").MustBool(false) | |||
| } | |||
| if sec.HasKey("USE_SENDMAIL") { | |||
| log.Warn("USE_SENDMAIL is deprecated, use MAILER_TYPE=sendmail") | |||
| if MailService.MailerType == "" && sec.Key("USE_SENDMAIL").MustBool(false) { | |||
| MailService.MailerType = "sendmail" | |||
| } | |||
| } | |||
| parsed, err := mail.ParseAddress(MailService.From) | |||
| if err != nil { | |||
| log.Fatal(4, "Invalid mailer.FROM (%s): %v", MailService.From, err) | |||
| } | |||
| MailService.FromName = parsed.Name | |||
| MailService.FromEmail = parsed.Address | |||
| if MailService.MailerType == "" { | |||
| MailService.MailerType = "smtp" | |||
| } | |||
| if MailService.MailerType == "sendmail" { | |||
| MailService.SendmailArgs, err = shellquote.Split(sec.Key("SENDMAIL_ARGS").String()) | |||
| if err != nil { | |||
| log.Error(4, "Failed to parse Sendmail args: %v", CustomConf, err) | |||
| } | |||
| } | |||
| log.Info("Mail Service Enabled") | |||
| } | |||
| func newRegisterMailService() { | |||
| if !Cfg.Section("service").Key("REGISTER_EMAIL_CONFIRM").MustBool() { | |||
| 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.Section("service").Key("ENABLE_NOTIFY_MAIL").MustBool() { | |||
| return | |||
| } else if MailService == nil { | |||
| log.Warn("Notify Mail Service: Mail Service is not enabled") | |||
| return | |||
| } | |||
| Service.EnableNotifyMail = true | |||
| log.Info("Notify Mail Service Enabled") | |||
| } | |||
| @@ -0,0 +1,89 @@ | |||
| // Copyright 2019 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 setting | |||
| import "regexp" | |||
| // Service settings | |||
| var Service struct { | |||
| ActiveCodeLives int | |||
| ResetPwdCodeLives int | |||
| RegisterEmailConfirm bool | |||
| EmailDomainWhitelist []string | |||
| DisableRegistration bool | |||
| AllowOnlyExternalRegistration bool | |||
| ShowRegistrationButton bool | |||
| RequireSignInView bool | |||
| EnableNotifyMail bool | |||
| EnableReverseProxyAuth bool | |||
| EnableReverseProxyAutoRegister bool | |||
| EnableReverseProxyEmail bool | |||
| EnableCaptcha bool | |||
| CaptchaType string | |||
| RecaptchaSecret string | |||
| RecaptchaSitekey string | |||
| DefaultKeepEmailPrivate bool | |||
| DefaultAllowCreateOrganization bool | |||
| EnableTimetracking bool | |||
| DefaultEnableTimetracking bool | |||
| DefaultEnableDependencies bool | |||
| DefaultAllowOnlyContributorsToTrackTime bool | |||
| NoReplyAddress string | |||
| EnableUserHeatmap bool | |||
| AutoWatchNewRepos bool | |||
| // OpenID settings | |||
| EnableOpenIDSignIn bool | |||
| EnableOpenIDSignUp bool | |||
| OpenIDWhitelist []*regexp.Regexp | |||
| OpenIDBlacklist []*regexp.Regexp | |||
| } | |||
| func newService() { | |||
| 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.AllowOnlyExternalRegistration = sec.Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").MustBool() | |||
| Service.EmailDomainWhitelist = sec.Key("EMAIL_DOMAIN_WHITELIST").Strings(",") | |||
| Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!(Service.DisableRegistration || Service.AllowOnlyExternalRegistration)) | |||
| Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool() | |||
| Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool() | |||
| Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool() | |||
| Service.EnableReverseProxyEmail = sec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool() | |||
| Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false) | |||
| Service.CaptchaType = sec.Key("CAPTCHA_TYPE").MustString(ImageCaptcha) | |||
| Service.RecaptchaSecret = sec.Key("RECAPTCHA_SECRET").MustString("") | |||
| Service.RecaptchaSitekey = sec.Key("RECAPTCHA_SITEKEY").MustString("") | |||
| Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool() | |||
| Service.DefaultAllowCreateOrganization = sec.Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").MustBool(true) | |||
| Service.EnableTimetracking = sec.Key("ENABLE_TIMETRACKING").MustBool(true) | |||
| if Service.EnableTimetracking { | |||
| Service.DefaultEnableTimetracking = sec.Key("DEFAULT_ENABLE_TIMETRACKING").MustBool(true) | |||
| } | |||
| Service.DefaultEnableDependencies = sec.Key("DEFAULT_ENABLE_DEPENDENCIES").MustBool(true) | |||
| Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true) | |||
| Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply.example.org") | |||
| Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true) | |||
| Service.AutoWatchNewRepos = sec.Key("AUTO_WATCH_NEW_REPOS").MustBool(true) | |||
| sec = Cfg.Section("openid") | |||
| Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(!InstallLock) | |||
| Service.EnableOpenIDSignUp = sec.Key("ENABLE_OPENID_SIGNUP").MustBool(!Service.DisableRegistration && Service.EnableOpenIDSignIn) | |||
| pats := sec.Key("WHITELISTED_URIS").Strings(" ") | |||
| if len(pats) != 0 { | |||
| Service.OpenIDWhitelist = make([]*regexp.Regexp, len(pats)) | |||
| for i, p := range pats { | |||
| Service.OpenIDWhitelist[i] = regexp.MustCompilePOSIX(p) | |||
| } | |||
| } | |||
| pats = sec.Key("BLACKLISTED_URIS").Strings(" ") | |||
| if len(pats) != 0 { | |||
| Service.OpenIDBlacklist = make([]*regexp.Regexp, len(pats)) | |||
| for i, p := range pats { | |||
| Service.OpenIDBlacklist[i] = regexp.MustCompilePOSIX(p) | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,35 @@ | |||
| // Copyright 2019 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 setting | |||
| import ( | |||
| "path" | |||
| "path/filepath" | |||
| "strings" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "github.com/go-macaron/session" | |||
| ) | |||
| var ( | |||
| // SessionConfig difines Session settings | |||
| SessionConfig session.Options | |||
| ) | |||
| func newSessionService() { | |||
| SessionConfig.Provider = Cfg.Section("session").Key("PROVIDER").In("memory", | |||
| []string{"memory", "file", "redis", "mysql", "postgres", "couchbase", "memcache", "nodb"}) | |||
| SessionConfig.ProviderConfig = strings.Trim(Cfg.Section("session").Key("PROVIDER_CONFIG").MustString(path.Join(AppDataPath, "sessions")), "\" ") | |||
| if SessionConfig.Provider == "file" && !filepath.IsAbs(SessionConfig.ProviderConfig) { | |||
| SessionConfig.ProviderConfig = path.Join(AppWorkPath, SessionConfig.ProviderConfig) | |||
| } | |||
| SessionConfig.CookieName = Cfg.Section("session").Key("COOKIE_NAME").MustString("i_like_gitea") | |||
| SessionConfig.CookiePath = AppSubURL | |||
| SessionConfig.Secure = Cfg.Section("session").Key("COOKIE_SECURE").MustBool(false) | |||
| SessionConfig.Gclifetime = Cfg.Section("session").Key("GC_INTERVAL_TIME").MustInt64(86400) | |||
| SessionConfig.Maxlifetime = Cfg.Section("session").Key("SESSION_LIFE_TIME").MustInt64(86400) | |||
| log.Info("Session Service Enabled") | |||
| } | |||
| @@ -7,9 +7,7 @@ package setting | |||
| import ( | |||
| "encoding/base64" | |||
| "fmt" | |||
| "net" | |||
| "net/mail" | |||
| "net/url" | |||
| "os" | |||
| "os/exec" | |||
| @@ -30,14 +28,12 @@ import ( | |||
| "github.com/Unknwon/com" | |||
| _ "github.com/go-macaron/cache/memcache" // memcache plugin for cache | |||
| _ "github.com/go-macaron/cache/redis" | |||
| "github.com/go-macaron/session" | |||
| _ "github.com/go-macaron/session/couchbase" // couchbase plugin for session store | |||
| _ "github.com/go-macaron/session/memcache" // memcache plugin for session store | |||
| _ "github.com/go-macaron/session/mysql" // mysql plugin for session store | |||
| _ "github.com/go-macaron/session/nodb" // nodb plugin for session store | |||
| _ "github.com/go-macaron/session/postgres" // postgres plugin for session store | |||
| _ "github.com/go-macaron/session/redis" // redis plugin for store session | |||
| "github.com/go-xorm/core" | |||
| shellquote "github.com/kballard/go-shellquote" | |||
| version "github.com/mcuadros/go-version" | |||
| ini "gopkg.in/ini.v1" | |||
| @@ -192,20 +188,6 @@ var ( | |||
| MaxIndexerFileSize int64 | |||
| } | |||
| // Webhook settings | |||
| Webhook = struct { | |||
| QueueLength int | |||
| DeliverTimeout int | |||
| SkipTLSVerify bool | |||
| Types []string | |||
| PagingNum int | |||
| }{ | |||
| QueueLength: 1000, | |||
| DeliverTimeout: 5, | |||
| SkipTLSVerify: false, | |||
| PagingNum: 10, | |||
| } | |||
| // Repository settings | |||
| Repository = struct { | |||
| AnsiCharset string | |||
| @@ -409,8 +391,6 @@ var ( | |||
| // Time settings | |||
| TimeFormat string | |||
| // Session settings | |||
| SessionConfig session.Options | |||
| CSRFCookieName = "_csrf" | |||
| // Cron tasks | |||
| @@ -1235,428 +1215,6 @@ func NewContext() { | |||
| } | |||
| } | |||
| // Service settings | |||
| var Service struct { | |||
| ActiveCodeLives int | |||
| ResetPwdCodeLives int | |||
| RegisterEmailConfirm bool | |||
| EmailDomainWhitelist []string | |||
| DisableRegistration bool | |||
| AllowOnlyExternalRegistration bool | |||
| ShowRegistrationButton bool | |||
| RequireSignInView bool | |||
| EnableNotifyMail bool | |||
| EnableReverseProxyAuth bool | |||
| EnableReverseProxyAutoRegister bool | |||
| EnableReverseProxyEmail bool | |||
| EnableCaptcha bool | |||
| CaptchaType string | |||
| RecaptchaSecret string | |||
| RecaptchaSitekey string | |||
| DefaultKeepEmailPrivate bool | |||
| DefaultAllowCreateOrganization bool | |||
| EnableTimetracking bool | |||
| DefaultEnableTimetracking bool | |||
| DefaultEnableDependencies bool | |||
| DefaultAllowOnlyContributorsToTrackTime bool | |||
| NoReplyAddress string | |||
| EnableUserHeatmap bool | |||
| AutoWatchNewRepos bool | |||
| // OpenID settings | |||
| EnableOpenIDSignIn bool | |||
| EnableOpenIDSignUp bool | |||
| OpenIDWhitelist []*regexp.Regexp | |||
| OpenIDBlacklist []*regexp.Regexp | |||
| } | |||
| func newService() { | |||
| 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.AllowOnlyExternalRegistration = sec.Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").MustBool() | |||
| Service.EmailDomainWhitelist = sec.Key("EMAIL_DOMAIN_WHITELIST").Strings(",") | |||
| Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!(Service.DisableRegistration || Service.AllowOnlyExternalRegistration)) | |||
| Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool() | |||
| Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool() | |||
| Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool() | |||
| Service.EnableReverseProxyEmail = sec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool() | |||
| Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false) | |||
| Service.CaptchaType = sec.Key("CAPTCHA_TYPE").MustString(ImageCaptcha) | |||
| Service.RecaptchaSecret = sec.Key("RECAPTCHA_SECRET").MustString("") | |||
| Service.RecaptchaSitekey = sec.Key("RECAPTCHA_SITEKEY").MustString("") | |||
| Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool() | |||
| Service.DefaultAllowCreateOrganization = sec.Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").MustBool(true) | |||
| Service.EnableTimetracking = sec.Key("ENABLE_TIMETRACKING").MustBool(true) | |||
| if Service.EnableTimetracking { | |||
| Service.DefaultEnableTimetracking = sec.Key("DEFAULT_ENABLE_TIMETRACKING").MustBool(true) | |||
| } | |||
| Service.DefaultEnableDependencies = sec.Key("DEFAULT_ENABLE_DEPENDENCIES").MustBool(true) | |||
| Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true) | |||
| Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply.example.org") | |||
| Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true) | |||
| Service.AutoWatchNewRepos = sec.Key("AUTO_WATCH_NEW_REPOS").MustBool(true) | |||
| sec = Cfg.Section("openid") | |||
| Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(!InstallLock) | |||
| Service.EnableOpenIDSignUp = sec.Key("ENABLE_OPENID_SIGNUP").MustBool(!Service.DisableRegistration && Service.EnableOpenIDSignIn) | |||
| pats := sec.Key("WHITELISTED_URIS").Strings(" ") | |||
| if len(pats) != 0 { | |||
| Service.OpenIDWhitelist = make([]*regexp.Regexp, len(pats)) | |||
| for i, p := range pats { | |||
| Service.OpenIDWhitelist[i] = regexp.MustCompilePOSIX(p) | |||
| } | |||
| } | |||
| pats = sec.Key("BLACKLISTED_URIS").Strings(" ") | |||
| if len(pats) != 0 { | |||
| Service.OpenIDBlacklist = make([]*regexp.Regexp, len(pats)) | |||
| for i, p := range pats { | |||
| Service.OpenIDBlacklist[i] = regexp.MustCompilePOSIX(p) | |||
| } | |||
| } | |||
| } | |||
| var logLevels = map[string]string{ | |||
| "Trace": "0", | |||
| "Debug": "1", | |||
| "Info": "2", | |||
| "Warn": "3", | |||
| "Error": "4", | |||
| "Critical": "5", | |||
| } | |||
| func getLogLevel(section string, key string, defaultValue string) string { | |||
| validLevels := []string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"} | |||
| return Cfg.Section(section).Key(key).In(defaultValue, validLevels) | |||
| } | |||
| func newLogService() { | |||
| log.Info("Gitea v%s%s", AppVer, AppBuiltWith) | |||
| LogModes = strings.Split(Cfg.Section("log").Key("MODE").MustString("console"), ",") | |||
| LogConfigs = make([]string, len(LogModes)) | |||
| useConsole := false | |||
| for i := 0; i < len(LogModes); i++ { | |||
| LogModes[i] = strings.TrimSpace(LogModes[i]) | |||
| if LogModes[i] == "console" { | |||
| useConsole = true | |||
| } | |||
| } | |||
| if !useConsole { | |||
| log.DelLogger("console") | |||
| } | |||
| for i, mode := range LogModes { | |||
| sec, err := Cfg.GetSection("log." + mode) | |||
| if err != nil { | |||
| sec, _ = Cfg.NewSection("log." + mode) | |||
| } | |||
| // Log level. | |||
| levelName := getLogLevel("log."+mode, "LEVEL", LogLevel) | |||
| level, ok := logLevels[levelName] | |||
| if !ok { | |||
| log.Fatal(4, "Unknown log level: %s", levelName) | |||
| } | |||
| // Generate log configuration. | |||
| switch mode { | |||
| case "console": | |||
| LogConfigs[i] = fmt.Sprintf(`{"level":%s}`, level) | |||
| case "file": | |||
| logPath := sec.Key("FILE_NAME").MustString(path.Join(LogRootPath, "gitea.log")) | |||
| if err = os.MkdirAll(path.Dir(logPath), os.ModePerm); err != nil { | |||
| panic(err.Error()) | |||
| } | |||
| LogConfigs[i] = fmt.Sprintf( | |||
| `{"level":%s,"filename":"%s","rotate":%v,"maxsize":%d,"daily":%v,"maxdays":%d}`, level, | |||
| logPath, | |||
| sec.Key("LOG_ROTATE").MustBool(true), | |||
| 1<<uint(sec.Key("MAX_SIZE_SHIFT").MustInt(28)), | |||
| sec.Key("DAILY_ROTATE").MustBool(true), | |||
| sec.Key("MAX_DAYS").MustInt(7)) | |||
| case "conn": | |||
| LogConfigs[i] = fmt.Sprintf(`{"level":%s,"reconnectOnMsg":%v,"reconnect":%v,"net":"%s","addr":"%s"}`, level, | |||
| sec.Key("RECONNECT_ON_MSG").MustBool(), | |||
| sec.Key("RECONNECT").MustBool(), | |||
| sec.Key("PROTOCOL").In("tcp", []string{"tcp", "unix", "udp"}), | |||
| sec.Key("ADDR").MustString(":7020")) | |||
| case "smtp": | |||
| LogConfigs[i] = fmt.Sprintf(`{"level":%s,"username":"%s","password":"%s","host":"%s","sendTos":["%s"],"subject":"%s"}`, level, | |||
| sec.Key("USER").MustString("example@example.com"), | |||
| sec.Key("PASSWD").MustString("******"), | |||
| sec.Key("HOST").MustString("127.0.0.1:25"), | |||
| strings.Replace(sec.Key("RECEIVERS").MustString("example@example.com"), ",", "\",\"", -1), | |||
| sec.Key("SUBJECT").MustString("Diagnostic message from serve")) | |||
| case "database": | |||
| LogConfigs[i] = fmt.Sprintf(`{"level":%s,"driver":"%s","conn":"%s"}`, level, | |||
| sec.Key("DRIVER").String(), | |||
| sec.Key("CONN").String()) | |||
| } | |||
| log.NewLogger(Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000), mode, LogConfigs[i]) | |||
| log.Info("Log Mode: %s(%s)", strings.Title(mode), levelName) | |||
| } | |||
| } | |||
| // NewXORMLogService initializes xorm logger service | |||
| func NewXORMLogService(disableConsole bool) { | |||
| logModes := strings.Split(Cfg.Section("log").Key("MODE").MustString("console"), ",") | |||
| var logConfigs string | |||
| for _, mode := range logModes { | |||
| mode = strings.TrimSpace(mode) | |||
| if disableConsole && mode == "console" { | |||
| continue | |||
| } | |||
| sec, err := Cfg.GetSection("log." + mode) | |||
| if err != nil { | |||
| sec, _ = Cfg.NewSection("log." + mode) | |||
| } | |||
| // Log level. | |||
| levelName := getLogLevel("log."+mode, "LEVEL", LogLevel) | |||
| level, ok := logLevels[levelName] | |||
| if !ok { | |||
| log.Fatal(4, "Unknown log level: %s", levelName) | |||
| } | |||
| // Generate log configuration. | |||
| switch mode { | |||
| case "console": | |||
| logConfigs = fmt.Sprintf(`{"level":%s}`, level) | |||
| case "file": | |||
| logPath := sec.Key("FILE_NAME").MustString(path.Join(LogRootPath, "xorm.log")) | |||
| if err = os.MkdirAll(path.Dir(logPath), os.ModePerm); err != nil { | |||
| panic(err.Error()) | |||
| } | |||
| logPath = path.Join(filepath.Dir(logPath), "xorm.log") | |||
| logConfigs = fmt.Sprintf( | |||
| `{"level":%s,"filename":"%s","rotate":%v,"maxsize":%d,"daily":%v,"maxdays":%d}`, level, | |||
| logPath, | |||
| sec.Key("LOG_ROTATE").MustBool(true), | |||
| 1<<uint(sec.Key("MAX_SIZE_SHIFT").MustInt(28)), | |||
| sec.Key("DAILY_ROTATE").MustBool(true), | |||
| sec.Key("MAX_DAYS").MustInt(7)) | |||
| case "conn": | |||
| logConfigs = fmt.Sprintf(`{"level":%s,"reconnectOnMsg":%v,"reconnect":%v,"net":"%s","addr":"%s"}`, level, | |||
| sec.Key("RECONNECT_ON_MSG").MustBool(), | |||
| sec.Key("RECONNECT").MustBool(), | |||
| sec.Key("PROTOCOL").In("tcp", []string{"tcp", "unix", "udp"}), | |||
| sec.Key("ADDR").MustString(":7020")) | |||
| case "smtp": | |||
| logConfigs = fmt.Sprintf(`{"level":%s,"username":"%s","password":"%s","host":"%s","sendTos":"%s","subject":"%s"}`, level, | |||
| 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")) | |||
| case "database": | |||
| logConfigs = fmt.Sprintf(`{"level":%s,"driver":"%s","conn":"%s"}`, level, | |||
| sec.Key("DRIVER").String(), | |||
| sec.Key("CONN").String()) | |||
| } | |||
| log.NewXORMLogger(Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000), mode, logConfigs) | |||
| if !disableConsole { | |||
| log.Info("XORM Log Mode: %s(%s)", strings.Title(mode), levelName) | |||
| } | |||
| var lvl core.LogLevel | |||
| switch levelName { | |||
| case "Trace", "Debug": | |||
| lvl = core.LOG_DEBUG | |||
| case "Info": | |||
| lvl = core.LOG_INFO | |||
| case "Warn": | |||
| lvl = core.LOG_WARNING | |||
| case "Error", "Critical": | |||
| lvl = core.LOG_ERR | |||
| } | |||
| log.XORMLogger.SetLevel(lvl) | |||
| } | |||
| if len(logConfigs) == 0 { | |||
| log.DiscardXORMLogger() | |||
| } | |||
| } | |||
| // Cache represents cache settings | |||
| type Cache struct { | |||
| Adapter string | |||
| Interval int | |||
| Conn string | |||
| TTL time.Duration | |||
| } | |||
| var ( | |||
| // CacheService the global cache | |||
| CacheService *Cache | |||
| ) | |||
| func newCacheService() { | |||
| sec := Cfg.Section("cache") | |||
| CacheService = &Cache{ | |||
| Adapter: sec.Key("ADAPTER").In("memory", []string{"memory", "redis", "memcache"}), | |||
| } | |||
| switch CacheService.Adapter { | |||
| case "memory": | |||
| CacheService.Interval = sec.Key("INTERVAL").MustInt(60) | |||
| case "redis", "memcache": | |||
| CacheService.Conn = strings.Trim(sec.Key("HOST").String(), "\" ") | |||
| default: | |||
| log.Fatal(4, "Unknown cache adapter: %s", CacheService.Adapter) | |||
| } | |||
| CacheService.TTL = sec.Key("ITEM_TTL").MustDuration(16 * time.Hour) | |||
| log.Info("Cache Service Enabled") | |||
| } | |||
| func newSessionService() { | |||
| SessionConfig.Provider = Cfg.Section("session").Key("PROVIDER").In("memory", | |||
| []string{"memory", "file", "redis", "mysql", "postgres", "couchbase", "memcache", "nodb"}) | |||
| SessionConfig.ProviderConfig = strings.Trim(Cfg.Section("session").Key("PROVIDER_CONFIG").MustString(path.Join(AppDataPath, "sessions")), "\" ") | |||
| if SessionConfig.Provider == "file" && !filepath.IsAbs(SessionConfig.ProviderConfig) { | |||
| SessionConfig.ProviderConfig = path.Join(AppWorkPath, SessionConfig.ProviderConfig) | |||
| } | |||
| SessionConfig.CookieName = Cfg.Section("session").Key("COOKIE_NAME").MustString("i_like_gitea") | |||
| SessionConfig.CookiePath = AppSubURL | |||
| SessionConfig.Secure = Cfg.Section("session").Key("COOKIE_SECURE").MustBool(false) | |||
| SessionConfig.Gclifetime = Cfg.Section("session").Key("GC_INTERVAL_TIME").MustInt64(86400) | |||
| SessionConfig.Maxlifetime = Cfg.Section("session").Key("SESSION_LIFE_TIME").MustInt64(86400) | |||
| log.Info("Session Service Enabled") | |||
| } | |||
| // Mailer represents mail service. | |||
| type Mailer struct { | |||
| // Mailer | |||
| QueueLength int | |||
| Name string | |||
| From string | |||
| FromName string | |||
| FromEmail string | |||
| SendAsPlainText bool | |||
| MailerType string | |||
| // SMTP sender | |||
| Host string | |||
| User, Passwd string | |||
| DisableHelo bool | |||
| HeloHostname string | |||
| SkipVerify bool | |||
| UseCertificate bool | |||
| CertFile, KeyFile string | |||
| IsTLSEnabled bool | |||
| // Sendmail sender | |||
| SendmailPath string | |||
| SendmailArgs []string | |||
| } | |||
| var ( | |||
| // MailService the global mailer | |||
| MailService *Mailer | |||
| ) | |||
| func newMailService() { | |||
| sec := Cfg.Section("mailer") | |||
| // Check mailer setting. | |||
| if !sec.Key("ENABLED").MustBool() { | |||
| return | |||
| } | |||
| MailService = &Mailer{ | |||
| QueueLength: sec.Key("SEND_BUFFER_LEN").MustInt(100), | |||
| Name: sec.Key("NAME").MustString(AppName), | |||
| SendAsPlainText: sec.Key("SEND_AS_PLAIN_TEXT").MustBool(false), | |||
| MailerType: sec.Key("MAILER_TYPE").In("", []string{"smtp", "sendmail", "dummy"}), | |||
| Host: sec.Key("HOST").String(), | |||
| User: sec.Key("USER").String(), | |||
| Passwd: sec.Key("PASSWD").String(), | |||
| DisableHelo: sec.Key("DISABLE_HELO").MustBool(), | |||
| HeloHostname: sec.Key("HELO_HOSTNAME").String(), | |||
| SkipVerify: sec.Key("SKIP_VERIFY").MustBool(), | |||
| UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(), | |||
| CertFile: sec.Key("CERT_FILE").String(), | |||
| KeyFile: sec.Key("KEY_FILE").String(), | |||
| IsTLSEnabled: sec.Key("IS_TLS_ENABLED").MustBool(), | |||
| SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"), | |||
| } | |||
| MailService.From = sec.Key("FROM").MustString(MailService.User) | |||
| if sec.HasKey("ENABLE_HTML_ALTERNATIVE") { | |||
| log.Warn("ENABLE_HTML_ALTERNATIVE is deprecated, use SEND_AS_PLAIN_TEXT") | |||
| MailService.SendAsPlainText = !sec.Key("ENABLE_HTML_ALTERNATIVE").MustBool(false) | |||
| } | |||
| if sec.HasKey("USE_SENDMAIL") { | |||
| log.Warn("USE_SENDMAIL is deprecated, use MAILER_TYPE=sendmail") | |||
| if MailService.MailerType == "" && sec.Key("USE_SENDMAIL").MustBool(false) { | |||
| MailService.MailerType = "sendmail" | |||
| } | |||
| } | |||
| parsed, err := mail.ParseAddress(MailService.From) | |||
| if err != nil { | |||
| log.Fatal(4, "Invalid mailer.FROM (%s): %v", MailService.From, err) | |||
| } | |||
| MailService.FromName = parsed.Name | |||
| MailService.FromEmail = parsed.Address | |||
| if MailService.MailerType == "" { | |||
| MailService.MailerType = "smtp" | |||
| } | |||
| if MailService.MailerType == "sendmail" { | |||
| MailService.SendmailArgs, err = shellquote.Split(sec.Key("SENDMAIL_ARGS").String()) | |||
| if err != nil { | |||
| log.Error(4, "Failed to parse Sendmail args: %v", CustomConf, err) | |||
| } | |||
| } | |||
| log.Info("Mail Service Enabled") | |||
| } | |||
| func newRegisterMailService() { | |||
| if !Cfg.Section("service").Key("REGISTER_EMAIL_CONFIRM").MustBool() { | |||
| 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.Section("service").Key("ENABLE_NOTIFY_MAIL").MustBool() { | |||
| return | |||
| } else if MailService == nil { | |||
| log.Warn("Notify Mail Service: Mail Service is not enabled") | |||
| return | |||
| } | |||
| Service.EnableNotifyMail = true | |||
| log.Info("Notify Mail Service Enabled") | |||
| } | |||
| func newWebhookService() { | |||
| sec := Cfg.Section("webhook") | |||
| Webhook.QueueLength = sec.Key("QUEUE_LENGTH").MustInt(1000) | |||
| Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5) | |||
| Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool() | |||
| Webhook.Types = []string{"gitea", "gogs", "slack", "discord", "dingtalk"} | |||
| Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10) | |||
| } | |||
| // NewServices initializes the services | |||
| func NewServices() { | |||
| newService() | |||
| @@ -0,0 +1,30 @@ | |||
| // Copyright 2019 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 setting | |||
| var ( | |||
| // Webhook settings | |||
| Webhook = struct { | |||
| QueueLength int | |||
| DeliverTimeout int | |||
| SkipTLSVerify bool | |||
| Types []string | |||
| PagingNum int | |||
| }{ | |||
| QueueLength: 1000, | |||
| DeliverTimeout: 5, | |||
| SkipTLSVerify: false, | |||
| PagingNum: 10, | |||
| } | |||
| ) | |||
| func newWebhookService() { | |||
| sec := Cfg.Section("webhook") | |||
| Webhook.QueueLength = sec.Key("QUEUE_LENGTH").MustInt(1000) | |||
| Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5) | |||
| Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool() | |||
| Webhook.Types = []string{"gitea", "gogs", "slack", "discord", "dingtalk"} | |||
| Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10) | |||
| } | |||