diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index ea26f1bd5..266ceef32 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -4,16 +4,15 @@ class AccountsController < ApplicationController #skip_before_action :check_account, :only => [:logout] - def simple_update + 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.merge(user_id: current_user.id)).validate! + Register::RemoteForm.new(simple_update_params).validate! ActiveRecord::Base.transaction do result = auto_update(current_user, simple_update_params) if result[:message].blank? - UserAction.create(:action_id => current_user.id, :action_type => "sync_educoder_user", :user_id => current_user.id, :ip => request.remote_ip) if params[:platform] == "educoder" render_ok else render_error(result[:message]) @@ -29,7 +28,7 @@ class AccountsController < ApplicationController def remote_register Register::RemoteForm.new(remote_register_params).validate! username = params[:username]&.gsub(/\s+/, "") - tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username) + tip_exception("无法使用以下关键词:#{username},请重新命名!") if ReversedKeyword.check_exists?(username) email = params[:email]&.gsub(/\s+/, "") password = params[:password] platform = (params[:platform] || 'forge')&.gsub(/\s+/, "") @@ -161,11 +160,8 @@ class AccountsController < ApplicationController successful_authentication(user) render_ok end - elsif interactor.result[:message].to_s.include?("user already exists") - UserAction.create(:action_id => 2, :action_type => "register_error", :user_id => user.try(:id).to_i, :ip => "code: #{register_params[:code]}; login: #{register_params[:login]}; namespace: #{register_params[:namespace]}; password: #{password};") - normal_status(-1, "用户已注册,请勿连续操作。") else - tip_exception(-1, interactor.result[:message]) + tip_exception(-1, interactor.error) end rescue Register::BaseForm::EmailError => e render_result(-2, e.message) @@ -180,21 +176,58 @@ class AccountsController < ApplicationController rescue Register::BaseForm::VerifiCodeError => e render_result(-6, e.message) rescue Exception => e - if user.present? && !e.message.to_s.include?("user already exists") - # Gitea::User::DeleteService.call(user.login) - # user.destroy - end - Rails.logger.error("##:register error--#{user.try(:id)},message:#{e.message}") - UserAction.create(:action_id => 1, :action_type => "register_error", :user_id => user.try(:id).to_i, :ip => "code: #{register_params[:code]}; login: #{register_params[:login]}; namespace: #{register_params[:namespace]}; password: #{password};") - logger_error(e) - tip_exception(-1, "注册失败") + 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 @@ -219,7 +252,38 @@ class AccountsController < ApplicationController sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步 # session[:user_id] = @user.id - end + 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]) @@ -273,7 +337,7 @@ class AccountsController < ApplicationController end end - def successful_authentication(user) + 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 @@ -288,6 +352,186 @@ class AccountsController < ApplicationController # 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) @@ -359,17 +603,6 @@ class AccountsController < ApplicationController Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate! render_ok end - - def check_keywords - text = params[:text].to_s.each_char.select { |c| c.bytes.first < 240 }.join('') - data = ! ReversedKeyword.check_exists?(text) - result = { - status: 0, - data: data, - message: data ? "" : "无法使用以下关键词:#{text},请重新命名" - } - render_ok(result) - end private