mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-11-05 01:20:25 +08:00
初步完成用户电子邮箱绑定(激活)
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -172,6 +173,21 @@ func (this *SysSettingDAO) ReadAdminUIConfig(tx *dbs.Tx, cacheMap *utils.CacheMa
|
|||||||
return &systemconfigs.AdminUIConfig{}, nil
|
return &systemconfigs.AdminUIConfig{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadProductName 读取设置的产品名称
|
||||||
|
func (this *SysSettingDAO) ReadProductName(tx *dbs.Tx) (string, error) {
|
||||||
|
productName, err := this.Query(tx).
|
||||||
|
Attr("code", systemconfigs.SettingCodeAdminUIConfig).
|
||||||
|
Result("JSON_EXTRACT(value, '$.productName')").
|
||||||
|
FindStringCol("")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if len(productName) > 0 {
|
||||||
|
return strconv.Unquote(productName)
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
// ReadUserUIConfig 读取用户UI配置
|
// ReadUserUIConfig 读取用户UI配置
|
||||||
func (this *SysSettingDAO) ReadUserUIConfig(tx *dbs.Tx) (*systemconfigs.UserUIConfig, error) {
|
func (this *SysSettingDAO) ReadUserUIConfig(tx *dbs.Tx) (*systemconfigs.UserUIConfig, error) {
|
||||||
valueJSON, err := this.ReadSetting(tx, systemconfigs.SettingCodeUserUIConfig)
|
valueJSON, err := this.ReadSetting(tx, systemconfigs.SettingCodeUserUIConfig)
|
||||||
@@ -228,3 +244,21 @@ func (this *SysSettingDAO) ReadUserServerConfig(tx *dbs.Tx) (*userconfigs.UserSe
|
|||||||
}
|
}
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadUserRegisterConfig 读取用户注册配置
|
||||||
|
func (this *SysSettingDAO) ReadUserRegisterConfig(tx *dbs.Tx) (*userconfigs.UserRegisterConfig, error) {
|
||||||
|
valueJSON, err := this.ReadSetting(tx, systemconfigs.SettingCodeUserRegisterConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(valueJSON) == 0 {
|
||||||
|
return userconfigs.DefaultUserRegisterConfig(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = userconfigs.DefaultUserRegisterConfig()
|
||||||
|
err = json.Unmarshal(valueJSON, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,3 +42,8 @@ func TestSysSettingDAO_CompareInt64Setting(t *testing.T) {
|
|||||||
}
|
}
|
||||||
t.Log("result:", i)
|
t.Log("result:", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSysSettingDAO_ReadProductName(t *testing.T) {
|
||||||
|
var tx *dbs.Tx
|
||||||
|
t.Log(NewSysSettingDAO().ReadProductName(tx))
|
||||||
|
}
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ func (this *UserDAO) ListEnabledUserIds(tx *dbs.Tx, offset, size int64) ([]int64
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckUserPassword 检查用户名、密码
|
// CheckUserPassword 检查用户名+密码
|
||||||
func (this *UserDAO) CheckUserPassword(tx *dbs.Tx, username string, encryptedPassword string) (int64, error) {
|
func (this *UserDAO) CheckUserPassword(tx *dbs.Tx, username string, encryptedPassword string) (int64, error) {
|
||||||
if len(username) == 0 || len(encryptedPassword) == 0 {
|
if len(username) == 0 || len(encryptedPassword) == 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
@@ -354,6 +354,20 @@ func (this *UserDAO) CheckUserPassword(tx *dbs.Tx, username string, encryptedPas
|
|||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckUserEmailPassword 检查邮箱+密码
|
||||||
|
func (this *UserDAO) CheckUserEmailPassword(tx *dbs.Tx, verifiedEmail string, encryptedPassword string) (int64, error) {
|
||||||
|
if len(verifiedEmail) == 0 || len(encryptedPassword) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return this.Query(tx).
|
||||||
|
Attr("verifiedEmail", verifiedEmail).
|
||||||
|
Attr("password", encryptedPassword).
|
||||||
|
Attr("state", UserStateEnabled).
|
||||||
|
Attr("isOn", true).
|
||||||
|
ResultPk().
|
||||||
|
FindInt64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
// FindUserClusterId 查找用户所在集群
|
// FindUserClusterId 查找用户所在集群
|
||||||
func (this *UserDAO) FindUserClusterId(tx *dbs.Tx, userId int64) (int64, error) {
|
func (this *UserDAO) FindUserClusterId(tx *dbs.Tx, userId int64) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
@@ -586,6 +600,30 @@ func (this *UserDAO) RenewUserServersState(tx *dbs.Tx, userId int64) (bool, erro
|
|||||||
return newServersEnabled, nil
|
return newServersEnabled, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindUserIdWithVerifiedEmail 使用验证后Email查找用户ID
|
||||||
|
func (this *UserDAO) FindUserIdWithVerifiedEmail(tx *dbs.Tx, verifiedEmail string) (int64, error) {
|
||||||
|
if len(verifiedEmail) == 0 {
|
||||||
|
|
||||||
|
}
|
||||||
|
return this.Query(tx).
|
||||||
|
ResultPk().
|
||||||
|
State(UserStateEnabled).
|
||||||
|
Attr("verifiedEmail", verifiedEmail).
|
||||||
|
FindInt64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateUserVerifiedEmail 修改已激活邮箱
|
||||||
|
func (this *UserDAO) UpdateUserVerifiedEmail(tx *dbs.Tx, userId int64, verifiedEmail string) error {
|
||||||
|
if userId <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(userId).
|
||||||
|
Set("verifiedEmail", verifiedEmail).
|
||||||
|
Set("emailIsVerified", true).
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 用户变更通知
|
// NotifyUpdate 用户变更通知
|
||||||
func (this *UserDAO) NotifyUpdate(tx *dbs.Tx, userId int64) error {
|
func (this *UserDAO) NotifyUpdate(tx *dbs.Tx, userId int64) error {
|
||||||
if userId <= 0 {
|
if userId <= 0 {
|
||||||
|
|||||||
28
internal/db/models/user_email_verification_dao.go
Normal file
28
internal/db/models/user_email_verification_dao.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserEmailVerificationDAO dbs.DAO
|
||||||
|
|
||||||
|
func NewUserEmailVerificationDAO() *UserEmailVerificationDAO {
|
||||||
|
return dbs.NewDAO(&UserEmailVerificationDAO{
|
||||||
|
DAOObject: dbs.DAOObject{
|
||||||
|
DB: Tea.Env,
|
||||||
|
Table: "edgeUserEmailVerifications",
|
||||||
|
Model: new(UserEmailVerification),
|
||||||
|
PkName: "id",
|
||||||
|
},
|
||||||
|
}).(*UserEmailVerificationDAO)
|
||||||
|
}
|
||||||
|
|
||||||
|
var SharedUserEmailVerificationDAO *UserEmailVerificationDAO
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
dbs.OnReady(func() {
|
||||||
|
SharedUserEmailVerificationDAO = NewUserEmailVerificationDAO()
|
||||||
|
})
|
||||||
|
}
|
||||||
6
internal/db/models/user_email_verification_dao_test.go
Normal file
6
internal/db/models/user_email_verification_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package models_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
|
)
|
||||||
28
internal/db/models/user_email_verification_model.go
Normal file
28
internal/db/models/user_email_verification_model.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
// UserEmailVerification 邮箱激活邮件队列
|
||||||
|
type UserEmailVerification struct {
|
||||||
|
Id uint64 `field:"id"` // ID
|
||||||
|
Email string `field:"email"` // 邮箱
|
||||||
|
UserId uint64 `field:"userId"` // 用户ID
|
||||||
|
Code string `field:"code"` // 激活码
|
||||||
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
|
IsSent bool `field:"isSent"` // 是否已发送
|
||||||
|
IsVerified bool `field:"isVerified"` // 是否已激活
|
||||||
|
Day string `field:"day"` // YYYYMMDD
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserEmailVerificationOperator struct {
|
||||||
|
Id any // ID
|
||||||
|
Email any // 邮箱
|
||||||
|
UserId any // 用户ID
|
||||||
|
Code any // 激活码
|
||||||
|
CreatedAt any // 创建时间
|
||||||
|
IsSent any // 是否已发送
|
||||||
|
IsVerified any // 是否已激活
|
||||||
|
Day any // YYYYMMDD
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserEmailVerificationOperator() *UserEmailVerificationOperator {
|
||||||
|
return &UserEmailVerificationOperator{}
|
||||||
|
}
|
||||||
1
internal/db/models/user_email_verification_model_ext.go
Normal file
1
internal/db/models/user_email_verification_model_ext.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package models
|
||||||
@@ -13,6 +13,7 @@ type User struct {
|
|||||||
Tel string `field:"tel"` // 联系电话
|
Tel string `field:"tel"` // 联系电话
|
||||||
Remark string `field:"remark"` // 备注
|
Remark string `field:"remark"` // 备注
|
||||||
Email string `field:"email"` // 邮箱地址
|
Email string `field:"email"` // 邮箱地址
|
||||||
|
VerifiedEmail string `field:"verifiedEmail"` // 激活后的邮箱
|
||||||
EmailIsVerified uint8 `field:"emailIsVerified"` // 邮箱是否已验证
|
EmailIsVerified uint8 `field:"emailIsVerified"` // 邮箱是否已验证
|
||||||
AvatarFileId uint64 `field:"avatarFileId"` // 头像文件ID
|
AvatarFileId uint64 `field:"avatarFileId"` // 头像文件ID
|
||||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
@@ -43,6 +44,7 @@ type UserOperator struct {
|
|||||||
Tel any // 联系电话
|
Tel any // 联系电话
|
||||||
Remark any // 备注
|
Remark any // 备注
|
||||||
Email any // 邮箱地址
|
Email any // 邮箱地址
|
||||||
|
VerifiedEmail any // 激活后的邮箱
|
||||||
EmailIsVerified any // 邮箱是否已验证
|
EmailIsVerified any // 邮箱是否已验证
|
||||||
AvatarFileId any // 头像文件ID
|
AvatarFileId any // 头像文件ID
|
||||||
CreatedAt any // 创建时间
|
CreatedAt any // 创建时间
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package nodes
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services/users"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -197,11 +198,6 @@ func (this *APINode) registerServices(server *grpc.Server) {
|
|||||||
pb.RegisterMessageReceiverServiceServer(server, instance)
|
pb.RegisterMessageReceiverServiceServer(server, instance)
|
||||||
this.rest(instance)
|
this.rest(instance)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
var instance = this.serviceInstance(&services.MessageMediaService{}).(*services.MessageMediaService)
|
|
||||||
pb.RegisterMessageMediaServiceServer(server, instance)
|
|
||||||
this.rest(instance)
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
var instance = this.serviceInstance(&services.MessageRecipientGroupService{}).(*services.MessageRecipientGroupService)
|
var instance = this.serviceInstance(&services.MessageRecipientGroupService{}).(*services.MessageRecipientGroupService)
|
||||||
pb.RegisterMessageRecipientGroupServiceServer(server, instance)
|
pb.RegisterMessageRecipientGroupServiceServer(server, instance)
|
||||||
@@ -343,7 +339,7 @@ func (this *APINode) registerServices(server *grpc.Server) {
|
|||||||
this.rest(instance)
|
this.rest(instance)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var instance = this.serviceInstance(&services.UserService{}).(*services.UserService)
|
var instance = this.serviceInstance(&users.UserService{}).(*users.UserService)
|
||||||
pb.RegisterUserServiceServer(server, instance)
|
pb.RegisterUserServiceServer(server, instance)
|
||||||
this.rest(instance)
|
this.rest(instance)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
||||||
"github.com/iwind/TeaGo/maps"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MessageMediaService 消息媒介服务
|
|
||||||
type MessageMediaService struct {
|
|
||||||
BaseService
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindAllMessageMedias 获取所有支持的媒介
|
|
||||||
func (this *MessageMediaService) FindAllMessageMedias(ctx context.Context, req *pb.FindAllMessageMediasRequest) (*pb.FindAllMessageMediasResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var tx = this.NullTx()
|
|
||||||
medias, err := models.SharedMessageMediaDAO.FindAllEnabledMessageMedias(tx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pbMedias := []*pb.MessageMedia{}
|
|
||||||
for _, media := range medias {
|
|
||||||
pbMedias = append(pbMedias, &pb.MessageMedia{
|
|
||||||
Id: int64(media.Id),
|
|
||||||
Type: media.Type,
|
|
||||||
Name: media.Name,
|
|
||||||
Description: media.Description,
|
|
||||||
UserDescription: media.UserDescription,
|
|
||||||
IsOn: media.IsOn,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return &pb.FindAllMessageMediasResponse{MessageMedias: pbMedias}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMessageMedias 设置所有支持的媒介
|
|
||||||
func (this *MessageMediaService) UpdateMessageMedias(ctx context.Context, req *pb.UpdateMessageMediasRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateMonitorNode(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaMaps := []maps.Map{}
|
|
||||||
for _, media := range req.MessageMedias {
|
|
||||||
mediaMaps = append(mediaMaps, maps.Map{
|
|
||||||
"name": media.Name,
|
|
||||||
"type": media.Type,
|
|
||||||
"description": media.Description,
|
|
||||||
"userDescription": media.UserDescription,
|
|
||||||
"isOn": media.IsOn,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
err = models.SharedMessageMediaDAO.UpdateMessageMedias(tx, mediaMaps)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
|
||||||
//go:build !plus
|
|
||||||
|
|
||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FindUserPriceInfo 读取用户计费信息
|
|
||||||
func (this *UserService) FindUserPriceInfo(ctx context.Context, req *pb.FindUserPriceInfoRequest) (*pb.FindUserPriceInfoResponse, error) {
|
|
||||||
return nil, this.NotImplementedYet()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateUserPriceType 修改用户计费方式
|
|
||||||
func (this *UserService) UpdateUserPriceType(ctx context.Context, req *pb.UpdateUserPriceTypeRequest) (*pb.RPCSuccess, error) {
|
|
||||||
return nil, this.NotImplementedYet()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateUserPricePeriod 修改用户计费周期
|
|
||||||
func (this *UserService) UpdateUserPricePeriod(ctx context.Context, req *pb.UpdateUserPricePeriodRequest) (*pb.RPCSuccess, error) {
|
|
||||||
return nil, this.NotImplementedYet()
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package services
|
package users
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||||
@@ -13,15 +14,15 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UserService 用户相关服务
|
// UserService 用户相关服务
|
||||||
type UserService struct {
|
type UserService struct {
|
||||||
BaseService
|
services.BaseService
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser 创建用户
|
// CreateUser 创建用户
|
||||||
@@ -40,59 +41,6 @@ func (this *UserService) CreateUser(ctx context.Context, req *pb.CreateUserReque
|
|||||||
return &pb.CreateUserResponse{UserId: userId}, nil
|
return &pb.CreateUserResponse{UserId: userId}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterUser 注册用户
|
|
||||||
func (this *UserService) RegisterUser(ctx context.Context, req *pb.RegisterUserRequest) (*pb.RPCSuccess, error) {
|
|
||||||
userId, err := this.ValidateUserNode(ctx, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if userId > 0 {
|
|
||||||
return nil, this.PermissionError()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册配置
|
|
||||||
configJSON, err := models.SharedSysSettingDAO.ReadSetting(nil, systemconfigs.SettingCodeUserRegisterConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(configJSON) == 0 {
|
|
||||||
return nil, errors.New("the registration has been disabled")
|
|
||||||
}
|
|
||||||
var config = userconfigs.DefaultUserRegisterConfig()
|
|
||||||
err = json.Unmarshal(configJSON, config)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !config.IsOn {
|
|
||||||
return nil, errors.New("the registration has been disabled")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
|
||||||
// 检查用户名
|
|
||||||
exists, err := models.SharedUserDAO.ExistUser(tx, 0, req.Username)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if exists {
|
|
||||||
return errors.New("the username exists already")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建用户
|
|
||||||
_, err = models.SharedUserDAO.CreateUser(tx, req.Username, req.Password, req.Fullname, req.Mobile, "", req.Email, "", req.Source, config.ClusterId, config.Features, req.Ip, !config.RequireVerification)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifyUser 审核用户
|
// VerifyUser 审核用户
|
||||||
func (this *UserService) VerifyUser(ctx context.Context, req *pb.VerifyUserRequest) (*pb.RPCSuccess, error) {
|
func (this *UserService) VerifyUser(ctx context.Context, req *pb.VerifyUserRequest) (*pb.RPCSuccess, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, err := this.ValidateAdmin(ctx)
|
||||||
@@ -300,6 +248,7 @@ func (this *UserService) FindEnabledUser(ctx context.Context, req *pb.FindEnable
|
|||||||
Mobile: user.Mobile,
|
Mobile: user.Mobile,
|
||||||
Tel: user.Tel,
|
Tel: user.Tel,
|
||||||
Email: user.Email,
|
Email: user.Email,
|
||||||
|
VerifiedEmail: user.VerifiedEmail,
|
||||||
Remark: user.Remark,
|
Remark: user.Remark,
|
||||||
IsOn: user.IsOn,
|
IsOn: user.IsOn,
|
||||||
CreatedAt: int64(user.CreatedAt),
|
CreatedAt: int64(user.CreatedAt),
|
||||||
@@ -360,6 +309,28 @@ func (this *UserService) LoginUser(ctx context.Context, req *pb.LoginUserRequest
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
// 邮箱登录
|
||||||
|
if strings.Contains(req.Username, "@") {
|
||||||
|
// 是否允许
|
||||||
|
registerConfig, err := models.SharedSysSettingDAO.ReadUserRegisterConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if registerConfig != nil && registerConfig.EmailVerification.CanLogin {
|
||||||
|
userId, err := models.SharedUserDAO.CheckUserEmailPassword(tx, req.Username, req.Password)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if userId > 0 {
|
||||||
|
return &pb.LoginUserResponse{
|
||||||
|
UserId: userId,
|
||||||
|
IsOk: true,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户名登录
|
||||||
userId, err := models.SharedUserDAO.CheckUserPassword(tx, req.Username, req.Password)
|
userId, err := models.SharedUserDAO.CheckUserPassword(tx, req.Username, req.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.PrintError(err)
|
utils.PrintError(err)
|
||||||
@@ -825,3 +796,25 @@ func (this *UserService) RenewUserServersState(ctx context.Context, req *pb.Rene
|
|||||||
IsEnabled: isEnabled,
|
IsEnabled: isEnabled,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckUserEmailIsUsing 检查邮箱是否被使用
|
||||||
|
func (this *UserService) CheckUserEmailIsUsing(ctx context.Context, req *pb.CheckUserEmailIsUsingRequest) (*pb.CheckUserEmailIsUsingResponse, error) {
|
||||||
|
userId, err := this.ValidateUserNode(ctx, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Email) == 0 {
|
||||||
|
return nil, errors.New("'email' required")
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
emailOwnerUserId, err := models.SharedUserDAO.FindUserIdWithVerifiedEmail(tx, req.Email)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if emailOwnerUserId > 0 && userId != emailOwnerUserId {
|
||||||
|
return &pb.CheckUserEmailIsUsingResponse{IsUsing: true}, nil
|
||||||
|
}
|
||||||
|
return &pb.CheckUserEmailIsUsingResponse{IsUsing: false}, nil
|
||||||
|
}
|
||||||
91
internal/rpc/services/users/service_user_ext.go
Normal file
91
internal/rpc/services/users/service_user_ext.go
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package users
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FindUserPriceInfo 读取用户计费信息
|
||||||
|
func (this *UserService) FindUserPriceInfo(ctx context.Context, req *pb.FindUserPriceInfoRequest) (*pb.FindUserPriceInfoResponse, error) {
|
||||||
|
return nil, this.NotImplementedYet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateUserPriceType 修改用户计费方式
|
||||||
|
func (this *UserService) UpdateUserPriceType(ctx context.Context, req *pb.UpdateUserPriceTypeRequest) (*pb.RPCSuccess, error) {
|
||||||
|
return nil, this.NotImplementedYet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateUserPricePeriod 修改用户计费周期
|
||||||
|
func (this *UserService) UpdateUserPricePeriod(ctx context.Context, req *pb.UpdateUserPricePeriodRequest) (*pb.RPCSuccess, error) {
|
||||||
|
return nil, this.NotImplementedYet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterUser 注册用户
|
||||||
|
func (this *UserService) RegisterUser(ctx context.Context, req *pb.RegisterUserRequest) (*pb.RegisterUserResponse, error) {
|
||||||
|
currentUserId, err := this.ValidateUserNode(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentUserId > 0 {
|
||||||
|
return nil, this.PermissionError()
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
// 检查邮箱是否已被使用
|
||||||
|
if len(req.Email) > 0 {
|
||||||
|
emailUserId, err := models.SharedUserDAO.FindUserIdWithVerifiedEmail(tx, req.Email)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if emailUserId > 0 {
|
||||||
|
return nil, errors.New("the email address '" + req.Email + "' is using by other user")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册配置
|
||||||
|
registerConfig, err := models.SharedSysSettingDAO.ReadUserRegisterConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if registerConfig == nil || !registerConfig.IsOn {
|
||||||
|
return nil, errors.New("the registration has been disabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
var requireEmailVerification = false
|
||||||
|
var createdUserId int64
|
||||||
|
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||||
|
// 检查用户名
|
||||||
|
exists, err := models.SharedUserDAO.ExistUser(tx, 0, req.Username)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if exists {
|
||||||
|
return errors.New("the username exists already")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建用户
|
||||||
|
userId, err := models.SharedUserDAO.CreateUser(tx, req.Username, req.Password, req.Fullname, req.Mobile, "", req.Email, "", req.Source, registerConfig.ClusterId, registerConfig.Features, req.Ip, !registerConfig.RequireVerification)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
createdUserId = userId
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &pb.RegisterUserResponse{
|
||||||
|
UserId: createdUserId,
|
||||||
|
RequireEmailVerification: requireEmailVerification,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -48,7 +48,7 @@ func (this *DNSTaskExecutor) Start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *DNSTaskExecutor) Loop() error {
|
func (this *DNSTaskExecutor) Loop() error {
|
||||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
if !this.IsPrimaryNode() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func (this *EventLooper) Start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *EventLooper) Loop() error {
|
func (this *EventLooper) Loop() error {
|
||||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
if !this.IsPrimaryNode() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func (this *HealthCheckClusterTask) Stop() {
|
|||||||
// Loop 单个循环任务
|
// Loop 单个循环任务
|
||||||
func (this *HealthCheckClusterTask) Loop() error {
|
func (this *HealthCheckClusterTask) Loop() error {
|
||||||
// 检查是否为主节点
|
// 检查是否为主节点
|
||||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
if !this.IsPrimaryNode() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func (this *LogTask) RunMonitor() {
|
|||||||
|
|
||||||
func (this *LogTask) LoopMonitor() error {
|
func (this *LogTask) LoopMonitor() error {
|
||||||
// 检查是否为主节点
|
// 检查是否为主节点
|
||||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
if !this.IsPrimaryNode() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func (this *NodeMonitorTask) Start() {
|
|||||||
|
|
||||||
func (this *NodeMonitorTask) Loop() error {
|
func (this *NodeMonitorTask) Loop() error {
|
||||||
// 检查是否为主节点
|
// 检查是否为主节点
|
||||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
if !this.IsPrimaryNode() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func (this *NodeTaskExtractor) Start() {
|
|||||||
|
|
||||||
func (this *NodeTaskExtractor) Loop() error {
|
func (this *NodeTaskExtractor) Loop() error {
|
||||||
// 检查是否为主节点
|
// 检查是否为主节点
|
||||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
if !this.IsPrimaryNode() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func (this *SSLCertExpireCheckExecutor) Start() {
|
|||||||
// Loop 单次执行
|
// Loop 单次执行
|
||||||
func (this *SSLCertExpireCheckExecutor) Loop() error {
|
func (this *SSLCertExpireCheckExecutor) Loop() error {
|
||||||
// 检查是否为主节点
|
// 检查是否为主节点
|
||||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
if !this.IsPrimaryNode() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ func (this *SSLCertUpdateOCSPTask) Start() {
|
|||||||
|
|
||||||
func (this *SSLCertUpdateOCSPTask) Loop() error {
|
func (this *SSLCertUpdateOCSPTask) Loop() error {
|
||||||
// 检查是否为主节点
|
// 检查是否为主节点
|
||||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
if !this.IsPrimaryNode() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
package tasks
|
package tasks
|
||||||
|
|
||||||
import "github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
|
)
|
||||||
|
|
||||||
type BaseTask struct {
|
type BaseTask struct {
|
||||||
}
|
}
|
||||||
@@ -10,3 +13,7 @@ type BaseTask struct {
|
|||||||
func (this *BaseTask) logErr(taskType string, errString string) {
|
func (this *BaseTask) logErr(taskType string, errString string) {
|
||||||
remotelogs.Error("TASK", "run '"+taskType+"' failed: "+errString)
|
remotelogs.Error("TASK", "run '"+taskType+"' failed: "+errString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *BaseTask) IsPrimaryNode() bool {
|
||||||
|
return models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr()
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user