diff --git a/app/controllers/admins/topic/glcc_news_controller.rb b/app/controllers/admins/topic/glcc_news_controller.rb new file mode 100644 index 000000000..3c1769e5f --- /dev/null +++ b/app/controllers/admins/topic/glcc_news_controller.rb @@ -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 \ No newline at end of file diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index de5e0a8c3..3aa98257a 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -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) diff --git a/app/controllers/compare_controller.rb b/app/controllers/compare_controller.rb index 07691d79f..1aab7adbe 100644 --- a/app/controllers/compare_controller.rb +++ b/app/controllers/compare_controller.rb @@ -9,6 +9,10 @@ class CompareController < ApplicationController load_compare_params compare @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 private @@ -16,6 +20,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 +55,14 @@ 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 + + def page_size + params.fetch(:page, 1).to_i + end + + def page_limit + params.fetch(:limit, 15).to_i end end diff --git a/app/controllers/concerns/login_helper.rb b/app/controllers/concerns/login_helper.rb index d8f2445fb..e608b7833 100644 --- a/app/controllers/concerns/login_helper.rb +++ b/app/controllers/concerns/login_helper.rb @@ -108,7 +108,11 @@ module LoginHelper def sync_pwd_to_gitea!(user, hash={}) 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)) if interactor.success? Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########" diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index ad53a4b3f..ddb0facdf 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -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") @@ -109,7 +109,7 @@ class IssuesController < ApplicationController def create 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) if @issue.save! SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu? @@ -223,7 +223,7 @@ class IssuesController < ApplicationController normal_status(-1, "不允许修改为关闭状态") else 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&.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? diff --git a/app/controllers/journals_controller.rb b/app/controllers/journals_controller.rb index 8fbe46924..6dc1e29c9 100644 --- a/app/controllers/journals_controller.rb +++ b/app/controllers/journals_controller.rb @@ -23,6 +23,7 @@ class JournalsController < ApplicationController normal_status(-1, "评论内容不能为空") else 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 = { journalized_id: @issue.id , journalized_type: "Issue", @@ -53,6 +54,9 @@ class JournalsController < ApplicationController end end end + rescue Exception => exception + puts exception.message + normal_status(-1, exception.message) end def destroy @@ -70,7 +74,8 @@ class JournalsController < ApplicationController def update 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) normal_status(0, "更新成功") else @@ -79,7 +84,9 @@ class JournalsController < ApplicationController else normal_status(-1, "评论的内容不能为空") end - + rescue Exception => exception + puts exception.message + normal_status(-1, exception.message) end def get_children_journals diff --git a/app/controllers/organizations/organization_users_controller.rb b/app/controllers/organizations/organization_users_controller.rb index 1cddabc90..5f358858d 100644 --- a/app/controllers/organizations/organization_users_controller.rb +++ b/app/controllers/organizations/organization_users_controller.rb @@ -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 diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index c31136f84..8bc2fb476 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -13,6 +13,8 @@ class ProjectsController < ApplicationController def menu_list menu = [] + user_is_admin = current_user.admin? || @project.manager?(current_user) + 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("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("resources")) if @project.has_menu_permission("resources") && @project.forge? 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 end @@ -88,7 +91,7 @@ class ProjectsController < ApplicationController return @branches = [] unless @project.forge? # 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 end @@ -135,7 +138,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 @@ -177,6 +180,22 @@ class ProjectsController < ApplicationController tip_exception(e.message) 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 watchers = @project.watchers.includes(:user).order("watchers.created_at desc").distinct @watchers_count = watchers.size @@ -190,7 +209,7 @@ class ProjectsController < ApplicationController end 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 @fork_users = paginate(fork_users) end diff --git a/app/controllers/pull_requests_controller.rb b/app/controllers/pull_requests_controller.rb index 2417e4fd5..f45d1f359 100644 --- a/app/controllers/pull_requests_controller.rb +++ b/app/controllers/pull_requests_controller.rb @@ -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}) @@ -29,7 +29,7 @@ class PullRequestsController < ApplicationController end 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? @projects_names = [{ project_user_login: @owner.try(:login), @@ -50,7 +50,7 @@ class PullRequestsController < ApplicationController end def get_branches - branch_result = Branches::ListService.call(@owner, @project) + branch_result = Branches::ListService.call(@owner, @project, params[:name]) render json: branch_result # return json: branch_result end @@ -58,6 +58,7 @@ class PullRequestsController < ApplicationController def create # return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user) 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) if @gitea_pull_request[:status] == :success @pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"]) @@ -89,7 +90,7 @@ class PullRequestsController < ApplicationController else ActiveRecord::Base.transaction do 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 @issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank? diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index c42051e0b..9fef22fc5 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -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 diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index 3a68ff7ba..f3eedd0a1 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -1,14 +1,24 @@ class SettingsController < ApplicationController def show @old_projects_url = nil + get_navbar get_add_menu get_common_menu + get_sub_competitions get_personal_menu get_third_party get_top_system_notification end 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 @add = [] Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site| @@ -20,6 +30,15 @@ class SettingsController < ApplicationController 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 @common = {} Site.common.select(:url, :key).each do |site| diff --git a/app/controllers/users/statistics_controller.rb b/app/controllers/users/statistics_controller.rb index dffd3f607..1948af9b3 100644 --- a/app/controllers/users/statistics_controller.rb +++ b/app/controllers/users/statistics_controller.rb @@ -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) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 5af634f18..f61ba2478 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -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 :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 :convert_image!, only: [:update, :update_image] skip_before_action :check_sign, only: [:attachment_show] @@ -97,6 +97,13 @@ class UsersController < ApplicationController render_error(-1, '头像修改失败!') 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 @user = current_user end @@ -306,6 +313,7 @@ class UsersController < ApplicationController :occupation, :technical_title, :school_id, :department_id, :province, :city, :custom_department, :identity, :student_id, :description, + :show_super_description, :super_description, :show_email, :show_location, :show_department] ) end @@ -321,4 +329,4 @@ class UsersController < ApplicationController render_not_found end -end +end \ No newline at end of file diff --git a/app/controllers/version_releases_controller.rb b/app/controllers/version_releases_controller.rb index 2d7546a1c..dd59098f7 100644 --- a/app/controllers/version_releases_controller.rb +++ b/app/controllers/version_releases_controller.rb @@ -14,7 +14,7 @@ class VersionReleasesController < ApplicationController def new #获取所有的分支 @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 get_all_branches.each do |b| @all_branches.push(b["name"]) diff --git a/app/forms/base_form.rb b/app/forms/base_form.rb index 598644fc2..ca82fa4bb 100644 --- a/app/forms/base_form.rb +++ b/app/forms/base_form.rb @@ -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 diff --git a/app/forms/issues/create_form.rb b/app/forms/issues/create_form.rb index 602775ff4..7ab942bc5 100644 --- a/app/forms/issues/create_form.rb +++ b/app/forms/issues/create_form.rb @@ -1,11 +1,11 @@ class Issues::CreateForm include ActiveModel::Model - attr_accessor :subject + attr_accessor :subject, :description validates :subject, presence: { message: "不能为空" } validates :subject, length: { maximum: 200, too_long: "不能超过200个字符" } - + validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符"} end diff --git a/app/forms/issues/update_form.rb b/app/forms/issues/update_form.rb index 64acdfb5c..1aa971e98 100644 --- a/app/forms/issues/update_form.rb +++ b/app/forms/issues/update_form.rb @@ -1,10 +1,12 @@ class Issues::UpdateForm include ActiveModel::Model - attr_accessor :subject + attr_accessor :subject, :description validates :subject, presence: { message: "不能为空" } validates :subject, length: { maximum: 200, too_long: "不能超过200个字符" } + validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符"} + end \ No newline at end of file diff --git a/app/forms/journals/create_form.rb b/app/forms/journals/create_form.rb new file mode 100644 index 000000000..8b96bc642 --- /dev/null +++ b/app/forms/journals/create_form.rb @@ -0,0 +1,7 @@ +class Journals::CreateForm + include ActiveModel::Model + + attr_accessor :notes + + validates :notes, length: { maximum: 65535, too_long: "不能超过65535个字符"} +end diff --git a/app/forms/journals/update_form.rb b/app/forms/journals/update_form.rb new file mode 100644 index 000000000..74f8fa6f4 --- /dev/null +++ b/app/forms/journals/update_form.rb @@ -0,0 +1,8 @@ +class Journals::UpdateForm + include ActiveModel::Model + + attr_accessor :notes + + validates :notes, length: { maximum: 65535, too_long: "不能超过65535个字符"} + +end \ No newline at end of file diff --git a/app/forms/projects/update_form.rb b/app/forms/projects/update_form.rb index 3048bc079..a351420bc 100644 --- a/app/forms/projects/update_form.rb +++ b/app/forms/projects/update_form.rb @@ -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 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 73b365039..c9096fe22 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -147,6 +147,15 @@ module ApplicationHelper 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图 def banner_img(source_type) if File.exist?(disk_filename(source_type, "banner")) diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index c69241858..3af3ef140 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -1,148 +1,169 @@ -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) + 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 diff --git a/app/libs/notice.rb b/app/libs/notice.rb index 93d5cb42d..18fdb070b 100644 --- a/app/libs/notice.rb +++ b/app/libs/notice.rb @@ -7,7 +7,7 @@ module Notice config = Rails.application.config_for(:configuration).symbolize_keys! notice_config = config[:notice].symbolize_keys! raise 'notice config missing' if notice_config.blank? - rescue => exception + rescue => ex raise ex if Rails.env.production? puts %Q{\033[33m [warning] gitea config or configuration.yml missing, diff --git a/app/libs/trace.rb b/app/libs/trace.rb new file mode 100644 index 000000000..3ec3b56a2 --- /dev/null +++ b/app/libs/trace.rb @@ -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 \ No newline at end of file diff --git a/app/models/fork_user.rb b/app/models/fork_user.rb index bddf8f75c..2d74af4a4 100644 --- a/app/models/fork_user.rb +++ b/app/models/fork_user.rb @@ -17,7 +17,7 @@ class ForkUser < ApplicationRecord 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 after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic diff --git a/app/models/journal.rb b/app/models/journal.rb index a1834ae2a..5bf05b0d2 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -6,7 +6,7 @@ # journalized_id :integer default("0"), not null # journalized_type :string(30) default(""), not null # user_id :integer default("0"), not null -# notes :text(65535) +# notes :text(4294967295) # created_on :datetime not null # private_notes :boolean default("0"), not null # parent_id :integer diff --git a/app/models/organization.rb b/app/models/organization.rb index 40c676e05..56351a415 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -83,6 +83,10 @@ class Organization < Owner 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 Cache::V2::OwnerCommonService.new(self.id).reset end diff --git a/app/models/pull_request.rb b/app/models/pull_request.rb index 74111ad0d..a9f215c8d 100644 --- a/app/models/pull_request.rb +++ b/app/models/pull_request.rb @@ -3,8 +3,8 @@ # Table name: pull_requests # # id :integer not null, primary key -# pull_request_id :integer -# gpid :integer +# gitea_id :integer +# gitea_number :integer # user_id :integer # created_at :datetime not null # updated_at :datetime not null @@ -12,7 +12,7 @@ # project_id :integer # title :string(255) # milestone :integer -# body :text(65535) +# body :text(4294967295) # head :string(255) # base :string(255) # issue_id :integer diff --git a/app/models/site.rb b/app/models/site.rb index 755fe3866..a8b725ef6 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -15,7 +15,7 @@ class Site < ApplicationRecord # add: 添加类链接 # personal: 个人名下类链接, # 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_site_type, -> (site_type){ where(site_type: strip_param(site_type)) unless strip_param(site_type).blank? } diff --git a/app/models/team.rb b/app/models/team.rb index c2e633380..b831cd069 100644 --- a/app/models/team.rb +++ b/app/models/team.rb @@ -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} diff --git a/app/models/topic.rb b/app/models/topic.rb index 13bf7b5bd..e464859ec 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -35,6 +35,8 @@ class Topic < ApplicationRecord 'Topic::ExcellentProject' when 'experience_forum' 'Topic::ExperienceForum' + when "glcc_news" + 'Topic::GlccNews' when 'pinned_forum' 'Topic::PinnedForum' end diff --git a/app/models/topic/glcc_news.rb b/app/models/topic/glcc_news.rb new file mode 100644 index 000000000..6b707bf07 --- /dev/null +++ b/app/models/topic/glcc_news.rb @@ -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 \ No newline at end of file diff --git a/app/models/trace_user.rb b/app/models/trace_user.rb new file mode 100644 index 000000000..e89641565 --- /dev/null +++ b/app/models/trace_user.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index c71a02497..66aeb6164 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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]) } @@ -187,7 +188,7 @@ class User < Owner attr_accessor :password, :password_confirmation 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 before_save :update_hashed_password, :set_lastname @@ -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位 diff --git a/app/models/user_extension.rb b/app/models/user_extension.rb index ee208af7e..c1046ac2f 100644 --- a/app/models/user_extension.rb +++ b/app/models/user_extension.rb @@ -2,35 +2,34 @@ # # Table name: user_extensions # -# id :integer not null, primary key -# user_id :integer not null -# birthday :date -# brief_introduction :string(255) -# gender :integer -# location :string(255) -# occupation :string(255) -# work_experience :integer -# zip_code :integer -# created_at :datetime not null -# updated_at :datetime not null -# technical_title :string(255) -# identity :integer -# student_id :string(255) -# teacher_realname :string(255) -# student_realname :string(255) -# location_city :string(255) -# school_id :integer -# description :string(255) default("") -# department_id :integer -# honor :text(65535) -# edu_background :integer -# edu_entry_year :integer -# province :string(255) -# city :string(255) -# custom_department :string(255) -# show_email :boolean default("0") -# show_location :boolean default("0") -# show_department :boolean default("0") +# id :integer not null, primary key +# user_id :integer not null +# birthday :date +# brief_introduction :string(255) +# gender :integer +# location :string(255) +# occupation :string(255) +# work_experience :integer +# zip_code :integer +# created_at :datetime not null +# updated_at :datetime not null +# technical_title :string(255) +# identity :integer +# student_id :string(255) +# teacher_realname :string(255) +# student_realname :string(255) +# location_city :string(255) +# school_id :integer +# description :string(255) default("") +# department_id :integer +# province :string(255) +# city :string(255) +# custom_department :string(255) +# show_email :boolean default("0") +# show_location :boolean default("0") +# show_department :boolean default("0") +# super_description :text(4294967295) +# show_super_description :boolean default("0") # # Indexes # diff --git a/app/services/branches/list_service.rb b/app/services/branches/list_service.rb index a3b77a7b0..7b47658e3 100644 --- a/app/services/branches/list_service.rb +++ b/app/services/branches/list_service.rb @@ -1,17 +1,18 @@ 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 @project = project + @name = name end def call all_branches = [] user_name = user.try(:show_real_name) 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 return all_branches end diff --git a/app/services/gitea/client_service.rb b/app/services/gitea/client_service.rb index 7cdfdd495..b0c842db1 100644 --- a/app/services/gitea/client_service.rb +++ b/app/services/gitea/client_service.rb @@ -82,7 +82,7 @@ class Gitea::ClientService < ApplicationService req.headers['Content-Type'] = 'application/json' req.response :logger # 显示日志 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 if token.blank? req.basic_auth(username, secret) diff --git a/app/services/gitea/repository/branches/list_name_service.rb b/app/services/gitea/repository/branches/list_name_service.rb index 716ee464c..c005c8359 100644 --- a/app/services/gitea/repository/branches/list_name_service.rb +++ b/app/services/gitea/repository/branches/list_name_service.rb @@ -1,9 +1,10 @@ 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 @repo = repo + @name = name end def call @@ -13,7 +14,7 @@ class Gitea::Repository::Branches::ListNameService < Gitea::ClientService private def params - Hash.new.merge(token: user.gitea_token) + Hash.new.merge(token: user.gitea_token, name: name) end def url diff --git a/app/services/gitea/repository/branches/list_service.rb b/app/services/gitea/repository/branches/list_service.rb index f42965098..7722ecd0b 100644 --- a/app/services/gitea/repository/branches/list_service.rb +++ b/app/services/gitea/repository/branches/list_service.rb @@ -1,9 +1,10 @@ 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 @repo = repo + @name = name end def call @@ -13,7 +14,7 @@ class Gitea::Repository::Branches::ListService < Gitea::ClientService private def params - Hash.new.merge(token: user.gitea_token) + Hash.new.merge(token: user.gitea_token, name: name) end def url diff --git a/app/services/issues/list_query_service.rb b/app/services/issues/list_query_service.rb index f85e2cb9d..73f0b438e 100644 --- a/app/services/issues/list_query_service.rb +++ b/app/services/issues/list_query_service.rb @@ -28,11 +28,11 @@ class Issues::ListQueryService < ApplicationService end 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 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" diff --git a/app/services/organizations/create_service.rb b/app/services/organizations/create_service.rb index a430ed6f4..263779191 100644 --- a/app/services/organizations/create_service.rb +++ b/app/services/organizations/create_service.rb @@ -47,7 +47,7 @@ class Organizations::CreateService < ApplicationService end 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, location, repo_admin_change_team_access, visibility, max_repo_creation) diff --git a/app/services/pull_requests/create_service.rb b/app/services/pull_requests/create_service.rb index d15b3f9fc..258d0e31b 100644 --- a/app/services/pull_requests/create_service.rb +++ b/app/services/pull_requests/create_service.rb @@ -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(:owner).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 diff --git a/app/services/trace/add_user_service.rb b/app/services/trace/add_user_service.rb new file mode 100644 index 000000000..0099f6e9a --- /dev/null +++ b/app/services/trace/add_user_service.rb @@ -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 \ No newline at end of file diff --git a/app/services/trace/check_result_service.rb b/app/services/trace/check_result_service.rb new file mode 100644 index 000000000..f1dd61ab0 --- /dev/null +++ b/app/services/trace/check_result_service.rb @@ -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 + diff --git a/app/services/trace/check_service.rb b/app/services/trace/check_service.rb new file mode 100644 index 000000000..d31bbcf09 --- /dev/null +++ b/app/services/trace/check_service.rb @@ -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 + diff --git a/app/services/trace/client_service.rb b/app/services/trace/client_service.rb new file mode 100644 index 000000000..72ffa8ca2 --- /dev/null +++ b/app/services/trace/client_service.rb @@ -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 \ No newline at end of file diff --git a/app/services/trace/login_service.rb b/app/services/trace/login_service.rb new file mode 100644 index 000000000..9f59d8e14 --- /dev/null +++ b/app/services/trace/login_service.rb @@ -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 \ No newline at end of file diff --git a/app/services/trace/pdf_report_service.rb b/app/services/trace/pdf_report_service.rb new file mode 100644 index 000000000..e91a78b30 --- /dev/null +++ b/app/services/trace/pdf_report_service.rb @@ -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 \ No newline at end of file diff --git a/app/services/trace/reload_check_service.rb b/app/services/trace/reload_check_service.rb new file mode 100644 index 000000000..62530af19 --- /dev/null +++ b/app/services/trace/reload_check_service.rb @@ -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 \ No newline at end of file diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index 3e659395a..4c6e6de70 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -42,7 +42,16 @@
| 序号 | +标题 | +跳转地址 | +帖子ID | +排序等级 | +操作 | +
|---|---|---|---|---|---|
| <%= list_index_no((params[:page] || 1).to_i, index) %> | +<%= news.title %> | +<%= news.url %> | +<%= news.uuid %> | +<%= news.order_index %> | ++ <%= 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" %> + | +