[feature/backend] implement /users handler + switch to username + add display name + user management cli
This commit is contained in:
parent
1d712d4e6c
commit
86ab334bc9
38 changed files with 1851 additions and 506 deletions
|
@ -24,7 +24,6 @@ import (
|
|||
"tss-rocks-be/ent/role"
|
||||
"tss-rocks-be/ent/user"
|
||||
"tss-rocks-be/internal/storage"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
@ -54,59 +53,74 @@ func NewService(client *ent.Client, storage storage.Storage) Service {
|
|||
}
|
||||
|
||||
// User operations
|
||||
func (s *serviceImpl) CreateUser(ctx context.Context, email, password string, roleStr string) (*ent.User, error) {
|
||||
// Hash the password
|
||||
func (s *serviceImpl) CreateUser(ctx context.Context, username, email, password string, roleStr string) (*ent.User, error) {
|
||||
// 验证邮箱格式
|
||||
emailRegex := regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
|
||||
if !emailRegex.MatchString(email) {
|
||||
return nil, fmt.Errorf("invalid email format")
|
||||
}
|
||||
|
||||
// 验证密码长度
|
||||
if len(password) < 8 {
|
||||
return nil, fmt.Errorf("password must be at least 8 characters")
|
||||
}
|
||||
|
||||
// 检查用户名是否已存在
|
||||
exists, err := s.client.User.Query().Where(user.Username(username)).Exist(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error checking username: %v", err)
|
||||
}
|
||||
if exists {
|
||||
return nil, fmt.Errorf("username '%s' already exists", username)
|
||||
}
|
||||
|
||||
// 生成密码哈希
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to hash password: %w", err)
|
||||
return nil, fmt.Errorf("error hashing password: %v", err)
|
||||
}
|
||||
|
||||
// Add the user role by default
|
||||
userRole, err := s.client.Role.Query().Where(role.NameEQ("user")).Only(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user role: %w", err)
|
||||
}
|
||||
|
||||
// If a specific role is requested and it's not "user", get that role too
|
||||
var additionalRole *ent.Role
|
||||
if roleStr != "" && roleStr != "user" {
|
||||
additionalRole, err = s.client.Role.Query().Where(role.NameEQ(roleStr)).Only(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get role: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create user with password and user role
|
||||
userCreate := s.client.User.Create().
|
||||
// 创建用户
|
||||
u, err := s.client.User.Create().
|
||||
SetUsername(username).
|
||||
SetEmail(email).
|
||||
SetPasswordHash(string(hashedPassword)).
|
||||
AddRoles(userRole)
|
||||
SetStatus("active").
|
||||
Save(ctx)
|
||||
|
||||
// Add the additional role if specified
|
||||
if additionalRole != nil {
|
||||
userCreate.AddRoles(additionalRole)
|
||||
}
|
||||
|
||||
// Save the user
|
||||
user, err := userCreate.Save(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create user: %w", err)
|
||||
return nil, fmt.Errorf("error creating user: %v", err)
|
||||
}
|
||||
|
||||
return user, nil
|
||||
// 分配角色
|
||||
err = s.AssignRole(ctx, u.ID, roleStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error assigning role: %v", err)
|
||||
}
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (s *serviceImpl) GetUserByUsername(ctx context.Context, username string) (*ent.User, error) {
|
||||
u, err := s.client.User.Query().Where(user.Username(username)).Only(ctx)
|
||||
if err != nil {
|
||||
if ent.IsNotFound(err) {
|
||||
return nil, fmt.Errorf("user with username '%s' not found", username)
|
||||
}
|
||||
return nil, fmt.Errorf("error getting user: %v", err)
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (s *serviceImpl) GetUserByEmail(ctx context.Context, email string) (*ent.User, error) {
|
||||
user, err := s.client.User.Query().
|
||||
Where(user.EmailEQ(email)).
|
||||
Only(ctx)
|
||||
u, err := s.client.User.Query().Where(user.Email(email)).Only(ctx)
|
||||
if err != nil {
|
||||
if ent.IsNotFound(err) {
|
||||
return nil, fmt.Errorf("user not found: %s", email)
|
||||
return nil, fmt.Errorf("user with email '%s' not found", email)
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get user: %w", err)
|
||||
return nil, fmt.Errorf("error getting user: %v", err)
|
||||
}
|
||||
return user, nil
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (s *serviceImpl) ValidatePassword(ctx context.Context, user *ent.User, password string) bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue