fix: merge from pre_trustie_server

This commit is contained in:
yystopf 2022-04-01 18:35:08 +08:00
commit 0154115f6b
37 changed files with 1059 additions and 648 deletions

View File

@ -217,7 +217,7 @@ class AttachmentsController < ApplicationController
if @file.container && current_user.logged?
if @file.container.is_a?(Issue)
course = @file.container.project
candown = course.member?(current_user)
candown = course.member?(current_user) || course.is_public
elsif @file.container.is_a?(Journal)
course = @file.container.issue.project
candown = course.member?(current_user)

View File

@ -16,6 +16,7 @@ class CompareController < ApplicationController
if @base.blank? || @head.blank?
return -2, "请选择分支"
else
return -2, "目标仓库未开启合并请求PR功能" unless @project.has_menu_permission("pulls")
if @head.include?(":")
fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take
return -2, "请选择正确的仓库" unless fork_project.present?
@ -50,6 +51,6 @@ class CompareController < ApplicationController
end
def gitea_compare(base, head)
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, CGI.escape(base), CGI.escape(head), current_user.gitea_token)
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), current_user.gitea_token)
end
end

View File

@ -24,7 +24,7 @@ class IssuesController < ApplicationController
@filter_issues = @all_issues
@filter_issues = @filter_issues.where.not(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::ADD
@filter_issues = @filter_issues.where(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::SOLVING
@filter_issues = @filter_issues.where("subject LIKE ? OR description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
@filter_issues = @filter_issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
@open_issues = @all_issues.where.not(status_id: IssueStatus::CLOSED)
@close_issues = @all_issues.where(status_id: IssueStatus::CLOSED)
scopes = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "Issue")

View File

@ -5,7 +5,11 @@ class Organizations::OrganizationUsersController < Organizations::BaseController
def index
@organization_users = @organization.organization_users.includes(:user)
search = params[:search].to_s.downcase
@organization_users = @organization_users.joins(:user).merge(User.like(search))
user_condition_users = User.like(search).to_sql
team_condition_teams = User.joins(:teams).merge(@organization.teams.like(search)).to_sql
users = User.from("( #{user_condition_users} UNION #{team_condition_teams }) AS users")
@organization_users = @organization_users.where(user_id: users).distinct
@organization_users = kaminari_paginate(@organization_users)
end

View File

@ -135,7 +135,7 @@ class ProjectsController < ApplicationController
validate_params = project_params.slice(:name, :description,
:project_category_id, :project_language_id, :private, :identifier)
Projects::UpdateForm.new(validate_params.merge(user_id: @project.user_id, project_identifier: @project.identifier)).validate!
Projects::UpdateForm.new(validate_params.merge(user_id: @project.user_id, project_identifier: @project.identifier, project_name: @project.name)).validate!
private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : params[:private] || false

View File

@ -2,7 +2,7 @@ class PullRequestsController < ApplicationController
before_action :require_login, except: [:index, :show, :files, :commits]
before_action :require_profile_completed, only: [:create]
before_action :load_repository
before_action :check_menu_authorize
before_action :check_menu_authorize, only: [:index, :show, :create, :update, :refuse_merge, :pr_merge]
before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos, :files, :commits]
before_action :load_pull_request, only: [:files, :commits]
before_action :find_atme_receivers, only: [:create, :update]
@ -16,7 +16,7 @@ class PullRequestsController < ApplicationController
issues = issues.where(is_private: false) unless current_user.present? && (current_user.admin? || @project.member?(current_user))
@all_issues = issues.distinct
@filter_issues = @all_issues
@filter_issues = @filter_issues.where("subject LIKE ? OR description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
@filter_issues = @filter_issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
@open_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::OPEN})
@close_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::CLOSED})
@merged_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::MERGED})

View File

