Merge pull request '20220507版本' (#305) from Trustie/forgeplus:trustie_server into master

This commit is contained in:
xxq250 2022-05-07 15:11:36 +08:00
commit 31d7f0a13c
78 changed files with 1420 additions and 726 deletions

View File

@ -0,0 +1,57 @@
class Admins::Topic::GlccNewsController < Admins::Topic::BaseController
before_action :find_glcc, only: [:edit, :update, :destroy]
def index
q = ::Topic::GlccNews.ransack(title_cont: params[:search])
glcc_news = q.result(distinct: true)
@glcc_news = paginate(glcc_news)
end
def new
@glcc = ::Topic::GlccNews.new
end
def create
@glcc = ::Topic::GlccNews.new(glcc_params)
if @glcc.save
redirect_to admins_topic_glcc_news_index_path
flash[:success] = "新增新闻稿成功"
else
redirect_to admins_topic_glcc_news_index_path
flash[:danger] = "新增新闻稿失败"
end
end
def edit
end
def update
@glcc.attributes = glcc_params
if @glcc.save
redirect_to admins_topic_glcc_news_index_path
flash[:success] = "更新新闻稿成功"
else
redirect_to admins_topic_glcc_news_index_path
flash[:danger] = "更新新闻稿失败"
end
end
def destroy
if @glcc.destroy
redirect_to admins_topic_glcc_news_index_path
flash[:success] = "删除新闻稿成功"
else
redirect_to admins_topic_glcc_news_index_path
flash[:danger] = "删除新闻稿失败"
end
end
private
def find_glcc
@glcc = ::Topic::GlccNews.find_by_id(params[:id])
end
def glcc_params
params.require(:topic_glcc_news).permit(:title, :uuid, :url, :order_index)
end
end

View File

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

View File

@ -9,6 +9,10 @@ class CompareController < ApplicationController
load_compare_params load_compare_params
compare compare
@merge_status, @merge_message = get_merge_message @merge_status, @merge_message = get_merge_message
@page_size = page_size <= 0 ? 1 : page_size
@page_limit = page_limit <=0 ? 15 : page_limit
@page_offset = (@page_size -1) * @page_limit
Rails.logger.info("+========#{@page_size}-#{@page_limit}-#{@page_offset}")
end end
private private
@ -16,6 +20,7 @@ class CompareController < ApplicationController
if @base.blank? || @head.blank? if @base.blank? || @head.blank?
return -2, "请选择分支" return -2, "请选择分支"
else else
return -2, "目标仓库未开启合并请求PR功能" unless @project.has_menu_permission("pulls")
if @head.include?(":") if @head.include?(":")
fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take
return -2, "请选择正确的仓库" unless fork_project.present? return -2, "请选择正确的仓库" unless fork_project.present?
@ -50,6 +55,14 @@ class CompareController < ApplicationController
end end
def gitea_compare(base, head) 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
def page_size
params.fetch(:page, 1).to_i
end
def page_limit
params.fetch(:limit, 15).to_i
end end
end end

View File

@ -108,7 +108,11 @@ module LoginHelper
def sync_pwd_to_gitea!(user, hash={}) def sync_pwd_to_gitea!(user, hash={})
return true if user.is_sync_pwd? return true if user.is_sync_pwd?
sync_params = { email: user.mail } sync_params = {
login_name: user.name,
source_id: 0,
email: user.mail
}
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params.merge(hash)) interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params.merge(hash))
if interactor.success? if interactor.success?
Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########" Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########"

View File

@ -24,7 +24,7 @@ class IssuesController < ApplicationController
@filter_issues = @all_issues @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.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(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) @open_issues = @all_issues.where.not(status_id: IssueStatus::CLOSED)
@close_issues = @all_issues.where(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") scopes = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "Issue")
@ -109,7 +109,7 @@ class IssuesController < ApplicationController
def create def create
issue_params = issue_send_params(params) issue_params = issue_send_params(params)
Issues::CreateForm.new({subject:issue_params[:subject]}).validate! Issues::CreateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate!
@issue = Issue.new(issue_params) @issue = Issue.new(issue_params)
if @issue.save! if @issue.save!
SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu?
@ -223,7 +223,7 @@ class IssuesController < ApplicationController
normal_status(-1, "不允许修改为关闭状态") normal_status(-1, "不允许修改为关闭状态")
else else
issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id) issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id)
Issues::UpdateForm.new({subject:issue_params[:subject]}).validate! Issues::UpdateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate!
if @issue.update_attributes(issue_params) if @issue.update_attributes(issue_params)
if @issue&.pull_request.present? if @issue&.pull_request.present?
SendTemplateMessageJob.perform_later('PullRequestChanged', current_user.id, @issue&.pull_request&.id, @issue.previous_changes.slice(:assigned_to_id, :priority_id, :fixed_version_id, :issue_tags_value)) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('PullRequestChanged', current_user.id, @issue&.pull_request&.id, @issue.previous_changes.slice(:assigned_to_id, :priority_id, :fixed_version_id, :issue_tags_value)) if Site.has_notice_menu?

View File

