You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // Copyright 2016 The Gogs Authors. All rights reserved.
  2. // Copyright 2016 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package cmd
  6. import (
  7. "fmt"
  8. "code.gitea.io/git"
  9. "code.gitea.io/gitea/models"
  10. "code.gitea.io/gitea/modules/log"
  11. "code.gitea.io/gitea/modules/setting"
  12. "github.com/urfave/cli"
  13. )
  14. var (
  15. // CmdAdmin represents the available admin sub-command.
  16. CmdAdmin = cli.Command{
  17. Name: "admin",
  18. Usage: "Perform admin operations on command line",
  19. Description: `Allow using internal logic of Gitea without hacking into the source code
  20. to make automatic initialization process more smoothly`,
  21. Subcommands: []cli.Command{
  22. subcmdCreateUser,
  23. subcmdChangePassword,
  24. subcmdRepoSyncReleases,
  25. },
  26. }
  27. subcmdCreateUser = cli.Command{
  28. Name: "create-user",
  29. Usage: "Create a new user in database",
  30. Action: runCreateUser,
  31. Flags: []cli.Flag{
  32. cli.StringFlag{
  33. Name: "name",
  34. Value: "",
  35. Usage: "Username",
  36. },
  37. cli.StringFlag{
  38. Name: "password",
  39. Value: "",
  40. Usage: "User password",
  41. },
  42. cli.StringFlag{
  43. Name: "email",
  44. Value: "",
  45. Usage: "User email address",
  46. },
  47. cli.BoolFlag{
  48. Name: "admin",
  49. Usage: "User is an admin",
  50. },
  51. cli.StringFlag{
  52. Name: "config, c",
  53. Value: "custom/conf/app.ini",
  54. Usage: "Custom configuration file path",
  55. },
  56. },
  57. }
  58. subcmdChangePassword = cli.Command{
  59. Name: "change-password",
  60. Usage: "Change a user's password",
  61. Action: runChangePassword,
  62. Flags: []cli.Flag{
  63. cli.StringFlag{
  64. Name: "username,u",
  65. Value: "",
  66. Usage: "The user to change password for",
  67. },
  68. cli.StringFlag{
  69. Name: "password,p",
  70. Value: "",
  71. Usage: "New password to set for user",
  72. },
  73. },
  74. }
  75. subcmdRepoSyncReleases = cli.Command{
  76. Name: "repo-sync-releases",
  77. Usage: "Synchronize repository releases with tags",
  78. Action: runRepoSyncReleases,
  79. }
  80. )
  81. func runChangePassword(c *cli.Context) error {
  82. if !c.IsSet("password") {
  83. return fmt.Errorf("Password is not specified")
  84. } else if !c.IsSet("username") {
  85. return fmt.Errorf("Username is not specified")
  86. }
  87. setting.NewContext()
  88. models.LoadConfigs()
  89. setting.NewXORMLogService(false)
  90. if err := models.SetEngine(); err != nil {
  91. return fmt.Errorf("models.SetEngine: %v", err)
  92. }
  93. uname := c.String("username")
  94. user, err := models.GetUserByName(uname)
  95. if err != nil {
  96. return fmt.Errorf("%v", err)
  97. }
  98. user.Passwd = c.String("password")
  99. if user.Salt, err = models.GetUserSalt(); err != nil {
  100. return fmt.Errorf("%v", err)
  101. }
  102. user.EncodePasswd()
  103. if err := models.UpdateUserCols(user, "passwd", "salt"); err != nil {
  104. return fmt.Errorf("%v", err)
  105. }
  106. fmt.Printf("User '%s' password has been successfully updated!\n", uname)
  107. return nil
  108. }
  109. func runCreateUser(c *cli.Context) error {
  110. if !c.IsSet("name") {
  111. return fmt.Errorf("Username is not specified")
  112. } else if !c.IsSet("password") {
  113. return fmt.Errorf("Password is not specified")
  114. } else if !c.IsSet("email") {
  115. return fmt.Errorf("Email is not specified")
  116. }
  117. if c.IsSet("config") {
  118. setting.CustomConf = c.String("config")
  119. }
  120. setting.NewContext()
  121. models.LoadConfigs()
  122. setting.NewXORMLogService(false)
  123. if err := models.SetEngine(); err != nil {
  124. return fmt.Errorf("models.SetEngine: %v", err)
  125. }
  126. if err := models.CreateUser(&models.User{
  127. Name: c.String("name"),
  128. Email: c.String("email"),
  129. Passwd: c.String("password"),
  130. IsActive: true,
  131. IsAdmin: c.Bool("admin"),
  132. }); err != nil {
  133. return fmt.Errorf("CreateUser: %v", err)
  134. }
  135. fmt.Printf("New user '%s' has been successfully created!\n", c.String("name"))
  136. return nil
  137. }
  138. func runRepoSyncReleases(c *cli.Context) error {
  139. setting.NewContext()
  140. models.LoadConfigs()
  141. setting.NewXORMLogService(false)
  142. if err := models.SetEngine(); err != nil {
  143. return fmt.Errorf("models.SetEngine: %v", err)
  144. }
  145. log.Trace("Synchronizing repository releases (this may take a while)")
  146. for page := 1; ; page++ {
  147. repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{
  148. Page: page,
  149. PageSize: models.RepositoryListDefaultPageSize,
  150. Private: true,
  151. })
  152. if err != nil {
  153. log.Fatal(4, "SearchRepositoryByName: %v", err)
  154. return err
  155. }
  156. if len(repos) == 0 {
  157. break
  158. }
  159. log.Trace("Processing next %d repos of %d", len(repos), count)
  160. for _, repo := range repos {
  161. log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RepoPath())
  162. gitRepo, err := git.OpenRepository(repo.RepoPath())
  163. if err != nil {
  164. log.Warn("OpenRepository: %v", err)
  165. continue
  166. }
  167. oldnum, err := models.GetReleaseCountByRepoID(repo.ID,
  168. models.FindReleasesOptions{
  169. IncludeDrafts: false,
  170. IncludeTags: true,
  171. })
  172. if err != nil {
  173. log.Warn(" GetReleaseCountByRepoID: %v", err)
  174. }
  175. log.Trace(" currentNumReleases is %d, running SyncReleasesWithTags", oldnum)
  176. if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
  177. log.Warn(" SyncReleasesWithTags: %v", err)
  178. continue
  179. }
  180. count, err = models.GetReleaseCountByRepoID(repo.ID,
  181. models.FindReleasesOptions{
  182. IncludeDrafts: false,
  183. IncludeTags: true,
  184. })
  185. if err != nil {
  186. log.Warn(" GetReleaseCountByRepoID: %v", err)
  187. continue
  188. }
  189. log.Trace(" repo %s releases synchronized to tags: from %d to %d",
  190. repo.FullName(), oldnum, count)
  191. }
  192. }
  193. return nil
  194. }