区块链确权相关

This commit is contained in:
2023-03-02 13:49:50 +08:00
parent 5216e61479
commit b1c10d66f9
26 changed files with 1354 additions and 97 deletions

View File

@@ -2,8 +2,8 @@ class UsersController < ApplicationController
include ApplicationHelper
include Ci::DbConnectable
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users, :hovercard]
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users, :hovercard]
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users, :hovercard, :hovercard4proj]
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users, :hovercard, :hovercard4proj]
before_action :require_login, only: %i[me sync_user_info]
before_action :connect_to_ci_db, only: [:get_user_info]
before_action :convert_image!, only: [:update, :update_image]
@@ -81,9 +81,134 @@ class UsersController < ApplicationController
@watchers = paginate(watchers)
end
def contribution_perc
project_id = params[:project_id]
@project = Project.find(project_id)
user_id = params[:id]
@user = User.find(user_id)
def cal_perc(count_user, count_all)
(count_user * 1.0 / (count_all + 0.000000001)).round(5)
end
if @project['use_blockchain'] == true or @project['use_blockchain'] == 1
balance_user = Blockchain::BalanceQueryOneProject.call({"user_id": user_id, "project_id": project_id})
balance_all = Blockchain::RepoBasicInfo.call({"project_id": project_id})["cur_supply"]
scores = {
"final" => cal_perc(balance_user, balance_all),
"blockchain" => true
}
else
# 获取所有行为对应的项目内记录总数和个人记录数
features = {
"requirement" => {},
"development" => {},
"review" => {}
}
# 1. issue创建
issues = Issue.where(project_id: project_id, issue_classify: 'issue')
issue_all = issues.count
issue_user = issues.where(author_id: user_id).count
features["requirement"] = features["requirement"].merge({"issue" => {"all" => issue_all, "perc" => cal_perc(issue_user, issue_all)}})
# 2. 里程碑创建
milestones = Version.where(project_id: project_id)
milestone_all = milestones.count
milestone_user = milestones.where(user_id: user_id).count
features["requirement"] = features["requirement"].merge({"milestone" => {"all" => milestone_all, "perc" => cal_perc(milestone_user, milestone_all)}})
# 3. issue评论
issue_comments = Journal.joins("INNER JOIN issues on journals.journalized_id=issues.id").where("issues.project_id=#{project_id} and journalized_type='Issue' and issues.issue_classify='issue'")
issue_comment_all = issue_comments.count
issue_comment_user = issue_comments.where("journals.user_id=#{user_id}").count
features["requirement"] = features["requirement"].merge({"issue_comment" => {"all" => issue_comment_all, "perc" => cal_perc(issue_comment_user, issue_comment_all)}})
# 4. 合并请求
prs = PullRequest.where(project_id: project_id)
pr_all = prs.count
pr_user = prs.where(user_id: user_id).count
features["development"] = features["development"].merge({"pr" => {"all" => pr_all, "perc" => cal_perc(pr_user, pr_all)}})
# 5. pr评论
pr_comments = Journal.joins("INNER JOIN issues on journals.journalized_id=issues.id").where("issues.project_id=#{project_id} and journalized_type='Issue' and issues.issue_classify='pull_request'")
pr_comment_all = pr_comments.count
pr_comment_user = pr_comments.where("journals.user_id=#{user_id}").count
features["review"] = features["review"].merge({"pr_comment" => {"all" => pr_comment_all, "perc" => cal_perc(pr_comment_user, pr_comment_all)}})
# 6. 代码行评论
line_comments = Journal.joins("INNER JOIN pull_requests on journals.journalized_id=pull_requests.id").where("pull_requests.project_id=#{project_id} and journalized_type='PullRequest'")
line_comment_all = line_comments.count
line_comment_user = line_comments.where("journals.user_id=#{user_id}").count
features["review"] = features["review"].merge({"line_comment" => {"all" => line_comment_all, "perc" => cal_perc(line_comment_user, line_comment_all)}})
# 7. 代码行、commit贡献统计
code_contributions = Api::V1::Projects::CodeStats::ListService.call(@project, {ref: nil})
commit_all = code_contributions["commit_count"]
addition_all = code_contributions["additions"]
deletion_all = code_contributions["deletions"]
commit_user = 0
addition_user = 0
deletion_user = 0
code_contributions["authors"].each do |author|
if author["name"] == @user.login
commit_user = author["commits"]
addition_user = author["additions"]
deletion_user = author["deletions"]
end
end
features["development"] = features["development"].merge({"commit" => {"all" => commit_all, "perc" => cal_perc(commit_user, commit_all)}})
features["development"] = features["development"].merge({"addition" => {"all" => addition_all, "perc" => cal_perc(addition_user, addition_all)}})
features["development"] = features["development"].merge({"deletion" => {"all" => deletion_all, "perc" => cal_perc(deletion_user, deletion_all)}})
def cal_weight(features)
weights = {} # 计算每一项的权重
categories = []
features.each do |key, _|
categories << key
weights[key] = Hash.new
end
count_all = 0
counts = {}
categories.each do |category|
count_1 = 0
features[category].each do |_, value|
count_1 += value["all"]
end
count_all += count_1
counts[category] = count_1
features[category].each do |key, value|
weight = cal_perc(value["all"], count_1)
weights[category] = weights[category].merge({key => weight})
end
end
categories.each do |category|
weight = cal_perc(counts[category], count_all)
weights[category] = weights[category].merge({"category_weight" => weight})
end
return weights
end
weights_categories = cal_weight(features)
scores = {
"final" => 0.0,
"blockchain" => false
}
features.each do |category, value_1|
category_score = 0.0
value_1.each do |action, value_2|
category_score += weights_categories[category][action] * value_2["perc"]
end
scores["final"] += weights_categories[category]["category_weight"] * category_score.round(4)
scores = scores.merge({category => category_score.round(4)})
end
end
render json: { scores: scores }
end
def hovercard
end
# author: zxh, 查询贡献者的贡献度
def hovercard4proj
end
def update
return render_not_found unless @user = User.find_by(login: params[:id]) || User.find_by_id(params[:id])
return render_forbidden unless User.current.logged? && (current_user&.admin? || current_user.id == @user.id)
@@ -94,11 +219,11 @@ class UsersController < ApplicationController
end
end
def update_image
return render_not_found unless @user = User.find_by(login: params[:id]) || User.find_by_id(params[:id])
def update_image
return render_not_found unless @user = User.find_by(login: params[:id]) || User.find_by_id(params[:id])
return render_forbidden unless User.current.logged? && (current_user&.admin? || current_user.id == @user.id)
Util.write_file(@image, avatar_path(@user))
Util.write_file(@image, avatar_path(@user))
return render_ok({message: '头像修改成功'})
rescue Exception => e
uid_logger_error(e.message)
@@ -284,6 +409,252 @@ class UsersController < ApplicationController
@projects = paginate(scope)
end
# query all projects with tokens by a user
def blockchain_balance
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
is_current_admin_user = true
results = Blockchain::BalanceQuery.call(params, is_current_admin_user)
if results[:status] == 0
@total_count = results[:projects].size
@projects = results[:projects]
else
@total_count = -1
@projects = []
end
render json: { status: results[:status], projects: @projects, total_count: @total_count }
end
# query one balance
def blockchain_balance_one_project
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
is_current_admin_user = true
if is_current_admin_user
owner = User.find_by(login: params['owner_login'])
if owner.nil?
normal_status(-1, "创建者无法找到")
else
p = Project.find_by(user_id: owner.id, identifier: params['project_identifier'])
balance = Blockchain::BalanceQueryOneProject.call({"user_id": params['user_id'].to_i, "project_id": p.id.to_i})
render json: { status: 0, balance: balance}
end
else
normal_status(-1, "缺少权限")
end
end
def blockchain_transfer
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['payer_id'].to_i)
is_current_admin_user = true
if is_current_admin_user
Blockchain::TransferService.call(params)
render json: {status: 2} # 重新查询余额
else
normal_status(-1, "缺少权限")
end
rescue Exception => e
normal_status(-1, e.to_s)
end
# exchange money
def blockchain_exchange
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
#require 'alipay'
## setup the client to communicate with either production API or sandbox API
## https://openapi.alipay.com/gateway.do (Production)
## https://openapi.alipaydev.com/gateway.do (Sandbox)
#api_url = 'https://openapi.alipay.com/gateway.do'
#
## setup your own credentials and certificates
#app_id = '2021002140631434'
#app_private_key="-----BEGIN RSA PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCPDsgc0n0RWRnbe9OMqtUbde8gu88OyjuZm8cJXeiSING18HX56C5zV4DsHQ6K9/JmQi/NYCc7/2Prh66Bei0L4Xm5TysJTPYi90+WlbJJESFF6fqULi8sSqZXUtaoMKRcUyeR144l2GQgXbZWBbVSQeZW5DqUDlurTF0I7vQ21wGqxQqBjQK8PSVw5hF+aIsNOfAY9M1tzdD5Jzo2Y3FJdsbXIJNMyhJJCZ+7KHFqma7lpjkXdCoyh/nOISkQdGtFI29gI94sqewI2AMU84uxuBIE3h90iLT+8xrd2dQKdBS7qfhQ3PgkBPVNs5jxsVBqSFdSFT6zcqFdHJzulCUJAgMBAAECggEAWocAGz0X5+J6emnhdSKluLrol85BORrAnHP3f/XtNouOKZQBFCPZQSQecUvx5/7/ZbZ8iXpPWahDkshJpaWq29nTLXDryvboyze1JZWVPKeaZqOp7htLvrt+h8PkEoq1d7cnUyMU0N4eflzPBaCXHXaWTGYgq5Bqcfvg48ZSxGBYeHt5WWU2+GW5fpsaVBBYkdyxxGMoy/bzYzGhvfSJkexqnl0XkAAODa02mu3WsHrzRid6Mf+3syYbq/MfUodU6Vng2tbCqwnWrHCyrD4RYl6rg1TKuAv2YAfBhLzwBxHYVC4SRqzjs+8AaOQoF+lCjr4JklPhEuRThzD31YwIAQKBgQDAg4S7ciMmxvbNxR+1eimoAYLLF9jPpPU6w3VFNPb4rDu4tX77bNf082YplfJX5TYtZKjKPKyYG87K6slGunyPL4AFRW81WPB9u1uP26dihyPCBSUE01jKRPPfRrQnnru5fpm8LL3L03V3yA6J+GyQ8wltRJJi1eBSSm+IWRsZewKBgQC+PBD9J1LYOEIVeK9KvN8BpkA1ZIkk//VuJaoGfVXn+1EzM1yFB05fnsEQkHFynisvuCIr7pH63HcdyffQhe1YOnw9iDCG1zPjsi5uTe9WAM0dnb7xdsaLPr/Q2LyoDOTN9344Qovy1AAnpWtGTn6omgHst5nZpp/mHOuBlKiqSwKBgBKRXM77fjpyPEGyfpFxW+0xYB0YirfUUDa/vWLUbfGkIwp4ruuvHtEoXLUsGjiyCdys9b6zxW3SWMqnhIxG1la1HSLlBInfryphVL52UBmnsSI4fs6NV+YCaocheaTMoYyNkmRc6F1tYsoPyJ80D7yXRFR+paPUvxMQzNsYxQ1bAoGAHd2uSSBQWFPUxCwzUQd/93FTaU6EXYO103okTGqG/ymsoN4ya0wvWMHCy8fxl64PV6mP69fDoV/Vb57SwjEUhyJ/eOWVwMWuhtPliDnCFn1/tmOao6wjFZ9fW/l6/OMxVMjDTy/bat8vuwm0YtBWAEBVhwV4KPyI5AasTqa5KCsCgYB/usnqhVx2zt+MxpBt2Q9Vxc0zXcZxMDs69UUdTY86gjcJyCFGe3bbumUcyfSJzIznC2hfFX5ZyS0oMwiAzWtslRMh9LRh3kofD/6BogL3RKOlBk3iekvQ8Gn0tbwk2Qzr4WJgfA7A4GTf5r7Y+bvOfazzsUQAfSK6nUTIlOj2Ew==\n-----END RSA PRIVATE KEY-----\n"
#alipay_public_key="-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgHXLD1BshMymbqqtZVKNyo95FNfxzXzaw3P1eI0KeO6RaL+JzrWxzIBFfTjkWv/8WM9u/NcXMOFt2QO9q5KIDx6PkqjRDTd1hgP/cTgdjOHQqnVSihCrQDVCDBSOXIujC8Lk/P4pFVRhQkYeZqEb1qb8b/2tzTY8g9PKKBSCQv7SfgL2TBcpAVbb+9xdJ6VainC/wYGk8T+c+st1hXnuBJSS0m7LFxJOsYkNk0wbA0tfdZLrO3us2F7sjC9t4h/05nr+gSuDkzo+1kCEefYLqScexN+vnQiLoylp/C82wNiP6okxfhmHz3EcYfUqUyGTN/oFaFcPFPpUtFNS8jFV9QIDAQAB\n-----END PUBLIC KEY-----\n"
#
## initialize a client to communicate with the Alipay API
#@alipay_client = Alipay::Client.new(
# url: api_url,
# app_id: app_id,
# app_private_key: app_private_key,
# alipay_public_key: alipay_public_key
#)
#
#return_result = @alipay_client.page_execute_url(
# method: 'alipay.trade.page.pay',
# biz_content: JSON.generate({
# out_trade_no: '20210420104600',
# product_code: 'FAST_INSTANT_TRADE_PAY',
# total_amount: '0.01',
# subject: 'test'
# }, ascii_only: true), # ascii_only is important!
# timestamp: '2021-04-20 10:46:00'
#)
#render json: { pay_url: return_result }
#
# 替代解决方案
# 读取所有交易信息
end
# #
# # def blockchain_create_trade
# # #is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
# # is_current_admin_user = true
# # if is_current_admin_user
# # user_id = params['user_id'].to_i
# # project_id = params['project_id'].to_i
# # money = params['money'].to_f
# # #description = params['description']
# # token_num = params['token_num'].to_i
# # # 锁仓
# # result = Blockchain::CreateTrade.call({user_id: user_id, project_id: project_id, token_num: token_num})
# # if result == false
# # normal_status(-1, "创建交易失败")
# # else
# # bt = BlockchainTrade.new(user_id: user_id, project_id: project_id, token_num: token_num, money: money, state: 0) # state=0表示创建交易; state=1表示执行中; state=2表示执行完成
# # bt.save()
# # status = 2 # 交易创建成功
# # render json: { status: status }
# # end
# # else
# # normal_status(-1, "缺少权限")
# # end
# # end
# #
# #
# # def blockchain_get_trades
# # trades = BlockchainTrade.where(state: 0).all()
# # results = []
# # trades.each do |t|
# # project_id = t.project_id
# # project = Project.find_by(id: project_id)
# # if !project.nil?
# # owner = User.find_by(id: project.user_id)
# # else
# # owner = nil
# # end
# # user_id = t.user_id
# # creator = User.find_by(id: user_id)
# # if project.nil? || owner.nil? || creator.nil?
# # else
# # results << [creator, owner, project, t]
# # end
# # end
# # render json: { results: results }
# # end
# #
# # def blockchain_trade
# # #is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
# # is_current_admin_user = true
# # if is_current_admin_user
# # user_id2 = params['user_id2'].to_i
# # trade_id = params['trade_id'].to_i
# # BlockchainTrade.find(trade_id).update(user_id2: user_id2, state: 1) # state=1表示锁定了等待线下卖家发货
# # render json: {status: 2} # window.location.reload()
# # else
# # normal_status(-1, "缺少权限")
# # end
# # end
#
#
# def blockchain_verify_trade
# #is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
# is_current_admin_user = true
# if is_current_admin_user
# trade_id = params['trade_id'].to_i
# BlockchainTrade.find(trade_id).update(state: 2) # state=2表示确认收货
# render json: {status: 2} # window.location.reload()
# else
# normal_status(-1, "缺少权限")
# end
# end
#
# def blockchain_get_verify_trades
# #is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
# is_current_admin_user = true
# if is_current_admin_user
# trades = BlockchainTrade.where(state: 1).all()
# results = []
# trades.each do |t|
# project_id = t.project_id
# project = Project.find_by(id: project_id)
# if !project.nil?
# owner = User.find_by(id: project.user_id)
# else
# owner = nil
# end
# user_id = t.user_id
# creator = User.find_by(id: user_id)
# user_id2 = t.user_id2
# buyer = User.find_by(id: user_id2)
# if project.nil? || owner.nil? || creator.nil? || buyer.nil?
# else
# results << [creator, owner, project, t, buyer]
# end
# end
# render json: { results: results }
# else
# normal_status(-1, "缺少权限")
# end
# end
#
# def blockchain_get_history_trades
# #is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
# is_current_admin_user = true
# if is_current_admin_user
# trades = BlockchainTrade.where(state: 2).all()
# results = []
# trades.each do |t|
# project_id = t.project_id
# project = Project.find_by(id: project_id)
# if !project.nil?
# owner = User.find_by(id: project.user_id)
# else
# owner = nil
# end
# user_id = t.user_id
# creator = User.find_by(id: user_id)
# user_id2 = t.user_id2
# buyer = User.find_by(id: user_id2)
# if project.nil? || owner.nil? || creator.nil? || buyer.nil?
# else
# results << [creator, owner, project, t, buyer]
# end
# end
# render json: { results: results }
# else
# normal_status(-1, "缺少权限")
# end
# end
def blockchain_get_issue_token_num
issue_id = params["issue_id"]['orderId'].to_i
issue = Issue.find_by(id: issue_id)
project = Project.find(issue.project_id)
if project[:use_blockchain]
render json: {"blockchain_token_num": issue.blockchain_token_num}
else
render json: {"blockchain_token_num": -1} # 未使用blockchain
end
end
def blockchain_get_unclosed_issue_list
ownername = params["ownername"]
identifier = params["reponame"]
owner = User.find_by(login: ownername)
project = Project.find_by(user_id: owner.id, identifier: identifier)
unclosed_issues = Issue.where(project_id: project.id, issue_classify: "issue").where.not(status_id: 5)
results = []
unclosed_issues.each do |i|
results << [i.id, i.subject]
end
render json: {unclosed_issues: results}
end
# TODO 其他平台登录时同步修改gitea平台对应用户的密码
# 该方法主要用于别的平台初次部署对接forge平台同步用户后gitea平台对应的用户密码与forge平台用户密码不一致是问题
def sync_gitea_pwd
@@ -322,7 +693,7 @@ class UsersController < ApplicationController
end
end
def email_search
def email_search
return render_error('请输入email') if params[:email].blank?
@user = User.find_by(mail: params[:email])
end