@ -1,390 +1,390 @@
class RepositoriesController < ApplicationController
include RepositoriesHelper
include ApplicationHelper
include OperateProjectAbilityAble
include Repository::LanguagesPercentagable
before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror]
before_action :require_profile_completed, only: [:create_file]
before_action :load_repository
before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive]
before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror]
before_action :get_ref, only: %i[entries sub_entries top_counts file archive]
before_action :get_latest_commit, only: %i[entries sub_entries top_counts]
before_action :get_statistics, only: %i[top_counts]
def files
result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token)
render json: result
end
# 新版项目详情
def detail
@user = current_user
@result = Repositories::DetailService.call(@owner, @repository, @user)
@project_fork_id = @project.try(:forked_from_project_id)
if @project_fork_id.present?
@fork_project = Project.find_by(id: @project_fork_id)
@fork_project_user = @fork_project.owner
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def show
@user = current_user
@repo = @project.repository
@result = @project.forge? ? Gitea::Repository::GetService.new(@owner, @project.identifier).call : nil
@project_fork_id = @project.try(:forked_from_project_id)
if @project_fork_id.present?
@fork_project = Project.find_by(id: @project_fork_id)
@fork_project_user = @fork_project.owner
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def entries
@project.increment!(:visits)
CacheAsyncSetJob.perform_later("project_common_service", {visits: 1}, @project.id)
if @project.educoder?
@entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder.repo_name)
else
@entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call
@entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : []
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
end
end
def top_counts
@result = @project.educoder? ? nil : Gitea::Repository::GetService.new(@project.owner, @project.identifier).call
end
def sub_entries
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
if @project.educoder?
if params[:type] === 'file'
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
logger.info "######### sub_entries: #{@sub_entries}"
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
tmp_entries = {
"content" => @sub_entries['data']['content'],
"type" => "blob"
}
@sub_entries = {
"trees"=>tmp_entries,
"commits" => [{}]
}
else
begin
@sub_entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder&.repo_name, {path: file_path_uri})
if @sub_entries.blank? || @sub_entries['status'].to_i === -1
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
tmp_entries = {
"content" => @sub_entries['data']['content'],
"type" => "blob"
}
@sub_entries = {
"trees"=>tmp_entries,
"commits" => [{}]
}
end
rescue
return render_error('该文件暂未开放,敬请期待.')
end
end
else
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref)
if interactor.success?
result = interactor.result
@sub_entries = result.is_a?(Array) ? result.sort_by{ |hash| hash['type'] } : result
else
render_error(interactor.error)
end
end
end
def commits
if @project.educoder?
@commits = Educoder::Repository::Commits::ListService.call(@project&.project_educoder&.repo_name)
else
if params[:filepath].present?
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
@hash_commit = Gitea::Repository::Commits::FileListService.new(@owner.login, @project.identifier, file_path_uri,
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
else
@hash_commit = Gitea::Repository::Commits::ListService.new(@owner.login, @project.identifier,
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
end
end
end
def commits_slice
@hash_commit = Gitea::Repository::Commits::ListSliceService.call(@owner.login, @project.identifier,
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token)
end
def commit
@sha = params[:sha]
if @project.educoder?
return render_error('暂未开放,敬请期待.')
else
@commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token)
@commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token, {diff: true})
end
end
def tags
result = Gitea::Repository::Tags::ListService.call(current_user&.gitea_token, @owner.login, @project.identifier, {page: params[:page], limit: params[:limit]})
@tags = result.is_a?(Hash) && result.key?(:status) ? [] : result
end
def contributors
if params[:filepath].present? || @project.educoder?
@contributors = []
else
result = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
@contributors = result.is_a?(Hash) && result.key?(:status) ? [] : result
end
rescue
@contributors = []
end
def edit
return render_forbidden if !@project.manager?(current_user) && !current_user.admin?
end
def create_file
interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params)
if interactor.success?
@file = interactor.result
# create_new_pr(params)
#如果是更新流水线文件
if params[:pipeline_id]
update_pipeline(params[:pipeline_id])
end
else
render_error(interactor.error)
end
end
def update_pipeline(pipeline_id)
pipeline = Ci::Pipeline.find(pipeline_id)
if pipeline
pipeline.update!(sync: 1)
end
end
def update_file
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
if interactor.success?
@file = interactor.result
# TODO: 是否创建pr
# create_new_pr(params)
render_result(1, "更新成功")
else
render_error(interactor.error)
end
end
def delete_file
interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
if interactor.success?
@file = interactor.result
render_result(1, "文件删除成功")
else
render_error(interactor.error)
end
end
def repo_hook
end
def sync_mirror
return render_error("正在镜像中..") if @repository.mirror.waiting?
@repository.sync_mirror!
SyncMirroredRepositoryJob.perform_later(@repository.id, current_user.id)
render_ok
end
def readme
if params[:filepath].present?
result = Gitea::Repository::Readme::DirService.call(@owner.login, @repository.identifier, params[:filepath], params[:ref], current_user&.gitea_token)
else
result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token)
end
@path = Gitea.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
@readme = result[:status] === :success ? result[:body] : nil
@readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path)
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha")
rescue
render json: nil
end
def languages
if @project.educoder?
render json: {}
else
render json: languages_precentagable
end
end
def archive
domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url]
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{CGI.escape(params[:archive])}"
file_path = [domain, api_url, archive_url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
return render_not_found if !request.format.zip? && !request.format.gzip?
redirect_to file_path
end
def raw
domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url]
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{CGI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}"
file_path = [domain, api_url, url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&")
redirect_to file_path
end
private
def find_project
@project = Project.find params[:id]
render_not_found("未找到相关的仓库") unless @project
end
def find_project_with_includes
@project = Project.includes(:repository, :owner, :watchers, :praise_treads).find params[:id]
end
def authorizate!
return if current_user && current_user.admin?
if @project.repository.hidden? && !@project.member?(current_user)
render_forbidden
end
end
# TODO 获取最新commit信息
def project_commits
if params[:filepath].present?
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
Gitea::Repository::Commits::FileListService.new(@project.owner.login, @project.identifier, file_path_uri,
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
else
Gitea::Repository::Commits::ListService.new(@project.owner.login, @project.identifier,
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
end
end
def get_statistics
@branches_count = @project.educoder? ? 0 : Gitea::Repository::Branches::ListService.new(@project.owner, @project.identifier).call&.size
@tags_count = @project.educoder? ? 0 : Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @project.owner.login, @project.identifier).call&.size
end
def get_ref
@ref = params[:ref] || @project&.default_branch
end
def get_latest_commit
latest_commit = @project.educoder? ? nil : project_commits
@latest_commit = latest_commit.present? ? latest_commit[:body][0] : nil
@commits_count = latest_commit.present? ? latest_commit[:total_count] : 0
end
def content_params
{
filepath: params[:filepath],
branch: params[:branch],
new_branch: params[:new_branch],
content: params[:content],
message: params[:message],
committer: {
email: current_user.mail,
name: current_user.login
},
identifier: @project.identifier
}
end
def hook_params(hook_type, params)
# if hook_type == "push"
# # TODO hook返回的记录中暂时没有文件代码数量的增减暂时根据 commits数量来计算
# uploadPushInfo = {
# "sha": params["commits"].present? ? params["commits"].last : "",
# "branch": params["ref"].to_s.split("/").last,
# "modification_lines": params["commits"].length
# }
# elsif hook_type == "pull_request" && params["action"].to_s == "closed" #合并请求合并后才会有上链操作
# uploadPushInfo = {
# "branch": params["base"]["ref"].to_s.split("/").last,
# "sha": params["pull_request"]["merge_base"],
# "modification_lines": 1 #pull_request中没有commits数量
# }
# else
# uploadPushInfo = {}
# end
# uploadPushInfo
end
def create_new_pr(params)
if params[:new_branch].present? && params[:new_branch] != params[:branch]
local_params = {
title: params[:message], #标题
body: params[:content], #内容
head: params[:new_branch], #源分支
base: params[:branch], #目标分支
milestone: 0 #里程碑,未与本地的里程碑关联
}
requests_params = local_params.merge({
assignee: current_user.try(:login),
assignees: [],
labels: [],
due_date: Time.now
})
issue_params = {
author_id: current_user.id,
project_id: @project.id,
subject: params[:message],
description: params[:content],
assigned_to_id: nil,
fixed_version_id: nil,
issue_tags_value: nil,
issue_classify: "pull_request",
issue_type: "1",
tracker_id: 2,
status_id: 1,
priority_id: params[:priority_id] || "2"
}
@pull_issue = Issue.new(issue_params)
if @pull_issue.save!
local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id))
if local_requests.save
gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call
if gitea_request[:status] == :success && local_requests.update_attributes(gpid: gitea_request["body"]["number"])
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
end
end
end
end
end
end
class RepositoriesController < ApplicationController
include RepositoriesHelper
include ApplicationHelper
include OperateProjectAbilityAble
include Repository::LanguagesPercentagable
before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror]
before_action :require_profile_completed, only: [:create_file]
before_action :load_repository
before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive]
before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror]
before_action :get_ref, only: %i[entries sub_entries top_counts file archive]
before_action :get_latest_commit, only: %i[entries sub_entries top_counts]
before_action :get_statistics, only: %i[top_counts]
def files
result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token)
render json: result
end
# 新版项目详情
def detail
@user = current_user
@result = Repositories::DetailService.call(@owner, @repository, @user)
@project_fork_id = @project.try(:forked_from_project_id)
if @project_fork_id.present?
@fork_project = Project.find_by(id: @project_fork_id)
@fork_project_user = @fork_project.owner
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def show
@user = current_user
@repo = @project.repository
@result = @project.forge? ? Gitea::Repository::GetService.new(@owner, @project.identifier).call : nil
@project_fork_id = @project.try(:forked_from_project_id)
if @project_fork_id.present?
@fork_project = Project.find_by(id: @project_fork_id)
@fork_project_user = @fork_project.owner
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def entries
@project.increment!(:visits)
CacheAsyncSetJob.perform_later("project_common_service", {visits: 1}, @project.id)
if @project.educoder?
@entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder.repo_name)
else
@entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call
@entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : []
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
end
end
def top_counts
@result = @project.educoder? ? nil : Gitea::Repository::GetService.new(@project.owner, @project.identifier).call
end
def sub_entries
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
if @project.educoder?
if params[:type] === 'file'
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
logger.info "######### sub_entries: #{@sub_entries}"
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
tmp_entries = {
"content" => @sub_entries['data']['content'],
"type" => "blob"
}
@sub_entries = {
"trees"=>tmp_entries,
"commits" => [{}]
}
else
begin
@sub_entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder&.repo_name, {path: file_path_uri})
if @sub_entries.blank? || @sub_entries['status'].to_i === -1
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
tmp_entries = {
"content" => @sub_entries['data']['content'],
"type" => "blob"
}
@sub_entries = {
"trees"=>tmp_entries,
"commits" => [{}]
}
end
rescue
return render_error('该文件暂未开放,敬请期待.')
end
end
else
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref)
if interactor.success?
result = interactor.result
@sub_entries = result.is_a?(Array) ? result.sort_by{ |hash| hash['type'] } : result
else
render_error(interactor.error)
end
end
end
def commits
if @project.educoder?
@commits = Educoder::Repository::Commits::ListService.call(@project&.project_educoder&.repo_name)
else
if params[:filepath].present?
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
@hash_commit = Gitea::Repository::Commits::FileListService.new(@owner.login, @project.identifier, file_path_uri,
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
else
@hash_commit = Gitea::Repository::Commits::ListService.new(@owner.login, @project.identifier,
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
end
end
end
def commits_slice
@hash_commit = Gitea::Repository::Commits::ListSliceService.call(@owner.login, @project.identifier,
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token)
end
def commit
@sha = params[:sha]
if @project.educoder?
return render_error('暂未开放,敬请期待.')
else
@commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token)
@commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token, {diff: true})
end
end
def tags
result = Gitea::Repository::Tags::ListService.call(current_user&.gitea_token, @owner.login, @project.identifier, {page: params[:page], limit: params[:limit]})
@tags = result.is_a?(Hash) && result.key?(:status) ? [] : result
end
def contributors
if params[:filepath].present? || @project.educoder?
@contributors = []
else
result = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
@contributors = result.is_a?(Hash) && result.key?(:status) ? [] : result
end
rescue
@contributors = []
end
def edit
return render_forbidden if !@project.manager?(current_user) && !current_user.admin?
end
def create_file
interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params)
if interactor.success?
@file = interactor.result
# create_new_pr(params)
#如果是更新流水线文件
if params[:pipeline_id]
update_pipeline(params[:pipeline_id])
end
else
render_error(interactor.error)
end
end
def update_pipeline(pipeline_id)
pipeline = Ci::Pipeline.find(pipeline_id)
if pipeline
pipeline.update!(sync: 1)
end
end
def update_file
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
if interactor.success?
@file = interactor.result
# TODO: 是否创建pr
# create_new_pr(params)
render_result(1, "更新成功")
else
render_error(interactor.error)
end
end
def delete_file
interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
if interactor.success?
@file = interactor.result
render_result(1, "文件删除成功")
else
render_error(interactor.error)
end
end
def repo_hook
end
def sync_mirror
return render_error("正在镜像中..") if @repository.mirror.waiting?
@repository.sync_mirror!
SyncMirroredRepositoryJob.perform_later(@repository.id, current_user.id)
render_ok
end
def readme
if params[:filepath].present?
result = Gitea::Repository::Readme::DirService.call(@owner.login, @repository.identifier, params[:filepath], params[:ref], current_user&.gitea_token)
else
result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token)
end
@path = Gitea.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
@readme = result[:status] === :success ? result[:body] : nil
@readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path)
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha")
rescue
render json: nil
end
def languages
if @project.educoder?
render json: {}
else
render json: languages_precentagable
end
end
def archive
domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url]
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{Addressable::URI.escape(params[:archive])}"
file_path = [domain, api_url, archive_url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
return render_not_found if !request.format.zip? && !request.format.gzip?
redirect_to file_path
end
def raw
domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url]
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{Addressable::URI.escape(params[:filepath])}?ref=#{Addressable::URI.escape(params[:ref])}"
file_path = [domain, api_url, url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&")
redirect_to file_path
end
private
def find_project
@project = Project.find params[:id]
render_not_found("未找到相关的仓库") unless @project
end
def find_project_with_includes
@project = Project.includes(:repository, :owner, :watchers, :praise_treads).find params[:id]
end
def authorizate!
return if current_user && current_user.admin?
if @project.repository.hidden? && !@project.member?(current_user)
render_forbidden
end
end
# TODO 获取最新commit信息
def project_commits
if params[:filepath].present?
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
Gitea::Repository::Commits::FileListService.new(@project.owner.login, @project.identifier, file_path_uri,
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
else
Gitea::Repository::Commits::ListService.new(@project.owner.login, @project.identifier,
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
end
end
def get_statistics
@branches_count = @project.educoder? ? 0 : Gitea::Repository::Branches::ListService.new(@project.owner, @project.identifier).call&.size
@tags_count = @project.educoder? ? 0 : Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @project.owner.login, @project.identifier).call&.size
end
def get_ref
@ref = params[:ref] || @project&.default_branch
end
def get_latest_commit
latest_commit = @project.educoder? ? nil : project_commits
@latest_commit = latest_commit.present? ? latest_commit[:body][0] : nil
@commits_count = latest_commit.present? ? latest_commit[:total_count] : 0
end
def content_params
{
filepath: params[:filepath],
branch: params[:branch],
new_branch: params[:new_branch],
content: params[:content],
message: params[:message],
committer: {
email: current_user.mail,
name: current_user.login
},
identifier: @project.identifier
}
end
def hook_params(hook_type, params)
# if hook_type == "push"
# # TODO hook返回的记录中暂时没有文件代码数量的增减暂时根据 commits数量来计算
# uploadPushInfo = {
# "sha": params["commits"].present? ? params["commits"].last : "",
# "branch": params["ref"].to_s.split("/").last,
# "modification_lines": params["commits"].length
# }
# elsif hook_type == "pull_request" && params["action"].to_s == "closed" #合并请求合并后才会有上链操作
# uploadPushInfo = {
# "branch": params["base"]["ref"].to_s.split("/").last,
# "sha": params["pull_request"]["merge_base"],
# "modification_lines": 1 #pull_request中没有commits数量
# }
# else
# uploadPushInfo = {}
# end
# uploadPushInfo
end
def create_new_pr(params)
if params[:new_branch].present? && params[:new_branch] != params[:branch]
local_params = {
title: params[:message], #标题
body: params[:content], #内容
head: params[:new_branch], #源分支
base: params[:branch], #目标分支
milestone: 0 #里程碑,未与本地的里程碑关联
}
requests_params = local_params.merge({
assignee: current_user.try(:login),
assignees: [],
labels: [],
due_date: Time.now
})
issue_params = {
author_id: current_user.id,
project_id: @project.id,
subject: params[:message],
description: params[:content],
assigned_to_id: nil,
fixed_version_id: nil,
issue_tags_value: nil,
issue_classify: "pull_request",
issue_type: "1",
tracker_id: 2,
status_id: 1,
priority_id: params[:priority_id] || "2"
}
@pull_issue = Issue.new(issue_params)
if @pull_issue.save!
local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id))
if local_requests.save
gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call
if gitea_request[:status] == :success && local_requests.update_attributes(gpid: gitea_request["body"]["number"])
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
end
end
end
end
end
end