@ -23,6 +23,7 @@ class JournalsController < ApplicationController
normal_status(-1, "评论内容不能为空") normal_status(-1, "评论内容不能为空")
else else
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
Journals::CreateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate!
journal_params = { journal_params = {
journalized_id: @issue.id , journalized_id: @issue.id ,
journalized_type: "Issue", journalized_type: "Issue",
@ -53,6 +54,9 @@ class JournalsController < ApplicationController
end end
end end
end end
rescue Exception => exception
puts exception.message
normal_status(-1, exception.message)
end end
def destroy def destroy
@ -71,6 +75,7 @@ class JournalsController < ApplicationController
def update def update
content = params[:content] content = params[:content]
if content.present? if content.present?
Journals::UpdateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate!
if @journal.update_attribute(:notes, content) if @journal.update_attribute(:notes, content)
normal_status(0, "更新成功") normal_status(0, "更新成功")
else else
@ -79,7 +84,9 @@ class JournalsController < ApplicationController
else else
normal_status(-1, "评论的内容不能为空") normal_status(-1, "评论的内容不能为空")
end end
rescue Exception => exception
puts exception.message
normal_status(-1, exception.message)
end end
def get_children_journals def get_children_journals

View File

@ -5,7 +5,11 @@ class Organizations::OrganizationUsersController < Organizations::BaseController
def index def index
@organization_users = @organization.organization_users.includes(:user) @organization_users = @organization.organization_users.includes(:user)
search = params[:search].to_s.downcase 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) @organization_users = kaminari_paginate(@organization_users)
end end

View File

@ -13,6 +13,8 @@ class ProjectsController < ApplicationController
def menu_list def menu_list
menu = [] menu = []
user_is_admin = current_user.admin? || @project.manager?(current_user)
menu.append(menu_hash_by_name("home")) menu.append(menu_hash_by_name("home"))
menu.append(menu_hash_by_name("code")) if @project.has_menu_permission("code") menu.append(menu_hash_by_name("code")) if @project.has_menu_permission("code")
menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues") menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues")
@ -22,7 +24,8 @@ class ProjectsController < ApplicationController
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki") && @project.forge? menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki") && @project.forge?
menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources") && @project.forge? menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources") && @project.forge?
menu.append(menu_hash_by_name("activity")) menu.append(menu_hash_by_name("activity"))
menu.append(menu_hash_by_name("settings")) if (current_user.admin? || @project.manager?(current_user)) && @project.forge? menu.append(menu_hash_by_name("settings")) if user_is_admin && @project.forge?
menu.append(menu_hash_by_name("quit")) if !user_is_admin && @project.member(current_user.id) && @project.forge?
render json: menu render json: menu
end end
@ -88,7 +91,7 @@ class ProjectsController < ApplicationController
return @branches = [] unless @project.forge? return @branches = [] unless @project.forge?
# result = Gitea::Repository::Branches::ListService.call(@owner, @project.identifier) # result = Gitea::Repository::Branches::ListService.call(@owner, @project.identifier)
result = Gitea::Repository::Branches::ListNameService.call(@owner, @project.identifier) result = Gitea::Repository::Branches::ListNameService.call(@owner, @project.identifier, params[:name])
@branches = result.is_a?(Hash) ? (result.key?(:status) ? [] : result["branch_name"]) : result @branches = result.is_a?(Hash) ? (result.key?(:status) ? [] : result["branch_name"]) : result
end end
@ -135,7 +138,7 @@ class ProjectsController < ApplicationController
validate_params = project_params.slice(:name, :description, validate_params = project_params.slice(:name, :description,
:project_category_id, :project_language_id, :private, :identifier) :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 private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : params[:private] || false
@ -177,6 +180,22 @@ class ProjectsController < ApplicationController
tip_exception(e.message) tip_exception(e.message)
end end
def quit
user_is_admin = current_user.admin? || @project.manager?(current_user)
if !user_is_admin && @project.member(current_user.id) && @project.forge?
ActiveRecord::Base.transaction do
Projects::DeleteMemberInteractor.call(@project.owner, @project, current_user)
SendTemplateMessageJob.perform_later('ProjectMemberLeft', current_user.id, current_user.id, @project.id) if Site.has_notice_menu?
render_ok
end
else
render_forbidden('你不能退出该仓库')
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def watch_users def watch_users
watchers = @project.watchers.includes(:user).order("watchers.created_at desc").distinct watchers = @project.watchers.includes(:user).order("watchers.created_at desc").distinct
@watchers_count = watchers.size @watchers_count = watchers.size
@ -190,7 +209,7 @@ class ProjectsController < ApplicationController
end end
def fork_users def fork_users
fork_users = @project.fork_users.includes(:user, :project, :fork_project).order("fork_users.created_at desc").distinct fork_users = @project.fork_users.includes(:owner, :project, :fork_project).order("fork_users.created_at desc").distinct
@forks_count = fork_users.size @forks_count = fork_users.size
@fork_users = paginate(fork_users) @fork_users = paginate(fork_users)
end end

View File

@ -2,7 +2,7 @@ class PullRequestsController < ApplicationController
before_action :require_login, except: [:index, :show, :files, :commits] before_action :require_login, except: [:index, :show, :files, :commits]
before_action :require_profile_completed, only: [:create] before_action :require_profile_completed, only: [:create]
before_action :load_repository 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 :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 :load_pull_request, only: [:files, :commits]
before_action :find_atme_receivers, only: [:create, :update] 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)) issues = issues.where(is_private: false) unless current_user.present? && (current_user.admin? || @project.member?(current_user))
@all_issues = issues.distinct @all_issues = issues.distinct
@filter_issues = @all_issues @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}) @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}) @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}) @merged_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::MERGED})
@ -29,7 +29,7 @@ class PullRequestsController < ApplicationController
end end
def new def new
@all_branches = Branches::ListService.call(@owner, @project) @all_branches = Branches::ListService.call(@owner, @project, params[:branch_name])
@is_fork = @project.forked_from_project_id.present? @is_fork = @project.forked_from_project_id.present?
@projects_names = [{ @projects_names = [{
project_user_login: @owner.try(:login), project_user_login: @owner.try(:login),
@ -50,7 +50,7 @@ class PullRequestsController < ApplicationController
end end
def get_branches def get_branches
branch_result = Branches::ListService.call(@owner, @project) branch_result = Branches::ListService.call(@owner, @project, params[:name])
render json: branch_result render json: branch_result
# return json: branch_result # return json: branch_result
end end
@ -58,6 +58,7 @@ class PullRequestsController < ApplicationController
def create def create
# return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user) # return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user)
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
Issues::CreateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate!
@pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params) @pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params)
if @gitea_pull_request[:status] == :success if @gitea_pull_request[:status] == :success
@pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"]) @pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"])
@ -89,7 +90,7 @@ class PullRequestsController < ApplicationController
else else
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
return normal_status(-1, "title不能超过255个字符") if params[:title].length > 255 Issues::UpdateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate!
merge_params merge_params
@issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank? @issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank?

