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_user_create.go 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package cmd
  4. import (
  5. "errors"
  6. "fmt"
  7. auth_model "code.gitea.io/gitea/models/auth"
  8. user_model "code.gitea.io/gitea/models/user"
  9. pwd "code.gitea.io/gitea/modules/auth/password"
  10. "code.gitea.io/gitea/modules/optional"
  11. "code.gitea.io/gitea/modules/setting"
  12. "github.com/urfave/cli/v2"
  13. )
  14. var microcmdUserCreate = &cli.Command{
  15. Name: "create",
  16. Usage: "Create a new user in database",
  17. Action: runCreateUser,
  18. Flags: []cli.Flag{
  19. &cli.StringFlag{
  20. Name: "name",
  21. Usage: "Username. DEPRECATED: use username instead",
  22. },
  23. &cli.StringFlag{
  24. Name: "username",
  25. Usage: "Username",
  26. },
  27. &cli.StringFlag{
  28. Name: "password",
  29. Usage: "User password",
  30. },
  31. &cli.StringFlag{
  32. Name: "email",
  33. Usage: "User email address",
  34. },
  35. &cli.BoolFlag{
  36. Name: "admin",
  37. Usage: "User is an admin",
  38. },
  39. &cli.BoolFlag{
  40. Name: "random-password",
  41. Usage: "Generate a random password for the user",
  42. },
  43. &cli.BoolFlag{
  44. Name: "must-change-password",
  45. Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)",
  46. },
  47. &cli.IntFlag{
  48. Name: "random-password-length",
  49. Usage: "Length of the random password to be generated",
  50. Value: 12,
  51. },
  52. &cli.BoolFlag{
  53. Name: "access-token",
  54. Usage: "Generate access token for the user",
  55. },
  56. &cli.BoolFlag{
  57. Name: "restricted",
  58. Usage: "Make a restricted user account",
  59. },
  60. },
  61. }
  62. func runCreateUser(c *cli.Context) error {
  63. if err := argsSet(c, "email"); err != nil {
  64. return err
  65. }
  66. if c.IsSet("name") && c.IsSet("username") {
  67. return errors.New("Cannot set both --name and --username flags")
  68. }
  69. if !c.IsSet("name") && !c.IsSet("username") {
  70. return errors.New("One of --name or --username flags must be set")
  71. }
  72. if c.IsSet("password") && c.IsSet("random-password") {
  73. return errors.New("cannot set both -random-password and -password flags")
  74. }
  75. var username string
  76. if c.IsSet("username") {
  77. username = c.String("username")
  78. } else {
  79. username = c.String("name")
  80. _, _ = fmt.Fprintf(c.App.ErrWriter, "--name flag is deprecated. Use --username instead.\n")
  81. }
  82. ctx, cancel := installSignals()
  83. defer cancel()
  84. if err := initDB(ctx); err != nil {
  85. return err
  86. }
  87. var password string
  88. if c.IsSet("password") {
  89. password = c.String("password")
  90. } else if c.IsSet("random-password") {
  91. var err error
  92. password, err = pwd.Generate(c.Int("random-password-length"))
  93. if err != nil {
  94. return err
  95. }
  96. fmt.Printf("generated random password is '%s'\n", password)
  97. } else {
  98. return errors.New("must set either password or random-password flag")
  99. }
  100. // always default to true
  101. changePassword := true
  102. // If this is the first user being created.
  103. // Take it as the admin and don't force a password update.
  104. if n := user_model.CountUsers(ctx, nil); n == 0 {
  105. changePassword = false
  106. }
  107. if c.IsSet("must-change-password") {
  108. changePassword = c.Bool("must-change-password")
  109. }
  110. restricted := optional.None[bool]()
  111. if c.IsSet("restricted") {
  112. restricted = optional.Some(c.Bool("restricted"))
  113. }
  114. // default user visibility in app.ini
  115. visibility := setting.Service.DefaultUserVisibilityMode
  116. u := &user_model.User{
  117. Name: username,
  118. Email: c.String("email"),
  119. Passwd: password,
  120. IsAdmin: c.Bool("admin"),
  121. MustChangePassword: changePassword,
  122. Visibility: visibility,
  123. }
  124. overwriteDefault := &user_model.CreateUserOverwriteOptions{
  125. IsActive: optional.Some(true),
  126. IsRestricted: restricted,
  127. }
  128. if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
  129. return fmt.Errorf("CreateUser: %w", err)
  130. }
  131. if c.Bool("access-token") {
  132. t := &auth_model.AccessToken{
  133. Name: "gitea-admin",
  134. UID: u.ID,
  135. }
  136. if err := auth_model.NewAccessToken(ctx, t); err != nil {
  137. return err
  138. }
  139. fmt.Printf("Access token was successfully created... %s\n", t.Token)
  140. }
  141. fmt.Printf("New user '%s' has been successfully created!\n", username)
  142. return nil
  143. }