FIX 调整注册接口

This commit is contained in:
jasder 2021-11-02 13:39:45 +08:00
parent 6c67b92bb1
commit 1008f17849
11 changed files with 269 additions and 89 deletions

View File

@ -51,6 +51,51 @@ http://localhost:3000/api/accounts/remote_register | jq
|-- token |string|用户token|
返回值
```json
{
"status": 0,
"message": "success",
"user": {
"id": 36400,
"token": "8c87a80d9cfacc92fcb2451845104f35119eda96"
}
}
```
---
#### 独立注册接口
```
POST accounts/register
```
*示例*
```bash
curl -X POST \
-d "login=2456233122@qq.com" \
-d "password=djs_D_00001" \
-d "namespace=16895620" \
-d "code=forge" \
http://localhost:3000/api/accounts/remote_register | jq
```
*请求参数说明:*
|参数名|必选|类型|说明|
|-|-|-|-|
|login |是|string |邮箱或者手机号 |
|namespace |是|string |登录名 |
|password |是|string |密码 |
|code |是|string |验证码 |
*返回参数说明:*
|参数名|类型|说明|
|-|-|-|
|user|json object |返回数据|
|-- id |int |用户id |
|-- token |string|用户token|
返回值
```json
{

View File

@ -1,4 +1,5 @@
class AccountsController < ApplicationController
include ApplicationHelper
#skip_before_action :check_account, :only => [:logout]
@ -109,60 +110,46 @@ class AccountsController < ApplicationController
# 用户注册
# 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用
# params[:login] 邮箱或者手机号
# params[:namespace] 登录名
# params[:code] 验证码
# code_type 1注册手机验证码 8邮箱注册验证码
# 本地forge注册入口
# 本地forge注册入口需要重新更改逻辑
def register
# type只可能是1或者8
user = nil
begin
# 查询验证码是否正确;type只可能是1或者8
type = phone_mail_type(params[:login].strip)
# code = params[:code].strip
Register::Form.new(register_params).validate!
if type == 1
uid_logger("start register by phone: type is #{type}")
pre = 'p'
email = nil
phone = params[:login]
# verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 1).last
# TODO: 暂时限定邮箱注册
return normal_status(-1, '只支持邮箱注册')
else
uid_logger("start register by email: type is #{type}")
pre = 'm'
email = params[:login]
phone = nil
return normal_status(-1, "该邮箱已注册") if User.exists?(mail: params[:login])
return normal_status(-1, "邮箱格式错误") unless params[:login] =~ CustomRegexp::EMAIL
# verifi_code = VerificationCode.where(email: email, code: code, code_type: 8).last
end
# uid_logger("start register: verifi_code is #{verifi_code}, code is #{code}, time is #{Time.now.to_i - verifi_code.try(:created_at).to_i}")
# check_code = (verifi_code.try(:code) == code.strip && (Time.now.to_i - verifi_code.created_at.to_i) <= 10*60)
# todo 上线前请删除万能验证码"513231"
return normal_status(-1, "8~16位密码支持字母数字和符号") unless params[:password] =~ CustomRegexp::PASSWORD
user = Users::RegisterService.call(register_params)
password = register_params[:password].strip
code = generate_identifier User, 8, pre
login = pre + code
@user = User.new(admin: false, login: login, mail: email, phone: phone, type: "User")
@user.password = params[:password]
# 现在因为是验证码,所以在注册的时候就可以激活
@user.activate
# 必须要用save操作密码的保存是在users中
interactor = Gitea::RegisterInteractor.call({username: login, email: email, password: params[:password]})
# gitea用户注册, email, username, password
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password})
if interactor.success?
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.new(login, params[:password]).call
@user.gitea_token = result['sha1']
@user.gitea_uid = gitea_user[:body]['id']
if @user.save!
UserExtension.create!(user_id: @user.id)
successful_authentication(@user)
normal_status("注册成功")
result = Gitea::User::GenerateTokenService.call(user.login, password)
user.gitea_token = result['sha1']
user.gitea_uid = gitea_user[:body]['id']
if user.save!
UserExtension.create!(user_id: user.id)
successful_authentication(user)
render_ok
end
else
tip_exception(-1, interactor.error)
end
rescue Register::BaseForm::EmailError => e
render_error(-2, e.message)
rescue Register::BaseForm::LoginError => e
render_error(-3, e.message)
rescue Register::BaseForm::PhoneError => e
render_error(-4, e.message)
rescue Register::BaseForm::PasswordFormatError => e
render_error(-5, e.message)
rescue Register::BaseForm::VerifiCodeError => e
render_error(-6, e.message)
rescue Exception => e
Gitea::User::DeleteService.call(user.login) unless user.nil?
uid_logger_error(e.message)
tip_exception(-1, e.message)
end
@ -297,7 +284,7 @@ class AccountsController < ApplicationController
# 发送验证码
# params[:login] 手机号或者邮箱号
# params[:type]为事件通知类型 1用户注册注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
# params[:type]为事件通知类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
# 发送验证码send_type 1注册手机验证码 2找回密码手机验证码 3找回密码邮箱验证码 4绑定手机 5绑定邮箱
# 6手机验证码登录 7邮箱验证码登录 8邮箱注册验证码 9: 验收手机号有效
def get_verification_code
@ -311,19 +298,14 @@ class AccountsController < ApplicationController
sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}")
tip_exception(501, "请求不合理") if sign != params[:smscode]
logger.info "########### 验证码:#{verification_code}"
logger.info("########get_verification_code: login_type #{login_type} send_type#{send_type}, ")
# 记录验证码
check_verification_code(verification_code, send_type, value)
sucess_status
render_ok
end
# 1 手机类型0 邮箱类型
# 注意新版的login是自动名生成的
def phone_mail_type value
value =~ /^1\d{10}$/ ? 1 : 0
end
# check user's login or email or phone is used
# params[:value] 手机号或者邮箱号或者登录名
# params[:type] 为事件类型 1登录名(login) 2email(邮箱) 3phone(手机号)
@ -381,4 +363,9 @@ class AccountsController < ApplicationController
def check_params
params.permit(:type, :value)
end
def register_params
params.permit(:login, :namespace, :password, :code)
end
end

View File

@ -3,8 +3,8 @@ module RenderHelper
render json: { status: 0, message: 'success' }.merge(data)
end
def render_error(message = '')
render json: { status: -1, message: message }
def render_error(status = -1, message = '')
render json: { status: status, message: message }
end
def render_not_acceptable(message = '请求已拒绝')

View File

@ -25,5 +25,9 @@ class BaseForm
def check_reversed_keyword(repository_name)
raise "项目标识已被占用." if ReversedKeyword.check_exists?(repository_name)
end
private
def strip(str)
str.to_s.strip.presence
end
end

View File

@ -0,0 +1,51 @@
module Register
class BaseForm < ::BaseForm
include ActiveModel::Model
Error = Class.new(StandardError)
EmailError = Class.new(Error)
LoginError = Class.new(Error)
PhoneError = Class.new(Error)
PasswordFormatError = Class.new(Error)
VerifiCodeError = Class.new(Error)
private
def check_login(login)
login = strip(login)
raise LoginError, "登录名格式有误" unless login =~ CustomRegexp::LOGIN
login_exist = Owner.exists?(login: login) || ReversedKeyword.check_exists?(login)
raise LoginError, '登录名已被使用' if login_exist
end
def check_mail(mail)
mail = strip(mail)
raise EmailError, "邮件格式有误" unless mail =~ CustomRegexp::EMAIL
mail_exist = Owner.exists?(mail: mail)
raise EmailError, '邮箱已被使用' if mail_exist
end
def check_phone(phone)
phone = strip(phone)
raise PhoneError, "手机号格式有误" unless phone =~ CustomRegexp::PHONE
phone_exist = Owner.exists?(phone: phone)
raise PhoneError, '手机号已被使用' if phone_exist
end
def check_password(password)
password = strip(password)
raise PasswordFormatError, "8~16位密码支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD
end
def check_verifi_code(verifi_code, code)
code = strip(code)
# return if code == "123123" # TODO 万能验证码,用于测试
raise VerifiCodeError, "验证码不正确" if verifi_code&.code != code
raise VerifiCodeError, "验证码已失效" if !verifi_code&.effective?
end
end
end

View File

@ -1,5 +1,5 @@
module Register
class CheckColumnsForm < BaseForm
class CheckColumnsForm < Register::BaseForm
attr_accessor :type, :value
validates :type, presence: true, numericality: true
@ -8,42 +8,12 @@ module Register
def check!
# params[:type] 为事件类型 1登录名(login) 2email(邮箱) 3phone(手机号)
case strip_type
when 1 then check_login
when 2 then check_mail
when 3 then check_phone
case strip(type).to_i
when 1 then check_login(strip(value))
when 2 then check_mail(strip(value))
when 3 then check_phone(strip(value))
else raise("type值无效")
end
end
private
def check_login
raise("登录名格式有误") unless strip_value =~ CustomRegexp::LOGIN
login_exist = Owner.exists?(login: strip_value) || ReversedKeyword.check_exists?(strip_value)
raise('登录名已被使用') if login_exist
end
def check_mail
raise("邮件格式有误") unless strip_value =~ CustomRegexp::EMAIL
mail_exist = Owner.exists?(mail: strip_value)
raise('邮箱已被使用') if mail_exist
end
def check_phone
raise("手机号格式有误") unless strip_value =~ CustomRegexp::PHONE
phone_exist = Owner.exists?(phone: strip_value)
raise('手机号已被使用') if phone_exist
end
def strip_value
value&.strip
end
def strip_type
type&.strip.to_i
end
end
end

View File

@ -0,0 +1,27 @@
module Register
class Form < Register::BaseForm
# login 登陆方式,支持邮箱、登陆、手机号等
# namespace 用户空间地址
# type: 1手机号注册2邮箱注册
attr_accessor :login, :namespace, :password, :code, :type
validates :login, :code, :password, :namespace, presence: true
validate :check!
def check!
Rails.logger.info "Register::Form params: code: #{code}; login: #{login}; namespace: #{namespace}; password: #{password}; type: #{type}"
db_verifi_code =
if type == 1
check_phone(login)
VerificationCode.where(phone: login, code: code, code_type: 1).last
elsif type == 0
check_mail(login)
VerificationCode.where(email: login, code: code, code_type: 8).last
end
check_login(namespace)
check_verifi_code(db_verifi_code, code)
check_password(password)
end
end
end

View File

@ -455,5 +455,11 @@ module ApplicationHelper
sidebar_item(url, "数据统计", icon: 'bar-chart', controller: 'root')
end
end
# 1 手机类型0 邮箱类型
# 注意新版的login是自动名生成的
def phone_mail_type value
value =~ /^1\d{10}$/ ? 1 : 0
end
end

View File

@ -1,10 +1,11 @@
class UserMailer < ApplicationMailer
# 注意:这个地方一定要和你的邮箱服务域名一致
default from: 'notification@gitlink.org.cn'
default from: 'notification@trustie.org'
# 用户注册验证码
def register_email(mail, code)
@code = code
mail(to: mail, subject: 'GitLink | 注册确实开源邮箱验证')
mail(to: mail, subject: 'Gitink | 注册验证')
end
end

View File

@ -0,0 +1,31 @@
class Gitea::User::DeleteService < Gitea::ClientService
attr_reader :username
def initialize(username)
@username = username
end
def call
response = delete(request_url, params)
render_status(response)
end
private
def token
{
username: Gitea.gitea_config[:access_key_id],
password: Gitea.gitea_config[:access_key_secret]
}
end
def request_url
"/admin/users/#{username}"
end
def params
Hash.new.merge(token: token)
end
end

View File

@ -0,0 +1,58 @@
class Users::RegisterService < ApplicationService
def initialize(params)
@login = params[:login]
@namespace = params[:namespace]
@password = params[:password]
@code = params[:code]
end
def call
code = strip(@code)
login = strip(@login)
namespace = strip(@namespace)
password = strip(@password)
Rails.logger.info "Users::RegisterService params: ##### #{params} "
email, phone =
if register_type == 1
phone_register(login, code)
elsif register_type == 0
mail_register(login, code)
end
user = User.new(admin: false, login: namespace, mail: email, phone: phone, type: "User")
user.password = password
user.activate # 现在因为是验证码,所以在注册的时候就可以激活
user
end
private
# 手机注册
def phone_register(login, code)
Rails.logger.info("start register by phone: phone is #{login}")
email = nil
phone = login
[email, phone]
end
# 邮箱注册
def mail_register(login, code)
Rails.logger.info("start register by email: email is #{login}")
email = login
phone = nil
[email, phone]
end
def register_type
phone_mail_type(@login)
end
def phone_mail_type value
value =~ /^1\d{10}$/ ? 1 : 0
end
end