Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
8 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
9 роки тому
8 роки тому
8 роки тому
8 роки тому
8 роки тому
8 роки тому
9 роки тому
10 роки тому
7 роки тому
9 роки тому
9 роки тому
10 роки тому
9 роки тому
Add support for federated avatars (#3320) * Add support for federated avatars Fixes #3105 Removes avatar fetching duplication code Adds an "Enable Federated Avatar" checkbox in user settings (defaults to unchecked) Moves avatar settings all in the same form, making local and remote avatars mutually exclusive Renames UploadAvatarForm to AvatarForm as it's not anymore only for uploading * Run gofmt on all modified files * Move Avatar form in its own page * Add go-libravatar dependency to vendor/ dir Hopefully helps with accepting the contribution. See also #3214 * Revert "Add go-libravatar dependency to vendor/ dir" This reverts commit a8cb93ae640bbb90f7d25012fc257bda9fae9b82. * Make federated avatar setting a global configuration Removes the per-user setting * Move avatar handling back to base tool, disable federated avatar in offline mode * Format, handle error * Properly set fallback host * Use unsupported github.com mirror for importing go-libravatar * Remove comment showing life exists outside of github.com ... pity, but contribution would not be accepted otherwise * Use Combo for Get and Post methods over /avatar * FEDERATED_AVATAR -> ENABLE_FEDERATED_AVATAR * Fix persistance of federated avatar lookup checkbox at install time * Federated Avatars -> Enable Federated Avatars * Use len(string) == 0 instead of string == "" * Move import line where it belong See https://github.com/Unknwon/go-code-convention/blob/master/en-US/import_packages.md Pity the import url is still the unofficial one, but oh well... * Save a line (and waste much more expensive time) * Remove redundant parens * Remove an empty line * Remove empty lines * Reorder lines to make diff smaller * Remove another newline Unknwon review got me start a fight against newlines * Move DISABLE_GRAVATAR and ENABLE_FEDERATED_AVATAR after OFFLINE_MODE On re-reading the diff I figured what Unknwon meant here: https://github.com/gogits/gogs/pull/3320/files#r73741106 * Remove newlines that weren't there before my intervention
7 роки тому
9 роки тому
8 роки тому
9 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
9 роки тому
10 роки тому
8 роки тому
8 роки тому
9 роки тому
9 роки тому
10 роки тому
10 роки тому
10 роки тому
9 роки тому
10 роки тому
9 роки тому
10 роки тому
9 роки тому
9 роки тому
8 роки тому
8 роки тому
8 роки тому
8 роки тому
8 роки тому
9 роки тому
10 роки тому
9 роки тому
9 роки тому
9 роки тому
Add support for federated avatars (#3320) * Add support for federated avatars Fixes #3105 Removes avatar fetching duplication code Adds an "Enable Federated Avatar" checkbox in user settings (defaults to unchecked) Moves avatar settings all in the same form, making local and remote avatars mutually exclusive Renames UploadAvatarForm to AvatarForm as it's not anymore only for uploading * Run gofmt on all modified files * Move Avatar form in its own page * Add go-libravatar dependency to vendor/ dir Hopefully helps with accepting the contribution. See also #3214 * Revert "Add go-libravatar dependency to vendor/ dir" This reverts commit a8cb93ae640bbb90f7d25012fc257bda9fae9b82. * Make federated avatar setting a global configuration Removes the per-user setting * Move avatar handling back to base tool, disable federated avatar in offline mode * Format, handle error * Properly set fallback host * Use unsupported github.com mirror for importing go-libravatar * Remove comment showing life exists outside of github.com ... pity, but contribution would not be accepted otherwise * Use Combo for Get and Post methods over /avatar * FEDERATED_AVATAR -> ENABLE_FEDERATED_AVATAR * Fix persistance of federated avatar lookup checkbox at install time * Federated Avatars -> Enable Federated Avatars * Use len(string) == 0 instead of string == "" * Move import line where it belong See https://github.com/Unknwon/go-code-convention/blob/master/en-US/import_packages.md Pity the import url is still the unofficial one, but oh well... * Save a line (and waste much more expensive time) * Remove redundant parens * Remove an empty line * Remove empty lines * Reorder lines to make diff smaller * Remove another newline Unknwon review got me start a fight against newlines * Move DISABLE_GRAVATAR and ENABLE_FEDERATED_AVATAR after OFFLINE_MODE On re-reading the diff I figured what Unknwon meant here: https://github.com/gogits/gogs/pull/3320/files#r73741106 * Remove newlines that weren't there before my intervention
7 роки тому
9 роки тому
8 роки тому
9 роки тому
10 роки тому
9 роки тому
9 роки тому
9 роки тому
9 роки тому
9 роки тому
9 роки тому
10 роки тому
10 роки тому
10 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package routers
  5. import (
  6. "errors"
  7. "os"
  8. "os/exec"
  9. "path"
  10. "path/filepath"
  11. "strings"
  12. "github.com/Unknwon/com"
  13. "github.com/go-xorm/xorm"
  14. "gopkg.in/ini.v1"
  15. "code.gitea.io/gitea/models"
  16. "code.gitea.io/gitea/modules/auth"
  17. "code.gitea.io/gitea/modules/base"
  18. "code.gitea.io/gitea/modules/context"
  19. "code.gitea.io/gitea/modules/log"
  20. "code.gitea.io/gitea/modules/setting"
  21. "code.gitea.io/gitea/modules/user"
  22. )
  23. const (
  24. // tplInstall template for installation page
  25. tplInstall base.TplName = "install"
  26. )
  27. // InstallInit prepare for rendering installation page
  28. func InstallInit(ctx *context.Context) {
  29. if setting.InstallLock {
  30. ctx.Handle(404, "Install", errors.New("Installation is prohibited"))
  31. return
  32. }
  33. ctx.Data["Title"] = ctx.Tr("install.install")
  34. ctx.Data["PageIsInstall"] = true
  35. dbOpts := []string{"MySQL", "PostgreSQL","MSSQL"}
  36. if models.EnableSQLite3 {
  37. dbOpts = append(dbOpts, "SQLite3")
  38. }
  39. if models.EnableTiDB {
  40. dbOpts = append(dbOpts, "TiDB")
  41. }
  42. ctx.Data["DbOptions"] = dbOpts
  43. }
  44. // Install render installation page
  45. func Install(ctx *context.Context) {
  46. form := auth.InstallForm{}
  47. // Database settings
  48. form.DbHost = models.DbCfg.Host
  49. form.DbUser = models.DbCfg.User
  50. form.DbName = models.DbCfg.Name
  51. form.DbPath = models.DbCfg.Path
  52. ctx.Data["CurDbOption"] = "MySQL"
  53. switch models.DbCfg.Type {
  54. case "postgres":
  55. ctx.Data["CurDbOption"] = "PostgreSQL"
  56. case "mssql":
  57. ctx.Data["CurDbOption"] = "MSSQL"
  58. case "sqlite3":
  59. if models.EnableSQLite3 {
  60. ctx.Data["CurDbOption"] = "SQLite3"
  61. }
  62. case "tidb":
  63. if models.EnableTiDB {
  64. ctx.Data["CurDbOption"] = "TiDB"
  65. }
  66. }
  67. // Application general settings
  68. form.AppName = setting.AppName
  69. form.RepoRootPath = setting.RepoRootPath
  70. // Note(unknwon): it's hard for Windows users change a running user,
  71. // so just use current one if config says default.
  72. if setting.IsWindows && setting.RunUser == "git" {
  73. form.RunUser = user.CurrentUsername()
  74. } else {
  75. form.RunUser = setting.RunUser
  76. }
  77. form.Domain = setting.Domain
  78. form.SSHPort = setting.SSH.Port
  79. form.HTTPPort = setting.HTTPPort
  80. form.AppURL = setting.AppURL
  81. form.LogRootPath = setting.LogRootPath
  82. // E-mail service settings
  83. if setting.MailService != nil {
  84. form.SMTPHost = setting.MailService.Host
  85. form.SMTPFrom = setting.MailService.From
  86. form.SMTPEmail = setting.MailService.User
  87. }
  88. form.RegisterConfirm = setting.Service.RegisterEmailConfirm
  89. form.MailNotify = setting.Service.EnableNotifyMail
  90. // Server and other services settings
  91. form.OfflineMode = setting.OfflineMode
  92. form.DisableGravatar = setting.DisableGravatar
  93. form.EnableFederatedAvatar = setting.EnableFederatedAvatar
  94. form.DisableRegistration = setting.Service.DisableRegistration
  95. form.EnableCaptcha = setting.Service.EnableCaptcha
  96. form.RequireSignInView = setting.Service.RequireSignInView
  97. auth.AssignForm(form, ctx.Data)
  98. ctx.HTML(200, tplInstall)
  99. }
  100. // InstallPost response for submit install items
  101. func InstallPost(ctx *context.Context, form auth.InstallForm) {
  102. var err error
  103. ctx.Data["CurDbOption"] = form.DbType
  104. if ctx.HasError() {
  105. if ctx.HasValue("Err_SMTPEmail") {
  106. ctx.Data["Err_SMTP"] = true
  107. }
  108. if ctx.HasValue("Err_AdminName") ||
  109. ctx.HasValue("Err_AdminPasswd") ||
  110. ctx.HasValue("Err_AdminEmail") {
  111. ctx.Data["Err_Admin"] = true
  112. }
  113. ctx.HTML(200, tplInstall)
  114. return
  115. }
  116. if _, err = exec.LookPath("git"); err != nil {
  117. ctx.RenderWithErr(ctx.Tr("install.test_git_failed", err), tplInstall, &form)
  118. return
  119. }
  120. // Pass basic check, now test configuration.
  121. // Test database setting.
  122. dbTypes := map[string]string{"MySQL": "mysql", "PostgreSQL": "postgres", "MSSQL": "mssql", "SQLite3": "sqlite3", "TiDB": "tidb"}
  123. models.DbCfg.Type = dbTypes[form.DbType]
  124. models.DbCfg.Host = form.DbHost
  125. models.DbCfg.User = form.DbUser
  126. models.DbCfg.Passwd = form.DbPasswd
  127. models.DbCfg.Name = form.DbName
  128. models.DbCfg.SSLMode = form.SSLMode
  129. models.DbCfg.Path = form.DbPath
  130. if (models.DbCfg.Type == "sqlite3" || models.DbCfg.Type == "tidb") &&
  131. len(models.DbCfg.Path) == 0 {
  132. ctx.Data["Err_DbPath"] = true
  133. ctx.RenderWithErr(ctx.Tr("install.err_empty_db_path"), tplInstall, &form)
  134. return
  135. } else if models.DbCfg.Type == "tidb" &&
  136. strings.ContainsAny(path.Base(models.DbCfg.Path), ".-") {
  137. ctx.Data["Err_DbPath"] = true
  138. ctx.RenderWithErr(ctx.Tr("install.err_invalid_tidb_name"), tplInstall, &form)
  139. return
  140. }
  141. // Set test engine.
  142. var x *xorm.Engine
  143. if err = models.NewTestEngine(x); err != nil {
  144. if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
  145. ctx.Data["Err_DbType"] = true
  146. ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "https://docs.gitea.io/installation/install_from_binary.html"), tplInstall, &form)
  147. } else {
  148. ctx.Data["Err_DbSetting"] = true
  149. ctx.RenderWithErr(ctx.Tr("install.invalid_db_setting", err), tplInstall, &form)
  150. }
  151. return
  152. }
  153. // Test repository root path.
  154. form.RepoRootPath = strings.Replace(form.RepoRootPath, "\\", "/", -1)
  155. if err = os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil {
  156. ctx.Data["Err_RepoRootPath"] = true
  157. ctx.RenderWithErr(ctx.Tr("install.invalid_repo_path", err), tplInstall, &form)
  158. return
  159. }
  160. // Test log root path.
  161. form.LogRootPath = strings.Replace(form.LogRootPath, "\\", "/", -1)
  162. if err = os.MkdirAll(form.LogRootPath, os.ModePerm); err != nil {
  163. ctx.Data["Err_LogRootPath"] = true
  164. ctx.RenderWithErr(ctx.Tr("install.invalid_log_root_path", err), tplInstall, &form)
  165. return
  166. }
  167. currentUser, match := setting.IsRunUserMatchCurrentUser(form.RunUser)
  168. if !match {
  169. ctx.Data["Err_RunUser"] = true
  170. ctx.RenderWithErr(ctx.Tr("install.run_user_not_match", form.RunUser, currentUser), tplInstall, &form)
  171. return
  172. }
  173. // Check logic loophole between disable self-registration and no admin account.
  174. if form.DisableRegistration && len(form.AdminName) == 0 {
  175. ctx.Data["Err_Services"] = true
  176. ctx.Data["Err_Admin"] = true
  177. ctx.RenderWithErr(ctx.Tr("install.no_admin_and_disable_registration"), tplInstall, form)
  178. return
  179. }
  180. // Check admin password.
  181. if len(form.AdminName) > 0 && len(form.AdminPasswd) == 0 {
  182. ctx.Data["Err_Admin"] = true
  183. ctx.Data["Err_AdminPasswd"] = true
  184. ctx.RenderWithErr(ctx.Tr("install.err_empty_admin_password"), tplInstall, form)
  185. return
  186. }
  187. if form.AdminPasswd != form.AdminConfirmPasswd {
  188. ctx.Data["Err_Admin"] = true
  189. ctx.Data["Err_AdminPasswd"] = true
  190. ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplInstall, form)
  191. return
  192. }
  193. if form.AppURL[len(form.AppURL)-1] != '/' {
  194. form.AppURL += "/"
  195. }
  196. // Save settings.
  197. cfg := ini.Empty()
  198. if com.IsFile(setting.CustomConf) {
  199. // Keeps custom settings if there is already something.
  200. if err = cfg.Append(setting.CustomConf); err != nil {
  201. log.Error(4, "Fail to load custom conf '%s': %v", setting.CustomConf, err)
  202. }
  203. }
  204. cfg.Section("database").Key("DB_TYPE").SetValue(models.DbCfg.Type)
  205. cfg.Section("database").Key("HOST").SetValue(models.DbCfg.Host)
  206. cfg.Section("database").Key("NAME").SetValue(models.DbCfg.Name)
  207. cfg.Section("database").Key("USER").SetValue(models.DbCfg.User)
  208. cfg.Section("database").Key("PASSWD").SetValue(models.DbCfg.Passwd)
  209. cfg.Section("database").Key("SSL_MODE").SetValue(models.DbCfg.SSLMode)
  210. cfg.Section("database").Key("PATH").SetValue(models.DbCfg.Path)
  211. cfg.Section("").Key("APP_NAME").SetValue(form.AppName)
  212. cfg.Section("repository").Key("ROOT").SetValue(form.RepoRootPath)
  213. cfg.Section("").Key("RUN_USER").SetValue(form.RunUser)
  214. cfg.Section("server").Key("DOMAIN").SetValue(form.Domain)
  215. cfg.Section("server").Key("HTTP_PORT").SetValue(form.HTTPPort)
  216. cfg.Section("server").Key("ROOT_URL").SetValue(form.AppURL)
  217. if form.SSHPort == 0 {
  218. cfg.Section("server").Key("DISABLE_SSH").SetValue("true")
  219. } else {
  220. cfg.Section("server").Key("DISABLE_SSH").SetValue("false")
  221. cfg.Section("server").Key("SSH_PORT").SetValue(com.ToStr(form.SSHPort))
  222. }
  223. if len(strings.TrimSpace(form.SMTPHost)) > 0 {
  224. cfg.Section("mailer").Key("ENABLED").SetValue("true")
  225. cfg.Section("mailer").Key("HOST").SetValue(form.SMTPHost)
  226. cfg.Section("mailer").Key("FROM").SetValue(form.SMTPFrom)
  227. cfg.Section("mailer").Key("USER").SetValue(form.SMTPEmail)
  228. cfg.Section("mailer").Key("PASSWD").SetValue(form.SMTPPasswd)
  229. } else {
  230. cfg.Section("mailer").Key("ENABLED").SetValue("false")
  231. }
  232. cfg.Section("service").Key("REGISTER_EMAIL_CONFIRM").SetValue(com.ToStr(form.RegisterConfirm))
  233. cfg.Section("service").Key("ENABLE_NOTIFY_MAIL").SetValue(com.ToStr(form.MailNotify))
  234. cfg.Section("server").Key("OFFLINE_MODE").SetValue(com.ToStr(form.OfflineMode))
  235. cfg.Section("picture").Key("DISABLE_GRAVATAR").SetValue(com.ToStr(form.DisableGravatar))
  236. cfg.Section("picture").Key("ENABLE_FEDERATED_AVATAR").SetValue(com.ToStr(form.EnableFederatedAvatar))
  237. cfg.Section("service").Key("DISABLE_REGISTRATION").SetValue(com.ToStr(form.DisableRegistration))
  238. cfg.Section("service").Key("ENABLE_CAPTCHA").SetValue(com.ToStr(form.EnableCaptcha))
  239. cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(com.ToStr(form.RequireSignInView))
  240. cfg.Section("").Key("RUN_MODE").SetValue("prod")
  241. cfg.Section("session").Key("PROVIDER").SetValue("file")
  242. cfg.Section("log").Key("MODE").SetValue("file")
  243. cfg.Section("log").Key("LEVEL").SetValue("Info")
  244. cfg.Section("log").Key("ROOT_PATH").SetValue(form.LogRootPath)
  245. cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
  246. var secretKey string
  247. if secretKey, err = base.GetRandomString(10); err != nil {
  248. ctx.RenderWithErr(ctx.Tr("install.secret_key_failed", err), tplInstall, &form)
  249. return
  250. }
  251. cfg.Section("security").Key("SECRET_KEY").SetValue(secretKey)
  252. err = os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm)
  253. if err != nil {
  254. ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
  255. return
  256. }
  257. if err = cfg.SaveTo(setting.CustomConf); err != nil {
  258. ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
  259. return
  260. }
  261. GlobalInit()
  262. // Create admin account
  263. if len(form.AdminName) > 0 {
  264. u := &models.User{
  265. Name: form.AdminName,
  266. Email: form.AdminEmail,
  267. Passwd: form.AdminPasswd,
  268. IsAdmin: true,
  269. IsActive: true,
  270. }
  271. if err = models.CreateUser(u); err != nil {
  272. if !models.IsErrUserAlreadyExist(err) {
  273. setting.InstallLock = false
  274. ctx.Data["Err_AdminName"] = true
  275. ctx.Data["Err_AdminEmail"] = true
  276. ctx.RenderWithErr(ctx.Tr("install.invalid_admin_setting", err), tplInstall, &form)
  277. return
  278. }
  279. log.Info("Admin account already exist")
  280. u, _ = models.GetUserByName(u.Name)
  281. }
  282. // Auto-login for admin
  283. if err = ctx.Session.Set("uid", u.ID); err != nil {
  284. ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
  285. return
  286. }
  287. if err = ctx.Session.Set("uname", u.Name); err != nil {
  288. ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
  289. return
  290. }
  291. }
  292. log.Info("First-time run install finished!")
  293. ctx.Flash.Success(ctx.Tr("install.install_success"))
  294. ctx.Redirect(form.AppURL + "user/login")
  295. }