View File

@ -241,7 +241,7 @@ class RepositoriesController < ApplicationController
def archive def archive
domain = Gitea.gitea_config[:domain] domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url] api_url = Gitea.gitea_config[:base_url]
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{CGI.escape(params[:archive])}" archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{Addressable::URI.escape(params[:archive])}"
file_path = [domain, api_url, archive_url].join file_path = [domain, api_url, archive_url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden? file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
@ -255,7 +255,7 @@ class RepositoriesController < ApplicationController
domain = Gitea.gitea_config[:domain] domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url] api_url = Gitea.gitea_config[:base_url]
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{CGI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}" 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 = [domain, api_url, url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&") file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&")

View File

@ -1,14 +1,24 @@
class SettingsController < ApplicationController class SettingsController < ApplicationController
def show def show
@old_projects_url = nil @old_projects_url = nil
get_navbar
get_add_menu get_add_menu
get_common_menu get_common_menu
get_sub_competitions
get_personal_menu get_personal_menu
get_third_party get_third_party
get_top_system_notification get_top_system_notification
end end
private private
def get_navbar
@navbar = default_laboratory.navbar
if User.current.logged?
pernal_index = {"name"=>"个人主页", "link"=>get_site_url("url", "#{Rails.application.config_for(:configuration)['platform_url']}/current_user"), "hidden"=>false}
@navbar << pernal_index
end
end
def get_add_menu def get_add_menu
@add = [] @add = []
Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site| Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site|
@ -20,6 +30,15 @@ class SettingsController < ApplicationController
end end
end end
def get_sub_competitions
@sub_competitions = []
Site.competition.pluck(:key).uniq.each do |key|
hash = {"identifier": "#{key.to_s}"}
hash.merge!("list": Site.competition.where(key: key).select(:id, :name, :url, :key).to_a.map(&:serializable_hash))
@sub_competitions << hash
end
end
def get_common_menu def get_common_menu
@common = {} @common = {}
Site.common.select(:url, :key).each do |site| Site.common.select(:url, :key).each do |site|

View File

@ -12,7 +12,7 @@ class Users::StatisticsController < Users::BaseController
@commit_data = [] @commit_data = []
date_range.each do |date| date_range.each do |date|
@date_data << date.strftime("%Y.%m.%d") @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 @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} 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) @commit_data << (date_commit_data.blank? ? 0 : date_commit_data[0]["contributions"].to_i)

View File

@ -4,7 +4,7 @@ class UsersController < ApplicationController
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :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]
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users, :hovercard] before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users, :hovercard]
before_action :require_login, only: %i[me list sync_user_info] before_action :require_login, only: %i[me sync_user_info]
before_action :connect_to_ci_db, only: [:get_user_info] before_action :connect_to_ci_db, only: [:get_user_info]
before_action :convert_image!, only: [:update, :update_image] before_action :convert_image!, only: [:update, :update_image]
skip_before_action :check_sign, only: [:attachment_show] skip_before_action :check_sign, only: [:attachment_show]
@ -97,6 +97,13 @@ class UsersController < ApplicationController
render_error(-1, '头像修改失败!') render_error(-1, '头像修改失败!')
end end
def get_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)
redirect_to Rails.application.config_for(:configuration)['platform_url'] + "/" + url_to_avatar(@user).to_s
end
def me def me
@user = current_user @user = current_user
end end
@ -306,6 +313,7 @@ class UsersController < ApplicationController
:occupation, :technical_title, :occupation, :technical_title,
:school_id, :department_id, :province, :city, :school_id, :department_id, :province, :city,
:custom_department, :identity, :student_id, :description, :custom_department, :identity, :student_id, :description,
:show_super_description, :super_description,
:show_email, :show_location, :show_department] :show_email, :show_location, :show_department]
) )
end end

View File

@ -14,7 +14,7 @@ class VersionReleasesController < ApplicationController
def new def new
#获取所有的分支 #获取所有的分支
@all_branches = [] @all_branches = []
get_all_branches = Gitea::Repository::Branches::ListService.new(@user, @repository.try(:identifier)).call get_all_branches = Gitea::Repository::Branches::ListService.new(@user, @repository.try(:identifier), params[:branch_name]).call
if get_all_branches && get_all_branches.size > 0 if get_all_branches && get_all_branches.size > 0
get_all_branches.each do |b| get_all_branches.each do |b|
@all_branches.push(b["name"]) @all_branches.push(b["name"])

View File

