package service import ( "context" "fmt" "opencatd-open/internal/consts" "opencatd-open/internal/dao" "opencatd-open/internal/model" "opencatd-open/internal/utils" "strings" "github.com/google/uuid" "gorm.io/gorm" ) // var _ TokenService = (*TokenServiceImpl)(nil) // type TokenService interface { // } type TokenServiceImpl struct { db *gorm.DB tokenRepo dao.TokenRepository } func NewTokenService(db *gorm.DB, tokenRepo dao.TokenRepository) *TokenServiceImpl { return &TokenServiceImpl{ db: db, tokenRepo: tokenRepo, } } func (t *TokenServiceImpl) CreateToken(ctx context.Context, token *model.Token) error { if token.UserID == 0 { token.UserID = ctx.Value("user_id").(int64) } if token.Active == nil { token.Active = utils.ToPtr(true) } if token.UnlimitedQuota == nil { token.UnlimitedQuota = utils.ToPtr(true) } if token.ExpiredAt == nil { token.ExpiredAt = utils.ToPtr(int64(-1)) } if token.Key == "" { token.Key = "sk-team-" + strings.ReplaceAll(uuid.New().String(), "-", "") } if !strings.HasPrefix(token.Key, "sk-team-") { token.Key = "sk-team-" + strings.ReplaceAll(token.Key, " ", "") } return t.tokenRepo.Create(ctx, token) } func (t *TokenServiceImpl) GetToken(ctx context.Context, id int64) (*model.Token, error) { userid := ctx.Value("user_id").(int64) tk := &model.Token{} return tk, t.db.Model(&model.Token{}).Where("user_id = ?", userid).Where("id = ?", id).First(tk).Error } func (t *TokenServiceImpl) ListToken(ctx context.Context, limit, offset int, active []string) ([]*model.Token, int64, error) { userid := ctx.Value("user_id").(int64) condition := make(map[string]interface{}) condition["user_id = ?"] = userid if len(active) > 0 { condition["active IN ?"] = utils.StringToBool(active) return t.tokenRepo.ListWithFilters(ctx, limit, offset, condition) } return t.tokenRepo.ListWithFilters(ctx, limit, offset, condition) } func (t *TokenServiceImpl) UpdateToken(ctx context.Context, token *model.Token) error { userid := ctx.Value("user_id").(int64) // 操作者 userRoleValue := ctx.Value("user_role") if userRoleValue == nil { return fmt.Errorf("user role not found in context") } role, ok := userRoleValue.(*consts.UserRole) // 操作角色 if !ok { return fmt.Errorf("user role in context is not an integer") } switch { case *role < consts.RoleAdmin: if userid != token.UserID { return fmt.Errorf("Permission denied") } case *role == consts.RoleAdmin: if *role <= *token.User.Role { return fmt.Errorf("Permission denied") } } return t.db.Model(&model.Token{}).Where("id = ?", token.ID).Updates(token).Error } func (t *TokenServiceImpl) ResetToken(ctx context.Context, id int64) error { userid := ctx.Value("user_id").(int64) // 操作者 userRoleValue := ctx.Value("user_role") if userRoleValue == nil { return fmt.Errorf("user role not found in context") } role, ok := userRoleValue.(*consts.UserRole) // 操作角色 if !ok { return fmt.Errorf("user role in context is not an integer") } switch { case *role < consts.RoleAdmin: if userid != id { return fmt.Errorf("Permission denied") } case *role == consts.RoleAdmin: var user = &model.User{} if err := t.db.Model(&model.User{}).Where("id = ?", id).First(user).Error; err != nil { return fmt.Errorf("User not found") } if *role <= *user.Role { return fmt.Errorf("Permission denied") } } token := "sk-team-" + strings.ReplaceAll(uuid.New().String(), "-", "") return t.db.Model(&model.Token{}).Where("user_id = ?", userid).Where("id = ?", id).Update("token", token).Error } func (t *TokenServiceImpl) DeleteToken(ctx context.Context, id int64) error { token, err := t.tokenRepo.GetByID(ctx, id) if err != nil { return fmt.Errorf("Token not found") } if token.User == nil { return fmt.Errorf("Token user not found") } role := ctx.Value("user_role").(*consts.UserRole) // 操作角色 userid := ctx.Value("user_id").(int64) // 操作者 switch { case *role < consts.RoleAdmin: if userid != token.UserID { return fmt.Errorf("Permission denied") } case *role == consts.RoleAdmin: if *role <= *token.User.Role { return fmt.Errorf("Permission denied") } } return t.db.Model(&model.Token{}).Where("id = ?", id).Delete(&model.Token{}).Error } func (t *TokenServiceImpl) DeleteTokens(ctx context.Context, userid int64, ids []int64) error { operator_id := ctx.Value("user_id").(int64) roleValue := ctx.Value("user_role") if roleValue == nil { return fmt.Errorf("user role not found in context") } operator_role, ok := roleValue.(*consts.UserRole) // 操作角色 if !ok { return fmt.Errorf("user role in context is not an integer") } switch { case *operator_role < consts.RoleAdmin: if operator_id != userid { return fmt.Errorf("Permission denied") } return t.tokenRepo.BatchDelete(ctx, ids, map[string]interface{}{"name != ?": "default", "user_id = ?": userid}) case *operator_role == consts.RoleAdmin: var user = &model.User{} if err := t.db.Model(&model.User{}).Where("id = ?", userid).First(user).Error; err != nil { return fmt.Errorf("User not found") } if *operator_role <= *user.Role { return fmt.Errorf("Permission denied") } return t.tokenRepo.BatchDelete(ctx, ids, map[string]interface{}{"name != ?": "default", "user_id = ?": userid}) default: return t.tokenRepo.BatchDelete(ctx, ids, map[string]interface{}{"name != ?": "default"}) } } func (t *TokenServiceImpl) EnableTokens(ctx context.Context, userid int64, ids []int64) error { operator_id := ctx.Value("user_id").(int64) roleValue := ctx.Value("user_role") if roleValue == nil { return fmt.Errorf("user role not found in context") } operator_role, ok := roleValue.(*consts.UserRole) // 操作角色 if !ok { return fmt.Errorf("user role in context is not an integer") } switch { case *operator_role < consts.RoleAdmin: if operator_id != userid { return fmt.Errorf("Permission denied") } return t.tokenRepo.BatchEnable(ctx, ids, map[string]interface{}{"user_id = ?": userid}) case *operator_role == consts.RoleAdmin: var user = &model.User{} if err := t.db.Model(&model.User{}).Where("id = ?", userid).First(user).Error; err != nil { return fmt.Errorf("User not found") } if *operator_role <= *user.Role { return fmt.Errorf("Permission denied") } return t.tokenRepo.BatchEnable(ctx, ids, map[string]interface{}{"user_id = ?": userid}) default: return t.tokenRepo.BatchEnable(ctx, ids, nil) } } func (t *TokenServiceImpl) DisableTokens(ctx context.Context, userid int64, ids []int64) error { operator_id := ctx.Value("user_id").(int64) roleValue := ctx.Value("user_role") if roleValue == nil { return fmt.Errorf("user role not found in context") } operator_role, ok := roleValue.(*consts.UserRole) // 操作角色 if !ok { return fmt.Errorf("user role in context is not an integer") } switch { case *operator_role < consts.RoleAdmin: if operator_id != userid { return fmt.Errorf("Permission denied") } return t.tokenRepo.BatchDisable(ctx, ids, map[string]interface{}{"user_id =": userid}) case *operator_role == consts.RoleAdmin: var user = &model.User{} if err := t.db.Model(&model.User{}).Where("id = ?", userid).First(user).Error; err != nil { return fmt.Errorf("User not found") } if *operator_role <= *user.Role { return fmt.Errorf("Permission denied") } return t.tokenRepo.BatchDisable(ctx, ids, map[string]interface{}{"user_id =": userid}) default: return t.tokenRepo.BatchDisable(ctx, ids, nil) } }