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.

197 lines
4.4 KiB

  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: "Command line interface to perform common administrative operations",
  19. Subcommands: []cli.Command{
  20. subcmdCreateUser,
  21. subcmdChangePassword,
  22. subcmdRepoSyncReleases,
  23. },
  24. }
  25. subcmdCreateUser = cli.Command{
  26. Name: "create-user",
  27. Usage: "Create a new user in database",
  28. Action: runCreateUser,
  29. Flags: []cli.Flag{
  30. cli.StringFlag{
  31. Name: "name",
  32. Usage: "Username",
  33. },
  34. cli.StringFlag{
  35. Name: "password",
  36. Usage: "User password",
  37. },
  38. cli.StringFlag{
  39. Name: "email",
  40. Usage: "User email address",
  41. },
  42. cli.BoolFlag{
  43. Name: "admin",
  44. Usage: "User is an admin",
  45. },
  46. cli.StringFlag{
  47. Name: "config, c",
  48. Value: "custom/conf/app.ini",
  49. Usage: "Custom configuration file path",
  50. },
  51. },
  52. }
  53. subcmdChangePassword = cli.Command{
  54. Name: "change-password",
  55. Usage: "Change a user's password",
  56. Action: runChangePassword,
  57. Flags: []cli.Flag{
  58. cli.StringFlag{
  59. Name: "username,u",
  60. Value: "",
  61. Usage: "The user to change password for",
  62. },
  63. cli.StringFlag{
  64. Name: "password,p",
  65. Value: "",
  66. Usage: "New password to set for user",
  67. },
  68. },
  69. }
  70. subcmdRepoSyncReleases = cli.Command{
  71. Name: "repo-sync-releases",
  72. Usage: "Synchronize repository releases with tags",
  73. Action: runRepoSyncReleases,
  74. }
  75. )
  76. func runChangePassword(c *cli.Context) error {
  77. if err := argsSet(c, "username", "password"); err != nil {
  78. return err
  79. }
  80. if err := initDB(); err != nil {
  81. return err
  82. }
  83. uname := c.String("username")
  84. user, err := models.GetUserByName(uname)
  85. if err != nil {
  86. return err
  87. }
  88. if user.Salt, err = models.GetUserSalt(); err != nil {
  89. return err
  90. }
  91. user.HashPassword(c.String("password"))
  92. if err := models.UpdateUserCols(user, "passwd", "salt"); err != nil {
  93. return err
  94. }
  95. fmt.Printf("%s's password has been successfully updated!\n", user.Name)
  96. return nil
  97. }
  98. func runCreateUser(c *cli.Context) error {
  99. if err := argsSet(c, "name", "password", "email"); err != nil {
  100. return err
  101. }
  102. if c.IsSet("config") {
  103. setting.CustomConf = c.String("config")
  104. }
  105. if err := initDB(); err != nil {
  106. return err
  107. }
  108. if err := models.CreateUser(&models.User{
  109. Name: c.String("name"),
  110. Email: c.String("email"),
  111. Passwd: c.String("password"),
  112. IsActive: true,
  113. IsAdmin: c.Bool("admin"),
  114. }); err != nil {
  115. return fmt.Errorf("CreateUser: %v", err)
  116. }
  117. fmt.Printf("New user '%s' has been successfully created!\n", c.String("name"))
  118. return nil
  119. }
  120. func runRepoSyncReleases(c *cli.Context) error {
  121. if err := initDB(); err != nil {
  122. return err
  123. }
  124. log.Trace("Synchronizing repository releases (this may take a while)")
  125. for page := 1; ; page++ {
  126. repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{
  127. Page: page,
  128. PageSize: models.RepositoryListDefaultPageSize,
  129. Private: true,
  130. })
  131. if err != nil {
  132. return fmt.Errorf("SearchRepositoryByName: %v", err)
  133. }
  134. if len(repos) == 0 {
  135. break
  136. }
  137. log.Trace("Processing next %d repos of %d", len(repos), count)
  138. for _, repo := range repos {
  139. log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RepoPath())
  140. gitRepo, err := git.OpenRepository(repo.RepoPath())
  141. if err != nil {
  142. log.Warn("OpenRepository: %v", err)
  143. continue
  144. }
  145. oldnum, err := getReleaseCount(repo.ID)
  146. if err != nil {
  147. log.Warn(" GetReleaseCountByRepoID: %v", err)
  148. }
  149. log.Trace(" currentNumReleases is %d, running SyncReleasesWithTags", oldnum)
  150. if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
  151. log.Warn(" SyncReleasesWithTags: %v", err)
  152. continue
  153. }
  154. count, err = getReleaseCount(repo.ID)
  155. if err != nil {
  156. log.Warn(" GetReleaseCountByRepoID: %v", err)
  157. continue
  158. }
  159. log.Trace(" repo %s releases synchronized to tags: from %d to %d",
  160. repo.FullName(), oldnum, count)
  161. }
  162. }
  163. return nil
  164. }
  165. func getReleaseCount(id int64) (int64, error) {
  166. return models.GetReleaseCountByRepoID(
  167. id,
  168. models.FindReleasesOptions{
  169. IncludeTags: true,
  170. },
  171. )
  172. }