@ -49,7 +49,7 @@ class BaseForm
def check_verifi_code(verifi_code, code) def check_verifi_code(verifi_code, code)
code = strip(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&.effective?
raise VerifiCodeError, "验证码不正确" if verifi_code&.code != code raise VerifiCodeError, "验证码不正确" if verifi_code&.code != code
end end

View File

@ -1,11 +1,11 @@
class Issues::CreateForm class Issues::CreateForm
include ActiveModel::Model include ActiveModel::Model
attr_accessor :subject attr_accessor :subject, :description
validates :subject, presence: { message: "不能为空" } validates :subject, presence: { message: "不能为空" }
validates :subject, length: { maximum: 200, too_long: "不能超过200个字符" } validates :subject, length: { maximum: 200, too_long: "不能超过200个字符" }
validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符"}
end end

View File

@ -1,10 +1,12 @@
class Issues::UpdateForm class Issues::UpdateForm
include ActiveModel::Model include ActiveModel::Model
attr_accessor :subject attr_accessor :subject, :description
validates :subject, presence: { message: "不能为空" } validates :subject, presence: { message: "不能为空" }
validates :subject, length: { maximum: 200, too_long: "不能超过200个字符" } validates :subject, length: { maximum: 200, too_long: "不能超过200个字符" }
validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符"}
end end

View File

@ -0,0 +1,7 @@
class Journals::CreateForm
include ActiveModel::Model
attr_accessor :notes
validates :notes, length: { maximum: 65535, too_long: "不能超过65535个字符"}
end

View File

@ -0,0 +1,8 @@
class Journals::UpdateForm
include ActiveModel::Model
attr_accessor :notes
validates :notes, length: { maximum: 65535, too_long: "不能超过65535个字符"}
end

View File

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

View File

@ -147,6 +147,15 @@ module ApplicationHelper
end end
end end
def url_to_avatar_with_platform_url(source)
platform_url = Rails.application.config_for(:configuration)['platform_url']
if platform_url
return Rails.application.config_for(:configuration)['platform_url'] + "/" + url_to_avatar(source).to_s
else
return url_to_avatar(source).to_s
end
end
# 主页banner图 # 主页banner图
def banner_img(source_type) def banner_img(source_type)
if File.exist?(disk_filename(source_type, "banner")) if File.exist?(disk_filename(source_type, "banner"))

View File

@ -36,7 +36,6 @@ module RepositoriesHelper
end end
def render_cache_commit_author(author_json) def render_cache_commit_author(author_json)
Rails.logger.info author_json['Email']
if author_json["name"].present? && author_json["email"].present? if author_json["name"].present? && author_json["email"].present?
return find_user_in_redis_cache(author_json['name'], author_json['email']) return find_user_in_redis_cache(author_json['name'], author_json['email'])
end end
@ -45,23 +44,40 @@ module RepositoriesHelper
end end
end end
def readme_render_decode64_content(str, owner, repo, ref) def readme_render_decode64_content(str, owner, repo, ref, path)
return nil if str.blank? return nil if str.blank?
begin begin
content = Base64.decode64(str).force_encoding('UTF-8') content = Base64.decode64(str).force_encoding('UTF-8')
c_regex = /\!\[.*?\]\((.*?)\)/ c_regex = /\!\[.*?\]\((.*?)\)/
src_regex = /src=\"(.*?)\"/ src_regex = /src=\"(.*?)\"/
src2_regex = /src='(.*?)'/
ss = content.to_s.scan(c_regex) ss = content.to_s.scan(c_regex)
ss_src = content.to_s.scan(src_regex) ss_src = content.scan(src_regex)
total_images = ss + ss_src ss_src2 = content.scan(src2_regex)
total_images = ss + ss_src + ss_src2
if total_images.length > 0 if total_images.length > 0
total_images.each do |s| total_images.each do |s|
begin
image_title = /\"(.*?)\"/ image_title = /\"(.*?)\"/
r_content = s[0] r_content = s[0]
remove_title = r_content.to_s.scan(image_title) remove_title = r_content.to_s.scan(image_title)
if remove_title.length > 0 # if remove_title.length > 0
r_content = r_content.gsub(/#{remove_title[0]}/, "").strip # 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 end
# if r_content.include?("?") # if r_content.include?("?")
# new_r_content = r_content + "&raw=true" # new_r_content = r_content + "&raw=true"
@ -72,9 +88,12 @@ module RepositoriesHelper
unless r_content.include?("http://") || r_content.include?("https://") || r_content.include?("mailto:") unless r_content.include?("http://") || r_content.include?("https://") || r_content.include?("mailto:")
# new_r_content = "#{path}" + new_r_content # new_r_content = "#{path}" + new_r_content
new_r_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{r_content}&ref=#{ref}"].join 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
content = content.gsub(/#{r_content}/, new_r_content)
end end
end end
@ -96,8 +115,10 @@ module RepositoriesHelper
def decode64_content(entry, owner, repo, ref, path=nil) def decode64_content(entry, owner, repo, ref, path=nil)
if is_readme?(entry['type'], entry['name']) if is_readme?(entry['type'], entry['name'])
content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] # content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content']
readme_render_decode64_content(content, owner, repo, ref) content = entry['content']
path = URI.escape(entry['path']).to_s.downcase.gsub("/readme.md","")
readme_render_decode64_content(content, owner, repo, ref, path)
else else
file_type = File.extname(entry['name'].to_s)[1..-1] file_type = File.extname(entry['name'].to_s)[1..-1]
if image_type?(file_type) if image_type?(file_type)

View File

@ -7,7 +7,7 @@ module Notice
config = Rails.application.config_for(:configuration).symbolize_keys! config = Rails.application.config_for(:configuration).symbolize_keys!
notice_config = config[:notice].symbolize_keys! notice_config = config[:notice].symbolize_keys!
raise 'notice config missing' if notice_config.blank? raise 'notice config missing' if notice_config.blank?
rescue => exception rescue => ex
raise ex if Rails.env.production? raise ex if Rails.env.production?
puts %Q{\033[33m [warning] gitea config or configuration.yml missing, puts %Q{\033[33m [warning] gitea config or configuration.yml missing,

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 => ex
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

@ -17,7 +17,7 @@
class ForkUser < ApplicationRecord class ForkUser < ApplicationRecord
belongs_to :project belongs_to :project
belongs_to :user belongs_to :owner, class_name: 'Owner', foreign_key: :user_id
belongs_to :fork_project, class_name: 'Project', foreign_key: :fork_project_id belongs_to :fork_project, class_name: 'Project', foreign_key: :fork_project_id
after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic

View File

@ -6,7 +6,7 @@
# journalized_id :integer default("0"), not null # journalized_id :integer default("0"), not null
# journalized_type :string(30) default(""), not null # journalized_type :string(30) default(""), not null
# user_id :integer default("0"), not null # user_id :integer default("0"), not null
# notes :text(65535) # notes :text(4294967295)
# created_on :datetime not null # created_on :datetime not null
# private_notes :boolean default("0"), not null # private_notes :boolean default("0"), not null
# parent_id :integer # parent_id :integer

View File

@ -83,6 +83,10 @@ class Organization < Owner
after_save :reset_cache_data after_save :reset_cache_data
def gitea_token
team_users.joins(:team).where(teams: {authorize: "owner"}).take&.user&.gitea_token
end
def reset_cache_data def reset_cache_data
Cache::V2::OwnerCommonService.new(self.id).reset Cache::V2::OwnerCommonService.new(self.id).reset
end end

View File

@ -3,8 +3,8 @@
# Table name: pull_requests # Table name: pull_requests
# #
# id :integer not null, primary key # id :integer not null, primary key
# pull_request_id :integer # gitea_id :integer
# gpid :integer # gitea_number :integer
# user_id :integer # user_id :integer
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
@ -12,7 +12,7 @@
# project_id :integer # project_id :integer
# title :string(255) # title :string(255)
# milestone :integer # milestone :integer
# body :text(65535) # body :text(4294967295)
# head :string(255) # head :string(255)
# base :string(255) # base :string(255)
# issue_id :integer # issue_id :integer

View File

@ -15,7 +15,7 @@ class Site < ApplicationRecord
# add: 添加类链接 # add: 添加类链接
# personal: 个人名下类链接, # personal: 个人名下类链接,
# common: 普通链接 # common: 普通链接
enum site_type: { add: 0, personal: 1, common: 2 } enum site_type: { add: 0, personal: 1, common: 2, competition: 3 }
scope :by_search, -> (keyword){ where("name LIKE :keyword OR url LIKE :keyword", keyword: "%#{strip_param(keyword)}%") unless strip_param(keyword).blank? } scope :by_search, -> (keyword){ where("name LIKE :keyword OR url LIKE :keyword", keyword: "%#{strip_param(keyword)}%") unless strip_param(keyword).blank? }
scope :by_site_type, -> (site_type){ where(site_type: strip_param(site_type)) unless strip_param(site_type).blank? } scope :by_site_type, -> (site_type){ where(site_type: strip_param(site_type)) unless strip_param(site_type).blank? }

View File

@ -29,6 +29,11 @@ class Team < ApplicationRecord
has_many :team_units, dependent: :destroy has_many :team_units, dependent: :destroy
has_many :team_users, 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} validates :name, uniqueness: {scope: :organization_id}
enum authorize: {read: 1, write: 2, admin: 3, owner: 4} enum authorize: {read: 1, write: 2, admin: 3, owner: 4}

View File

@ -35,6 +35,8 @@ class Topic < ApplicationRecord
'Topic::ExcellentProject' 'Topic::ExcellentProject'
when 'experience_forum' when 'experience_forum'
'Topic::ExperienceForum' 'Topic::ExperienceForum'
when "glcc_news"
'Topic::GlccNews'
when 'pinned_forum' when 'pinned_forum'
'Topic::PinnedForum' 'Topic::PinnedForum'
end end

View File

@ -0,0 +1,17 @@
# == Schema Information
#
# Table name: topics
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# uuid :integer
# image_url :string(255)
# url :string(255)
# order_index :integer
#
# GLCC 新闻稿
class Topic::GlccNews < Topic
end

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_notification_histories
has_many :system_notifications, through: :system_notification_histories has_many :system_notifications, through: :system_notification_histories
has_one :trace_user, dependent: :destroy
# Groups and active users # Groups and active users
scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) } scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) }
@ -187,7 +188,7 @@ class User < Owner
attr_accessor :password, :password_confirmation attr_accessor :password, :password_confirmation
delegate :description, :gender, :department_id, :school_id, :location, :location_city, delegate :description, :gender, :department_id, :school_id, :location, :location_city,
:show_email, :show_location, :show_department, :show_email, :show_location, :show_department, :super_description, :show_super_description,
:technical_title, :province, :city, :custom_department, to: :user_extension, allow_nil: true :technical_title, :province, :city, :custom_department, to: :user_extension, allow_nil: true
before_save :update_hashed_password, :set_lastname before_save :update_hashed_password, :set_lastname
@ -789,6 +790,24 @@ class User < Owner
self.nickname.present? && self.mail.present? self.nickname.present? && self.mail.present?
end 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 protected
def validate_password_length def validate_password_length
# 管理员的初始密码是5位 # 管理员的初始密码是5位

View File

@ -22,15 +22,14 @@
# school_id :integer # school_id :integer
# description :string(255) default("") # description :string(255) default("")
# department_id :integer # department_id :integer
# honor :text(65535)
# edu_background :integer
# edu_entry_year :integer
# province :string(255) # province :string(255)
# city :string(255) # city :string(255)
# custom_department :string(255) # custom_department :string(255)
# show_email :boolean default("0") # show_email :boolean default("0")
# show_location :boolean default("0") # show_location :boolean default("0")
# show_department :boolean default("0") # show_department :boolean default("0")
# super_description :text(4294967295)
# show_super_description :boolean default("0")
# #
# Indexes # Indexes
# #

View File

@ -1,17 +1,18 @@
class Branches::ListService < ApplicationService class Branches::ListService < ApplicationService
attr_reader :user, :project attr_reader :user, :project, :name
def initialize(user, project) def initialize(user, project, name=nil)
@user = user @user = user
@project = project @project = project
@name = name
end end
def call def call
all_branches = [] all_branches = []
user_name = user.try(:show_real_name) user_name = user.try(:show_real_name)
identifier = project.repository.try(:identifier) identifier = project.repository.try(:identifier)
get_all_branches = Gitea::Repository::Branches::ListService.new(user, identifier).call get_all_branches = Gitea::Repository::Branches::ListService.new(user, identifier, name).call
all_branches = branch_lists(user_name,user.try(:login), identifier, get_all_branches) if get_all_branches && get_all_branches.size > 0 all_branches = branch_lists(user_name,user.try(:login), identifier, get_all_branches) if get_all_branches && get_all_branches.size > 0
return all_branches return all_branches
end end

View File

@ -82,7 +82,7 @@ class Gitea::ClientService < ApplicationService
req.headers['Content-Type'] = 'application/json' req.headers['Content-Type'] = 'application/json'
req.response :logger # 显示日志 req.response :logger # 显示日志
req.adapter Faraday.default_adapter req.adapter Faraday.default_adapter
req.options.timeout = 100 # open/read timeout in seconds req.options.timeout = 1200 # open/read timeout in seconds
req.options.open_timeout = 10 # connection open timeout in seconds req.options.open_timeout = 10 # connection open timeout in seconds
if token.blank? if token.blank?
req.basic_auth(username, secret) req.basic_auth(username, secret)

View File

@ -1,9 +1,10 @@
class Gitea::Repository::Branches::ListNameService < Gitea::ClientService class Gitea::Repository::Branches::ListNameService < Gitea::ClientService
attr_reader :user, :repo attr_reader :user, :repo, :name
def initialize(user, repo) def initialize(user, repo, name=nil)
@user = user @user = user
@repo = repo @repo = repo
@name = name
end end
def call def call
@ -13,7 +14,7 @@ class Gitea::Repository::Branches::ListNameService < Gitea::ClientService
private private
def params def params
Hash.new.merge(token: user.gitea_token) Hash.new.merge(token: user.gitea_token, name: name)
end end
def url def url

View File

@ -1,9 +1,10 @@
class Gitea::Repository::Branches::ListService < Gitea::ClientService class Gitea::Repository::Branches::ListService < Gitea::ClientService
attr_reader :user, :repo attr_reader :user, :repo, :name
def initialize(user, repo) def initialize(user, repo, name=nil)
@user = user @user = user
@repo = repo @repo = repo
@name = name
end end
def call def call
@ -13,7 +14,7 @@ class Gitea::Repository::Branches::ListService < Gitea::ClientService
private private
def params def params
Hash.new.merge(token: user.gitea_token) Hash.new.merge(token: user.gitea_token, name: name)
end end
def url def url

View File

@ -28,11 +28,11 @@ class Issues::ListQueryService < ApplicationService
end end
if search_name.present? if search_name.present?
issues = issues.where("subject LIKE ? OR description LIKE ? ", "%#{search_name}%", "%#{search_name}%") issues = issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{search_name}%", "%#{search_name}%")
end end
if start_time&.present? || end_time&.present? 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 end
issues = issues.where(author_id: params[:author_id]) if params[:author_id].present? && params[:author_id].to_s != "all" issues = issues.where(author_id: params[:author_id]) if params[:author_id].present? && params[:author_id].to_s != "all"

View File

@ -47,7 +47,7 @@ class Organizations::CreateService < ApplicationService
end end
def create_org_and_extension def create_org_and_extension
@organization = Organization.build(params[:name], params[:nickname], user.gitea_token) @organization = Organization.build(params[:name], params[:nickname])
org_extension = OrganizationExtension.build(organization.id, description, website, org_extension = OrganizationExtension.build(organization.id, description, website,
location, repo_admin_change_team_access, location, repo_admin_change_team_access,
visibility, max_repo_creation) visibility, max_repo_creation)

View File

@ -132,8 +132,8 @@ class PullRequests::CreateService < ApplicationService
end end
def merge_original_pull_params def merge_original_pull_params
base_pull_params[:head] = CGI.escape(base_pull_params[:head]) base_pull_params[:head] = Addressable::URI.escape(base_pull_params[:head])
base_pull_params[:base] = CGI.escape(base_pull_params[:base]) base_pull_params[:base] = Addressable::URI.escape(base_pull_params[:base])
if pull_request.is_original && @params[:merge_user_login] if pull_request.is_original && @params[:merge_user_login]
base_pull_params.merge(head: "#{@params[:merge_user_login]}:#{base_pull_params[:head]}") base_pull_params.merge(head: "#{@params[:merge_user_login]}:#{base_pull_params[:head]}")
else else
@ -157,6 +157,7 @@ class PullRequests::CreateService < ApplicationService
raise "head参数不能为空" if @params[:head].blank? raise "head参数不能为空" if @params[:head].blank?
raise "base参数不能为空" if @params[:base].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 "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(:owner).where(users: {login: @params[:merge_user_login]}).blank?
raise "分支内容相同,无需创建合并请求" if @params[:head] === @params[:base] && !is_original 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 "合并请求已存在" 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? raise @pull_issue.errors.full_messages.join(", ") unless pull_issue.valid?
@ -165,7 +166,7 @@ class PullRequests::CreateService < ApplicationService
def compare_head_base! def compare_head_base!
head = pull_request.is_original && @params[:merge_user_login] ? "#{@params[:merge_user_login]}/#{@project.identifier}:#{@params[:head]}" : @params[:head] 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? raise '分支内容相同,无需创建合并请求' if compare_result["Commits"].blank? && compare_result["Diff"].blank?
end 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,110 @@
class Trace::ClientService < ApplicationService
def post(url, params={})
puts "[trace][POST] request params: #{params}"
conn.post(full_url(url), params[:data])
end
def authed_post(token, url, params={})
puts "[trace][POST] request params: #{params}"
puts "[trace][POST] request token: #{token}"
conn.headers['Authorization'] = token
conn.post(full_url(url), params[:data])
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(full_url(url), params[:data])
end
def authed_delete(token, url, params={})
puts "[trace][DELETE] request params: #{params}"
puts "[trace][DELETE] request token: #{token}"
conn.headers['Authorization'] = token
conn.delete(full_url(url), params[:data])
end
def patch(url, params={})
puts "[trace][PATCH] request params: #{params}"
conn.patch(full_url(url), params[:data])
end
def authed_patch(token, url, params={})
puts "[trace][PATCH] request params: #{params}"
puts "[trace][PATCH] request token: #{token}"
conn.headers['Authorization'] = token
conn.patch(full_url(url), params[:data])
end
def put(url, params={})
puts "[trace][PUT] request params: #{params}"
conn.put(full_url(url), params[:data])
end
def authed_put(token, url, params={})
puts "[trace][PUT] request params: #{params}"
puts "[trace][PUT] request token: #{token}"
conn.headers['Authorization'] = token
conn.put(full_url(url), params[:data])
end
def conn
Faraday.new(url: domain)
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

@ -42,7 +42,16 @@
<li><%= sidebar_item(admins_topic_cooperators_path, '合作伙伴管理', icon: 'user', controller: 'admins-topic-cooperators') %></li> <li><%= sidebar_item(admins_topic_cooperators_path, '合作伙伴管理', icon: 'user', controller: 'admins-topic-cooperators') %></li>
<% end %> <% end %>
</li> </li>
<li>
<%= sidebar_item_group('#setting-glcc', 'GLCC配置', icon: 'fire') do %>
<li><%= sidebar_item(admins_topic_glcc_news_index_path, '新闻稿管理', icon: 'edit', controller: 'admins-topic-glcc_news') %></li>
<li>
<% if EduSetting.get("glcc_apply_informations_admin_url")%>
<%= sidebar_item(EduSetting.get("glcc_apply_informations_admin_url"), '报名列表', icon: 'user', controller: 'root') %>
<% end %>
</li>
<% end %>
</li>
<li> <li>
<%= sidebar_item_group('#setting-submenu', '网站建设', icon: 'cogs') do %> <%= sidebar_item_group('#setting-submenu', '网站建设', icon: 'cogs') do %>
<li><%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs') %></li> <li><%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs') %></li>

