diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index b8783c44e..70e5b603b 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -1,8 +1,6 @@ class AccountsController < ApplicationController include ApplicationHelper - #skip_before_action :check_account, :only => [:logout] - def index render json: session end @@ -139,15 +137,17 @@ class AccountsController < ApplicationController tip_exception(-1, interactor.error) end rescue Register::BaseForm::EmailError => e - render_error(-2, e.message) + render_result(-2, e.message) rescue Register::BaseForm::LoginError => e - render_error(-3, e.message) + render_result(-3, e.message) rescue Register::BaseForm::PhoneError => e - render_error(-4, e.message) + render_result(-4, e.message) rescue Register::BaseForm::PasswordFormatError => e - render_error(-5, e.message) + render_result(-5, e.message) + rescue Register::BaseForm::PasswordConfirmationError => e + render_result(-7, e.message) rescue Register::BaseForm::VerifiCodeError => e - render_error(-6, e.message) + render_result(-6, e.message) rescue Exception => e Gitea::User::DeleteService.call(user.login) unless user.nil? uid_logger_error(e.message) @@ -157,7 +157,7 @@ class AccountsController < ApplicationController # 用户登录 def login - Users::LoginForm.new(account_params).validate! + Users::LoginForm.new(login_params).validate! @user = User.try_to_login(params[:login], params[:password]) return normal_status(-2, "错误的账号或密码") if @user.blank? @@ -206,28 +206,27 @@ class AccountsController < ApplicationController # 忘记密码 def reset_password begin - code = params[:code] - login_type = phone_mail_type(params[:login].strip) - # 获取验证码 - if login_type == 1 - phone = params[:login] - verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 2).last - user = User.find_by_phone(phone) - else - email = params[:login] - verifi_code = VerificationCode.where(email: email, code: code, code_type: 3).last - user = User.find_by_mail(email) #这里有问题,应该是为email,而不是mail 6.13-hs - end - return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip - return normal_status(-2, "验证码已失效") if !verifi_code&.effective? - return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:new_password] =~ CustomRegexp::PASSWORD + Accounts::ResetPasswordForm.new(reset_password_params).validate! - user.password, user.password_confirmation = params[:new_password], params[:new_password_confirmation] - ActiveRecord::Base.transaction do - user.save! - LimitForbidControl::UserLogin.new(user).clear - end - sucess_status + user = find_user + return render_error('未找到相关账号') if user.blank? + + user = Accounts::ResetPasswordService.call(user, reset_password_params) + LimitForbidControl::UserLogin.new(user).clear if user.save! + + render_ok + rescue Register::BaseForm::EmailError => e + render_result(-2, e.message) + rescue Register::BaseForm::PhoneError => e + render_result(-4, e.message) + rescue Register::BaseForm::PasswordFormatError => e + render_result(-5, e.message) + rescue Register::BaseForm::PasswordConfirmationError => e + render_result(-7, e.message) + rescue Register::BaseForm::VerifiCodeError => e + render_result(-6, e.message) + rescue ActiveRecord::Rollback => e + render_result(-1, "服务器异常") rescue Exception => e uid_logger_error(e.message) tip_exception(e.message) @@ -356,7 +355,7 @@ class AccountsController < ApplicationController params.require(:user).permit(:login, :email, :phone) end - def account_params + def login_params params.require(:account).permit(:login, :password) end @@ -365,7 +364,16 @@ class AccountsController < ApplicationController end def register_params - params.permit(:login, :namespace, :password, :code) + params.permit(:login, :namespace, :password, :password_confirmation, :code) + end + + def reset_password_params + params.permit(:login, :password, :password_confirmation, :code) + end + + def find_user + phone_or_mail = strip(reset_password_params[:login]) + User.where("phone = :search OR mail = :search", search: phone_or_mail).last end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 70ccd69d0..643a3e6ab 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -26,7 +26,8 @@ class ApplicationController < ActionController::Base end DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z) - OPENKEY = "79e33abd4b6588941ab7622aed1e67e8" + OPENKEY = Rails.application.config_for(:configuration)['sign_key'] || "79e33abd4b6588941ab7622aed1e67e8" + helper_method :current_user, :base_url @@ -335,11 +336,6 @@ class ApplicationController < ActionController::Base @message = message end - # 实训等对应的仓库地址 - def repo_ip_url(repo_path) - "#{edu_setting('git_address_ip')}/#{repo_path}" - end - def repo_url(repo_path) "#{edu_setting('git_address_domain')}/#{repo_path}" end @@ -741,37 +737,10 @@ class ApplicationController < ActionController::Base render json: exception.tip_json end - def render_parameter_missing - render json: { status: -1, message: '参数缺失' } - end - def set_export_cookies cookies[:fileDownload] = true end - # 149课程的评审用户数据创建(包含创建课堂学生) - def open_class_user - user = User.find_by(login: "OpenClassUser") - unless user - ActiveRecord::Base.transaction do - user_params = {status: 1, login: "OpenClassUser", lastname: "开放课程", - nickname: "开放课程", professional_certification: 1, certification: 1, grade: 0, - password: "12345678", phone: "11122223333", profile_completed: 1} - user = User.create!(user_params) - - UserExtension.create!(user_id: user.id, gender: 0, school_id: 3396, :identity => 1, :student_id => "openclassuser") # 3396 - - subject = Subject.find_by(id: 149) - if subject - subject.courses.each do |course| - CourseMember.create!(course_id: course.id, role: 3, user_id: user.id) if !course.course_members.exists?(user_id: user.id) - end - end - end - end - user - end - # 记录热门搜索关键字 def record_search_keyword keyword = params[:keyword].to_s.strip diff --git a/app/controllers/concerns/render_helper.rb b/app/controllers/concerns/render_helper.rb index 81e85d1ce..b54ac90ce 100644 --- a/app/controllers/concerns/render_helper.rb +++ b/app/controllers/concerns/render_helper.rb @@ -3,8 +3,8 @@ module RenderHelper render json: { status: 0, message: 'success' }.merge(data) end - def render_error(status = -1, message = '') - render json: { status: status, message: message } + def render_error(message = '') + render json: { status: -1, message: message } end def render_not_acceptable(message = '请求已拒绝') @@ -28,4 +28,8 @@ module RenderHelper def render_result(status=1, message='success') render json: { status: status, message: message } end + + def render_parameter_missing + render json: { status: -1, message: '参数缺失' } + end end diff --git a/app/forms/accounts/reset_password_form.rb b/app/forms/accounts/reset_password_form.rb new file mode 100644 index 000000000..a451d13c2 --- /dev/null +++ b/app/forms/accounts/reset_password_form.rb @@ -0,0 +1,41 @@ +module Accounts + class ResetPasswordForm < ::BaseForm + # login 邮箱、手机号 + # code 验证码 + # type: 1:手机号注册;2:邮箱注册 + attr_accessor :login, :password, :password_confirmation, :code + + validates :login, :code, :password, :password_confirmation, presence: true, allow_blank: false + validate :check! + + def check! + Rails.logger.info "ResetPasswordForm params: code: #{code} login: #{login} + password: #{password} password_confirmation: #{password_confirmation}" + + type = phone_mail_type(login) + + db_verifi_code = + if type == 1 + check_phone_format(login) + VerificationCode.where(phone: login, code: code, code_type: 2).last + elsif type == 0 + check_email_format(login) + VerificationCode.where(email: login, code: code, code_type: 3).last + end + + check_password(password) + check_password_confirmation(password, password_confirmation) + check_verifi_code(db_verifi_code, code) + end + + def check_phone_format(phone) + phone = strip(phone) + raise LoginError, "登录名格式有误" unless phone =~ CustomRegexp::LOGIN + end + + def check_email_format(mail) + mail = strip(mail) + raise EmailError, "邮件格式有误" unless mail =~ CustomRegexp::EMAIL + end + end +end diff --git a/app/forms/base_form.rb b/app/forms/base_form.rb index 437217f00..46eaa9b58 100644 --- a/app/forms/base_form.rb +++ b/app/forms/base_form.rb @@ -1,6 +1,14 @@ class 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) + PasswordConfirmationError = Class.new(Error) + def check_project_category(project_category_id) unless project_category_id == '' raise "project_category_id参数值无效." if project_category_id && !ProjectCategory.exists?(project_category_id) @@ -26,8 +34,35 @@ class BaseForm raise "项目标识已被占用." if ReversedKeyword.check_exists?(repository_name) end + def check_password(password) + password = strip(password) + raise PasswordFormatError, "密码8~16位密码,支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD + end + + def check_password_confirmation(password, password_confirmation) + password = strip(password) + password_confirmation = strip(password_confirmation) + + raise PasswordFormatError, "确认密码为8~16位密码,支持字母数字和符号" unless password_confirmation =~ CustomRegexp::PASSWORD + raise PasswordConfirmationError, "两次输入的密码不一致" unless password == password_confirmation + 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 + private def strip(str) str.to_s.strip.presence end + + # 1 手机类型;0 邮箱类型 + # 注意新版的login是自动名生成的 + def phone_mail_type value + value =~ /^1\d{10}$/ ? 1 : 0 + end end diff --git a/app/forms/register/base_form.rb b/app/forms/register/base_form.rb index df5abd871..150fef73a 100644 --- a/app/forms/register/base_form.rb +++ b/app/forms/register/base_form.rb @@ -2,13 +2,6 @@ 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) @@ -33,19 +26,5 @@ module Register 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 diff --git a/app/forms/register/form.rb b/app/forms/register/form.rb index bad7a23e6..6800fa1de 100644 --- a/app/forms/register/form.rb +++ b/app/forms/register/form.rb @@ -3,13 +3,16 @@ module Register # login 登陆方式,支持邮箱、登陆、手机号等 # namespace 用户空间地址 # type: 1:手机号注册;2:邮箱注册 - attr_accessor :login, :namespace, :password, :code, :type + attr_accessor :login, :namespace, :password, :password_confirmation, :code, :type - validates :login, :code, :password, :namespace, presence: true + validates :login, :code, :password, :password_confirmation, :namespace, presence: true, allow_blank: false validate :check! def check! - Rails.logger.info "Register::Form params: code: #{code}; login: #{login}; namespace: #{namespace}; password: #{password}; type: #{type}" + Rails.logger.info "Register::Form params: code: #{code}; login: #{login}; + namespace: #{namespace}; password: #{password}; password_confirmation: #{password_confirmation}" + + type = phone_mail_type(strip(login)) db_verifi_code = if type == 1 check_phone(login) @@ -22,6 +25,7 @@ module Register check_login(namespace) check_verifi_code(db_verifi_code, code) check_password(password) + check_password_confirmation(password, password_confirmation) end end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index f58436285..c63fb8443 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -469,5 +469,9 @@ module ApplicationHelper def phone_mail_type value value =~ /^1\d{10}$/ ? 1 : 0 end + + def strip(str) + str.to_s.strip.presence + end end diff --git a/app/services/accounts/reset_password_service.rb b/app/services/accounts/reset_password_service.rb new file mode 100644 index 000000000..5202fe77a --- /dev/null +++ b/app/services/accounts/reset_password_service.rb @@ -0,0 +1,30 @@ +module Accounts + class ResetPasswordService < ApplicationService + # login、code、password、password_confirmation + def initialize(user, params) + @user = user + @password = params[:password] + @password_confirmation = params[:password_confirmation] + end + + def call + return if @user.blank? + password = strip(@password) + password_confirmation = strip(@password_confirmation) + + Rails.logger.info "Accounts::ResetPasswordService params: + ##### password: #{@password} password_confirmation: #{@password_confirmation}" + + @user.password, @user.password_confirmation = password, password_confirmation + + sync_params = { + password: password, + email: @user.mail + } + interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params) + raise ActiveRecord::Rollback unless interactor.success? + + @user + end + end +end diff --git a/app/services/application_service.rb b/app/services/application_service.rb index 2fa59ed29..81ecf5f7b 100644 --- a/app/services/application_service.rb +++ b/app/services/application_service.rb @@ -18,4 +18,9 @@ class ApplicationService def str_to_boolean str ActiveModel::Type::Boolean.new.cast str end + + def phone_mail_type value + value =~ /^1\d{10}$/ ? 1 : 0 + end + end diff --git a/app/services/users/register_service.rb b/app/services/users/register_service.rb index bb3b3ada1..fc0e4231e 100644 --- a/app/services/users/register_service.rb +++ b/app/services/users/register_service.rb @@ -12,7 +12,8 @@ class Users::RegisterService < ApplicationService namespace = strip(@namespace) password = strip(@password) - Rails.logger.info "Users::RegisterService params: ##### #{params} " + Rails.logger.info "Users::RegisterService params: + ##### code: #{code} login: #{login} namespace: #{namespace} password: #{password} " email, phone = if register_type == 1 @@ -50,9 +51,4 @@ class Users::RegisterService < ApplicationService def register_type phone_mail_type(@login) end - - def phone_mail_type value - value =~ /^1\d{10}$/ ? 1 : 0 - end - end diff --git a/config/configuration.yml.example b/config/configuration.yml.example index 77da3ebe4..a1fb37c87 100644 --- a/config/configuration.yml.example +++ b/config/configuration.yml.example @@ -2,7 +2,7 @@ default: &default # 用户登入的时候设置/登出的时候清空 autologin_cookie_name: 'autologin_trustie' platform_url: 'http://localhost:3000' - + sign_key: '' #附件上传路径 attachment_folder: '/tmp'