init
This commit is contained in:
125
internal/store/mongo/admin_profile_store.go
Normal file
125
internal/store/mongo/admin_profile_store.go
Normal file
@@ -0,0 +1,125 @@
|
||||
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[:])
|
||||
}
|
||||
Reference in New Issue
Block a user