|
- // Copyright 2023 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package cmd
-
- import (
- "context"
- "errors"
- "fmt"
-
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- pwd "code.gitea.io/gitea/modules/auth/password"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
-
- "github.com/urfave/cli/v2"
- )
-
- var microcmdUserCreate = &cli.Command{
- Name: "create",
- Usage: "Create a new user in database",
- Action: runCreateUser,
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: "name",
- Usage: "Username. DEPRECATED: use username instead",
- },
- &cli.StringFlag{
- Name: "username",
- Usage: "Username",
- },
- &cli.StringFlag{
- Name: "password",
- Usage: "User password",
- },
- &cli.StringFlag{
- Name: "email",
- Usage: "User email address",
- },
- &cli.BoolFlag{
- Name: "admin",
- Usage: "User is an admin",
- },
- &cli.BoolFlag{
- Name: "random-password",
- Usage: "Generate a random password for the user",
- },
- &cli.BoolFlag{
- Name: "must-change-password",
- Usage: "User must change password after initial login, defaults to true for all users except the first one (can be disabled by --must-change-password=false)",
- DisableDefaultText: true,
- },
- &cli.IntFlag{
- Name: "random-password-length",
- Usage: "Length of the random password to be generated",
- Value: 12,
- },
- &cli.BoolFlag{
- Name: "access-token",
- Usage: "Generate access token for the user",
- },
- &cli.BoolFlag{
- Name: "restricted",
- Usage: "Make a restricted user account",
- },
- },
- }
-
- func runCreateUser(c *cli.Context) error {
- if err := argsSet(c, "email"); err != nil {
- return err
- }
-
- if c.IsSet("name") && c.IsSet("username") {
- return errors.New("cannot set both --name and --username flags")
- }
- if !c.IsSet("name") && !c.IsSet("username") {
- return errors.New("one of --name or --username flags must be set")
- }
-
- if c.IsSet("password") && c.IsSet("random-password") {
- return errors.New("cannot set both -random-password and -password flags")
- }
-
- var username string
- if c.IsSet("username") {
- username = c.String("username")
- } else {
- username = c.String("name")
- _, _ = fmt.Fprintf(c.App.ErrWriter, "--name flag is deprecated. Use --username instead.\n")
- }
-
- ctx := c.Context
- if !setting.IsInTesting {
- // FIXME: need to refactor the "installSignals/initDB" related code later
- // it doesn't make sense to call it in (almost) every command action function
- var cancel context.CancelFunc
- ctx, cancel = installSignals()
- defer cancel()
- if err := initDB(ctx); err != nil {
- return err
- }
- }
-
- var password string
- if c.IsSet("password") {
- password = c.String("password")
- } else if c.IsSet("random-password") {
- var err error
- password, err = pwd.Generate(c.Int("random-password-length"))
- if err != nil {
- return err
- }
- fmt.Printf("generated random password is '%s'\n", password)
- } else {
- return errors.New("must set either password or random-password flag")
- }
-
- isAdmin := c.Bool("admin")
- mustChangePassword := true // always default to true
- if c.IsSet("must-change-password") {
- // if the flag is set, use the value provided by the user
- mustChangePassword = c.Bool("must-change-password")
- } else {
- // check whether there are users in the database
- hasUserRecord, err := db.IsTableNotEmpty(&user_model.User{})
- if err != nil {
- return fmt.Errorf("IsTableNotEmpty: %w", err)
- }
- if !hasUserRecord {
- // if this is the first one being created, don't force to change password (keep the old behavior)
- mustChangePassword = false
- }
- }
-
- restricted := optional.None[bool]()
-
- if c.IsSet("restricted") {
- restricted = optional.Some(c.Bool("restricted"))
- }
-
- // default user visibility in app.ini
- visibility := setting.Service.DefaultUserVisibilityMode
-
- u := &user_model.User{
- Name: username,
- Email: c.String("email"),
- Passwd: password,
- IsAdmin: isAdmin,
- MustChangePassword: mustChangePassword,
- Visibility: visibility,
- }
-
- overwriteDefault := &user_model.CreateUserOverwriteOptions{
- IsActive: optional.Some(true),
- IsRestricted: restricted,
- }
-
- if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
- return fmt.Errorf("CreateUser: %w", err)
- }
-
- if c.Bool("access-token") {
- t := &auth_model.AccessToken{
- Name: "gitea-admin",
- UID: u.ID,
- }
-
- if err := auth_model.NewAccessToken(ctx, t); err != nil {
- return err
- }
-
- fmt.Printf("Access token was successfully created... %s\n", t.Token)
- }
-
- fmt.Printf("New user '%s' has been successfully created!\n", username)
- return nil
- }
|