|
- class AccountsController < ApplicationController
- before_action :require_login, only: [:login_check, :simple_update]
- include ApplicationHelper
-
- #skip_before_action :check_account, :only => [:logout]
-
- def simple_update
- simple_update_params.merge!(username: params[:username]&.gsub(/\s+/, ""))
- simple_update_params.merge!(email: params[:email]&.gsub(/\s+/, ""))
- simple_update_params.merge!(platform: (params[:platform] || 'forge')&.gsub(/\s+/, ""))
- Register::RemoteForm.new(simple_update_params).validate!
-
- ActiveRecord::Base.transaction do
- result = auto_update(current_user, simple_update_params)
- if result[:message].blank?
- render_ok
- else
- render_error(result[:message])
- end
- end
- end
-
- def index
- render json: session
- end
-
- # 其他平台同步注册的用户
- def remote_register
- Register::RemoteForm.new(remote_register_params).validate!
- username = params[:username]&.gsub(/\s+/, "")
- tip_exception("无法使用以下关键词:#{username},请重新命名!") if ReversedKeyword.check_exists?(username)
- email = params[:email]&.gsub(/\s+/, "")
- password = params[:password]
- platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
-
- ActiveRecord::Base.transaction do
- result = autologin_register(username, email, password, platform)
- if result[:message].blank?
- render_ok({user: result[:user]})
- else
- render_error(result[:message])
- end
- end
- rescue Exception => e
- uid_logger_error(e.message)
- tip_exception(-1, e.message)
- end
-
- # 其他平台修改用户的信息,这边同步修改
- def remote_update
- ActiveRecord::Base.transaction do
- user_params = params[:user_params]
- user_extension_params = params[:user_extension_params]
-
- u = User.find_by(login: params[:old_user_login])
- user_mail = u.try(:mail)
-
- if u.present?
- ue = u.user_extension
- u.login = user_params["login"] if user_params["login"]
- u.mail = user_params["mail"] if user_params["mail"]
- u.lastname = user_params["lastname"] if user_params["lastname"]
-
- ue.gender = user_extension_params["gender"]
- ue.school_id = user_extension_params["school_id"]
- ue.location = user_extension_params["location"]
- ue.location_city = user_extension_params["location_city"]
- ue.identity = user_extension_params["identity"]
- ue.technical_title = user_extension_params["technical_title"]
- ue.student_id = user_extension_params["student_id"]
- ue.description = user_extension_params["description"]
- ue.save!
- u.save!
-
- sync_params = {}
-
- if (user_params["mail"] && user_params["mail"] != user_mail)
- sync_params = sync_params.merge(email: user_params["mail"])
- end
-
- if sync_params.present?
- interactor = Gitea::User::UpdateInteractor.call(u.login, sync_params)
- if interactor.success?
- render_ok
- else
- render_error(interactor.error)
- end
- end
- end
- end
- rescue Exception => e
- uid_logger_error(e.message)
- tip_exception(-1, e.message)
- end
-
- # 其他平台同步登录
- def remote_login
- @user = User.try_to_login(params[:login], params[:password])
- if @user
- successful_authentication(@user)
- render_ok({user: {id: @user.id, token: @user.gitea_token}})
- else
- render_error("用户不存在")
- end
- end
-
- #修改密码
- def remote_password
- @user = User.find_by(login: params[:login])
- return render_error("未找到相关用户!") if @user.blank?
-
- sync_params = {
- password: params[:password].to_s,
- email: @user.mail,
- login_name: @user.login,
- source_id: 0
- }
-
- interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
- if interactor.success?
- @user.update_attribute(:password, params[:password])
- render_ok
- else
- render_error(interactor.error)
- end
- end
-
-
-
- # 用户注册
- # 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用
- # params[:login] 邮箱或者手机号
- # params[:namespace] 登录名
- # params[:code] 验证码
- # code_type 1:注册手机验证码 8:邮箱注册验证码
- # 本地forge注册入口需要重新更改逻辑
- def register
- # type只可能是1或者8
- user = nil
- begin
- Register::Form.new(register_params).validate!
-
- user = Users::RegisterService.call(register_params)
- user.mail = "#{user.login}@example.org" if user.mail.blank?
- password = register_params[:password].strip
-
- # 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.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)
- # 绑定授权账号
- if ["qq", "wechat", "gitee", "github", "educoder"].include?(params[:type].to_s) && session[:unionid].present?
- "OpenUsers::#{params[:type].to_s.capitalize}".constantize.create!(user: user, uid: session[:unionid])
- end
- successful_authentication(user)
- render_ok
- end
- else
- tip_exception(-1, interactor.error)
- end
- rescue Register::BaseForm::EmailError => e
- render_result(-2, e.message)
- rescue Register::BaseForm::LoginError => e
- render_result(-3, 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 Exception => e
- Gitea::User::DeleteService.call(user.login) unless user.nil?
- uid_logger_error(e.message)
- tip_exception(-1, e.message)
- end
- end
-
-
-
-
- # 用户登录
- def login_old
- Rails.logger.info("####login_s:#{login_params}")
- Users::LoginForm.new(login_params).validate!
- @user = User.try_to_login(params[:login], params[:password])
-
-
-
- return normal_status(-2, "错误的账号或密码") if @user.blank?
- # user is already in local database
- return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked?
-
- login_control = LimitForbidControl::UserLogin.new(@user)
- return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
-
- password_ok = @user.check_password?(params[:password].to_s)
- unless password_ok
- if login_control.remain_times-1 == 0
- normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
- else
- normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会")
- end
- # login_control.increment!
- return
- end
-
- LimitForbidControl::UserLogin.new(@user).clear
- successful_authentication(@user)
- sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
-
- # session[:user_id] = @user.id
- end
-
- # 用户登录
- def login
- Rails.logger.info("####login_s:#{login_params}")
- Users::LoginForm.new(login_params).validate!
- @user = User.try_to_login(params[:login], params[:password])
- #未查找到对应用户,则转实验室内部,获取access_token
- if @user.blank?
- get_zhejianglab_userinfo(login_params)
- end
- @user = User.try_to_login(params[:login], params[:password])
-
- return normal_status(-2, "错误的账号或密码") if @user.blank?
- # user is already in local database
- return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked?
-
- login_control = LimitForbidControl::UserLogin.new(@user)
- return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
-
- password_ok = @user.check_password?(params[:password].to_s)
- unless password_ok
- if login_control.remain_times-1 == 0
- normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
- else
- normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会")
- end
- login_control.increment!
- return
- end
-
- LimitForbidControl::UserLogin.new(@user).clear
- successful_authentication(@user)
- sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
-
- # session[:user_id] = @user.id
- end
-
- # 用户登录(sso)
- def login_sso
- Rails.logger.info("####login_params:#{login_params}")
- Users::LoginForm.new(login_params).validate!
- @user = User.try_to_login(params[:login], params[:password])
-
- return normal_status(-2, "错误的账号或密码") if @user.blank?
- # user is already in local database
- return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked?
-
- login_control = LimitForbidControl::UserLogin.new(@user)
- return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
-
- password_ok = @user.check_password?(params[:password].to_s)
- unless password_ok
- if login_control.remain_times-1 == 0
- normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
- else
- normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会")
- end
- #login_control.increment!
- return
- end
-
- LimitForbidControl::UserLogin.new(@user).clear
- successful_authentication(@user)
- sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
-
- # session[:user_id] = @user.id
- end
-
- def change_password
- @user = User.find_by(login: params[:login])
- return render_error("此用户禁止修改密码!") if @user.id.to_i === 104691
- return render_error("未找到相关用户!") if @user.blank?
- return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])
-
- sync_params = {
- password: params[:password].to_s,
- email: @user.mail,
- login_name: @user.name,
- source_id: 0
- }
-
- interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
- if interactor.success?
- @user.update_attribute(:password, params[:password])
- render_ok
- else
- render_error(interactor.error)
- end
- end
-
- # 忘记密码
- def reset_password
- begin
- Accounts::ResetPasswordForm.new(reset_password_params).validate!
-
- 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)
- end
- end
-
- def successful_authentication(user)
- uid_logger("Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}")
- # Valid user
- self.logged_user = user
- # generate a key and set cookie if autologin
-
- set_autologin_cookie(user)
- UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip)
- user.update_column(:last_login_on, Time.now)
- session[:"#{default_yun_session}"] = user.id
- Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}")
- # 注册完成后有一天的试用申请(先去掉)
- # UserDayCertification.create(user_id: user.id, status: 1)
- end
-
- def get_zhejianglab_userinfo(login_params)
- Rails.logger.info("############get_zhejianglab_userinfo----#{login_params}")
- # 分离 URL、用户名和密码
- url = 'https://onekey.zhejianglab.com/maxkey/oauth/v20/token'
- # username = '001786'
- # password = 'WYH!0218!wyh'
- username = login_params['login']
- password = login_params['password']
- clientid = 'ff2ca7d0-d7dc-4a04-bf22-22765d7f29b1'
- clientsecret = 'sVOwMTIxMDIwMjMxNzMyMjA1OTECkR'
-
- # 创建 Faraday 连接
- connection = Faraday.new(url) do |conn|
- conn.request :url_encoded
- conn.adapter Faraday.default_adapter
- end
-
- # 构建请求数据
- request_data = {
- 'grant_type' => 'password',
- 'username' => username,
- 'password' => password,
- 'client_id' => clientid,
- 'client_secret' => clientsecret,
- 'scope' => 'all'
- }
-
- # 发送请求
- response = connection.post do |req|
- req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
- req.headers['Cookie'] = 'JSESSIONID=6603118F3EE586D27CA50513B5D403CE'
- req.body = URI.encode_www_form(request_data)
- end
-
- # 处理响应
- if response.status == 200
- #puts '请求成功'
- #puts response.body
- result = JSON.parse(response.body)
- if result['access_token'].nil?
- # puts result['msg']
- else
- get_zhejianglab_userinfo_by_access_token(login_params,result['access_token'])
- end
- else
- puts '请求失败'
- puts "HTTP 响应码: #{response.status}"
- puts "错误消息: #{response.body}"
- end
-
-
- end
-
-
-
- def avatar_path(user)
- ApplicationController.helpers.disk_filename(user.class, user.id)
- end
-
-
- def get_zhejianglab_userinfo_by_access_token(login_params,access_token)
- api_url = 'https://onekey.zhejianglab.com/maxkey/api/oauth/v20/me'
- # puts 'get_zhejianglab_userinfo_by_access_token'
- # puts access_token
- access_token = access_token
-
- # 创建 Faraday 连接
- connection = Faraday.new(url: api_url)
-
- # 构建请求
- response = connection.post do |req|
- req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
- req.headers['Cookie'] = 'JSESSIONID=852C63FD783F4BA98D46A8FF24CDDB5D'
- req.body = URI.encode_www_form(access_token: access_token)
- end
-
- # 处理响应
- if response.status == 200
- puts '请求成功'
- zhejiang_user_info = JSON.parse(response.body)
-
- # zhejiang_user_info = JSON.parse('{"birthday":null,"gender":0,"mobile":"13521478105","createdate":"2022-06-07 18:08:09","title":null,"employeeNumber":null,"realname":"吴煜华","uid":"1533995283613675522","randomId":"71e7fe39-fd27-4bb6-8a79-83bb36b01508","state":null,"department":null,"email":"wuyuhua@zhejianglab.com","username":"001786"}')
- login = zhejiang_user_info["username"]
- email = zhejiang_user_info["email"]
- phone = zhejiang_user_info["mobile"]
- gender = 1
- extension_url = 'http://gateway.cmind.zhejianglab.com/user-center/user/user-info-by-account'
- query_params = { tenantId: '000000', account: login }
- extension_response = Faraday.get(extension_url, query_params)
- if extension_response.status == 200
- body = JSON.parse(extension_response.body)
- gender = body['data']['sex']
- end
- real_name = zhejiang_user_info["realname"]
- department_name = zhejiang_user_info["department"]
- password = login_params['password']
- # puts login
- # puts email
- # puts phone
- # puts real_name
- # puts department_name
- # puts password
- user = User.where("login = ? or phone = ? or mail = ? ", "#{login}", phone, email).first
- if user.present?
- # 手机号先记录,后续用
- user.update_column(:phone, "#{phone}") if phone.present?
- else
- ActiveRecord::Base.transaction do
- email = "#{login}@gitlink.org.cn" if email.blank?
- user_params = { status: 1, type: 'User', login: "#{login}", lastname: "#{real_name}", mail: "#{email}",
- nickname: "#{real_name}", professional_certification: 0, certification: 0, grade: 0,
- password: "#{password}", phone: "#{phone}", profile_completed: 1 }
- user = User.create!(user_params)
- UserExtension.create!(user_id: user.id, gender: "#{gender}", custom_department: "#{department_name}")
- interactor = Gitea::RegisterInteractor.call({username: login, email: email, password: password})
- if interactor.success?
- gitea_user = interactor.result
- Rails.logger.info("Gitea::RegisterInteractor.call result====== #{gitea_user}")
- result = Gitea::User::GenerateTokenService.call(login, password)
- user.gitea_token = result['sha1']
- user.gitea_uid = gitea_user[:body]['id']
- user.save!
- else
- Rails.logger.info("Gitea::RegisterInteractor.call error====== #{interactor.error}")
- end
- end
- end
- successful_authentication(user) if user.present?
-
- # 同步头像
-
- puts "开始同步头像了!!!!"
- # @user = User.try_to_login(login, password)
-
- # avatar_url = 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'
- avatar_url = "https://portal.zhejianglab.com/file/zjlab-humanface/upload/avatar/"+"#{login}"+".jpg?access_token="+"#{access_token}"
-
- require 'base64'
-
- response = Faraday.get(avatar_url)
-
- if response.success?
- # 如果请求成功,将图片数据转换为 Base64 编码
-
- image_data = response.body
- mime_type = "image/png"
- image = Base64.encode64(image_data)
- # 打印 Base64 编码后的图片数据
- # puts image_data
- max_size = EduSetting.get('upload_avatar_max_size')
- image = "data:#{mime_type};base64,#{image}"
- begin
- image = Util.convert_base64_image(image.to_s.strip, max_size: max_size)
- Util.write_file(image, avatar_path(user))
- rescue => e
- puts "Error: #{e.message}"
- end
-
-
-
-
-
- else
- # 处理请求失败的情况
- puts "Failed to download image"
- end
-
-
-
-
- else
- puts '请求失败'
- puts "HTTP 响应码: #{response.status}"
- puts "错误消息: #{response.body}"
- end
-
- end
-
-
-
- def set_autologin_cookie(user)
- token = Token.get_or_create_permanent_login_token(user, "autologin")
- # sync_user_token_to_trustie(user.login, token.value)
-
- cookie_options = {
- :value => token.value,
- :expires => 1.month.from_now,
- :path => '/',
- :secure => false,
- :httponly => true
- }
- if edu_setting('cookie_domain').present?
- cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
- end
- cookies[autologin_cookie_name] = cookie_options
- cookies.signed[:user_id] ||= user.id
-
- logger.info("cookies is #{cookies} ======> #{cookies.signed[:user_id]} =====> #{cookies[autologin_cookie_name]}")
- end
-
- def logout
- Rails.logger.info("########___logout_current_user____________########{current_user.try(:id)}")
- UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip)
- logout_user
- render :json => {status: 1, message: "退出成功!"}
- end
-
- # 检验邮箱是否已被注册及邮箱或者手机号是否合法
- # 参数type为事件类型 1:注册;2:忘记密码;3:绑定
- def valid_email_and_phone
- check_mail_and_phone_valid(params[:login], params[:type])
- end
-
- # 发送验证码
- # params[:login] 手机号或者邮箱号
- # params[:type]为事件通知类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
- # 发送验证码:send_type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱
- # 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9: 验收手机号有效
- def get_verification_code
- code = %W(0 1 2 3 4 5 6 7 8 9)
- value = params[:login]
- type = params[:type].strip.to_i
- login_type = phone_mail_type(value)
- send_type = verify_type(login_type, type)
- verification_code = code.sample(6).join
-
- status, message = InfoRiskControlService.call(value, request.remote_ip)
- tip_exception(420, message) if status == 0
- 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)
- render_ok
- end
-
- # check user's login or email or phone is used
- # params[:value] 手机号或者邮箱号或者登录名
- # params[:type] 为事件类型 1:登录名(login) 2:email(邮箱) 3:phone(手机号)
- def check
- Register::CheckColumnsForm.new(check_params).validate!
- render_ok
- end
-
- def login_check
- Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate!
- render_ok
- end
-
- private
-
- # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
- # login_type 1:手机类型 2:邮箱类型
- def verify_type login_type, type
- case type
- when 1
- login_type == 1 ? 1 : 8
- when 2
- login_type == 1 ? 2 : 3
- when 3
- login_type == 1 ? 4 : tip_exception('请填写正确的手机号')
- when 4
- login_type == 1 ? tip_exception('请填写正确的邮箱') : 5
- when 5
- login_type == 1 ? 9 : tip_exception('请填写正确的手机号')
- end
- end
-
- def generate_login(login)
- type = phone_mail_type(login.strip)
-
- if type == 1
- uid_logger("start register by phone: type is #{type}")
- pre = 'p'
- email = nil
- phone = login
- else
- uid_logger("start register by email: type is #{type}")
- pre = 'm'
- email = login
- phone = nil
- end
- code = generate_identifier User, 8, pre
-
- { login: pre + code, email: email, phone: phone }
- end
-
- def user_params
- params.require(:user).permit(:login, :email, :phone)
- end
-
- def login_params
- params.require(:account).permit(:login, :password)
- end
-
- def check_params
- params.permit(:type, :value)
- end
-
- def register_params
- params.permit(:login, :namespace, :password, :password_confirmation, :code, :type)
- 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
-
- def remote_register_params
- params.permit(:username, :email, :password, :platform)
- end
-
- def simple_update_params
- params.permit(:username, :email, :password, :platform)
- end
- end
|