126 lines
3.1 KiB
Go
126 lines
3.1 KiB
Go
package mongo
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"errors"
|
|
"time"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
mongodriver "go.mongodb.org/mongo-driver/mongo"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
|
|
"scheduler-backend/internal/store/model"
|
|
)
|
|
|
|
const defaultAdminPassword = "admin123"
|
|
|
|
type AdminProfileStore struct {
|
|
collection *mongodriver.Collection
|
|
}
|
|
|
|
func NewAdminProfileStore(db *mongodriver.Database) *AdminProfileStore {
|
|
return &AdminProfileStore{
|
|
collection: db.Collection("admin_profiles"),
|
|
}
|
|
}
|
|
|
|
func (s *AdminProfileStore) Get(ctx context.Context) (*model.AdminProfile, error) {
|
|
findCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
defer cancel()
|
|
|
|
var item model.AdminProfile
|
|
err := s.collection.FindOne(findCtx, bson.D{}, options.FindOne().SetSort(bson.D{{Key: "updatedAt", Value: -1}})).Decode(&item)
|
|
if err == nil {
|
|
return &item, nil
|
|
}
|
|
if !errors.Is(err, mongodriver.ErrNoDocuments) {
|
|
return nil, err
|
|
}
|
|
|
|
now := time.Now()
|
|
item = model.AdminProfile{
|
|
ID: primitive.NewObjectID(),
|
|
Account: "admin",
|
|
Nickname: "调度管理员",
|
|
Avatar: "",
|
|
Remark: "default admin profile",
|
|
PasswordHash: hashPassword(defaultAdminPassword),
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
if _, err := s.collection.InsertOne(findCtx, item); err != nil {
|
|
return nil, err
|
|
}
|
|
return &item, nil
|
|
}
|
|
|
|
func (s *AdminProfileStore) Upsert(ctx context.Context, profile *model.AdminProfile) error {
|
|
updateCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
defer cancel()
|
|
|
|
now := time.Now()
|
|
profile.UpdatedAt = now
|
|
if profile.CreatedAt.IsZero() {
|
|
profile.CreatedAt = now
|
|
}
|
|
|
|
if profile.ID.IsZero() {
|
|
current, err := s.Get(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
profile.ID = current.ID
|
|
if profile.PasswordHash == "" {
|
|
profile.PasswordHash = current.PasswordHash
|
|
}
|
|
if profile.CreatedAt.IsZero() {
|
|
profile.CreatedAt = current.CreatedAt
|
|
}
|
|
}
|
|
|
|
_, err := s.collection.UpdateByID(updateCtx, profile.ID, bson.M{
|
|
"$set": bson.M{
|
|
"account": profile.Account,
|
|
"nickname": profile.Nickname,
|
|
"avatar": profile.Avatar,
|
|
"remark": profile.Remark,
|
|
"passwordHash": profile.PasswordHash,
|
|
"createdAt": profile.CreatedAt,
|
|
"updatedAt": profile.UpdatedAt,
|
|
},
|
|
}, options.Update().SetUpsert(true))
|
|
return err
|
|
}
|
|
|
|
func (s *AdminProfileStore) ChangePassword(ctx context.Context, oldPassword, newPassword string) error {
|
|
current, err := s.Get(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if current.PasswordHash != hashPassword(oldPassword) {
|
|
return ErrInvalidPassword
|
|
}
|
|
|
|
current.PasswordHash = hashPassword(newPassword)
|
|
return s.Upsert(ctx, current)
|
|
}
|
|
|
|
func (s *AdminProfileStore) Authenticate(ctx context.Context, account, password string) (*model.AdminProfile, error) {
|
|
current, err := s.Get(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if current.Account != account || current.PasswordHash != hashPassword(password) {
|
|
return nil, ErrInvalidPassword
|
|
}
|
|
return current, nil
|
|
}
|
|
|
|
func hashPassword(password string) string {
|
|
sum := sha256.Sum256([]byte(password))
|
|
return hex.EncodeToString(sum[:])
|
|
}
|