THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

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.

admin.go 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. subcmdRegenerate,
  24. },
  25. }
  26. subcmdCreateUser = cli.Command{
  27. Name: "create-user",
  28. Usage: "Create a new user in database",
  29. Action: runCreateUser,
  30. Flags: []cli.Flag{
  31. cli.StringFlag{
  32. Name: "name",
  33. Usage: "Username",
  34. },
  35. cli.StringFlag{
  36. Name: "password",
  37. Usage: "User password",
  38. },
  39. cli.StringFlag{
  40. Name: "email",
  41. Usage: "User email address",
  42. },
  43. cli.BoolFlag{
  44. Name: "admin",
  45. Usage: "User is an admin",
  46. },
  47. cli.StringFlag{
  48. Name: "config, c",
  49. Value: "custom/conf/app.ini",
  50. Usage: "Custom configuration file path",
  51. },
  52. },
  53. }
  54. subcmdChangePassword = cli.Command{
  55. Name: "change-password",
  56. Usage: "Change a user's password",
  57. Action: runChangePassword,
  58. Flags: []cli.Flag{
  59. cli.StringFlag{
  60. Name: "username,u",
  61. Value: "",
  62. Usage: "The user to change password for",
  63. },
  64. cli.StringFlag{
  65. Name: "password,p",
  66. Value: "",
  67. Usage: "New password to set for user",
  68. },
  69. cli.StringFlag{
  70. Name: "config, c",
  71. Value: "custom/conf/app.ini",
  72. Usage: "Custom configuration file path",
  73. },
  74. },
  75. }
  76. subcmdRepoSyncReleases = cli.Command{
  77. Name: "repo-sync-releases",
  78. Usage: "Synchronize repository releases with tags",
  79. Action: runRepoSyncReleases,
  80. }
  81. subcmdRegenerate = cli.Command{
  82. Name: "regenerate",
  83. Usage: "Regenerate specific files",
  84. Subcommands: []cli.Command{
  85. microcmdRegenHooks,
  86. microcmdRegenKeys,
  87. },
  88. }
  89. microcmdRegenHooks = cli.Command{
  90. Name: "hooks",
  91. Usage: "Regenerate git-hooks",
  92. Action: runRegenerateHooks,
  93. Flags: []cli.Flag{
  94. cli.StringFlag{
  95. Name: "config, c",
  96. Value: "custom/conf/app.ini",
  97. Usage: "Custom configuration file path",
  98. },
  99. },
  100. }
  101. microcmdRegenKeys = cli.Command{
  102. Name: "keys",
  103. Usage: "Regenerate authorized_keys file",
  104. Action: runRegenerateKeys,
  105. Flags: []cli.Flag{
  106. cli.StringFlag{
  107. Name: "config, c",
  108. Value: "custom/conf/app.ini",
  109. Usage: "Custom configuration file path",
  110. },
  111. },
  112. }
  113. )
  114. func runChangePassword(c *cli.Context) error {
  115. if err := argsSet(c, "username", "password"); err != nil {
  116. return err
  117. }
  118. if c.IsSet("config") {
  119. setting.CustomConf = c.String("config")
  120. }
  121. if err := initDB(); err != nil {
  122. return err
  123. }
  124. uname := c.String("username")
  125. user, err := models.GetUserByName(uname)
  126. if err != nil {
  127. return err
  128. }
  129. if user.Salt, err = models.GetUserSalt(); err != nil {
  130. return err
  131. }
  132. user.HashPassword(c.String("password"))
  133. if err := models.UpdateUserCols(user, "passwd", "salt"); err != nil {
  134. return err
  135. }
  136. fmt.Printf("%s's password has been successfully updated!\n", user.Name)
  137. return nil
  138. }
  139. func runCreateUser(c *cli.Context) error {
  140. if err := argsSet(c, "name", "password", "email"); err != nil {
  141. return err
  142. }
  143. if c.IsSet("config") {
  144. setting.CustomConf = c.String("config")
  145. }
  146. if err := initDB(); err != nil {
  147. return err
  148. }
  149. if err := models.CreateUser(&models.User{
  150. Name: c.String("name"),
  151. Email: c.String("email"),
  152. Passwd: c.String("password"),
  153. IsActive: true,
  154. IsAdmin: c.Bool("admin"),
  155. }); err != nil {
  156. return fmt.Errorf("CreateUser: %v", err)
  157. }
  158. fmt.Printf("New user '%s' has been successfully created!\n", c.String("name"))
  159. return nil
  160. }
  161. func runRepoSyncReleases(c *cli.Context) error {
  162. if err := initDB(); err != nil {
  163. return err
  164. }
  165. log.Trace("Synchronizing repository releases (this may take a while)")
  166. for page := 1; ; page++ {
  167. repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{
  168. Page: page,
  169. PageSize: models.RepositoryListDefaultPageSize,
  170. Private: true,
  171. })
  172. if err != nil {
  173. return fmt.Errorf("SearchRepositoryByName: %v", err)
  174. }
  175. if len(repos) == 0 {
  176. break
  177. }
  178. log.Trace("Processing next %d repos of %d", len(repos), count)
  179. for _, repo := range repos {
  180. log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RepoPath())
  181. gitRepo, err := git.OpenRepository(repo.RepoPath())
  182. if err != nil {
  183. log.Warn("OpenRepository: %v", err)
  184. continue
  185. }
  186. oldnum, err := getReleaseCount(repo.ID)
  187. if err != nil {
  188. log.Warn(" GetReleaseCountByRepoID: %v", err)
  189. }
  190. log.Trace(" currentNumReleases is %d, running SyncReleasesWithTags", oldnum)
  191. if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
  192. log.Warn(" SyncReleasesWithTags: %v", err)
  193. continue
  194. }
  195. count, err = getReleaseCount(repo.ID)
  196. if err != nil {
  197. log.Warn(" GetReleaseCountByRepoID: %v", err)
  198. continue
  199. }
  200. log.Trace(" repo %s releases synchronized to tags: from %d to %d",
  201. repo.FullName(), oldnum, count)
  202. }
  203. }
  204. return nil
  205. }
  206. func getReleaseCount(id int64) (int64, error) {
  207. return models.GetReleaseCountByRepoID(
  208. id,
  209. models.FindReleasesOptions{
  210. IncludeTags: true,
  211. },
  212. )
  213. }
  214. func runRegenerateHooks(c *cli.Context) error {
  215. if c.IsSet("config") {
  216. setting.CustomConf = c.String("config")
  217. }
  218. if err := initDB(); err != nil {
  219. return err
  220. }
  221. return models.SyncRepositoryHooks()
  222. }
  223. func runRegenerateKeys(c *cli.Context) error {
  224. if c.IsSet("config") {
  225. setting.CustomConf = c.String("config")
  226. }
  227. if err := initDB(); err != nil {
  228. return err
  229. }
  230. return models.RewriteAllPublicKeys()
  231. }