From 95c8d53d280307568a4637db1eb3ccf28c8dc0a9 Mon Sep 17 00:00:00 2001
From: mscherer <mscherer@users.noreply.github.com>
Date: Fri, 4 Mar 2022 20:53:35 +0100
Subject: [PATCH] Add a "admin user generate-access-token" subcommand (#17722)

* Add a "admin user generate-access-token" subcommand

Fixes #17721

* Update cmd/admin.go

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>

* Update cmd/admin.go

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>

* Fix code to match new interfaces

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: zeripath <art27@cantab.net>
---
 cmd/admin.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/cmd/admin.go b/cmd/admin.go
index 66c7959ab3..70d44c39e0 100644
--- a/cmd/admin.go
+++ b/cmd/admin.go
@@ -56,6 +56,7 @@ var (
 			microcmdUserList,
 			microcmdUserChangePassword,
 			microcmdUserDelete,
+			microcmdUserGenerateAccessToken,
 		},
 	}
 
@@ -154,6 +155,27 @@ var (
 		Action: runDeleteUser,
 	}
 
+	microcmdUserGenerateAccessToken = cli.Command{
+		Name:  "generate-access-token",
+		Usage: "Generate a access token for a specific user",
+		Flags: []cli.Flag{
+			cli.StringFlag{
+				Name:  "username,u",
+				Usage: "Username",
+			},
+			cli.StringFlag{
+				Name:  "token-name,t",
+				Usage: "Token name",
+				Value: "gitea-admin",
+			},
+			cli.BoolFlag{
+				Name:  "raw",
+				Usage: "Display only the token value",
+			},
+		},
+		Action: runGenerateAccessToken,
+	}
+
 	subcmdRepoSyncReleases = cli.Command{
 		Name:   "repo-sync-releases",
 		Usage:  "Synchronize repository releases with tags",
@@ -641,6 +663,41 @@ func runDeleteUser(c *cli.Context) error {
 	return user_service.DeleteUser(user)
 }
 
+func runGenerateAccessToken(c *cli.Context) error {
+	if !c.IsSet("username") {
+		return fmt.Errorf("You must provide the username to generate a token for them")
+	}
+
+	ctx, cancel := installSignals()
+	defer cancel()
+
+	if err := initDB(ctx); err != nil {
+		return err
+	}
+
+	user, err := user_model.GetUserByName(c.String("username"))
+	if err != nil {
+		return err
+	}
+
+	t := &models.AccessToken{
+		Name: c.String("token-name"),
+		UID:  user.ID,
+	}
+
+	if err := models.NewAccessToken(t); err != nil {
+		return err
+	}
+
+	if c.Bool("raw") {
+		fmt.Printf("%s\n", t.Token)
+	} else {
+		fmt.Printf("Access token was successfully created: %s\n", t.Token)
+	}
+
+	return nil
+}
+
 func runRepoSyncReleases(_ *cli.Context) error {
 	ctx, cancel := installSignals()
 	defer cancel()