You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudreve/service/user/register.go

140 lines
4.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package user
import (
"net/url"
"strings"
"time"
model "github.com/cloudreve/Cloudreve/v3/models"
"github.com/cloudreve/Cloudreve/v3/pkg/auth"
"github.com/cloudreve/Cloudreve/v3/pkg/email"
"github.com/cloudreve/Cloudreve/v3/pkg/hashid"
"github.com/cloudreve/Cloudreve/v3/pkg/recaptcha"
"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
"github.com/cloudreve/Cloudreve/v3/pkg/util"
"github.com/gin-gonic/gin"
"github.com/mojocn/base64Captcha"
)
// UserRegisterService 管理用户注册的服务
type UserRegisterService struct {
//TODO 细致调整验证规则
UserName string `form:"userName" json:"userName" binding:"required,email"`
Password string `form:"Password" json:"Password" binding:"required,min=4,max=64"`
CaptchaCode string `form:"captchaCode" json:"captchaCode"`
}
// Register 新用户注册
func (service *UserRegisterService) Register(c *gin.Context) serializer.Response {
// 相关设定
options := model.GetSettingByNames("email_active", "reg_captcha")
// 检查验证码
isCaptchaRequired := model.IsTrueVal(options["reg_captcha"])
useRecaptcha := model.IsTrueVal(model.GetSettingByName("captcha_IsUseReCaptcha"))
recaptchaSecret := model.GetSettingByName("captcha_ReCaptchaSecret")
if isCaptchaRequired && !useRecaptcha {
captchaID := util.GetSession(c, "captchaID")
util.DeleteSession(c, "captchaID")
if captchaID == nil || !base64Captcha.VerifyCaptcha(captchaID.(string), service.CaptchaCode) {
return serializer.ParamErr("验证码错误", nil)
}
} else if isCaptchaRequired && useRecaptcha {
captcha, err := recaptcha.NewReCAPTCHA(recaptchaSecret, recaptcha.V2, 10*time.Second)
if err != nil {
util.Log().Error(err.Error())
}
err = captcha.Verify(service.CaptchaCode)
if err != nil {
util.Log().Error(err.Error())
return serializer.ParamErr("验证失败,请刷新网页后再次验证", nil)
}
}
// 相关设定
isEmailRequired := model.IsTrueVal(options["email_active"])
defaultGroup := model.GetIntSetting("default_group", 2)
// 创建新的用户对象
user := model.NewUser()
user.Email = service.UserName
user.Nick = strings.Split(service.UserName, "@")[0]
user.SetPassword(service.Password)
user.Status = model.Active
if isEmailRequired {
user.Status = model.NotActivicated
}
user.GroupID = uint(defaultGroup)
userNotActivated := false
// 创建用户
if err := model.DB.Create(&user).Error; err != nil {
//检查已存在使用者是否尚未激活
expectedUser, err := model.GetUserByEmail(service.UserName)
if expectedUser.Status == model.NotActivicated {
userNotActivated = true
user = expectedUser
} else {
return serializer.DBErr("此邮箱已被使用", err)
}
}
// 发送激活邮件
if isEmailRequired {
// 签名激活请求API
base := model.GetSiteURL()
userID := hashid.HashID(user.ID, hashid.UserID)
controller, _ := url.Parse("/api/v3/user/activate/" + userID)
activateURL, err := auth.SignURI(auth.General, base.ResolveReference(controller).String(), 86400)
if err != nil {
return serializer.Err(serializer.CodeEncryptError, "无法签名激活URL", err)
}
// 取得签名
credential := activateURL.Query().Get("sign")
// 生成对用户访问的激活地址
controller, _ = url.Parse("/activate")
finalURL := base.ResolveReference(controller)
queries := finalURL.Query()
queries.Add("id", userID)
queries.Add("sign", credential)
finalURL.RawQuery = queries.Encode()
// 返送激活邮件
title, body := email.NewActivationEmail(user.Email,
finalURL.String(),
)
if err := email.Send(user.Email, title, body); err != nil {
return serializer.Err(serializer.CodeInternalSetting, "无法发送激活邮件", err)
}
if userNotActivated == true {
//原本在上面要抛出的DBErr放来这边抛出
return serializer.DBErr("用户未激活,已重新发送激活邮件", nil)
} else {
return serializer.Response{Code: 203}
}
}
return serializer.Response{}
}
// Activate 激活用户
func (service *SettingService) Activate(c *gin.Context) serializer.Response {
// 查找待激活用户
uid, _ := c.Get("object_id")
user, err := model.GetUserByID(uid.(uint))
if err != nil {
return serializer.Err(serializer.CodeNotFound, "用户不存在", err)
}
// 检查状态
if user.Status != model.NotActivicated {
return serializer.Err(serializer.CodeNoPermissionErr, "该用户无法被激活", nil)
}
// 激活用户
user.SetStatus(model.Active)
return serializer.Response{Data: user.Email}
}