View File

@ -1,6 +1,7 @@
class SettingsController < ApplicationController
def show
@old_projects_url = nil
get_navbar
get_add_menu
get_common_menu
get_personal_menu
@ -9,6 +10,14 @@ class SettingsController < ApplicationController
end
private
def get_navbar
@navbar = default_laboratory.navbar
if User.current.logged?
pernal_index = {"name"=>"个人主页", "link"=>get_site_url("link", "/current_user"), "hidden"=>false}
@navbar << pernal_index
end
end
def get_add_menu
@add = []
Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site|

View File

@ -12,7 +12,7 @@ class Users::StatisticsController < Users::BaseController
@commit_data = []
date_range.each do |date|
@date_data << date.strftime("%Y.%m.%d")
@issue_data << observed_user.issues.where("DATE(created_on) = ?", date).size
@issue_data << observed_user.issues.issue_issue.where("DATE(created_on) = ?", date).size
@pull_request_data << observed_user.pull_requests.where("DATE(created_at) = ?", date).size
date_commit_data = commit_data.blank? ? nil : commit_data.select{|item| item["timestamp"] == date.to_time.to_i}
@commit_data << (date_commit_data.blank? ? 0 : date_commit_data[0]["contributions"].to_i)

View File

@ -49,7 +49,7 @@ class BaseForm
def check_verifi_code(verifi_code, code)
code = strip(code)
# return if code == "123123" # TODO 万能验证码,用于测试
return if code == "123123" && EduSetting.get("code_debug") # 万能验证码,用于测试 # TODO 万能验证码,用于测试
raise VerifiCodeError, "验证码已失效" if !verifi_code&.effective?
raise VerifiCodeError, "验证码不正确" if verifi_code&.code != code
end

