186 lines
4.8 KiB
Go
186 lines
4.8 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
libmongo "gateway/internal/library/mongo"
|
|
permission "gateway/internal/model/permission/domain"
|
|
"gateway/internal/model/permission/domain/entity"
|
|
"gateway/internal/model/permission/domain/enum"
|
|
domrepo "gateway/internal/model/permission/domain/repository"
|
|
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
mongodriver "go.mongodb.org/mongo-driver/v2/mongo"
|
|
)
|
|
|
|
// UserRoleRepositoryParam configures the Mongo user-role repository.
|
|
type UserRoleRepositoryParam struct {
|
|
Conf *libmongo.Conf
|
|
}
|
|
|
|
type userRoleRepository struct {
|
|
db libmongo.DocumentDBUseCase
|
|
}
|
|
|
|
// NewUserRoleRepository creates a Mongo-backed UserRoleRepository.
|
|
func NewUserRoleRepository(param UserRoleRepositoryParam) domrepo.UserRoleRepository {
|
|
documentDB, err := libmongo.NewDocumentDB(param.Conf, entity.UserRole{}.CollectionName())
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return &userRoleRepository{db: documentDB}
|
|
}
|
|
|
|
func (r *userRoleRepository) Insert(ctx context.Context, ur *entity.UserRole) error {
|
|
now := time.Now().UTC().UnixMilli()
|
|
if ur.ID.IsZero() {
|
|
ur.ID = bson.NewObjectID()
|
|
}
|
|
if ur.Source == "" {
|
|
ur.Source = enum.RoleSourceManual
|
|
}
|
|
if ur.CreateAt == 0 {
|
|
ur.CreateAt = now
|
|
}
|
|
if ur.UpdateAt == 0 {
|
|
ur.UpdateAt = now
|
|
}
|
|
_, err := r.db.GetClient().InsertOne(ctx, ur)
|
|
if err != nil {
|
|
if mongodriver.IsDuplicateKeyError(err) {
|
|
return permission.ErrUserRoleDuplicate
|
|
}
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *userRoleRepository) BulkInsert(ctx context.Context, urs []*entity.UserRole) error {
|
|
if len(urs) == 0 {
|
|
return nil
|
|
}
|
|
now := time.Now().UTC().UnixMilli()
|
|
docs := make([]any, 0, len(urs))
|
|
for _, ur := range urs {
|
|
if ur.ID.IsZero() {
|
|
ur.ID = bson.NewObjectID()
|
|
}
|
|
if ur.Source == "" {
|
|
ur.Source = enum.RoleSourceManual
|
|
}
|
|
if ur.CreateAt == 0 {
|
|
ur.CreateAt = now
|
|
}
|
|
if ur.UpdateAt == 0 {
|
|
ur.UpdateAt = now
|
|
}
|
|
docs = append(docs, ur)
|
|
}
|
|
_, err := r.db.GetClient().InsertMany(ctx, docs)
|
|
if err != nil && !mongodriver.IsDuplicateKeyError(err) {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *userRoleRepository) Delete(ctx context.Context, tenantID, uid, roleID string) error {
|
|
filter := bson.M{
|
|
permission.BSONFieldTenantID: tenantID,
|
|
permission.BSONFieldUID: uid,
|
|
permission.BSONFieldRoleID: roleID,
|
|
}
|
|
res, err := r.db.GetClient().DeleteOne(ctx, filter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if res == 0 {
|
|
return permission.ErrUserRoleNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *userRoleRepository) DeleteByRole(ctx context.Context, tenantID, roleID string) (int64, error) {
|
|
filter := bson.M{
|
|
permission.BSONFieldTenantID: tenantID,
|
|
permission.BSONFieldRoleID: roleID,
|
|
}
|
|
return r.db.GetClient().DeleteMany(ctx, filter)
|
|
}
|
|
|
|
func (r *userRoleRepository) ReplaceForSource(
|
|
ctx context.Context,
|
|
tenantID, uid string,
|
|
source enum.RoleSource,
|
|
roleIDs []string,
|
|
) error {
|
|
filter := bson.M{
|
|
permission.BSONFieldTenantID: tenantID,
|
|
permission.BSONFieldUID: uid,
|
|
permission.BSONFieldSource: source,
|
|
}
|
|
if _, err := r.db.GetClient().DeleteMany(ctx, filter); err != nil {
|
|
return err
|
|
}
|
|
if len(roleIDs) == 0 {
|
|
return nil
|
|
}
|
|
now := time.Now().UTC().UnixMilli()
|
|
rows := make([]*entity.UserRole, 0, len(roleIDs))
|
|
for _, rid := range roleIDs {
|
|
rows = append(rows, &entity.UserRole{
|
|
ID: bson.NewObjectID(),
|
|
TenantID: tenantID,
|
|
UID: uid,
|
|
RoleID: rid,
|
|
Source: source,
|
|
CreateAt: now,
|
|
UpdateAt: now,
|
|
})
|
|
}
|
|
return r.BulkInsert(ctx, rows)
|
|
}
|
|
|
|
func (r *userRoleRepository) ListByUser(ctx context.Context, tenantID, uid string) ([]*entity.UserRole, error) {
|
|
q := bson.M{
|
|
permission.BSONFieldTenantID: tenantID,
|
|
permission.BSONFieldUID: uid,
|
|
}
|
|
var docs []*entity.UserRole
|
|
if err := r.db.GetClient().Find(ctx, &docs, q); err != nil {
|
|
return nil, err
|
|
}
|
|
return docs, nil
|
|
}
|
|
|
|
func (r *userRoleRepository) ListByRole(ctx context.Context, tenantID, roleID string) ([]*entity.UserRole, error) {
|
|
q := bson.M{
|
|
permission.BSONFieldTenantID: tenantID,
|
|
permission.BSONFieldRoleID: roleID,
|
|
}
|
|
var docs []*entity.UserRole
|
|
if err := r.db.GetClient().Find(ctx, &docs, q); err != nil {
|
|
return nil, err
|
|
}
|
|
return docs, nil
|
|
}
|
|
|
|
// Index20260521001UP ensures user_roles collection indexes exist.
|
|
func (r *userRoleRepository) Index20260521001UP(ctx context.Context) error {
|
|
if err := r.db.PopulateMultiIndex(ctx,
|
|
[]string{permission.BSONFieldTenantID, permission.BSONFieldUID, permission.BSONFieldRoleID},
|
|
[]int32{1, 1, 1}, true); err != nil {
|
|
return err
|
|
}
|
|
if err := r.db.PopulateMultiIndex(ctx,
|
|
[]string{permission.BSONFieldTenantID, permission.BSONFieldRoleID},
|
|
[]int32{1, 1}, false); err != nil {
|
|
return err
|
|
}
|
|
return r.db.PopulateMultiIndex(ctx,
|
|
[]string{permission.BSONFieldTenantID, permission.BSONFieldUID, permission.BSONFieldSource},
|
|
[]int32{1, 1, 1}, false)
|
|
}
|
|
|
|
var _ domrepo.UserRoleRepository = (*userRoleRepository)(nil)
|