| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- package service
- import (
- "context"
- "dsbqj-admin/model/mongo/admin"
- "dsbqj-admin/pkg/util"
- "errors"
- "os"
- "strings"
- "time"
- "github.com/kamva/mgm/v3"
- "go.mongodb.org/mongo-driver/bson"
- "golang.org/x/crypto/bcrypt"
- )
- const defaultAdminUsername = "admin"
- const defaultAdminPassword = "admin123"
- type AdminClaims struct {
- Username string `json:"username"`
- ExpiresAt int64 `json:"expires_at"`
- }
- type LoginService struct {
- Username string `json:"username" binding:"required"`
- Password string `json:"password" binding:"required"`
- }
- type ChangePasswordService struct {
- Username string `json:"-"`
- OldPassword string `json:"oldPassword" binding:"required"`
- NewPassword string `json:"newPassword" binding:"required,min=6"`
- }
- func EnsureDefaultAdmin() error {
- coll := mgm.Coll(&admin.Admin{})
- count, err := coll.CountDocuments(context.Background(), bson.M{})
- if err != nil || count > 0 {
- return err
- }
- username := strings.TrimSpace(os.Getenv("ADMIN_USERNAME"))
- password := os.Getenv("ADMIN_PASSWORD")
- if username == "" {
- username = defaultAdminUsername
- }
- if password == "" {
- password = defaultAdminPassword
- }
- hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
- if err != nil {
- return err
- }
- return coll.Create(&admin.Admin{Username: username, PasswordHash: string(hash)})
- }
- func (s *LoginService) Login() (map[string]interface{}, error) {
- var account admin.Admin
- err := mgm.Coll(&account).First(bson.M{"username": strings.TrimSpace(s.Username)}, &account)
- if err != nil || bcrypt.CompareHashAndPassword([]byte(account.PasswordHash), []byte(s.Password)) != nil {
- return nil, errors.New("invalid username or password")
- }
- claims := AdminClaims{Username: account.Username, ExpiresAt: time.Now().Add(24 * time.Hour).Unix()}
- token := util.GenerateToken(claims, util.AdminTokenSecret())
- if token == "" {
- return nil, errors.New("failed to generate login token")
- }
- return map[string]interface{}{
- "token": token, "username": account.Username, "role": "admin",
- "roleId": "admin", "permissions": []string{"*"},
- }, nil
- }
- func (s *ChangePasswordService) Change() error {
- if len(s.NewPassword) < 6 {
- return errors.New("new password must contain at least 6 characters")
- }
- if s.OldPassword == s.NewPassword {
- return errors.New("new password must differ from old password")
- }
- var account admin.Admin
- coll := mgm.Coll(&account)
- if err := coll.First(bson.M{"username": s.Username}, &account); err != nil {
- return errors.New("account not found")
- }
- if bcrypt.CompareHashAndPassword([]byte(account.PasswordHash), []byte(s.OldPassword)) != nil {
- return errors.New("old password is incorrect")
- }
- hash, err := bcrypt.GenerateFromPassword([]byte(s.NewPassword), bcrypt.DefaultCost)
- if err != nil {
- return err
- }
- _, err = coll.UpdateOne(context.Background(), bson.M{"_id": account.ID}, bson.M{
- "$set": bson.M{"password_hash": string(hash), "updated_at": time.Now()},
- })
- return err
- }
|