View File

@ -1,5 +1,5 @@
class Projects::UpdateForm < BaseForm
attr_accessor :name, :description, :project_category_id, :project_language_id, :private, :identifier, :user_id, :project_identifier
attr_accessor :name, :description, :project_category_id, :project_language_id, :private, :identifier, :user_id, :project_identifier, :project_name
validates :name, presence: true
validates :name, length: { maximum: 50 }
validates :description, length: { maximum: 200 }
@ -10,6 +10,7 @@ class Projects::UpdateForm < BaseForm
check_project_language(project_language_id)
check_repository_name(user_id, identifier) unless identifier.blank? || identifier == project_identifier
check_project_name(user_id, name) unless name.blank? || name == project_name
end
end

View File

@ -1,148 +1,170 @@
module RepositoriesHelper
def render_permission(user, project)
return "Admin" if user&.admin?
project.get_premission(user)
end
def render_decode64_content(str)
return nil if str.blank?
Base64.decode64(str).force_encoding("UTF-8").encode("UTF-8", invalid: :replace)
end
def download_type(str)
default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb RData rdata doc docx mpp vsdx dot otf eot ttf woff woff2 mp4 mov wmv flv mpeg avi avchd webm mkv)
default_type.include?(str&.downcase) || str.blank?
end
def image_type?(str)
default_type = %w(png jpg gif tif psd svg bmp webp jpeg ico psd)
default_type.include?(str&.downcase)
end
def is_readme?(type, str)
return false if type != 'file' || str.blank?
readme_types = ["readme.md", "readme", "readme_en.md", "readme_zh.md", "readme_en", "readme_zh"]
readme_types.include?(str.to_s.downcase)
end
def render_commit_author(author_json)
return nil if author_json.blank? || (author_json["id"].blank? && author_json['name'].blank?)
if author_json["id"].present?
return find_user_by_gitea_uid author_json['id']
end
if author_json["id"].nil? && (author_json["name"].present? && author_json["email"].present?)
return find_user_by_login_and_mail(author_json['name'], author_json["email"])
end
end
def render_cache_commit_author(author_json)
Rails.logger.info author_json['Email']
if author_json["name"].present? && author_json["email"].present?
return find_user_in_redis_cache(author_json['name'], author_json['email'])
end
if author_json["Name"].present? && author_json["Email"].present?
return find_user_in_redis_cache(author_json['Name'], author_json['Email'])
end
end
def readme_render_decode64_content(str, owner, repo, ref)
return nil if str.blank?
begin
content = Base64.decode64(str).force_encoding('UTF-8')
c_regex = /\!\[.*?\]\((.*?)\)/
src_regex = /src=\"(.*?)\"/
ss = content.to_s.scan(c_regex)
ss_src = content.to_s.scan(src_regex)
total_images = ss + ss_src
if total_images.length > 0
total_images.each do |s|
image_title = /\"(.*?)\"/
r_content = s[0]
remove_title = r_content.to_s.scan(image_title)
if remove_title.length > 0
r_content = r_content.gsub(/#{remove_title[0]}/, "").strip
end
# if r_content.include?("?")
# new_r_content = r_content + "&raw=true"
# else
# new_r_content = r_content + "?raw=true"
# end
new_r_content = r_content
unless r_content.include?("http://") || r_content.include?("https://") || r_content.include?("mailto:")
# new_r_content = "#{path}" + new_r_content
new_r_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{r_content}&ref=#{ref}"].join
end
content = content.gsub(/#{r_content}/, new_r_content)
end
end
return content
rescue
return str
end
end
# unix_time values for example: 1604382982
def render_format_time_with_unix(unix_time)
Time.at(unix_time).strftime("%Y-%m-%d %H:%M")
end
# date for example: 2020-11-01T19:57:27+08:00
def render_format_time_with_date(date)
date.to_time.strftime("%Y-%m-%d %H:%M")
end
def decode64_content(entry, owner, repo, ref, path=nil)
if is_readme?(entry['type'], entry['name'])
content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content']
readme_render_decode64_content(content, owner, repo, ref)
else
file_type = File.extname(entry['name'].to_s)[1..-1]
if image_type?(file_type)
return entry['content'].nil? ? Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] : entry['content']
end
if download_type(file_type)
return entry['content']
end
render_decode64_content(entry['content'])
end
end
def base64_to_image(path, content)
# generate to https://git.trusite.net/pawm36ozq/-/raw/branch/master/entrn.png"
content = Base64.decode64(content)
File.open(path, 'wb') { |f| f.write(content) }
end
def render_download_image_url(dir_path, file_path, content)
full_path = file_path.starts_with?("/") ? [dir_path, file_path].join("") : [dir_path, file_path].join("/")
file_name = full_path.split("/")[-1]
# 用户名/项目标识/文件路径
dir_path = generate_dir_path(full_path.split("/"+file_name)[0])
file_path = [dir_path, file_name].join('/')
puts "##### render_download_image_url file_path: #{file_path}"
base64_to_image(file_path, content)
file_path = file_path[6..-1]
File.join(base_url, file_path)
end
def generate_dir_path(dir_path)
# tmp_dir_path
# eg: jasder/forgeplus/raw/branch/ref
dir_path = ["public", tmp_dir, dir_path].join('/')
puts "#### dir_path: #{dir_path}"
unless Dir.exists?(dir_path)
FileUtils.mkdir_p(dir_path) ##不成功这里会抛异常
end
dir_path
end
def tmp_dir
"repo"
end
end
module RepositoriesHelper
def render_permission(user, project)
return "Admin" if user&.admin?
project.get_premission(user)
end
def render_decode64_content(str)
return nil if str.blank?
Base64.decode64(str).force_encoding("UTF-8").encode("UTF-8", invalid: :replace)
end
def download_type(str)
default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb RData rdata doc docx mpp vsdx dot otf eot ttf woff woff2 mp4 mov wmv flv mpeg avi avchd webm mkv)
default_type.include?(str&.downcase) || str.blank?
end
def image_type?(str)
default_type = %w(png jpg gif tif psd svg bmp webp jpeg ico psd)
default_type.include?(str&.downcase)
end
def is_readme?(type, str)
return false if type != 'file' || str.blank?
readme_types = ["readme.md", "readme", "readme_en.md", "readme_zh.md", "readme_en", "readme_zh"]
readme_types.include?(str.to_s.downcase)
end
def render_commit_author(author_json)
return nil if author_json.blank? || (author_json["id"].blank? && author_json['name'].blank?)
if author_json["id"].present?
return find_user_by_gitea_uid author_json['id']
end
if author_json["id"].nil? && (author_json["name"].present? && author_json["email"].present?)
return find_user_by_login_and_mail(author_json['name'], author_json["email"])
end
end
def render_cache_commit_author(author_json)
Rails.logger.info author_json['Email']
if author_json["name"].present? && author_json["email"].present?
return find_user_in_redis_cache(author_json['name'], author_json['email'])
end
if author_json["Name"].present? && author_json["Email"].present?
return find_user_in_redis_cache(author_json['Name'], author_json['Email'])
end
end
def readme_render_decode64_content(str, owner, repo, ref, path)
return nil if str.blank?
begin
content = Base64.decode64(str).force_encoding('UTF-8')
c_regex = /\!\[.*?\]\((.*?)\)/
src_regex = /src=\"(.*?)\"/
src2_regex = /src='(.*?)'/
ss = content.to_s.scan(c_regex)
ss_src = content.scan(src_regex)
ss_src2 = content.scan(src2_regex)
total_images = ss + ss_src + ss_src2
if total_images.length > 0
total_images.each do |s|
begin
image_title = /\"(.*?)\"/
r_content = s[0]
remove_title = r_content.to_s.scan(image_title)
# if remove_title.length > 0
# r_content = r_content.gsub(/#{remove_title[0]}/, "").strip
# end
path_last = r_content
path_current = ""
# 相对路径处理
if r_content.start_with?("../")
relative_path_length = r_content.split("../").size - 1
path_pre = path.split("/").size - 1 - relative_path_length
path_pre = 0 if path_pre < 0
path_current = path_pre == 0 ? "" : path.split("/")[0..path_pre].join("/")
path_last = r_content.split("../").last
elsif r_content.start_with?("/") # 根路径处理
path_last = r_content[1..r_content.size]
else
path_current = path
end
# if r_content.include?("?")
# new_r_content = r_content + "&raw=true"
# else
# new_r_content = r_content + "?raw=true"
# end
new_r_content = r_content
unless r_content.include?("http://") || r_content.include?("https://") || r_content.include?("mailto:")
# new_r_content = "#{path}" + new_r_content
new_r_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{path_current}/#{path_last}&ref=#{ref}"].join
end
content = content.gsub(/src=\"#{r_content}\"/, "src=\"#{new_r_content}\"").gsub(/src='#{r_content}'/, "src=\"#{new_r_content}\"")
rescue
next
end
end
end
return content
rescue
return str
end
end
# unix_time values for example: 1604382982
def render_format_time_with_unix(unix_time)
Time.at(unix_time).strftime("%Y-%m-%d %H:%M")
end
# date for example: 2020-11-01T19:57:27+08:00
def render_format_time_with_date(date)
date.to_time.strftime("%Y-%m-%d %H:%M")
end
def decode64_content(entry, owner, repo, ref, path=nil)
if is_readme?(entry['type'], entry['name'])
# content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content']
content = entry['content']
path = URI.escape(entry['path']).to_s.downcase.gsub("/readme.md","")
readme_render_decode64_content(content, owner, repo, ref, path)
else
file_type = File.extname(entry['name'].to_s)[1..-1]
if image_type?(file_type)
return entry['content'].nil? ? Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] : entry['content']
end
if download_type(file_type)
return entry['content']
end
render_decode64_content(entry['content'])
end
end
def base64_to_image(path, content)
# generate to https://git.trusite.net/pawm36ozq/-/raw/branch/master/entrn.png"
content = Base64.decode64(content)
File.open(path, 'wb') { |f| f.write(content) }
end
def render_download_image_url(dir_path, file_path, content)
full_path = file_path.starts_with?("/") ? [dir_path, file_path].join("") : [dir_path, file_path].join("/")
file_name = full_path.split("/")[-1]
# 用户名/项目标识/文件路径
dir_path = generate_dir_path(full_path.split("/"+file_name)[0])
file_path = [dir_path, file_name].join('/')
puts "##### render_download_image_url file_path: #{file_path}"
base64_to_image(file_path, content)
file_path = file_path[6..-1]
File.join(base_url, file_path)
end
def generate_dir_path(dir_path)
# tmp_dir_path
# eg: jasder/forgeplus/raw/branch/ref
dir_path = ["public", tmp_dir, dir_path].join('/')
puts "#### dir_path: #{dir_path}"
unless Dir.exists?(dir_path)
FileUtils.mkdir_p(dir_path) ##不成功这里会抛异常
end
dir_path
end
def tmp_dir
"repo"
end
end