View File

@ -0,0 +1,44 @@
<div class="modal fade glcc-news-change-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><%= type == "create" ? "新增" : "编辑" %></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<%= form_for @glcc, url: {controller: "topic/glcc_news", action: "#{type}"} do |p| %>
<div class="modal-body">
<div class="form-group">
<label>
标题 <span class="ml10 color-orange mr20">*</span>
</label>
<%= p.text_field :title,class: "form-control input-lg",required: true%>
</div>
<div class="form-group">
<label>
跳转地址 <span class="ml10 color-orange mr20">*</span>
</label>
<%= p.text_field :url,class: "form-control input-lg",required: true%>
</div>
<div class="form-group">
<label>
帖子ID <span class="ml10 color-orange mr20">*</span>
</label>
<%= p.text_field :uuid,class: "form-control input-lg",required: true%>
</div>
<div class="form-group">
<label>
排序等级
</label>
<%= p.number_field :order_index, class: "form-control",placeholder: ""%>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<%= p.submit "确认", class: "btn btn-primary submit-btn" %>
</div>
<% end %>
</div>
</div>
</div>

View File

@ -0,0 +1,33 @@
<table class="table table-hover text-center subject-list-table">
<thead class="thead-light">
<tr>
<th width="5%">序号</th>
<th width="20%">标题</th>
<th width="20%">跳转地址</th>
<th width="10%">帖子ID</th>
<th width="20%">排序等级</th>
<th width="25%">操作</th>
</tr>
</thead>
<tbody>
<% if glcc_news.present? %>
<% glcc_news.each_with_index do |news, index| %>
<tr class="glcc-news-item-<%= news.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td><%= news.title %></td>
<td><%= news.url %></td>
<td><%= news.uuid %></td>
<td><%= news.order_index %></td>
<td class="action-container">
<%= link_to "编辑", edit_admins_topic_glcc_news_path(news), remote: true, class: "action" %>
<%= link_to "删除", admins_topic_glcc_news_path(news), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
</td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: glcc_news } %>

