411 lines
11 KiB
Go
411 lines
11 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"text/tabwriter"
|
|
|
|
"tss-rocks-be/ent/user"
|
|
"tss-rocks-be/ent/role"
|
|
"tss-rocks-be/internal/config"
|
|
"tss-rocks-be/internal/server"
|
|
|
|
"github.com/spf13/cobra"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
func GetUserCmd() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "user",
|
|
Short: "User management commands",
|
|
Long: `Commands for managing users, including create, delete, password, and role management.`,
|
|
}
|
|
|
|
configPath := cmd.PersistentFlags().String("config", "config/config.yaml", "Path to config file")
|
|
|
|
cmd.AddCommand(getCreateUserCmd(*configPath))
|
|
cmd.AddCommand(getPasswordCmd(*configPath))
|
|
cmd.AddCommand(getListUsersCmd(*configPath))
|
|
cmd.AddCommand(getDeleteUserCmd(*configPath))
|
|
cmd.AddCommand(getRoleCmd(*configPath))
|
|
|
|
return cmd
|
|
}
|
|
|
|
func getCreateUserCmd(configPath string) *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "create",
|
|
Short: "Create a new user",
|
|
Long: `Create a new user with specified username, email and password.`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
username, _ := cmd.Flags().GetString("username")
|
|
email, _ := cmd.Flags().GetString("email")
|
|
password, _ := cmd.Flags().GetString("password")
|
|
|
|
// 加载配置
|
|
cfg, err := config.Load(configPath)
|
|
if err != nil {
|
|
return fmt.Errorf("error loading config: %v", err)
|
|
}
|
|
|
|
// 初始化数据库连接
|
|
client := server.NewEntClient(cfg)
|
|
if client == nil {
|
|
return fmt.Errorf("failed to create database client")
|
|
}
|
|
defer client.Close()
|
|
|
|
// 检查用户名是否已存在
|
|
exists, err := client.User.Query().Where(user.Username(username)).Exist(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("error checking username: %v", err)
|
|
}
|
|
if exists {
|
|
return fmt.Errorf("username '%s' already exists", username)
|
|
}
|
|
|
|
// 检查邮箱是否已存在
|
|
exists, err = client.User.Query().Where(user.Email(email)).Exist(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("error checking email: %v", err)
|
|
}
|
|
if exists {
|
|
return fmt.Errorf("email '%s' already exists", email)
|
|
}
|
|
|
|
// 生成密码哈希
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return fmt.Errorf("error hashing password: %v", err)
|
|
}
|
|
|
|
// 创建用户
|
|
u, err := client.User.Create().
|
|
SetUsername(username).
|
|
SetEmail(email).
|
|
SetPasswordHash(string(hashedPassword)).
|
|
SetStatus("active").
|
|
Save(cmd.Context())
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("error creating user: %v", err)
|
|
}
|
|
|
|
fmt.Printf("Successfully created user '%s' with email '%s'\n", u.Username, u.Email)
|
|
return nil
|
|
},
|
|
}
|
|
|
|
// 添加命令行参数
|
|
cmd.Flags().String("username", "", "username for the new user")
|
|
cmd.Flags().String("email", "", "email for the new user")
|
|
cmd.Flags().String("password", "", "password for the new user")
|
|
|
|
// 设置必需的参数
|
|
cmd.MarkFlagRequired("username")
|
|
cmd.MarkFlagRequired("email")
|
|
cmd.MarkFlagRequired("password")
|
|
|
|
return cmd
|
|
}
|
|
|
|
func getPasswordCmd(configPath string) *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "password",
|
|
Short: "Change user password",
|
|
Long: `Change the password for an existing user.`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
username, _ := cmd.Flags().GetString("username")
|
|
password, _ := cmd.Flags().GetString("password")
|
|
|
|
// 加载配置
|
|
cfg, err := config.Load(configPath)
|
|
if err != nil {
|
|
return fmt.Errorf("error loading config: %v", err)
|
|
}
|
|
|
|
// 初始化数据库连接
|
|
client := server.NewEntClient(cfg)
|
|
if client == nil {
|
|
return fmt.Errorf("failed to create database client")
|
|
}
|
|
defer client.Close()
|
|
|
|
// 查找用户
|
|
u, err := client.User.Query().Where(user.Username(username)).Only(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("user with username '%s' not found", username)
|
|
}
|
|
|
|
// 生成新的密码哈希
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return fmt.Errorf("error hashing password: %v", err)
|
|
}
|
|
|
|
// 更新密码
|
|
_, err = u.Update().SetPasswordHash(string(hashedPassword)).Save(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("error updating password: %v", err)
|
|
}
|
|
|
|
fmt.Printf("Successfully updated password for user '%s'\n", username)
|
|
return nil
|
|
},
|
|
}
|
|
|
|
// 添加命令行参数
|
|
cmd.Flags().String("username", "", "username of the user")
|
|
cmd.Flags().String("password", "", "new password")
|
|
|
|
// 设置必需的参数
|
|
cmd.MarkFlagRequired("username")
|
|
cmd.MarkFlagRequired("password")
|
|
|
|
return cmd
|
|
}
|
|
|
|
func getListUsersCmd(configPath string) *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "list",
|
|
Short: "List all users",
|
|
Long: `List all users in the system.`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
// 加载配置
|
|
cfg, err := config.Load(configPath)
|
|
if err != nil {
|
|
return fmt.Errorf("error loading config: %v", err)
|
|
}
|
|
|
|
// 初始化数据库连接
|
|
client := server.NewEntClient(cfg)
|
|
if client == nil {
|
|
return fmt.Errorf("failed to create database client")
|
|
}
|
|
defer client.Close()
|
|
|
|
// 获取所有用户
|
|
users, err := client.User.Query().All(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("error querying users: %v", err)
|
|
}
|
|
|
|
// 创建表格写入器
|
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
|
fmt.Fprintln(w, "USERNAME\tEMAIL\tSTATUS\tCREATED AT")
|
|
|
|
// 输出用户信息
|
|
for _, u := range users {
|
|
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n",
|
|
u.Username,
|
|
u.Email,
|
|
u.Status,
|
|
u.CreatedAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
w.Flush()
|
|
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func getDeleteUserCmd(configPath string) *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "delete",
|
|
Short: "Delete a user",
|
|
Long: `Delete an existing user from the system.`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
username, _ := cmd.Flags().GetString("username")
|
|
force, _ := cmd.Flags().GetBool("force")
|
|
|
|
// 加载配置
|
|
cfg, err := config.Load(configPath)
|
|
if err != nil {
|
|
return fmt.Errorf("error loading config: %v", err)
|
|
}
|
|
|
|
// 初始化数据库连接
|
|
client := server.NewEntClient(cfg)
|
|
if client == nil {
|
|
return fmt.Errorf("failed to create database client")
|
|
}
|
|
defer client.Close()
|
|
|
|
// 查找用户
|
|
u, err := client.User.Query().Where(user.Username(username)).Only(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("user with username '%s' not found", username)
|
|
}
|
|
|
|
// 检查用户的角色
|
|
hasRoles, err := client.User.QueryRoles(u).Exist(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("error checking user roles: %v", err)
|
|
}
|
|
if hasRoles && !force {
|
|
return fmt.Errorf("user '%s' has roles assigned. Use --force to override", username)
|
|
}
|
|
|
|
// 删除用户
|
|
err = client.User.DeleteOne(u).Exec(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("error deleting user: %v", err)
|
|
}
|
|
|
|
fmt.Printf("Successfully deleted user '%s'\n", username)
|
|
return nil
|
|
},
|
|
}
|
|
|
|
// 添加命令行参数
|
|
cmd.Flags().String("username", "", "username of the user to delete")
|
|
cmd.Flags().Bool("force", false, "force delete even if user has roles")
|
|
|
|
// 设置必需的参数
|
|
cmd.MarkFlagRequired("username")
|
|
|
|
return cmd
|
|
}
|
|
|
|
func getRoleCmd(configPath string) *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "role",
|
|
Short: "User role management commands",
|
|
Long: `Commands for managing user roles, including adding and removing roles.`,
|
|
}
|
|
|
|
cmd.AddCommand(getRoleAddCmd(configPath))
|
|
cmd.AddCommand(getRoleRemoveCmd(configPath))
|
|
|
|
return cmd
|
|
}
|
|
|
|
func getRoleAddCmd(configPath string) *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "add",
|
|
Short: "Add a role to a user",
|
|
Long: `Add a role to an existing user.`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
username, _ := cmd.Flags().GetString("username")
|
|
roleName, _ := cmd.Flags().GetString("role")
|
|
|
|
// 加载配置
|
|
cfg, err := config.Load(configPath)
|
|
if err != nil {
|
|
return fmt.Errorf("error loading config: %v", err)
|
|
}
|
|
|
|
// 初始化数据库连接
|
|
client := server.NewEntClient(cfg)
|
|
if client == nil {
|
|
return fmt.Errorf("failed to create database client")
|
|
}
|
|
defer client.Close()
|
|
|
|
// 查找用户
|
|
u, err := client.User.Query().Where(user.Username(username)).Only(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("user with username '%s' not found", username)
|
|
}
|
|
|
|
// 检查角色是否已存在
|
|
hasRole, err := client.User.QueryRoles(u).Where(role.Name(roleName)).Exist(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("error checking user roles: %v", err)
|
|
}
|
|
if hasRole {
|
|
return fmt.Errorf("user '%s' already has role '%s'", username, roleName)
|
|
}
|
|
|
|
// 获取要添加的角色
|
|
r, err := client.Role.Query().Where(role.Name(roleName)).Only(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("role '%s' not found", roleName)
|
|
}
|
|
|
|
// 添加角色
|
|
err = client.User.UpdateOne(u).AddRoles(r).Exec(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("error adding role: %v", err)
|
|
}
|
|
|
|
fmt.Printf("Successfully added role '%s' to user '%s'\n", roleName, username)
|
|
return nil
|
|
},
|
|
}
|
|
|
|
// 添加命令行参数
|
|
cmd.Flags().String("username", "", "username of the user")
|
|
cmd.Flags().String("role", "", "role to add (admin/editor/contributor)")
|
|
|
|
// 设置必需的参数
|
|
cmd.MarkFlagRequired("username")
|
|
cmd.MarkFlagRequired("role")
|
|
|
|
return cmd
|
|
}
|
|
|
|
func getRoleRemoveCmd(configPath string) *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "remove",
|
|
Short: "Remove a role from a user",
|
|
Long: `Remove a role from an existing user.`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
username, _ := cmd.Flags().GetString("username")
|
|
roleName, _ := cmd.Flags().GetString("role")
|
|
|
|
// 加载配置
|
|
cfg, err := config.Load(configPath)
|
|
if err != nil {
|
|
return fmt.Errorf("error loading config: %v", err)
|
|
}
|
|
|
|
// 初始化数据库连接
|
|
client := server.NewEntClient(cfg)
|
|
if client == nil {
|
|
return fmt.Errorf("failed to create database client")
|
|
}
|
|
defer client.Close()
|
|
|
|
// 查找用户
|
|
u, err := client.User.Query().Where(user.Username(username)).Only(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("user with username '%s' not found", username)
|
|
}
|
|
|
|
// 检查角色是否存在
|
|
r, err := client.Role.Query().Where(role.Name(roleName)).Only(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("role '%s' not found", roleName)
|
|
}
|
|
|
|
// 检查用户是否有该角色
|
|
hasRole, err := client.User.QueryRoles(u).Where(role.Name(roleName)).Exist(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("error checking user roles: %v", err)
|
|
}
|
|
if !hasRole {
|
|
return fmt.Errorf("user '%s' does not have role '%s'", username, roleName)
|
|
}
|
|
|
|
// 移除角色
|
|
err = client.User.UpdateOne(u).RemoveRoles(r).Exec(cmd.Context())
|
|
if err != nil {
|
|
return fmt.Errorf("error removing role: %v", err)
|
|
}
|
|
|
|
fmt.Printf("Successfully removed role '%s' from user '%s'\n", roleName, username)
|
|
return nil
|
|
},
|
|
}
|
|
|
|
// 添加命令行参数
|
|
cmd.Flags().String("username", "", "username of the user")
|
|
cmd.Flags().String("role", "", "role to remove (admin/editor/contributor)")
|
|
|
|
// 设置必需的参数
|
|
cmd.MarkFlagRequired("username")
|
|
cmd.MarkFlagRequired("role")
|
|
|
|
return cmd
|
|
}
|