21
app/libs/trace.rb Normal file
View File

@ -0,0 +1,21 @@
module Trace
class << self
def trace_config
trace_config = {}
begin
config = Rails.application.config_for(:configuration).symbolize_keys!
trace_config = config[:trace].symbolize_keys!
raise 'trace config missing' if trace_config.blank?
rescue => exception
raise ex if Rails.env.production?
puts %Q{\033[33m [warning] gitea config or configuration.yml missing,
please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
trace_config = {}
end
trace_config
end
end
end

View File

@ -29,6 +29,11 @@ class Team < ApplicationRecord
has_many :team_units, dependent: :destroy
has_many :team_users, dependent: :destroy
scope :like, lambda { |keywords|
sql = "teams.nickname LIKE :search OR teams.name LIKE :search"
where(sql, :search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank?
}
validates :name, uniqueness: {scope: :organization_id}
enum authorize: {read: 1, write: 2, admin: 3, owner: 4}

58
app/models/trace_user.rb Normal file
View File

@ -0,0 +1,58 @@
# == Schema Information
#
# Table name: trace_users
#
# id :integer not null, primary key
# user_id :integer
# username :string(255)
# password :string(255)
# unit :string(255)
# telnumber :string(255)
# email :string(255)
# name :string(255)
# token :text(65535)
# expired_at :datetime
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_trace_users_on_user_id (user_id)
#
# 代码溯源 用户
class TraceUser < ApplicationRecord
belongs_to :user
def build_self_data
return if user.nil?
self.username = user.login
self.password = SecureRandom.hex
self.unit = user.custom_department.blank? ? 'GitLink' : user.custom_department
self.telnumber = user.phone.blank? ? '13800000000' : user.phone
self.email = user.mail
self.name = user.nickname.blank? ? user.login : user.nickname
self
end
def build_token
return if username.blank? || password.blank? || unit.blank? || telnumber.blank? || email.blank? || name.blank?
response = Trace::AddUserService.call(username, password, unit, telnumber, email, name)
self.token = response[1]['token']
self.expired_at = Time.now + 1.hours
end
def refresh_token
return if username.blank? || password.blank? || unit.blank? || telnumber.blank? || email.blank? || name.blank?
response = Trace::LoginService.call(username, password)
self.token = response[1]['token']
self.expired_at = Time.now + 1.hours
end
end

View File

@ -174,6 +174,7 @@ class User < Owner
has_many :system_notification_histories
has_many :system_notifications, through: :system_notification_histories
has_one :trace_user, dependent: :destroy
# Groups and active users
scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) }
@ -789,6 +790,24 @@ class User < Owner
self.nickname.present? && self.mail.present?
end
def trace_token
if trace_user.present?
if trace_user.expired_at < Time.now
trace_user.refresh_token
trace_user.save
end
return trace_user.token
else
tu = TraceUser.new
tu.user = self
tu.build_self_data
tu.build_token
tu.save
return tu.token
end
end
protected
def validate_password_length
# 管理员的初始密码是5位

View File

@ -27,12 +27,12 @@ class Issues::ListQueryService < ApplicationService
issues = issues.joins(:pull_request).where(pull_requests: {status: 1})
end
if search_name.present?
issues = issues.where("subject LIKE ? OR description LIKE ? ", "%#{search_name}%", "%#{search_name}%")
end
# if search_name.present?
# issues = issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{search_name}%", "%#{search_name}%")
# end
if start_time&.present? || end_time&.present?
issues = issues.where("start_date between ? and ?",start_time&.present? ? start_time.to_date : Time.now.to_date, end_time&.present? ? end_time.to_date : Time.now.to_date)
issues = issues.where("issues.start_date between ? and ?",start_time&.present? ? start_time.to_date : Time.now.to_date, end_time&.present? ? end_time.to_date : Time.now.to_date)
end
issues = issues.where(author_id: params[:author_id]) if params[:author_id].present? && params[:author_id].to_s != "all"

View File

@ -132,8 +132,8 @@ class PullRequests::CreateService < ApplicationService
end
def merge_original_pull_params
base_pull_params[:head] = CGI.escape(base_pull_params[:head])
base_pull_params[:base] = CGI.escape(base_pull_params[:base])
base_pull_params[:head] = Addressable::URI.escape(base_pull_params[:head])
base_pull_params[:base] = Addressable::URI.escape(base_pull_params[:base])
if pull_request.is_original && @params[:merge_user_login]
base_pull_params.merge(head: "#{@params[:merge_user_login]}:#{base_pull_params[:head]}")
else
@ -157,6 +157,7 @@ class PullRequests::CreateService < ApplicationService
raise "head参数不能为空" if @params[:head].blank?
raise "base参数不能为空" if @params[:base].blank?
raise "fork_project_id参数错误" if is_original && !@project.forked_projects.pluck(:id).include?(@params[:fork_project_id].to_i)
raise "merge_user_login参数错误" if is_original && @project.fork_users.joins(:user).where(users: {login: @params[:merge_user_login]}).blank?
raise "分支内容相同,无需创建合并请求" if @params[:head] === @params[:base] && !is_original
raise "合并请求已存在" if @project&.pull_requests.where(head: @params[:head], base: @params[:base], status: 0, is_original: is_original, fork_project_id: @params[:fork_project_id]).present?
raise @pull_issue.errors.full_messages.join(", ") unless pull_issue.valid?
@ -165,7 +166,7 @@ class PullRequests::CreateService < ApplicationService
def compare_head_base!
head = pull_request.is_original && @params[:merge_user_login] ? "#{@params[:merge_user_login]}/#{@project.identifier}:#{@params[:head]}" : @params[:head]
compare_result = Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, CGI.escape(@params[:base]), CGI.escape(head), @current_user.gitea_token)
compare_result = Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, Addressable::URI.escape(@params[:base]), Addressable::URI.escape(head), @current_user.gitea_token)
raise '分支内容相同,无需创建合并请求' if compare_result["Commits"].blank? && compare_result["Diff"].blank?
end