View File

@ -0,0 +1,2 @@
$("#glcc-news-modals").html("<%= j render(partial: 'admins/topic/glcc_news/form_modal', locals: {type: 'update'}) %>")
$(".glcc-news-change-modal").modal('show');

View File

@ -0,0 +1,18 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('新闻稿管理') %>
<% end %>
<div class="box search-form-container project-list-form">
<%= form_tag(admins_topic_glcc_news_index_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '标题检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
<%= link_to "新增", new_admins_topic_glcc_news_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
</div>
<div class="box admin-list-container glcc-news-list-container">
<%= render partial: 'admins/topic/glcc_news/list', locals: { glcc_news: @glcc_news } %>
</div>
<div id="glcc-news-modals">
</div>

View File

@ -0,0 +1 @@
$('.glcc-news-list-container').html("<%= j( render partial: 'admins/topic/glcc_news/list', locals: { glcc_news: @glcc_news } ) %>");

View File

@ -0,0 +1,2 @@
$("#glcc-news-modals").html("<%= j render(partial: 'admins/topic/glcc_news/form_modal', locals: {type: 'create'}) %>")
$(".glcc-news-change-modal").modal('show');

View File

@ -1,7 +1,7 @@
json.commits_count @compare_result['Commits']&.size json.commits_count @compare_result['CommitsCount']
# json.commits @compare_result['Commits'], partial: 'pull_requests/commit', as: :commit # json.commits @compare_result['Commits'], partial: 'pull_requests/commit', as: :commit
json.commits do json.commits do
json.array! @compare_result['Commits'] do |commit| json.array! @compare_result['Commits'][@page_offset...(@page_offset + @page_limit)] do |commit|
json.author do json.author do
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Committer']), name: commit['Committer']['Name'] } json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Committer']), name: commit['Committer']['Name'] }
end end

