chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"xorm.io/builder"
|
||||
|
||||
"github.com/apache/answer/internal/base/data"
|
||||
"github.com/apache/answer/internal/base/pager"
|
||||
"github.com/apache/answer/internal/base/reason"
|
||||
"github.com/apache/answer/internal/entity"
|
||||
"github.com/apache/answer/internal/service/auth"
|
||||
"github.com/apache/answer/internal/service/user_admin"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
)
|
||||
|
||||
// userAdminRepo user repository
|
||||
type userAdminRepo struct {
|
||||
data *data.Data
|
||||
authRepo auth.AuthRepo
|
||||
}
|
||||
|
||||
// NewUserAdminRepo new repository
|
||||
func NewUserAdminRepo(data *data.Data, authRepo auth.AuthRepo) user_admin.UserAdminRepo {
|
||||
return &userAdminRepo{
|
||||
data: data,
|
||||
authRepo: authRepo,
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateUserStatus update user status
|
||||
func (ur *userAdminRepo) UpdateUserStatus(ctx context.Context, userID string, userStatus, mailStatus int,
|
||||
email string, suspendedUntil time.Time,
|
||||
) (err error) {
|
||||
cond := &entity.User{Status: userStatus, MailStatus: mailStatus, EMail: email}
|
||||
switch userStatus {
|
||||
case entity.UserStatusSuspended:
|
||||
cond.SuspendedAt = time.Now()
|
||||
cond.SuspendedUntil = suspendedUntil
|
||||
case entity.UserStatusDeleted:
|
||||
cond.DeletedAt = time.Now()
|
||||
case entity.UserStatusAvailable:
|
||||
// When restoring user status, clear suspended until time to zero
|
||||
cond.SuspendedUntil = time.Time{}
|
||||
}
|
||||
_, err = ur.data.DB.Context(ctx).ID(userID).MustCols("status", "mail_status", "e_mail", "suspended_at", "suspended_until", "deleted_at").Update(cond)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
||||
userCacheInfo := &entity.UserCacheInfo{
|
||||
UserID: userID,
|
||||
EmailStatus: mailStatus,
|
||||
UserStatus: userStatus,
|
||||
}
|
||||
t, _ := json.Marshal(userCacheInfo)
|
||||
log.Infof("user change status: %s", string(t))
|
||||
err = ur.authRepo.SetUserStatus(ctx, userID, userCacheInfo)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddUser add user
|
||||
func (ur *userAdminRepo) AddUser(ctx context.Context, user *entity.User) (err error) {
|
||||
_, err = ur.data.DB.Context(ctx).Insert(user)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddUsers add users
|
||||
func (ur *userAdminRepo) AddUsers(ctx context.Context, users []*entity.User) (err error) {
|
||||
_, err = ur.data.DB.Context(ctx).Insert(users)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateUserPassword update user password
|
||||
func (ur *userAdminRepo) UpdateUserPassword(ctx context.Context, userID string, password string) (err error) {
|
||||
_, err = ur.data.DB.Context(ctx).ID(userID).Update(&entity.User{Pass: password})
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetUserInfo get user info
|
||||
func (ur *userAdminRepo) GetUserInfo(ctx context.Context, userID string) (user *entity.User, exist bool, err error) {
|
||||
user = &entity.User{}
|
||||
exist, err = ur.data.DB.Context(ctx).ID(userID).Get(user)
|
||||
if err != nil {
|
||||
return nil, false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
err = tryToDecorateUserInfoFromUserCenter(ctx, ur.data, user)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetUserInfoByEmail get user info
|
||||
func (ur *userAdminRepo) GetUserInfoByEmail(ctx context.Context, email string) (user *entity.User, exist bool, err error) {
|
||||
userInfo := &entity.User{}
|
||||
exist, err = ur.data.DB.Context(ctx).Where("e_mail = ?", email).
|
||||
Where("status != ?", entity.UserStatusDeleted).Get(userInfo)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return
|
||||
}
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
err = tryToDecorateUserInfoFromUserCenter(ctx, ur.data, user)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetUserPage get user page
|
||||
func (ur *userAdminRepo) GetUserPage(ctx context.Context, page, pageSize int, user *entity.User,
|
||||
usernameOrDisplayName string, isStaff bool) (users []*entity.User, total int64, err error) {
|
||||
users = make([]*entity.User, 0)
|
||||
session := ur.data.DB.Context(ctx)
|
||||
switch user.Status {
|
||||
case entity.UserStatusDeleted:
|
||||
session.Desc("`user`.deleted_at")
|
||||
case entity.UserStatusSuspended:
|
||||
session.Desc("`user`.suspended_at")
|
||||
default:
|
||||
session.Desc("`user`.created_at")
|
||||
}
|
||||
|
||||
if len(usernameOrDisplayName) > 0 {
|
||||
session.And(builder.Or(
|
||||
builder.Like{"`user`.username", usernameOrDisplayName},
|
||||
builder.Like{"`user`.display_name", usernameOrDisplayName},
|
||||
))
|
||||
}
|
||||
if isStaff {
|
||||
session.Join("INNER", "user_role_rel", "`user`.id = `user_role_rel`.user_id AND `user_role_rel`.role_id > 1")
|
||||
}
|
||||
|
||||
total, err = pager.Help(page, pageSize, &users, user, session)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return
|
||||
}
|
||||
tryToDecorateUserListFromUserCenter(ctx, ur.data, users)
|
||||
return
|
||||
}
|
||||
|
||||
// DeletePermanentlyUsers delete permanently users
|
||||
func (ur *userAdminRepo) DeletePermanentlyUsers(ctx context.Context) (err error) {
|
||||
_, err = ur.data.DB.Context(ctx).Where("status = ?", entity.UserStatusDeleted).Delete(&entity.User{})
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetExpiredSuspendedUsers gets all suspended users whose suspension has expired
|
||||
func (ur *userAdminRepo) GetExpiredSuspendedUsers(ctx context.Context) (users []*entity.User, err error) {
|
||||
users = make([]*entity.User, 0)
|
||||
now := time.Now()
|
||||
|
||||
err = ur.data.DB.Context(ctx).
|
||||
Where("status = ?", entity.UserStatusSuspended).
|
||||
Where("suspended_until < ?", now).
|
||||
Find(&users)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/apache/answer/internal/base/data"
|
||||
"github.com/apache/answer/internal/base/reason"
|
||||
"github.com/apache/answer/internal/entity"
|
||||
"github.com/apache/answer/internal/schema"
|
||||
usercommon "github.com/apache/answer/internal/service/user_common"
|
||||
"github.com/apache/answer/pkg/converter"
|
||||
"github.com/apache/answer/plugin"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// userRepo user repository
|
||||
type userRepo struct {
|
||||
data *data.Data
|
||||
}
|
||||
|
||||
// NewUserRepo new repository
|
||||
func NewUserRepo(data *data.Data) usercommon.UserRepo {
|
||||
return &userRepo{
|
||||
data: data,
|
||||
}
|
||||
}
|
||||
|
||||
// AddUser add user
|
||||
func (ur *userRepo) AddUser(ctx context.Context, user *entity.User) (err error) {
|
||||
_, err = ur.data.DB.Transaction(func(session *xorm.Session) (any, error) {
|
||||
session = session.Context(ctx)
|
||||
userInfo := &entity.User{}
|
||||
exist, err := session.Where("username = ?", user.Username).Get(userInfo)
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
if exist {
|
||||
return nil, errors.InternalServer(reason.UsernameDuplicate)
|
||||
}
|
||||
_, err = session.Insert(user)
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil, nil
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// IncreaseAnswerCount increase answer count
|
||||
func (ur *userRepo) IncreaseAnswerCount(ctx context.Context, userID string, amount int) (err error) {
|
||||
user := &entity.User{}
|
||||
_, err = ur.data.DB.Context(ctx).Where("id = ?", userID).Incr("answer_count", amount).Update(user)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IncreaseQuestionCount increase question count
|
||||
func (ur *userRepo) IncreaseQuestionCount(ctx context.Context, userID string, amount int) (err error) {
|
||||
user := &entity.User{}
|
||||
_, err = ur.data.DB.Context(ctx).Where("id = ?", userID).Incr("question_count", amount).Update(user)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ur *userRepo) UpdateQuestionCount(ctx context.Context, userID string, count int64) (err error) {
|
||||
user := &entity.User{}
|
||||
user.QuestionCount = int(count)
|
||||
_, err = ur.data.DB.Context(ctx).Where("id = ?", userID).Cols("question_count").Update(user)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ur *userRepo) UpdateAnswerCount(ctx context.Context, userID string, count int) (err error) {
|
||||
user := &entity.User{}
|
||||
user.AnswerCount = count
|
||||
_, err = ur.data.DB.Context(ctx).Where("id = ?", userID).Cols("answer_count").Update(user)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateLastLoginDate update last login date
|
||||
func (ur *userRepo) UpdateLastLoginDate(ctx context.Context, userID string) (err error) {
|
||||
user := &entity.User{LastLoginDate: time.Now()}
|
||||
_, err = ur.data.DB.Context(ctx).Where("id = ?", userID).Cols("last_login_date").Update(user)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateEmailStatus update email status
|
||||
func (ur *userRepo) UpdateEmailStatus(ctx context.Context, userID string, emailStatus int) error {
|
||||
cond := &entity.User{MailStatus: emailStatus}
|
||||
_, err := ur.data.DB.Context(ctx).Where("id = ?", userID).Cols("mail_status").Update(cond)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateNoticeStatus update notice status
|
||||
func (ur *userRepo) UpdateNoticeStatus(ctx context.Context, userID string, noticeStatus int) error {
|
||||
cond := &entity.User{NoticeStatus: noticeStatus}
|
||||
_, err := ur.data.DB.Context(ctx).Where("id = ?", userID).Cols("notice_status").Update(cond)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ur *userRepo) UpdatePass(ctx context.Context, userID, pass string) error {
|
||||
_, err := ur.data.DB.Context(ctx).Where("id = ?", userID).Cols("pass").Update(&entity.User{Pass: pass})
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ur *userRepo) UpdateEmail(ctx context.Context, userID, email string) (err error) {
|
||||
_, err = ur.data.DB.Context(ctx).Where("id = ?", userID).Update(&entity.User{EMail: email})
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ur *userRepo) UpdateUserInterface(ctx context.Context, userID, language, colorSchema string) (err error) {
|
||||
session := ur.data.DB.Context(ctx).Where("id = ?", userID)
|
||||
_, err = session.Cols("language", "color_scheme").Update(&entity.User{Language: language, ColorScheme: colorSchema})
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateInfo update user info
|
||||
func (ur *userRepo) UpdateInfo(ctx context.Context, userInfo *entity.User) (err error) {
|
||||
_, err = ur.data.DB.Context(ctx).Where("id = ?", userInfo.ID).
|
||||
Cols("username", "display_name", "avatar", "bio", "bio_html", "website", "location").Update(userInfo)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateUserProfile update user profile
|
||||
func (ur *userRepo) UpdateUserProfile(ctx context.Context, userInfo *entity.User) (err error) {
|
||||
_, err = ur.data.DB.Context(ctx).Where("id = ?", userInfo.ID).
|
||||
Cols("username", "e_mail", "mail_status", "display_name").Update(userInfo)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetByUserID get user info by user id
|
||||
func (ur *userRepo) GetByUserID(ctx context.Context, userID string) (userInfo *entity.User, exist bool, err error) {
|
||||
userInfo = &entity.User{}
|
||||
exist, err = ur.data.DB.Context(ctx).Where("id = ?", userID).Get(userInfo)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return
|
||||
}
|
||||
err = tryToDecorateUserInfoFromUserCenter(ctx, ur.data, userInfo)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ur *userRepo) BatchGetByID(ctx context.Context, ids []string) ([]*entity.User, error) {
|
||||
list := make([]*entity.User, 0)
|
||||
err := ur.data.DB.Context(ctx).In("id", ids).Find(&list)
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
tryToDecorateUserListFromUserCenter(ctx, ur.data, list)
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// GetByUsername get user by username
|
||||
func (ur *userRepo) GetByUsername(ctx context.Context, username string) (userInfo *entity.User, exist bool, err error) {
|
||||
userInfo = &entity.User{}
|
||||
exist, err = ur.data.DB.Context(ctx).Where("username = ?", username).Get(userInfo)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return
|
||||
}
|
||||
err = tryToDecorateUserInfoFromUserCenter(ctx, ur.data, userInfo)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ur *userRepo) GetByUsernames(ctx context.Context, usernames []string) ([]*entity.User, error) {
|
||||
list := make([]*entity.User, 0)
|
||||
err := ur.data.DB.Context(ctx).Where("status =?", entity.UserStatusAvailable).In("username", usernames).Find(&list)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return list, err
|
||||
}
|
||||
tryToDecorateUserListFromUserCenter(ctx, ur.data, list)
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// GetByEmail get user by email
|
||||
func (ur *userRepo) GetByEmail(ctx context.Context, email string) (userInfo *entity.User, exist bool, err error) {
|
||||
userInfo = &entity.User{}
|
||||
exist, err = ur.data.DB.Context(ctx).Where("e_mail = ?", email).
|
||||
Where("status != ?", entity.UserStatusDeleted).Get(userInfo)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ur *userRepo) GetUserCount(ctx context.Context) (count int64, err error) {
|
||||
session := ur.data.DB.Context(ctx)
|
||||
session.Where("status = ? OR status = ?", entity.UserStatusAvailable, entity.UserStatusSuspended)
|
||||
count, err = session.Count(&entity.User{})
|
||||
if err != nil {
|
||||
return count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (ur *userRepo) SearchUserListByName(ctx context.Context, name string, limit int,
|
||||
onlyStaff bool) (userList []*entity.User, err error) {
|
||||
userList = make([]*entity.User, 0)
|
||||
session := ur.data.DB.Context(ctx)
|
||||
if onlyStaff {
|
||||
session.Join("INNER", "user_role_rel", "`user`.id = `user_role_rel`.user_id AND `user_role_rel`.role_id > 1")
|
||||
}
|
||||
session.Where("status = ?", entity.UserStatusAvailable)
|
||||
session.Where("username LIKE ? OR display_name LIKE ?", strings.ToLower(name)+"%", name+"%")
|
||||
session.OrderBy("username ASC, `user`.id DESC")
|
||||
session.Limit(limit)
|
||||
err = session.Find(&userList)
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
tryToDecorateUserListFromUserCenter(ctx, ur.data, userList)
|
||||
return
|
||||
}
|
||||
|
||||
func tryToDecorateUserInfoFromUserCenter(ctx context.Context, data *data.Data, original *entity.User) (err error) {
|
||||
if original == nil {
|
||||
return nil
|
||||
}
|
||||
uc, ok := plugin.GetUserCenter()
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
userInfo := &entity.UserExternalLogin{}
|
||||
session := data.DB.Context(ctx).Where("user_id = ?", original.ID)
|
||||
session.Where("provider = ?", uc.Info().SlugName)
|
||||
exist, err := session.Get(userInfo)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
if !exist {
|
||||
return nil
|
||||
}
|
||||
|
||||
userCenterBasicUserInfo, err := uc.UserInfo(userInfo.ExternalID)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return errors.BadRequest(reason.UserNotFound).WithError(err).WithStack()
|
||||
}
|
||||
|
||||
decorateByUserCenterUser(original, userCenterBasicUserInfo)
|
||||
return nil
|
||||
}
|
||||
|
||||
func tryToDecorateUserListFromUserCenter(ctx context.Context, data *data.Data, original []*entity.User) {
|
||||
uc, ok := plugin.GetUserCenter()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
ids := make([]string, 0)
|
||||
originalUserIDMapping := make(map[string]*entity.User, 0)
|
||||
for _, user := range original {
|
||||
originalUserIDMapping[user.ID] = user
|
||||
ids = append(ids, user.ID)
|
||||
}
|
||||
|
||||
userExternalLoginList := make([]*entity.UserExternalLogin, 0)
|
||||
session := data.DB.Context(ctx).Where("provider = ?", uc.Info().SlugName)
|
||||
session.In("user_id", ids)
|
||||
err := session.Find(&userExternalLoginList)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
userExternalIDs := make([]string, 0)
|
||||
originalExternalIDMapping := make(map[string]*entity.User, 0)
|
||||
for _, u := range userExternalLoginList {
|
||||
originalExternalIDMapping[u.ExternalID] = originalUserIDMapping[u.UserID]
|
||||
userExternalIDs = append(userExternalIDs, u.ExternalID)
|
||||
}
|
||||
if len(userExternalIDs) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
ucUsers, err := uc.UserList(userExternalIDs)
|
||||
if err != nil {
|
||||
log.Errorf("get user list from user center failed: %v, %v", err, userExternalIDs)
|
||||
return
|
||||
}
|
||||
|
||||
for _, ucUser := range ucUsers {
|
||||
decorateByUserCenterUser(originalExternalIDMapping[ucUser.ExternalID], ucUser)
|
||||
}
|
||||
}
|
||||
|
||||
func decorateByUserCenterUser(original *entity.User, ucUser *plugin.UserCenterBasicUserInfo) {
|
||||
if original == nil || ucUser == nil {
|
||||
return
|
||||
}
|
||||
// In general, usernames should be guaranteed unique by the User Center plugin, so there are no inconsistencies.
|
||||
if original.Username != ucUser.Username {
|
||||
log.Warnf("user %s username is inconsistent with user center", original.ID)
|
||||
}
|
||||
if len(ucUser.DisplayName) > 0 {
|
||||
original.DisplayName = ucUser.DisplayName
|
||||
}
|
||||
if len(ucUser.Email) > 0 {
|
||||
original.EMail = ucUser.Email
|
||||
}
|
||||
if len(ucUser.Avatar) > 0 {
|
||||
original.Avatar = schema.CustomAvatar(ucUser.Avatar).ToJsonString()
|
||||
}
|
||||
if len(ucUser.Mobile) > 0 {
|
||||
original.Mobile = ucUser.Mobile
|
||||
}
|
||||
if len(ucUser.Bio) > 0 {
|
||||
original.BioHTML = converter.Markdown2HTML(ucUser.Bio) + original.BioHTML
|
||||
}
|
||||
|
||||
// If plugin enable rank agent, use rank from user center.
|
||||
if plugin.RankAgentEnabled() {
|
||||
original.Rank = ucUser.Rank
|
||||
}
|
||||
if ucUser.Status != plugin.UserStatusAvailable {
|
||||
original.Status = int(ucUser.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func (ur *userRepo) IsAvatarFileUsed(ctx context.Context, filePath string) (bool, error) {
|
||||
user := &entity.User{}
|
||||
count, err := ur.data.DB.Context(ctx).
|
||||
Table("user").
|
||||
Where(builder.Like{"avatar", "%" + filePath + "%"}).
|
||||
Count(&user)
|
||||
|
||||
if err != nil {
|
||||
return false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
Reference in New Issue
Block a user