swirl/biz/user.go
2022-02-10 11:09:03 +08:00

194 lines
5.3 KiB
Go

package biz
import (
"context"
"github.com/cuigh/auxo/errors"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/auxo/security/passwd"
"github.com/cuigh/swirl/dao"
"github.com/cuigh/swirl/misc"
)
const (
// UserTypeInternal is internal user of swirl
UserTypeInternal = "internal"
// UserTypeLDAP is external user of LDAP
UserTypeLDAP = "ldap"
)
const (
// UserStatusBlocked is the status which user is blocked
UserStatusBlocked = 0
// UserStatusActive is the normal status
UserStatusActive = 1
)
type UserBiz interface {
Search(ctx context.Context, name, loginName, filter string, pageIndex, pageSize int) (users []*dao.User, total int, err error)
Create(ctx context.Context, user *dao.User, ctxUser web.User) (id string, err error)
Update(ctx context.Context, user *dao.User, ctxUser web.User) (err error)
FindByID(ctx context.Context, id string) (user *dao.User, err error)
FindByName(ctx context.Context, loginName string) (user *dao.User, err error)
FindByToken(ctx context.Context, token string) (user *dao.User, err error)
FindPrivacy(ctx context.Context, loginName string) (privacy *UserPrivacy, err error)
Count(ctx context.Context) (count int, err error)
Delete(ctx context.Context, id, name string, user web.User) (err error)
SetStatus(ctx context.Context, id string, status int32, user web.User) (err error)
ModifyPassword(ctx context.Context, oldPwd, newPwd string, user web.User) (err error)
ModifyProfile(ctx context.Context, user *dao.User, ctxUser web.User) (err error)
}
func NewUser(d dao.Interface, eb EventBiz) UserBiz {
return &userBiz{d: d, eb: eb}
}
type userBiz struct {
d dao.Interface
eb EventBiz
}
func (b *userBiz) Search(ctx context.Context, name, loginName, filter string, pageIndex, pageSize int) (users []*dao.User, total int, err error) {
var args = &dao.UserSearchArgs{
Name: name,
LoginName: loginName,
Status: -1,
PageIndex: pageIndex,
PageSize: pageSize,
}
switch filter {
case "admins":
args.Admin = true
case "active":
args.Status = UserStatusActive
case "blocked":
args.Status = UserStatusBlocked
}
return b.d.UserSearch(ctx, args)
}
func (b *userBiz) FindByID(ctx context.Context, id string) (user *dao.User, err error) {
return b.d.UserGet(ctx, id)
}
func (b *userBiz) FindByName(ctx context.Context, loginName string) (user *dao.User, err error) {
return b.d.UserGetByName(ctx, loginName)
}
func (b *userBiz) FindByToken(ctx context.Context, token string) (user *dao.User, err error) {
return b.d.UserGetByToken(ctx, token)
}
func (b *userBiz) FindPrivacy(ctx context.Context, loginName string) (privacy *UserPrivacy, err error) {
var u *dao.User
u, err = b.d.UserGetByName(ctx, loginName)
if u != nil {
privacy = &UserPrivacy{
ID: u.ID,
Name: u.Name,
Password: u.Password,
Salt: u.Salt,
Type: u.Type,
Status: u.Status,
}
}
return
}
func (b *userBiz) Create(ctx context.Context, user *dao.User, ctxUser web.User) (id string, err error) {
user.ID = createId()
user.Status = UserStatusActive
user.CreatedAt = now()
if ctxUser != nil {
user.CreatedBy = newOperator(ctxUser)
}
user.UpdatedAt = user.CreatedAt
user.UpdatedBy = user.CreatedBy
if user.Type == UserTypeInternal {
user.Password, user.Salt, err = passwd.Generate(user.Password)
if err != nil {
return
}
}
if err = b.d.UserCreate(ctx, user); err == nil && ctxUser != nil {
b.eb.CreateUser(EventActionCreate, user.LoginName, user.Name, ctxUser)
}
id = user.ID
return
}
func (b *userBiz) Update(ctx context.Context, user *dao.User, ctxUser web.User) (err error) {
user.UpdatedAt = now()
user.UpdatedBy = newOperator(ctxUser)
if err = b.d.UserUpdate(ctx, user); err == nil {
go func() {
_ = b.d.SessionUpdateDirty(ctx, user.ID, "")
b.eb.CreateUser(EventActionUpdate, user.LoginName, user.Name, ctxUser)
}()
}
return
}
func (b *userBiz) SetStatus(ctx context.Context, id string, status int32, user web.User) (err error) {
u := &dao.User{
ID: id,
Status: status,
UpdatedAt: now(),
UpdatedBy: newOperator(user),
}
return b.d.UserUpdateStatus(ctx, u)
}
func (b *userBiz) Delete(ctx context.Context, id, name string, user web.User) (err error) {
err = b.d.UserDelete(ctx, id)
if err == nil {
b.eb.CreateUser(EventActionDelete, id, name, user)
}
return
}
func (b *userBiz) ModifyPassword(ctx context.Context, oldPwd, newPwd string, user web.User) (err error) {
var u *dao.User
u, err = b.d.UserGet(ctx, user.ID())
if err != nil {
return err
} else if u == nil {
return errors.Format("user not found: %s", user.ID())
}
if !passwd.Validate(oldPwd, u.Password, u.Salt) {
return errors.Coded(misc.ErrOldPasswordIncorrect, "current password is incorrect")
}
if u.Password, u.Salt, err = passwd.Generate(newPwd); err != nil {
return
}
u.UpdatedAt = now()
u.UpdatedBy = newOperator(user)
return b.d.UserUpdatePassword(ctx, u)
}
func (b *userBiz) ModifyProfile(ctx context.Context, u *dao.User, user web.User) (err error) {
u.ID = user.ID()
u.UpdatedAt = now()
u.UpdatedBy = newOperator(user)
return b.d.UserUpdateProfile(ctx, u)
}
func (b *userBiz) Count(ctx context.Context) (count int, err error) {
return b.d.UserCount(ctx)
}
type UserPrivacy struct {
ID string
Name string
Password string `json:"-"`
Salt string `json:"-"`
Type string
Status int32
}