View File

@ -3,5 +3,5 @@ json.user do
json.partial! "organizations/user_detail", user: org_user.user json.partial! "organizations/user_detail", user: org_user.user
end 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") json.created_at org_user.created_at.strftime("%Y-%m-%d")

View File

@ -1,7 +1,7 @@
json.count @forks_count json.count @forks_count
json.users do json.users do
json.array! @fork_users.each do |f| json.array! @fork_users.each do |f|
user = f.user.present? ? f.user : Organization.find_by(id: f.user_id) user = f.owner.present? ? f.owner : Organization.find_by(id: f.user_id)
json.id f.fork_project.id json.id f.fork_project.id
json.identifier f.fork_project.identifier json.identifier f.fork_project.identifier
json.name "#{user.try(:show_real_name)}/#{f.fork_project.try(:name)}" json.name "#{user.try(:show_real_name)}/#{f.fork_project.try(:name)}"

View File

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

View File

@ -18,7 +18,7 @@ json.setting do
# #
# end # end
nav_bar = default_setting.navbar # nav_bar = default_setting.navbar
# if User.current.logged? # if User.current.logged?
# nav_bar[2]["link"] = "https://forgeplus.trustie.net/users/#{current_user.login}/projects" # 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.moop_cases_banner_url default_setting.moop_cases_banner_url&.[](1..-1)
json.oj_banner_url default_setting.oj_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 json.footer default_setting.footer
@ -51,6 +51,10 @@ json.setting do
json.array! @add json.array! @add
end end
json.sub_competitions do
json.array! @sub_competitions
end
json.personal do json.personal do
json.array! @personal json.array! @personal
end end

