|
- // Copyright © 2023 OpenIM open source community. All rights reserved.
- //
- // Licensed 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 service
-
- import (
- "errors"
- "fmt"
- "net"
-
- "github.com/gin-gonic/gin"
-
- "github.com/openimsdk/openkf/server/internal/common"
- "github.com/openimsdk/openkf/server/internal/config"
- "github.com/openimsdk/openkf/server/internal/dal/dao"
- "github.com/openimsdk/openkf/server/internal/models/base"
- systemroles "github.com/openimsdk/openkf/server/internal/models/system_roles"
- requestparams "github.com/openimsdk/openkf/server/internal/params/request"
- responseparams "github.com/openimsdk/openkf/server/internal/params/response"
- internal_utils "github.com/openimsdk/openkf/server/internal/utils"
- "github.com/openimsdk/openkf/server/pkg/openim/param/request"
- "github.com/openimsdk/openkf/server/pkg/openim/param/response"
- "github.com/openimsdk/openkf/server/pkg/openim/sdk/auth"
- "github.com/openimsdk/openkf/server/pkg/openim/sdk/user"
- "github.com/openimsdk/openkf/server/pkg/utils"
- )
-
- // UserService user service.
- type UserService struct {
- Service
-
- SysUserDao *dao.SysUserDao
- SysCommunityDao *dao.SysCommunityDao
- }
-
- // NewUserService return new service with gin context.
- func NewUserService(c *gin.Context) *UserService {
- return &UserService{
- Service: Service{
- ctx: c,
- },
- SysUserDao: dao.NewSysUserDao(),
- SysCommunityDao: dao.NewSysCommunityDao(),
- }
- }
-
- // CreateAdmin create admin user.
- func (svc *UserService) CreateAdmin(user *requestparams.RegisterAdminParams) (string, uint, error) {
- // Check code
- mService := NewMailService((svc.ctx).(*gin.Context))
- if isExist := mService.CheckCode(user.UserInfo.Email, user.Code); !isExist {
- return "", 0, errors.New("code is not valid")
- }
-
- // Create community
- communityParam := user.CommunityInfo
- cService := NewCommunityService((svc.ctx).(*gin.Context))
- _, cid, err := cService.Create(&communityParam)
- if err != nil {
- return "", 0, err
- }
-
- // Create admin
- uuid := utils.GenUUIDWithoutHyphen()
- adminParam := user.UserInfo
- admin := &systemroles.SysUser{
- UserBase: base.UserBase{
- UUID: uuid,
- Email: adminParam.Email,
- Nickname: adminParam.Nickname,
- Avatar: *adminParam.Avatar,
- IsEnable: true,
- },
- IsAdmin: true,
- Password: utils.EncryptPassword(adminParam.Password),
- CommunityId: cid,
- }
- if err = svc.SysUserDao.Create(admin); err != nil {
- return uuid, 0, err
- }
-
- u, _ := svc.SysUserDao.FindFirstByUUID(uuid)
-
- // TODO: set pipline to tx.
- param := &request.RegisterUserParams{
- Secret: config.Config.OpenIM.Secret,
- Users: []request.User{
- {
- UserID: uuid,
- Nickname: adminParam.Nickname,
- FaceURL: "", // Use OpenKF avatar
- },
- },
- }
- ok, err := registerUserToOpenIM(param)
- if err != nil || !ok {
- // Assume that the user has been created/deleted successfully
- _ = svc.SysUserDao.Delete(u)
-
- return uuid, u.Id, err
- }
-
- return uuid, u.Id, nil
- }
-
- // CreateStaff create staff user.
- func (svc *UserService) CreateStaff(cid string, user *requestparams.RegisterStaffParams) (string, uint, error) {
- // Create staff
- uid := utils.GenUUIDWithoutHyphen()
-
- communityInfo, err := svc.SysCommunityDao.FindFirstByUUID(cid)
- if err != nil {
- return "", 0, err
- }
-
- staffParam := user.UserInfo
- staff := &systemroles.SysUser{
- UserBase: base.UserBase{
- UUID: uid,
- Email: staffParam.Email,
- Nickname: staffParam.Nickname,
- Avatar: *staffParam.Avatar,
- IsEnable: true,
- },
- IsAdmin: false,
- Password: utils.EncryptPassword(staffParam.Password),
- CommunityId: communityInfo.Id,
- }
- if err = svc.SysUserDao.Create(staff); err != nil {
- return uid, 0, err
- }
-
- // TODO: Send email to staff
-
- u, _ := svc.SysUserDao.FindFirstByUUID(uid)
-
- // TODO: set pipline to tx.
- param := &request.RegisterUserParams{
- Secret: config.Config.OpenIM.Secret,
- Users: []request.User{
- {
- UserID: uid,
- Nickname: staffParam.Nickname,
- FaceURL: "", // Use OpenKF avatar
- },
- },
- }
- ok, err := registerUserToOpenIM(param)
- if err != nil || !ok {
- // Assume that the user has been created/deleted successfully
- _ = svc.SysUserDao.Delete(u)
-
- return uid, u.Id, err
- }
-
- return uid, u.Id, nil
- }
-
- // registerUserToOpenIM register user to openim.
- func registerUserToOpenIM(param *request.RegisterUserParams) (bool, error) {
- // TODO: Add get operationID
-
- // Default not use tls/ssl
- host := fmt.Sprintf("http://%s", net.JoinHostPort(config.Config.OpenIM.Ip, fmt.Sprintf("%d", config.Config.OpenIM.ApiPort)))
- resp, err := user.RegisterUser(param, "registerUserToOpenIM", host)
- if err != nil {
- return false, err
- }
-
- if resp.ErrCode != 0 {
- return false, errors.New(resp.ErrMsg)
- }
-
- return true, nil
- }
-
- // DeleteStaff delete staff user.
- func (svc *UserService) DeleteStaff(uid string) error {
- if uid == "" {
- return common.NewError(common.I_INVALID_PARAM)
- }
-
- u, err := svc.SysUserDao.FindFirstByUUID(uid)
- if err != nil {
- return err
- }
-
- err = svc.SysUserDao.Delete(u)
- if err != nil {
- return err
- }
-
- return nil
- }
-
- // LoginWithAccount login with account.
- func (svc *UserService) LoginWithAccount(param *requestparams.LoginParamsWithAccount) (*responseparams.UserTokenResponse, error) {
- resp := &responseparams.UserTokenResponse{}
-
- // Check user
- u, err := svc.SysUserDao.FindFirstByEmail(param.Email)
- if err != nil {
- return resp, err
- }
-
- // Check password
- if !utils.ComparePassword(param.Password, u.Password) {
- return resp, errors.New("password is not correct")
- }
-
- // Get community id
- cService := NewCommunityService((svc.ctx).(*gin.Context))
- c, err := cService.GetCommunityInfoById(u.CommunityId)
- if err != nil {
- return resp, err
- }
-
- // Generate KF token
- kfToken, kfExpireTimeSeconds, err := internal_utils.GenerateJwtToken(u.UUID, c.UUID)
- if err != nil {
- return resp, err
- }
-
- // Get IM token
- imParam := &request.UserTokenParams{
- Secret: config.Config.OpenIM.Secret,
- UserID: u.UUID,
- PlatformID: uint(config.Config.OpenIM.PlatformID),
- }
- imResp, err := getUserIMToken(imParam)
- if err != nil {
- return resp, err
- }
-
- // Fill response data
- resp.UUID = u.UUID
- resp.KFToken = &responseparams.TokenResponse{
- Token: kfToken,
- ExpireTimeSeconds: kfExpireTimeSeconds,
- }
- resp.IMToken = &responseparams.TokenResponse{
- Token: imResp.Token,
- ExpireTimeSeconds: imResp.ExpireTimeSeconds,
- }
-
- // TODO: Set Online in OpenIM or do this in js-sdk
-
- return resp, nil
- }
-
- // getUserIMToken get user im token.
- func getUserIMToken(param *request.UserTokenParams) (*response.TokenData, error) {
- // TODO: Add operationID
-
- // Default not use tls/ssl
- host := fmt.Sprintf("http://%s", net.JoinHostPort(config.Config.OpenIM.Ip, fmt.Sprintf("%d", config.Config.OpenIM.ApiPort)))
- resp, err := auth.GetUserToken(param, "getUserIMToken", host)
- if err != nil {
- return &response.TokenData{}, err
- }
-
- if resp.ErrCode != 0 {
- return &response.TokenData{}, errors.New(resp.ErrMsg)
- }
-
- return &resp.Data, nil
- }
-
- // GetAdminToken get admin token.
- func (svc *UserService) GetAdminToken() (*response.TokenData, error) {
- params := &request.UserTokenParams{
- Secret: config.Config.OpenIM.Secret,
- PlatformID: uint(config.Config.OpenIM.PlatformID),
- UserID: config.Config.OpenIM.AdminID,
- }
-
- // TODO: Get cache from redis
-
- return getUserIMToken(params)
- }
-
- // GetUserInfoByUUID get user info by uuid.
- func (svc *UserService) GetUserInfoByUUID(uid string) (*responseparams.UserInfoResponse, error) {
- resp := &responseparams.UserInfoResponse{}
-
- if uid == "" {
- return resp, common.NewError(common.I_INVALID_PARAM)
- }
-
- u, err := svc.SysUserDao.FindFirstByUUID(uid)
- if err != nil {
- return resp, err
- }
-
- resp.UUID = u.UUID
- resp.Email = u.Email
- resp.Nickname = u.Nickname
- resp.Avatar = u.Avatar
- resp.Description = u.Description
- resp.IsAdmin = u.IsAdmin
- resp.IsEnable = u.IsEnable
- resp.CreatedAt = u.CreatedAt.Format("2006-01-02 15:04:05")
-
- return resp, nil
- }
-
- // UpdateUserInfo update user info.
- func (svc *UserService) UpdateUserInfo(uid string, params *requestparams.UpdateUserInfoParams) (*responseparams.UserInfoResponse, error) {
- resp := &responseparams.UserInfoResponse{}
-
- if uid == "" {
- return resp, common.NewError(common.I_INVALID_PARAM)
- }
-
- u, err := svc.SysUserDao.FindFirstByUUID(uid)
- if err != nil {
- return resp, err
- }
-
- // Update user info
- if params.Nickname != nil {
- u.Nickname = *params.Nickname
- }
- if params.Description != nil {
- u.Description = *params.Description
- }
- if params.Avatar != nil {
- u.Avatar = *params.Avatar
- }
- if params.Email != nil {
- u.Email = *params.Email
- }
-
- // TODO: Check if the user is admin
- if params.IsEnable != nil {
- u.IsEnable = *params.IsEnable
- }
- if params.IsAdmin != nil {
- u.IsAdmin = *params.IsAdmin
- }
-
- // Update user info
- if err = svc.SysUserDao.Update(u); err != nil {
- return resp, err
- }
-
- // Get new info
- u, _ = svc.SysUserDao.FindFirstByUUID(uid)
- resp.UUID = u.UUID
- resp.Email = u.Email
- resp.Nickname = u.Nickname
- resp.Avatar = u.Avatar
- resp.Description = u.Description
- resp.IsAdmin = u.IsAdmin
- resp.IsEnable = u.IsEnable
- resp.CreatedAt = u.CreatedAt.Format("2006-01-02 15:04:05")
-
- return resp, nil
- }
-
- // UpdateUserPassword update user password.
- func (svc *UserService) UpdateUserPassword(uid string, params *requestparams.UpdateUserPasswordParams) error {
- if uid == "" {
- return common.NewError(common.I_INVALID_PARAM)
- }
-
- u, err := svc.SysUserDao.FindFirstByUUID(uid)
- if err != nil {
- return err
- }
-
- // Update user info
- if params.Password != "" && params.RepeatPassword != "" &&
- params.Password == params.RepeatPassword {
- u.Password = utils.EncryptPassword(params.Password)
- }
-
- // Update user info
- if err = svc.SysUserDao.Update(u); err != nil {
- return err
- }
-
- return nil
- }
-
- // GetCommunityUserList get community user list.
- func (svc *UserService) GetCommunityUserList(cid string, params *requestparams.ListPageParams) (*responseparams.ListPageResponse, error) {
- resp := &responseparams.ListPageResponse{}
- userInfos := make([]*responseparams.UserInfoResponse, 0)
-
- csvc := NewCommunityService((svc.ctx).(*gin.Context))
- info, err := csvc.GetCommunityInfoByUUIDV2(cid)
- if err != nil {
- return resp, err
- }
-
- // Get user list
- users, total, err := svc.SysUserDao.FindByCommunityIdPage(info.Id, (params.Page-1)*params.PageSize, params.PageSize)
- if err != nil {
- return resp, err
- }
-
- // Fill response data
- for _, u := range users {
- userInfos = append(userInfos, &responseparams.UserInfoResponse{
- UUID: u.UUID,
- Email: u.Email,
- Nickname: u.Nickname,
- Avatar: u.Avatar,
- Description: u.Description,
- IsAdmin: u.IsAdmin,
- IsEnable: u.IsEnable,
- CreatedAt: u.CreatedAt.Format("2006-01-02 15:04:05"),
- })
- }
-
- resp.List = userInfos
- resp.Page = params.Page
- resp.PageSize = params.PageSize
- resp.Total = int(total)
-
- return resp, nil
- }
|