View File

@ -0,0 +1,37 @@
# 代码溯源 添加用户
class Trace::AddUserService < Trace::ClientService
# 用户名 密码 单位 手机号 邮箱 昵称
attr_accessor :username, :password, :unit, :telnumber, :email, :name
def initialize(username, password, unit, telnumber, email, name)
@username = username
@password = password
@unit = unit
@telnumber = telnumber
@email = email
@name = name
end
def call
result = post(url, {data: request_params})
response = render_response(result)
end
private
def request_params
{
username: username,
password: password,
unit: unit,
telnumber: telnumber,
email: email,
name: name
}
end
def url
"/user/addccfuser".freeze
end
end

View File

@ -0,0 +1,33 @@
# 代码溯源 查询检测结果
class Trace::CheckResultService < Trace::ClientService
attr_accessor :token, :project_name, :file_name, :page_num, :page_size
def initialize(token, project_name=nil, file_name=nil, page_num=1, page_size=15)
@token = token
@project_name = project_name
@file_name = file_name
@page_num = page_num
@page_size = page_size
end
def call
result = authed_get(token, url, request_params)
reponse = render_response(result)
end
private
def request_params
{
product_name: project_name,
file_name: file_name,
pageNum: page_num,
pageSize: page_size,
}
end
def url
"/user/checkresult".freeze
end
end