View File

@ -0,0 +1,4 @@
json.(glcc_news, :id, :title, :url, :uuid)
request_memo = Forum::Memos::GetService.call(glcc_news&.uuid)
json.visits request_memo.nil? ? 0 : request_memo["memo"]["viewed_count"]
json.created_time request_memo.nil? ? format_time(Time.now) : request_memo["memo"]["published_time"]

View File

@ -17,6 +17,8 @@ json.topics do
json.partial! "excellent_project", locals: {excellent_project: topic} json.partial! "excellent_project", locals: {excellent_project: topic}
when "Topic::ExperienceForum" when "Topic::ExperienceForum"
json.partial! "experience_forum", locals: {experience_forum: topic} json.partial! "experience_forum", locals: {experience_forum: topic}
when "Topic::GlccNews"
json.partial! "glcc_news", locals: {glcc_news: topic}
when "Topic::PinnedForum" when "Topic::PinnedForum"
json.partial! "pinned_forum", locals: {pinned_forum: topic} json.partial! "pinned_forum", locals: {pinned_forum: topic}
else else
@ -39,6 +41,8 @@ json.topics do
json.partial! "excellent_project", locals: {excellent_project: topic} json.partial! "excellent_project", locals: {excellent_project: topic}
when "Topic::ExperienceForum" when "Topic::ExperienceForum"
json.partial! "experience_forum", locals: {experience_forum: topic} json.partial! "experience_forum", locals: {experience_forum: topic}
when "Topic::GlccNews"
json.partial! "glcc_news", locals: {glcc_news: topic}
when "Topic::PinnedForum" when "Topic::PinnedForum"
json.partial! "pinned_forum", locals: {pinned_forum: topic} json.partial! "pinned_forum", locals: {pinned_forum: topic}
else else

View File

@ -3,6 +3,8 @@ json.array! users do |user|
json.username user.full_name json.username user.full_name
json.login user.login json.login user.login
json.user_id user.id json.user_id user.id
json.mail user.mail
json.custom_department user.custom_department
json.image_url url_to_avatar(user) json.image_url url_to_avatar(user)
json.profile_completed user.profile_completed json.profile_completed user.profile_completed
end end

View File

@ -22,5 +22,6 @@ json.province @user.province
json.city @user.city json.city @user.city
json.custom_department @user.custom_department json.custom_department @user.custom_department
json.description @user.description json.description @user.description
json.(@user, :show_email, :show_department, :show_location) json.super_description @user.super_description
json.(@user, :show_email, :show_department, :show_location, :show_super_description)
json.message_unread_total @message_unread_total json.message_unread_total @message_unread_total

View File

@ -13,4 +13,6 @@ json.email @user.show_email ? @user.mail : nil
json.province @user.show_location ? @user.province : nil json.province @user.show_location ? @user.province : nil
json.city @user.show_location ? @user.city : nil json.city @user.show_location ? @user.city : nil
json.custom_department @user.show_department ? @user.custom_department : nil json.custom_department @user.show_department ? @user.custom_department : nil
json.super_description @user.show_super_description ? @user.super_description : nil
json.show_super_description @user.show_super_description
json.description @user.description json.description @user.description

View File

@ -68,6 +68,10 @@ default: &default
read_domain: '' read_domain: ''
base_url: '' base_url: ''
trace:
domain: ''
base_url: ''
forum: forum:
domain: '' domain: ''
base_url: '/api' base_url: '/api'

View File

@ -3,5 +3,11 @@
attributes: attributes:
issues/create_form: issues/create_form:
subject: 标题 subject: 标题
description: 描述
issues/update_form: issues/update_form:
subject: 标题 subject: 标题
description: 描述
journals/create_form:
notes: 评论
journals/update_form:
notes: 评论

View File

@ -225,6 +225,7 @@ Rails.application.routes.draw do
get :fan_users get :fan_users
get :hovercard get :hovercard
put :update_image put :update_image
get :get_image
end end
collection do collection do
post :following post :following
@ -446,6 +447,7 @@ Rails.application.routes.draw do
get :stargazers, to: 'projects#praise_users' get :stargazers, to: 'projects#praise_users'
get :forks, to: 'projects#fork_users' get :forks, to: 'projects#fork_users'
match :about, :via => [:get, :put, :post] match :about, :via => [:get, :put, :post]
post :quit
end end
end end
@ -690,9 +692,9 @@ Rails.application.routes.draw do
resources :cooperators resources :cooperators
resources :excellent_projects resources :excellent_projects
resources :experience_forums resources :experience_forums
resources :glcc_news
resources :pinned_forums resources :pinned_forums
end end
resources :project_statistics, only: [:index] do resources :project_statistics, only: [:index] do
collection do collection do
get :visits_static 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

View File

@ -0,0 +1,6 @@
class AddSuperDescriptionToUserExtensions < ActiveRecord::Migration[5.2]
def change
add_column :user_extensions, :super_description, :text, :limit => 4294967295
add_column :user_extensions, :show_super_description, :boolean, default: false
end
end

View File

@ -0,0 +1,7 @@
class ChangeIssuesDescriptionAndJournalsNotesColumn < ActiveRecord::Migration[5.2]
def change
change_column :issues, :description, :text, :limit => 4294967295
change_column :journals, :notes, :text, :limit => 4294967295
change_column :pull_requests, :body, :text, :limit => 4294967295
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