code.gitea.io/gitea@v1.21.7/routers/web/admin/config.go (about) 1 // Copyright 2014 The Gogs Authors. All rights reserved. 2 // Copyright 2019 The Gitea Authors. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 5 package admin 6 7 import ( 8 "net/http" 9 "net/url" 10 "strings" 11 12 system_model "code.gitea.io/gitea/models/system" 13 "code.gitea.io/gitea/modules/base" 14 "code.gitea.io/gitea/modules/container" 15 "code.gitea.io/gitea/modules/context" 16 "code.gitea.io/gitea/modules/git" 17 "code.gitea.io/gitea/modules/json" 18 "code.gitea.io/gitea/modules/log" 19 "code.gitea.io/gitea/modules/setting" 20 "code.gitea.io/gitea/modules/setting/config" 21 "code.gitea.io/gitea/modules/util" 22 "code.gitea.io/gitea/services/mailer" 23 24 "gitea.com/go-chi/session" 25 ) 26 27 const tplConfig base.TplName = "admin/config" 28 29 // SendTestMail send test mail to confirm mail service is OK 30 func SendTestMail(ctx *context.Context) { 31 email := ctx.FormString("email") 32 // Send a test email to the user's email address and redirect back to Config 33 if err := mailer.SendTestMail(email); err != nil { 34 ctx.Flash.Error(ctx.Tr("admin.config.test_mail_failed", email, err)) 35 } else { 36 ctx.Flash.Info(ctx.Tr("admin.config.test_mail_sent", email)) 37 } 38 39 ctx.Redirect(setting.AppSubURL + "/admin/config") 40 } 41 42 func shadowPasswordKV(cfgItem, splitter string) string { 43 fields := strings.Split(cfgItem, splitter) 44 for i := 0; i < len(fields); i++ { 45 if strings.HasPrefix(fields[i], "password=") { 46 fields[i] = "password=******" 47 break 48 } 49 } 50 return strings.Join(fields, splitter) 51 } 52 53 func shadowURL(provider, cfgItem string) string { 54 u, err := url.Parse(cfgItem) 55 if err != nil { 56 log.Error("Shadowing Password for %v failed: %v", provider, err) 57 return cfgItem 58 } 59 if u.User != nil { 60 atIdx := strings.Index(cfgItem, "@") 61 if atIdx > 0 { 62 colonIdx := strings.LastIndex(cfgItem[:atIdx], ":") 63 if colonIdx > 0 { 64 return cfgItem[:colonIdx+1] + "******" + cfgItem[atIdx:] 65 } 66 } 67 } 68 return cfgItem 69 } 70 71 func shadowPassword(provider, cfgItem string) string { 72 switch provider { 73 case "redis": 74 return shadowPasswordKV(cfgItem, ",") 75 case "mysql": 76 // root:@tcp(localhost:3306)/macaron?charset=utf8 77 atIdx := strings.Index(cfgItem, "@") 78 if atIdx > 0 { 79 colonIdx := strings.Index(cfgItem[:atIdx], ":") 80 if colonIdx > 0 { 81 return cfgItem[:colonIdx+1] + "******" + cfgItem[atIdx:] 82 } 83 } 84 return cfgItem 85 case "postgres": 86 // user=jiahuachen dbname=macaron port=5432 sslmode=disable 87 if !strings.HasPrefix(cfgItem, "postgres://") { 88 return shadowPasswordKV(cfgItem, " ") 89 } 90 fallthrough 91 case "couchbase": 92 return shadowURL(provider, cfgItem) 93 // postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full 94 // Notice: use shadowURL 95 } 96 return cfgItem 97 } 98 99 // Config show admin config page 100 func Config(ctx *context.Context) { 101 ctx.Data["Title"] = ctx.Tr("admin.config") 102 ctx.Data["PageIsAdminConfig"] = true 103 104 ctx.Data["CustomConf"] = setting.CustomConf 105 ctx.Data["AppUrl"] = setting.AppURL 106 ctx.Data["AppBuiltWith"] = setting.AppBuiltWith 107 ctx.Data["Domain"] = setting.Domain 108 ctx.Data["OfflineMode"] = setting.OfflineMode 109 ctx.Data["RunUser"] = setting.RunUser 110 ctx.Data["RunMode"] = util.ToTitleCase(setting.RunMode) 111 ctx.Data["GitVersion"] = git.VersionInfo() 112 113 ctx.Data["AppDataPath"] = setting.AppDataPath 114 ctx.Data["RepoRootPath"] = setting.RepoRootPath 115 ctx.Data["CustomRootPath"] = setting.CustomPath 116 ctx.Data["LogRootPath"] = setting.Log.RootPath 117 ctx.Data["ScriptType"] = setting.ScriptType 118 ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser 119 ctx.Data["ReverseProxyAuthEmail"] = setting.ReverseProxyAuthEmail 120 121 ctx.Data["SSH"] = setting.SSH 122 ctx.Data["LFS"] = setting.LFS 123 124 ctx.Data["Service"] = setting.Service 125 ctx.Data["DbCfg"] = setting.Database 126 ctx.Data["Webhook"] = setting.Webhook 127 128 ctx.Data["MailerEnabled"] = false 129 if setting.MailService != nil { 130 ctx.Data["MailerEnabled"] = true 131 ctx.Data["Mailer"] = setting.MailService 132 } 133 134 ctx.Data["CacheAdapter"] = setting.CacheService.Adapter 135 ctx.Data["CacheInterval"] = setting.CacheService.Interval 136 137 ctx.Data["CacheConn"] = shadowPassword(setting.CacheService.Adapter, setting.CacheService.Conn) 138 ctx.Data["CacheItemTTL"] = setting.CacheService.TTL 139 140 sessionCfg := setting.SessionConfig 141 if sessionCfg.Provider == "VirtualSession" { 142 var realSession session.Options 143 if err := json.Unmarshal([]byte(sessionCfg.ProviderConfig), &realSession); err != nil { 144 log.Error("Unable to unmarshall session config for virtual provider config: %s\nError: %v", sessionCfg.ProviderConfig, err) 145 } 146 sessionCfg.Provider = realSession.Provider 147 sessionCfg.ProviderConfig = realSession.ProviderConfig 148 sessionCfg.CookieName = realSession.CookieName 149 sessionCfg.CookiePath = realSession.CookiePath 150 sessionCfg.Gclifetime = realSession.Gclifetime 151 sessionCfg.Maxlifetime = realSession.Maxlifetime 152 sessionCfg.Secure = realSession.Secure 153 sessionCfg.Domain = realSession.Domain 154 } 155 sessionCfg.ProviderConfig = shadowPassword(sessionCfg.Provider, sessionCfg.ProviderConfig) 156 ctx.Data["SessionConfig"] = sessionCfg 157 158 ctx.Data["Git"] = setting.Git 159 ctx.Data["AccessLogTemplate"] = setting.Log.AccessLogTemplate 160 ctx.Data["LogSQL"] = setting.Database.LogSQL 161 162 ctx.Data["Loggers"] = log.GetManager().DumpLoggers() 163 config.GetDynGetter().InvalidateCache() 164 ctx.Data["SystemConfig"] = setting.Config() 165 prepareDeprecatedWarningsAlert(ctx) 166 167 ctx.HTML(http.StatusOK, tplConfig) 168 } 169 170 func ChangeConfig(ctx *context.Context) { 171 key := strings.TrimSpace(ctx.FormString("key")) 172 value := ctx.FormString("value") 173 cfg := setting.Config() 174 allowedKeys := container.SetOf(cfg.Picture.DisableGravatar.DynKey(), cfg.Picture.EnableFederatedAvatar.DynKey()) 175 if !allowedKeys.Contains(key) { 176 ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key)) 177 return 178 } 179 if err := system_model.SetSettings(ctx, map[string]string{key: value}); err != nil { 180 log.Error("set setting failed: %v", err) 181 ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key)) 182 return 183 } 184 185 config.GetDynGetter().InvalidateCache() 186 ctx.JSONOK() 187 }