View File

@ -0,0 +1,36 @@
# 代码溯源 开始检测
class Trace::CheckService < Trace::ClientService
attr_accessor :token, :project, :if_branch, :branch_tag
def initialize(token, project, if_branch, branch_tag)
@token = token
@project = project
@if_branch = if_branch
@branch_tag = branch_tag
end
def call
result = authed_post(token, url, {data: request_params})
reponse = render_response(result)
end
private
def request_params
repo = Gitea::Repository::GetService.call(project&.owner&.login, project&.identifier)
{
product_name: project&.name,
product_type: project&.category&.name,
code_type: project&.language&.name,
product_desc: project&.description,
git_url: repo['clone_url'],
if_branch: if_branch,
branch_tag: branch_tag
}
end
def url
"/user/check".freeze
end
end

View File

@ -0,0 +1,143 @@
class Trace::ClientService < ApplicationService
def post(url, params={})
puts "[trace][POST] request params: #{params}"
conn.post do |req|
req.url full_url(url)
req.body = params[:data].to_json
end
end
def authed_post(token, url, params={})
puts "[trace][POST] request params: #{params}"
puts "[trace][POST] request token: #{token}"
conn.post do |req|
req.url full_url(url)
req.body = params[:data].to_json
req.headers['Authorization'] = token
end
end
def get(url, params={})
puts "[trace][GET] request params: #{params}"
conn.get do |req|
req.url full_url(url, 'get')
params.each_pair do |key, value|
req.params["#{key}"] = value
end
end
end
def authed_get(token, url, params={})
puts "[trace][GET] request params: #{params}"
puts "[trace][GET] request token: #{token}"
conn.get do |req|
req.url full_url(url, 'get')
params.each_pair do |key, value|
req.params["#{key}"] = value
end
req.headers['Authorization'] = token
end
end
def delete(url, params={})
puts "[trace][DELETE] request params: #{params}"
conn.delete do |req|
req.url full_url(url)
req.body = params[:data].to_json
end
end
def authed_delete(token, url, params={})
puts "[trace][DELETE] request params: #{params}"
puts "[trace][DELETE] request token: #{token}"
conn.delete do |req|
req.url full_url(url)
req.body = params[:data].to_json
req.headers['Authorization'] = token
end
end
def patch(url, params={})
puts "[trace][PATCH] request params: #{params}"
conn.patch do |req|
req.url full_url(url)
req.body = params[:data].to_json
end
end
def authed_patch(token, url, params={})
puts "[trace][PATCH] request params: #{params}"
puts "[trace][PATCH] request token: #{token}"
conn.patch do |req|
req.url full_url(url)
req.body = params[:data].to_json
req.headers['Authorization'] = token
end
end
def put(url, params={})
puts "[trace][PUT] request params: #{params}"
conn.put do |req|
req.url full_url(url)
req.body = params[:data].to_json
end
end
def authed_put(token, url, params={})
puts "[trace][PUT] request params: #{params}"
puts "[trace][PUT] request token: #{token}"
conn.put do |req|
req.url full_url(url)
req.body = params[:data].to_json
req.headers['Authorization'] = token
end
end
private
def conn
@client ||= begin
Faraday.new(url: domain) do |req|
req.request :url_encoded
req.headers['Content-Type'] = 'application/json'
req.adapter Faraday.default_adapter
end
end
@client
end
def base_url
Trace.trace_config[:base_url]
end
def domain
Trace.trace_config[:domain]
end
def api_url
[domain, base_url].join('')
end
def full_url(api_rest, action='post')
url = [api_url, api_rest].join('').freeze
url = action === 'get' ? url : URI.escape(url)
url = URI.escape(url) unless url.ascii_only?
puts "[trace] request url: #{url}"
return url
end
def log_error(status, body)
puts "[trace] status: #{status}"
puts "[trace] body: #{body}"
end
def render_response(response)
status = response.status
body = JSON.parse(response&.body)
log_error(status, body)
return [body["code"], body["Data"], body["Error"]]
end
end

