Merge branch 'pre_trustie_server' into trustie_server
This commit is contained in:
commit
12061f4ce8
|
@ -1,6 +1,7 @@
|
||||||
class AccountsController < ApplicationController
|
class AccountsController < ApplicationController
|
||||||
before_action :require_login, only: [:login_check, :simple_update, :change_password]
|
before_action :require_login, only: [:login_check, :simple_update, :change_password]
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
include AesCryptHelper
|
||||||
|
|
||||||
#skip_before_action :check_account, :only => [:logout]
|
#skip_before_action :check_account, :only => [:logout]
|
||||||
|
|
||||||
|
@ -143,7 +144,8 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
user = Users::RegisterService.call(register_params)
|
user = Users::RegisterService.call(register_params)
|
||||||
user.mail = "#{user.login}@example.org" if user.mail.blank?
|
user.mail = "#{user.login}@example.org" if user.mail.blank?
|
||||||
password = register_params[:password].strip
|
password = decrypt(register_params[:password]) rescue ""
|
||||||
|
password = password.strip
|
||||||
|
|
||||||
# gitea用户注册, email, username, password
|
# gitea用户注册, email, username, password
|
||||||
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password})
|
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password})
|
||||||
|
@ -193,8 +195,9 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
# 用户登录
|
# 用户登录
|
||||||
def login
|
def login
|
||||||
Users::LoginForm.new(login_params).validate!
|
password = decrypt(login_params[:password]) rescue ""
|
||||||
@user = User.try_to_login(params[:login], params[:password])
|
Users::LoginForm.new(login_params.merge!({password: password})).validate!
|
||||||
|
@user = User.try_to_login(params[:login], password)
|
||||||
|
|
||||||
return normal_status(-2, "错误的账号或密码") if @user.blank?
|
return normal_status(-2, "错误的账号或密码") if @user.blank?
|
||||||
# user is already in local database
|
# user is already in local database
|
||||||
|
@ -203,7 +206,7 @@ class AccountsController < ApplicationController
|
||||||
login_control = LimitForbidControl::UserLogin.new(@user)
|
login_control = LimitForbidControl::UserLogin.new(@user)
|
||||||
return normal_status(-2, "登录密码出错已达上限,账号已被锁定,请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
|
return normal_status(-2, "登录密码出错已达上限,账号已被锁定,请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
|
||||||
|
|
||||||
password_ok = @user.check_password?(params[:password].to_s)
|
password_ok = @user.check_password?(password.to_s)
|
||||||
unless password_ok
|
unless password_ok
|
||||||
if login_control.remain_times-1 == 0
|
if login_control.remain_times-1 == 0
|
||||||
normal_status(-2, "登录密码出错已达上限,账号已被锁定,请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
|
normal_status(-2, "登录密码出错已达上限,账号已被锁定,请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
|
||||||
|
@ -216,21 +219,24 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
LimitForbidControl::UserLogin.new(@user).clear
|
LimitForbidControl::UserLogin.new(@user).clear
|
||||||
successful_authentication(@user)
|
successful_authentication(@user)
|
||||||
sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
|
sync_pwd_to_gitea!(@user, {password: password.to_s}) # TODO用户密码未同步
|
||||||
|
|
||||||
# session[:user_id] = @user.id
|
# session[:user_id] = @user.id
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_password
|
def change_password
|
||||||
return render_error("两次输入的密码不一致") if params[:password].to_s != params[:new_password_repeat].to_s
|
password = decrypt(params[:password]) rescue ""
|
||||||
|
new_password_repeat = decrypt(params[:new_password_repeat]) rescue ""
|
||||||
|
old_password = decrypt(params[:old_password]) rescue ""
|
||||||
|
return render_error("两次输入的密码不一致") if password.to_s != new_password_repeat.to_s
|
||||||
@user = User.find_by(login: params[:login])
|
@user = User.find_by(login: params[:login])
|
||||||
return render_forbidden unless User.current.login == @user&.login
|
return render_forbidden unless User.current.login == @user&.login
|
||||||
return render_error("此用户禁止修改密码!") if @user.id.to_i === 104691
|
return render_error("此用户禁止修改密码!") if @user.id.to_i === 104691
|
||||||
return render_error("未找到相关用户!") if @user.blank?
|
return render_error("未找到相关用户!") if @user.blank?
|
||||||
return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])
|
return render_error("旧密码不正确") unless @user.check_password?(old_password)
|
||||||
|
|
||||||
sync_params = {
|
sync_params = {
|
||||||
password: params[:password].to_s,
|
password: password.to_s,
|
||||||
email: @user.mail,
|
email: @user.mail,
|
||||||
login_name: @user.name,
|
login_name: @user.name,
|
||||||
source_id: 0
|
source_id: 0
|
||||||
|
@ -238,7 +244,7 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||||
if interactor.success?
|
if interactor.success?
|
||||||
@user.update_attribute(:password, params[:password])
|
@user.update_attribute(:password, password)
|
||||||
render_ok
|
render_ok
|
||||||
else
|
else
|
||||||
render_error(interactor.error)
|
render_error(interactor.error)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
class Api::V1::UsersController < Api::V1::BaseController
|
class Api::V1::UsersController < Api::V1::BaseController
|
||||||
|
include AesCryptHelper
|
||||||
|
|
||||||
before_action :load_observe_user, except: [:check_user_id, :check_user_login]
|
before_action :load_observe_user, except: [:check_user_id, :check_user_login]
|
||||||
before_action :check_auth_for_observe_user, except: [:check_user_id, :check_user_login]
|
before_action :check_auth_for_observe_user, except: [:check_user_id, :check_user_login]
|
||||||
|
@ -53,7 +54,7 @@ class Api::V1::UsersController < Api::V1::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_password
|
def check_password
|
||||||
password = params[:password]
|
password = decrypt(params[:password]) rescue ""
|
||||||
return tip_exception(-5, "8~16位密码,支持字母数字和符号") unless password =~ CustomRegexp::PASSWORD
|
return tip_exception(-5, "8~16位密码,支持字母数字和符号") unless password =~ CustomRegexp::PASSWORD
|
||||||
return tip_exception(-5, "密码错误") unless @observe_user.check_password?(password)
|
return tip_exception(-5, "密码错误") unless @observe_user.check_password?(password)
|
||||||
render_ok
|
render_ok
|
||||||
|
@ -126,7 +127,8 @@ class Api::V1::UsersController < Api::V1::BaseController
|
||||||
|
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
return tip_exception(-1, "密码不正确.") unless @observe_user.check_password?(params[:password])
|
password = decrypt(params[:password]) rescue ""
|
||||||
|
return tip_exception(-1, "密码不正确.") unless @observe_user.check_password?(password)
|
||||||
org_ids = TeamUser.where(user_id: @observe_user.id).pluck(:organization_id) | OrganizationUser.where(user_id: @observe_user.id).pluck(:organization_id)
|
org_ids = TeamUser.where(user_id: @observe_user.id).pluck(:organization_id) | OrganizationUser.where(user_id: @observe_user.id).pluck(:organization_id)
|
||||||
org_count = TeamUser.where(organization_id: org_ids).where(user_id: @observe_user.id).joins(:team).where(teams: {authorize: %w(owner)}).count
|
org_count = TeamUser.where(organization_id: org_ids).where(user_id: @observe_user.id).joins(:team).where(teams: {authorize: %w(owner)}).count
|
||||||
project_count = Project.where(user_id: @observe_user.id).count
|
project_count = Project.where(user_id: @observe_user.id).count
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
class Organizations::OrganizationsController < Organizations::BaseController
|
class Organizations::OrganizationsController < Organizations::BaseController
|
||||||
|
include AesCryptHelper
|
||||||
before_action :require_login, except: [:index, :show, :recommend, :languages]
|
before_action :require_login, except: [:index, :show, :recommend, :languages]
|
||||||
# before_action :require_profile_completed, only: [:create]
|
# before_action :require_profile_completed, only: [:create]
|
||||||
before_action :convert_image!, only: [:create, :update]
|
before_action :convert_image!, only: [:create, :update]
|
||||||
|
@ -139,7 +140,7 @@ class Organizations::OrganizationsController < Organizations::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def password
|
def password
|
||||||
params.fetch(:password, "")
|
decrypt(params[:password]) rescue ""
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_organization
|
def load_organization
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
class BaseForm
|
class BaseForm
|
||||||
include ActiveModel::Model
|
include ActiveModel::Model
|
||||||
|
include AesCryptHelper
|
||||||
|
|
||||||
Error = Class.new(StandardError)
|
Error = Class.new(StandardError)
|
||||||
EmailError = Class.new(Error)
|
EmailError = Class.new(Error)
|
||||||
|
@ -53,11 +54,15 @@ class BaseForm
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_password(password)
|
def check_password(password)
|
||||||
|
password = decrypt(password) rescue ""
|
||||||
password = strip(password)
|
password = strip(password)
|
||||||
raise PasswordFormatError, "密码8~16位密码,支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD
|
raise PasswordFormatError, "密码8~16位密码,支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_password_confirmation(password, password_confirmation)
|
def check_password_confirmation(password, password_confirmation)
|
||||||
|
password = decrypt(password) rescue ""
|
||||||
|
password_confirmation = decrypt(password_confirmation) rescue ""
|
||||||
|
|
||||||
password = strip(password)
|
password = strip(password)
|
||||||
password_confirmation = strip(password_confirmation)
|
password_confirmation = strip(password_confirmation)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
module AesCryptHelper
|
||||||
|
|
||||||
|
AES_KEY = EduSetting.get("login_crypt_key") || '59c96c3572ab8cc1'
|
||||||
|
|
||||||
|
def encrypt(plain_text, output_encoding = 'base64')
|
||||||
|
|
||||||
|
# 将字符串密钥和IV转换为16字节的字节数组
|
||||||
|
key = AES_KEY.byteslice(0, 16)
|
||||||
|
iv = AES_KEY.byteslice(0, 16)
|
||||||
|
|
||||||
|
# 创建并设置AES-CBC加密器
|
||||||
|
cipher = OpenSSL::Cipher.new('AES-128-CBC')
|
||||||
|
cipher.encrypt
|
||||||
|
cipher.key = key
|
||||||
|
cipher.iv = iv
|
||||||
|
|
||||||
|
# 加密数据,并添加PKCS7填充
|
||||||
|
encrypted_data = cipher.update(plain_text) + cipher.final
|
||||||
|
# 将加密数据转换为Base64编码
|
||||||
|
Base64.strict_encode64(encrypted_data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def decrypt(cipher_text, input_encoding = 'base64')
|
||||||
|
# 确保密钥是16字节长
|
||||||
|
key = AES_KEY.byteslice(0, 16) # 如果密钥不足16字节,填充空格;如果超过,截断
|
||||||
|
iv = AES_KEY.byteslice(0, 16)
|
||||||
|
|
||||||
|
decipher = OpenSSL::Cipher.new('AES-128-CBC')
|
||||||
|
decipher.decrypt
|
||||||
|
decipher.key = key
|
||||||
|
decipher.iv = iv
|
||||||
|
|
||||||
|
# 根据输入编码解码密文
|
||||||
|
decrypted_data = case input_encoding
|
||||||
|
when 'base64'
|
||||||
|
Base64.strict_decode64(cipher_text)
|
||||||
|
else
|
||||||
|
cipher_text
|
||||||
|
end
|
||||||
|
|
||||||
|
decrypted = decipher.update(decrypted_data) + decipher.final
|
||||||
|
decrypted
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -9,17 +9,16 @@ class ChangeIssueStatusByMessageJob < ApplicationJob
|
||||||
|
|
||||||
|
|
||||||
def get_pm_issue_data(user, org, pm_project_id, issue_id)
|
def get_pm_issue_data(user, org, pm_project_id, issue_id)
|
||||||
url = URI("#{EduSetting.get("pms_server_url")}/api/pms/#{org.login}/pmsProjectIssues/#{issue_id}?pmProjectId=#{pm_project_id}")
|
url = "#{EduSetting.get("pms_server_url")}/api/pms/#{org.login}/pmsProjectIssues/#{issue_id}?pmProjectId=#{pm_project_id}"
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'Cookie' => "autologin_trustie=#{Token.get_or_create_permanent_login_token(user, 'autologin')&.value}",
|
||||||
|
}
|
||||||
|
|
||||||
|
response = RestClient.get(url, headers)
|
||||||
|
|
||||||
https = Net::HTTP.new(url.host, url.port)
|
puts response.body
|
||||||
https.use_ssl = true
|
return JSON.parse(response.body)["code"].to_i == 200
|
||||||
request = Net::HTTP::Get.new(url)
|
|
||||||
request["Cookie"] = "autologin_trustie=#{Token.get_or_create_permanent_login_token(user, 'autologin')&.value}"
|
|
||||||
response = https.request(request)
|
|
||||||
|
|
||||||
puts response.read_body
|
|
||||||
return JSON.parse(response.read_body)['code'].to_i == 200
|
|
||||||
rescue
|
rescue
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -33,6 +32,7 @@ class ChangeIssueStatusByMessageJob < ApplicationJob
|
||||||
issue = project.issues.issue_issue.where(project_issues_index: issue_id).where.not(id: issue_id).take || Issue.issue_issue.find_by_id(issue_id)
|
issue = project.issues.issue_issue.where(project_issues_index: issue_id).where.not(id: issue_id).take || Issue.issue_issue.find_by_id(issue_id)
|
||||||
next unless issue.present? # issue不存在 跳过
|
next unless issue.present? # issue不存在 跳过
|
||||||
next if issue.project.present? && !issue.project.member?(user) # issue归属项目,用户没有修改issue的权限,跳过
|
next if issue.project.present? && !issue.project.member?(user) # issue归属项目,用户没有修改issue的权限,跳过
|
||||||
|
next if issue.pm_project_id.nil? && project.id.to_i != issue.project&.id.to_i
|
||||||
next if issue.pm_project_id.present? && !get_pm_issue_data(user, project.owner, issue.pm_project_id, issue.id) # issue是组织下工作项,不具备组织的访问权限,跳过
|
next if issue.pm_project_id.present? && !get_pm_issue_data(user, project.owner, issue.pm_project_id, issue.id) # issue是组织下工作项,不具备组织的访问权限,跳过
|
||||||
|
|
||||||
issue_project = issue.project || Project.new(id: 0, user_id: 0, name: 'pm_mm', identifier: 'pm_mm', is_public:true)
|
issue_project = issue.project || Project.new(id: 0, user_id: 0, name: 'pm_mm', identifier: 'pm_mm', is_public:true)
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
#
|
#
|
||||||
# Table name: edu_settings
|
# Table name: edu_settings
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# name :string(255)
|
# name :string(255)
|
||||||
# value :string(255)
|
# value :string(255)
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# description :string(255)
|
# description :string(255)
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
# index_edu_settings_on_name (name) UNIQUE
|
# index_edu_settings_on_name (name) UNIQUE
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class EduSetting < ApplicationRecord
|
class EduSetting < ApplicationRecord
|
||||||
after_commit :expire_value_cache
|
after_commit :expire_value_cache, on: [:create, :update]
|
||||||
|
after_commit :clear_value_cache, on: :destroy
|
||||||
|
|
||||||
scope :by_search, -> (keyword){ where("name LIKE :keyword OR value LIKE :keyword", keyword: "%#{strip_param(keyword)}%") unless strip_param(keyword).blank? }
|
scope :by_search, -> (keyword){ where("name LIKE :keyword OR value LIKE :keyword", keyword: "%#{strip_param(keyword)}%") unless strip_param(keyword).blank? }
|
||||||
|
|
||||||
|
@ -25,7 +26,11 @@ class EduSetting < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.get(key)
|
def self.get(key)
|
||||||
Rails.cache.fetch(value_cache_key(key), expires_in: 1.days) do
|
begin
|
||||||
|
Rails.cache.fetch(value_cache_key(key), expires_in: 1.days) do
|
||||||
|
find_by_name(key.to_s)&.value
|
||||||
|
end
|
||||||
|
rescue Exception => e
|
||||||
find_by_name(key.to_s)&.value
|
find_by_name(key.to_s)&.value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -41,4 +46,8 @@ class EduSetting < ApplicationRecord
|
||||||
def expire_value_cache
|
def expire_value_cache
|
||||||
Rails.cache.write(value_cache_key, value)
|
Rails.cache.write(value_cache_key, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def clear_value_cache
|
||||||
|
Rails.cache.delete(value_cache_key)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
module Accounts
|
module Accounts
|
||||||
class ResetPasswordService < ApplicationService
|
class ResetPasswordService < ApplicationService
|
||||||
|
include AesCryptHelper
|
||||||
# login、code、password、password_confirmation
|
# login、code、password、password_confirmation
|
||||||
def initialize(user, params)
|
def initialize(user, params)
|
||||||
@user = user
|
@user = user
|
||||||
@password = params[:password]
|
@password = decrypt(params[:password]) rescue ""
|
||||||
@password_confirmation = params[:password_confirmation]
|
@password_confirmation = decrypt(params[:password_confirmation]) rescue ""
|
||||||
end
|
end
|
||||||
|
|
||||||
def call
|
def call
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
class Api::V1::Users::UpdateEmailService < ApplicationService
|
class Api::V1::Users::UpdateEmailService < ApplicationService
|
||||||
include ActiveModel::Model
|
include ActiveModel::Model
|
||||||
|
include AesCryptHelper
|
||||||
|
|
||||||
attr_reader :user, :token, :password, :mail, :old_mail, :code, :verify_code
|
attr_reader :user, :token, :password, :mail, :old_mail, :code, :verify_code
|
||||||
attr_accessor :gitea_data
|
attr_accessor :gitea_data
|
||||||
|
@ -10,7 +11,7 @@ class Api::V1::Users::UpdateEmailService < ApplicationService
|
||||||
def initialize(user, params, token =nil)
|
def initialize(user, params, token =nil)
|
||||||
@user = user
|
@user = user
|
||||||
@token = token
|
@token = token
|
||||||
@password = params[:password]
|
@password = decrypt(params[:password]) rescue ""
|
||||||
@mail = params[:email]
|
@mail = params[:email]
|
||||||
@old_mail = user.mail
|
@old_mail = user.mail
|
||||||
@code = params[:code]
|
@code = params[:code]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
class Api::V1::Users::UpdatePhoneService < ApplicationService
|
class Api::V1::Users::UpdatePhoneService < ApplicationService
|
||||||
include ActiveModel::Model
|
include ActiveModel::Model
|
||||||
|
include AesCryptHelper
|
||||||
|
|
||||||
attr_reader :user, :password, :phone, :code, :verify_code
|
attr_reader :user, :password, :phone, :code, :verify_code
|
||||||
|
|
||||||
|
@ -8,7 +9,7 @@ class Api::V1::Users::UpdatePhoneService < ApplicationService
|
||||||
|
|
||||||
def initialize(user, params)
|
def initialize(user, params)
|
||||||
@user = user
|
@user = user
|
||||||
@password = params[:password]
|
@password = decrypt(params[:password]) rescue ""
|
||||||
@phone = params[:phone]
|
@phone = params[:phone]
|
||||||
@code = params[:code]
|
@code = params[:code]
|
||||||
@verify_code = VerificationCode.where(phone: @phone, code_type: 4).last
|
@verify_code = VerificationCode.where(phone: @phone, code_type: 4).last
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
class Users::RegisterService < ApplicationService
|
class Users::RegisterService < ApplicationService
|
||||||
|
include AesCryptHelper
|
||||||
|
|
||||||
def initialize(params)
|
def initialize(params)
|
||||||
@login = params[:login]
|
@login = params[:login]
|
||||||
@namespace = params[:namespace]
|
@namespace = params[:namespace]
|
||||||
@password = params[:password]
|
@password = decrypt(params[:password]) rescue ""
|
||||||
@code = params[:code]
|
@code = params[:code]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue