package services import ( "errors" "time" "oidc-oauth2-server/models" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" ) type AdminService struct { db *gorm.DB } func NewAdminService(db *gorm.DB) *AdminService { return &AdminService{db: db} } type AdminCreateRequest struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required"` Email string `json:"email" binding:"required,email"` Role string `json:"role"` } type AdminUpdateRequest struct { Password string `json:"password"` Email string `json:"email" binding:"omitempty,email"` IsActive *bool `json:"is_active"` Role string `json:"role"` } type AdminResponse struct { ID uint `json:"id"` Username string `json:"username"` Email string `json:"email"` LastLogin time.Time `json:"last_login"` IsActive bool `json:"is_active"` Role string `json:"role"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } func (s *AdminService) Create(req *AdminCreateRequest) (*AdminResponse, error) { hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) if err != nil { return nil, err } admin := &models.Admin{ Username: req.Username, Password: string(hashedPassword), Email: req.Email, Role: req.Role, } if err := s.db.Create(admin).Error; err != nil { return nil, err } return s.toResponse(admin), nil } func (s *AdminService) Update(id uint, req *AdminUpdateRequest) (*AdminResponse, error) { admin := &models.Admin{} if err := s.db.First(admin, id).Error; err != nil { return nil, err } if req.Password != "" { hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) if err != nil { return nil, err } admin.Password = string(hashedPassword) } if req.Email != "" { admin.Email = req.Email } if req.IsActive != nil { admin.IsActive = *req.IsActive } if req.Role != "" { admin.Role = req.Role } if err := s.db.Save(admin).Error; err != nil { return nil, err } return s.toResponse(admin), nil } func (s *AdminService) Delete(id uint) error { return s.db.Delete(&models.Admin{}, id).Error } func (s *AdminService) Get(id uint) (*AdminResponse, error) { admin := &models.Admin{} if err := s.db.First(admin, id).Error; err != nil { return nil, err } return s.toResponse(admin), nil } func (s *AdminService) List(page, pageSize int) ([]AdminResponse, int64, error) { var admins []models.Admin var total int64 query := s.db.Model(&models.Admin{}) query.Count(&total) if err := query.Offset((page - 1) * pageSize).Limit(pageSize).Find(&admins).Error; err != nil { return nil, 0, err } responses := make([]AdminResponse, len(admins)) for i, admin := range admins { responses[i] = *s.toResponse(&admin) } return responses, total, nil } func (s *AdminService) Authenticate(username, password string) (*AdminResponse, error) { admin := &models.Admin{} if err := s.db.Where("username = ?", username).First(admin).Error; err != nil { return nil, errors.New("invalid credentials") } if err := bcrypt.CompareHashAndPassword([]byte(admin.Password), []byte(password)); err != nil { return nil, errors.New("invalid credentials") } admin.LastLogin = time.Now() if err := s.db.Save(admin).Error; err != nil { return nil, err } return s.toResponse(admin), nil } func (s *AdminService) toResponse(admin *models.Admin) *AdminResponse { return &AdminResponse{ ID: admin.ID, Username: admin.Username, Email: admin.Email, LastLogin: admin.LastLogin, IsActive: admin.IsActive, Role: admin.Role, CreatedAt: admin.CreatedAt, UpdatedAt: admin.UpdatedAt, } } func (s *AdminService) ListUsers(page, pageSize int) ([]models.User, int64, error) { var users []models.User var total int64 s.db.Model(&models.User{}).Count(&total) err := s.db.Offset((page - 1) * pageSize).Limit(pageSize).Find(&users).Error return users, total, err } func (s *AdminService) ListClients(page, pageSize int) ([]models.Client, int64, error) { var clients []models.Client var total int64 s.db.Model(&models.Client{}).Count(&total) err := s.db.Offset((page - 1) * pageSize).Limit(pageSize).Find(&clients).Error return clients, total, err }