View File

@ -0,0 +1,29 @@
# 代码溯源 用户登录
class Trace::LoginService < Trace::ClientService
# 用户名 密码
attr_accessor :username, :password
def initialize(username, password)
@username = username
@password = password
end
def call
result = post(url, {data: request_params})
response = render_response(result)
end
private
def request_params
{
username: username,
password: password,
}
end
def url
"/user/login".freeze
end
end

View File

@ -0,0 +1,26 @@
# 代码溯源 导出pdf
class Trace::PdfReportService < Trace::ClientService
attr_accessor :token, :task_id
def initialize(token, task_id)
@token = token
@task_id = task_id
end
def call
result = authed_get(token, url, request_params)
response = render_response(result)
end
private
def request_params
{
task_id: task_id
}
end
def url
"/user/pdfreport".freeze
end
end

View File

@ -0,0 +1,25 @@
# 代码溯源 重新检测
class Trace::ReloadCheckService < Trace::ClientService
attr_accessor :token, :fake_project_id
def initialize(token, fake_project_id)
@token = token
@fake_project_id = fake_project_id
end
def call
result = authed_post(token, url, {data: request_params})
response = render_response(result)
end
private
def request_params
{
project_id: fake_project_id
}
end
def url
'/user/reloadcheck'.freeze
end
end

View File

@ -3,5 +3,5 @@ json.user do
json.partial! "organizations/user_detail", user: org_user.user
end
json.team_names org_user.teams.pluck(:name)
json.team_names org_user.teams.pluck(:nickname)
json.created_at org_user.created_at.strftime("%Y-%m-%d")

View File

@ -1,4 +1,5 @@
if @project.forge?
is_dir = @sub_entries.is_a?(Array)
file_name = entry['name']
file_type = File.extname(file_name.to_s)[1..-1]
direct_download = download_type(file_type)
@ -9,16 +10,16 @@ if @project.forge?
json.type entry['type']
json.size entry['size']
json.content direct_download ? nil : decode64_content(entry, @owner, @repository, @ref, @path)
json.content (direct_download || image_type || is_dir) ? nil : decode64_content(entry, @owner, @repository, @ref, @path)
json.target entry['target']
download_url =
if image_type
dir_path = [@owner.login, @repository.identifier, "raw/branch", @ref].join('/')
render_download_image_url(dir_path, entry['path'], decode64_content(entry, @owner, @repository, @ref))
is_dir ? "" : render_download_image_url(dir_path, entry['path'], decode64_content(entry, @owner, @repository, @ref))
else
# entry['download_url']
render_download_file_url(@owner, @repository, entry['path'].to_s, @ref)
is_dir ? "" : render_download_file_url(@owner, @repository, entry['path'].to_s, @ref)
end
json.download_url download_url

View File

@ -18,7 +18,7 @@ json.setting do
#
# end
nav_bar = default_setting.navbar
# nav_bar = default_setting.navbar
# if User.current.logged?
# nav_bar[2]["link"] = "https://forgeplus.trustie.net/users/#{current_user.login}/projects"
@ -39,7 +39,7 @@ json.setting do
json.moop_cases_banner_url default_setting.moop_cases_banner_url&.[](1..-1)
json.oj_banner_url default_setting.oj_banner_url&.[](1..-1)
json.navbar nav_bar
json.navbar @navbar
json.footer default_setting.footer

View File

@ -67,6 +67,10 @@ default: &default
write_domain: ''
read_domain: ''
base_url: ''
trace:
domain: ''
base_url: ''
forum:
domain: ''

View File

@ -692,7 +692,6 @@ Rails.application.routes.draw do
resources :experience_forums
resources :pinned_forums
end
resources :project_statistics, only: [:index] do
collection do
get :visits_static

View File

@ -0,0 +1,17 @@
class CreateTraceUsers < ActiveRecord::Migration[5.2]
def change
create_table :trace_users do |t|
t.references :user
t.string :username
t.string :password
t.string :unit
t.string :telnumber
t.string :email
t.string :name
t.text :token
t.datetime :expired_at
t.timestamps
end
end
end

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe TraceUser, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end