| @@ -84,4 +84,5 @@ redis_data/ | |||
| Dockerfile | |||
| dump.rdb | |||
| .tags* | |||
| ceshi_user.xlsx | |||
| ceshi_user.xlsx | |||
| public/trace_task_results | |||
| @@ -22,6 +22,7 @@ class ProjectsController < ApplicationController | |||
| menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops") && @project.forge? | |||
| menu.append(menu_hash_by_name("versions")) if @project.has_menu_permission("versions") | |||
| menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki") && @project.forge? | |||
| menu.append(menu_hash_by_name("services")) if @project.has_menu_permission("services") && @project.forge? && (current_user.admin? || @project.member?(current_user.id)) | |||
| 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 user_is_admin && @project.forge? | |||
| @@ -0,0 +1,18 @@ | |||
| class Traces::BaseController < ApplicationController | |||
| helper_method :observed_logged_user?, :observed_user | |||
| def observed_user | |||
| @_observed_user ||= (User.find_by_login(params[:user_id]) || User.find_by_id(params[:user_id])) | |||
| end | |||
| def observed_logged_user? | |||
| observed_user.id == User.current&.id | |||
| end | |||
| protected | |||
| def check_auth | |||
| return render_forbidden unless current_user.admin? || observed_logged_user? | |||
| end | |||
| end | |||
| @@ -0,0 +1,83 @@ | |||
| class Traces::ProjectsController < Traces::BaseController | |||
| include OperateProjectAbilityAble | |||
| before_action :require_login | |||
| before_action :load_project | |||
| before_action :authorizate_user_can_edit_project!, except: [:task_results] | |||
| def tasks | |||
| branch_name = params[:branch_name] | |||
| return render_error("无可用检测次数") if @project.user_trace_tasks.size >= 5 | |||
| return render_error("分支名不能为空!") if branch_name.blank? | |||
| @all_branches = Gitea::Repository::Branches::ListNameService.call(@project&.owner, @project.identifier) | |||
| return render_error("请输入正确的分支名!") unless @all_branches["branch_name"].include?(branch_name) | |||
| code, data, error = Trace::CheckService.call(current_user.trace_token, @project, "1", branch_name) | |||
| if code == 200 | |||
| UserTraceTask.create!( | |||
| user_id: current_user.id, | |||
| project_id: @project.id, | |||
| branch_tag: branch_name, | |||
| task_id: data["task_id"] | |||
| ) | |||
| render_ok | |||
| else | |||
| render_error("检测失败 Error:#{error}") | |||
| end | |||
| rescue Exception => exception | |||
| puts exception.message | |||
| normal_status(-1, exception.message) | |||
| end | |||
| def task_results | |||
| limit = params[:limit] || params[:per_page] | |||
| limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i | |||
| page = params[:page].to_i.zero? ? 1 : params[:page].to_i | |||
| return render :json => {left_tasks_count: 5, data: []} if current_user.trace_user.nil? | |||
| code, data, error = Trace::CheckResultService.call(current_user.trace_token, @project, nil, page, limit) | |||
| if code == 200 | |||
| render :json => {left_tasks_count: 5 - @project.user_trace_tasks.size, data: data} | |||
| else | |||
| render_error("获取检测记录失败 Error:#{error}") | |||
| end | |||
| rescue Exception => exception | |||
| puts exception.message | |||
| normal_status(-1, exception.message) | |||
| end | |||
| def reload_task | |||
| return render_error("project_id错误") if params[:project_id].blank? | |||
| branch_name = params[:branch_name] | |||
| return render_error("分支名不能为空!") if branch_name.blank? | |||
| @all_branches = Gitea::Repository::Branches::ListNameService.call(@project&.owner, @project.identifier) | |||
| return render_error("请输入正确的分支名!") unless @all_branches["branch_name"].include?(branch_name) | |||
| code, data, error = Trace::ReloadCheckService.call(current_user.trace_token, params[:project_id]) | |||
| if code == 200 | |||
| UserTraceTask.create!( | |||
| user_id: current_user.id, | |||
| project_id: @project.id, | |||
| branch_tag: branch_name, | |||
| task_id: data["task_id"] | |||
| ) | |||
| render_ok | |||
| else | |||
| render_error("重新检测失败 Error:#{error}") | |||
| end | |||
| rescue Exception => exception | |||
| puts exception.message | |||
| normal_status(-1, exception.message) | |||
| end | |||
| def task_pdf | |||
| return render_error("task_id错误") if params[:task_id].blank? | |||
| result = Trace::PdfReportService.call(current_user.trace_token, params[:task_id]) | |||
| if result.is_a?(Hash) && result[:code] == 200 | |||
| redirect_to result[:download_url] | |||
| else | |||
| render_error("下载报告失败!") | |||
| end | |||
| rescue Exception => exception | |||
| puts exception.message | |||
| normal_status(-1, exception.message) | |||
| end | |||
| end | |||
| @@ -0,0 +1,14 @@ | |||
| class Traces::TraceUsersController < Traces::BaseController | |||
| before_action :require_login | |||
| def create | |||
| if current_user.trace_token.present? | |||
| render_ok | |||
| else | |||
| render_error(-1, "代码溯源用户初始化失败") | |||
| end | |||
| rescue Exception => exception | |||
| puts exception.message | |||
| normal_status(-1, exception.message) | |||
| end | |||
| end | |||
| @@ -16,6 +16,7 @@ includes: | |||
| - users | |||
| - projects | |||
| - repositories | |||
| - traces | |||
| - pulls | |||
| - issues | |||
| - organizations | |||
| @@ -280,7 +280,7 @@ repo |是| |string |项目标识identifier | |||
| ### 返回字段说明 | |||
| 参数 | 类型 | 字段说明 | |||
| --------- | ----------- | ----------- | |||
| menu_name |string|导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置 | |||
| menu_name |string|导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,wiki:维基,services:服务,activity:动态,setting:仓库设置 | |||
| > 返回的JSON示例: | |||
| @@ -408,7 +408,7 @@ await octokit.request('POST /api/yystopf/ceshi/project_units') | |||
| ### 请求参数 | |||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||
| --------- | ------- | ------- | -------- | ---------- | |||
| |unit_types |是| |array | 项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑 | | |||
| |unit_types |是| |array | 项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,wiki:维基,resources:资源库,services:服务 | | |||
| ### 返回字段说明: | |||
| @@ -0,0 +1,217 @@ | |||
| # Traces | |||
| ## 代码溯源初始化 | |||
| 用户同意协议后请求的接口,创建代码溯源的账号 | |||
| > 示例: | |||
| ```shell | |||
| curl -X POST \ | |||
| http://localhost:3000/api/traces/trace_users.json | |||
| ``` | |||
| ```javascript | |||
| await octokit.request('POST /api/traces/trace_users.json') | |||
| ``` | |||
| ### HTTP 请求 | |||
| `POST api/traces/trace_users.json` | |||
| > 返回的JSON示例: | |||
| ```json | |||
| { | |||
| "status": 0, | |||
| "message": "success" | |||
| } | |||
| ``` | |||
| <aside class="success"> | |||
| Success — a happy kitten is an authenticated kitten! | |||
| </aside> | |||
| ## 代码分析结果列表 | |||
| 查询项目下代码分析的结果 | |||
| > 示例: | |||
| ```shell | |||
| curl -X GET \ | |||
| http://localhost:3000/api/traces/yystopf/many_branch/task_results.json | |||
| ``` | |||
| ```javascript | |||
| await octokit.request('GET /api/traces/:owner/:repo/task_results.json') | |||
| ``` | |||
| ### HTTP 请求 | |||
| `GET api/traces/:owner/:repo/task_results.json` | |||
| ### 请求参数 | |||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||
| --------- | ------- | ------- | -------- | ---------- | |||
| owner|是|否|string | 项目所有者标识| | |||
| repo|是 | 否|string | 项目标识 | | |||
| page |否| 1 | int | 页码 | | |||
| limit |否| 15 | int | 每页数量 | | |||
| ### 返回字段说明(暂缺) | |||
| <!-- 参数 | 类型 | 字段说明 | |||
| --------- | ----------- | ----------- | |||
| total_count |int |总数 | | |||
| public_keys.id |int |ID| | |||
| public_keys.name |string|密钥标题| | |||
| public_keys.content |string|密钥内容| | |||
| public_keys.fingerprint |string|密钥标识| | |||
| public_keys.created_time |string|密钥创建时间| --> | |||
| > 返回的JSON示例: | |||
| ```json | |||
| { | |||
| "data": [ | |||
| { | |||
| "accuracy": "20", | |||
| "code_type": "C", | |||
| "depth": "2", | |||
| "detect_flag": "快速-组件级", | |||
| "detect_rule": "快速-组件级,2,20,,开源软件,50,10", | |||
| "detect_startdate": "2022-05-10 15:59:46 ", | |||
| "detect_status": "fail", | |||
| "detectflag": "快速-组件级", | |||
| "fail_reason": "Invalid package type", | |||
| "file_name": "many_branch.zip", | |||
| "license_process": "100", | |||
| "licenseparam": "开源软件", | |||
| "package_type": "", | |||
| "product_name": "84727546110", | |||
| "project_id": "6dbc3e42-5857-4ca4-a54d-58fd9dbf6dc5", | |||
| "sim_process": "100", | |||
| "similarity_process": "2", | |||
| "task_id": "15139171-091b-4316-98b1-6068970efa44", | |||
| "totalsize": 5, | |||
| "uid": "78", | |||
| "vuln_process": "", | |||
| "vulnlevel": "" | |||
| } | |||
| ] | |||
| } | |||
| ``` | |||
| <aside class="success"> | |||
| Success — a happy kitten is an authenticated kitten! | |||
| </aside> | |||
| ## 新建分析 | |||
| 用户选择仓库分支进行代码分析的接口 | |||
| > 示例: | |||
| ```shell | |||
| curl -X POST \ | |||
| http://localhost:3000/api/traces/yystopf/many_branch/tasks.json | |||
| ``` | |||
| ```javascript | |||
| await octokit.request('POST /api/traces/:owner/:repo/tasks.json') | |||
| ``` | |||
| ### HTTP 请求 | |||
| `POST api/traces/:owner/:repo/tasks.json` | |||
| ### 请求参数 | |||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||
| --------- | ------- | ------- | -------- | ---------- | |||
| owner |是 | 否 | string | 项目所有者标识 | | |||
| repo |是 | 否 | string | 项目标识 | | |||
| branch_name|是 | 否| string | 分支名称 | | |||
| > 返回的JSON示例: | |||
| ```json | |||
| { | |||
| "status": 0, | |||
| "message": "success" | |||
| } | |||
| ``` | |||
| <aside class="success"> | |||
| Success — a happy kitten is an authenticated kitten! | |||
| </aside> | |||
| ## 重新扫描 | |||
| 对代码分析结果进行再次分析 | |||
| > 示例: | |||
| ```shell | |||
| curl -X GET \ | |||
| http://localhost:3000/api/traces/yystopf/many_branch/reload_task.json | |||
| ``` | |||
| ```javascript | |||
| await octokit.request('GET /api/traces/:owner/:repo/reload_task.json') | |||
| ``` | |||
| ### HTTP 请求 | |||
| `GET api/traces/:owner/:repo/reload_task.json` | |||
| ### 请求参数 | |||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||
| --------- | ------- | ------- | -------- | ---------- | |||
| owner |是 | 否 | string | 项目所有者标识 | | |||
| repo |是 | 否 | string | 项目标识 | | |||
| project_id|是 | 否| string | 代码分析结果里的project_id | | |||
| branch_name|是 | 否| string | 分支名称 | | |||
| > 返回的JSON示例: | |||
| ```json | |||
| { | |||
| "status": 0, | |||
| "message": "success" | |||
| } | |||
| ``` | |||
| <aside class="success"> | |||
| Success — a happy kitten is an authenticated kitten! | |||
| </aside> | |||
| ## 下载报告 | |||
| 把代码分析的结果下载到本地 | |||
| > 示例: | |||
| ```shell | |||
| curl -X GET \ | |||
| http://localhost:3000/api/traces/yystopf/many_branch/task_pdf.json | |||
| ``` | |||
| ```javascript | |||
| await octokit.request('GET /api/traces/:owner/:repo/task_pdf.json') | |||
| ``` | |||
| ### HTTP 请求 | |||
| `GET api/traces/:owner/:repo/task_pdf.json` | |||
| ### 请求参数 | |||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | |||
| --------- | ------- | ------- | -------- | ---------- | |||
| owner |是 | 否 | string | 项目所有者标识 | | |||
| repo |是 | 否 | string | 项目标识 | | |||
| task_id|是 | 否| string | 代码分析结果里的task_id | | |||
| > 返回的JSON示例: | |||
| ```json | |||
| { | |||
| "status": 0, | |||
| "message": "success" | |||
| } | |||
| ``` | |||
| <aside class="success"> | |||
| Success — a happy kitten is an authenticated kitten! | |||
| </aside> | |||
| @@ -141,6 +141,7 @@ class MessageTemplate::ProjectSettingChanged < MessageTemplate | |||
| navbar.gsub!('devops', '工作流') | |||
| navbar.gsub!('versions', '里程碑') | |||
| navbar.gsub!('resources', '资源库') | |||
| navbar.gsub!('services', '服务') | |||
| if change_count > 1 | |||
| content.sub!('{ifnavbar}', '<br/>') | |||
| else | |||
| @@ -290,6 +291,7 @@ class MessageTemplate::ProjectSettingChanged < MessageTemplate | |||
| navbar.gsub!('devops', '工作流') | |||
| navbar.gsub!('versions', '里程碑') | |||
| navbar.gsub!('resources', '资源库') | |||
| navbar.gsub!('services', '服务') | |||
| if change_count > 1 | |||
| content.sub!('{ifnavbar}', '<br/>') | |||
| else | |||
| @@ -124,6 +124,7 @@ class Project < ApplicationRecord | |||
| has_many :pinned_projects, dependent: :destroy | |||
| has_many :has_pinned_users, through: :pinned_projects, source: :user | |||
| has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id | |||
| has_many :user_trace_tasks, dependent: :destroy | |||
| after_create :incre_user_statistic, :incre_platform_statistic | |||
| after_save :check_project_members | |||
| before_save :set_invite_code, :reset_unmember_followed, :set_recommend_and_is_pinned, :reset_cache_data | |||
| @@ -16,7 +16,7 @@ | |||
| class ProjectUnit < ApplicationRecord | |||
| belongs_to :project | |||
| enum unit_type: {code: 1, issues: 2, pulls: 3, wiki:4, devops: 5, versions: 6, resources: 7} | |||
| enum unit_type: {code: 1, issues: 2, pulls: 3, wiki:4, devops: 5, versions: 6, resources: 7, services: 8} | |||
| validates :unit_type, uniqueness: { scope: :project_id} | |||
| @@ -175,6 +175,7 @@ class User < Owner | |||
| has_many :system_notification_histories | |||
| has_many :system_notifications, through: :system_notification_histories | |||
| has_one :trace_user, dependent: :destroy | |||
| has_many :user_trace_tasks, dependent: :destroy | |||
| # Groups and active users | |||
| scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) } | |||
| @@ -0,0 +1,25 @@ | |||
| # == Schema Information | |||
| # | |||
| # Table name: user_trace_tasks | |||
| # | |||
| # id :integer not null, primary key | |||
| # user_id :integer | |||
| # project_id :integer | |||
| # branch_tag :string(255) | |||
| # task_id :string(255) | |||
| # created_at :datetime not null | |||
| # updated_at :datetime not null | |||
| # | |||
| # Indexes | |||
| # | |||
| # index_user_trace_tasks_on_project_id (project_id) | |||
| # index_user_trace_tasks_on_user_id (user_id) | |||
| # | |||
| class UserTraceTask < ApplicationRecord | |||
| belongs_to :user | |||
| belongs_to :project | |||
| end | |||
| @@ -1,11 +1,11 @@ | |||
| # 代码溯源 查询检测结果 | |||
| class Trace::CheckResultService < Trace::ClientService | |||
| attr_accessor :token, :project_name, :file_name, :page_num, :page_size | |||
| attr_accessor :token, :project, :file_name, :page_num, :page_size | |||
| def initialize(token, project_name=nil, file_name=nil, page_num=1, page_size=15) | |||
| def initialize(token, project, file_name=nil, page_num=1, page_size=15) | |||
| @token = token | |||
| @project_name = project_name | |||
| @project = project | |||
| @file_name = file_name | |||
| @page_num = page_num | |||
| @page_size = page_size | |||
| @@ -19,7 +19,7 @@ class Trace::CheckResultService < Trace::ClientService | |||
| private | |||
| def request_params | |||
| { | |||
| product_name: project_name, | |||
| product_name: Digest::MD5.hexdigest(project&.id.to_s)[0...20], | |||
| file_name: file_name, | |||
| pageNum: page_num, | |||
| pageSize: page_size, | |||
| @@ -11,26 +11,25 @@ class Trace::CheckService < Trace::ClientService | |||
| end | |||
| def call | |||
| result = authed_post(token, url, {data: request_params}) | |||
| result = http_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) | |||
| repo = Gitea::Repository::GetService.call(project&.owner, project&.identifier) | |||
| { | |||
| product_name: project&.name, | |||
| product_type: project&.category&.name, | |||
| code_type: project&.language&.name, | |||
| product_name: Digest::MD5.hexdigest(project&.id.to_s)[0...20], | |||
| product_type: project&.project_category&.name || '其他', | |||
| code_type: project&.project_language&.name || '其他', | |||
| product_desc: project&.description, | |||
| git_url: repo['clone_url'], | |||
| if_branch: if_branch, | |||
| branch_tag: branch_tag | |||
| } | |||
| }.compact | |||
| end | |||
| def url | |||
| "/user/check".freeze | |||
| end | |||
| end | |||
| end | |||
| @@ -12,6 +12,19 @@ class Trace::ClientService < ApplicationService | |||
| conn.post(full_url(url), params[:data]) | |||
| end | |||
| def http_authed_post(token, url, params={}) | |||
| puts "[trace][POST] request params: #{params}" | |||
| puts "[trace][POST] request token: #{token}" | |||
| url = URI("#{full_url(url)}") | |||
| http = Net::HTTP.new(url.host, url.port) | |||
| http.read_timeout = 1200 | |||
| request = Net::HTTP::Post.new(url) | |||
| request["Authorization"] = token | |||
| form_data = params[:data].stringify_keys.to_a | |||
| request.set_form form_data, 'multipart/form-data' | |||
| http.request(request) | |||
| end | |||
| def get(url, params={}) | |||
| puts "[trace][GET] request params: #{params}" | |||
| conn.get do |req| | |||
| @@ -100,11 +113,22 @@ class Trace::ClientService < ApplicationService | |||
| end | |||
| def render_response(response) | |||
| status = response.status | |||
| body = JSON.parse(response&.body) | |||
| if response.is_a?(Faraday::Response) | |||
| status = response.status | |||
| body = JSON.parse(response&.body) | |||
| log_error(status, body) | |||
| log_error(status, body) | |||
| return [body["code"], body["data"], body["error"]] | |||
| return [body["code"], body["data"], body["error"]] | |||
| end | |||
| if response.is_a?(Net::HTTPOK) | |||
| status = 200 | |||
| body = JSON.parse(response&.body) | |||
| log_error(status, body) | |||
| return [body["code"], body["data"], body["error"]] | |||
| end | |||
| end | |||
| end | |||
| @@ -1,4 +1,7 @@ | |||
| # 代码溯源 导出pdf | |||
| require 'open-uri' | |||
| require 'fileutils' | |||
| class Trace::PdfReportService < Trace::ClientService | |||
| attr_accessor :token, :task_id | |||
| @@ -9,15 +12,23 @@ class Trace::PdfReportService < Trace::ClientService | |||
| end | |||
| def call | |||
| result = authed_get(token, url, request_params) | |||
| response = render_response(result) | |||
| content = open("#{domain}#{base_url}#{url}?task_id=#{task_id}", "Authorization" => token) | |||
| if content.is_a?(Tempfile) | |||
| check_file_path | |||
| IO.copy_stream(content, "#{save_path}/#{task_id}.pdf") | |||
| return {code: 200, download_url: "/trace_task_results/#{task_id}.pdf"} | |||
| else | |||
| return {code: 404} | |||
| end | |||
| end | |||
| private | |||
| def request_params | |||
| { | |||
| task_id: task_id | |||
| } | |||
| def check_file_path | |||
| FileUtils.mkdir_p save_path | |||
| end | |||
| def save_path | |||
| "public/trace_task_results" | |||
| end | |||
| def url | |||
| @@ -25,3 +25,4 @@ json.description @user.description | |||
| 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.has_trace_user @user.trace_user.present? | |||
| @@ -427,6 +427,20 @@ Rails.application.routes.draw do | |||
| end | |||
| end | |||
| namespace :traces do | |||
| resources :trace_users, only: [:create] | |||
| scope "/:owner/:repo" do | |||
| resource :projects, path: '/', only: [:index] do | |||
| member do | |||
| post :tasks | |||
| get :task_results | |||
| get :reload_task | |||
| get :task_pdf | |||
| end | |||
| end | |||
| end | |||
| end | |||
| # Project Area START | |||
| scope "/:owner/:repo" do | |||
| scope do | |||
| @@ -0,0 +1,12 @@ | |||
| class CreateUserTraceTasks < ActiveRecord::Migration[5.2] | |||
| def change | |||
| create_table :user_trace_tasks do |t| | |||
| t.references :user | |||
| t.references :project | |||
| t.string :branch_tag | |||
| t.string :task_id | |||
| t.timestamps | |||
| end | |||
| end | |||
| end | |||
| @@ -543,6 +543,26 @@ | |||
| </li> | |||
| </ul> | |||
| </li> | |||
| <li> | |||
| <a href="#traces" class="toc-h1 toc-link" data-title="Traces">Traces</a> | |||
| <ul class="toc-list-h2"> | |||
| <li> | |||
| <a href="#ca438fc3ca" class="toc-h2 toc-link" data-title="代码溯源初始化">代码溯源初始化</a> | |||
| </li> | |||
| <li> | |||
| <a href="#bb16c601f1" class="toc-h2 toc-link" data-title="代码分析结果列表">代码分析结果列表</a> | |||
| </li> | |||
| <li> | |||
| <a href="#32497859e0" class="toc-h2 toc-link" data-title="新建分析">新建分析</a> | |||
| </li> | |||
| <li> | |||
| <a href="#7b3a48e274" class="toc-h2 toc-link" data-title="重新扫描">重新扫描</a> | |||
| </li> | |||
| <li> | |||
| <a href="#87775b1430" class="toc-h2 toc-link" data-title="下载报告">下载报告</a> | |||
| </li> | |||
| </ul> | |||
| </li> | |||
| <li> | |||
| <a href="#pulls" class="toc-h1 toc-link" data-title="Pulls">Pulls</a> | |||
| <ul class="toc-list-h2"> | |||
| @@ -4968,7 +4988,7 @@ http://localhost:3000/api/yystopf/ceshi/menu_list | jq | |||
| <tr> | |||
| <td>menu_name</td> | |||
| <td>string</td> | |||
| <td>导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置</td> | |||
| <td>导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,wiki:维基,services:服务,activity:动态,setting:仓库设置</td> | |||
| </tr> | |||
| </tbody></table> | |||
| @@ -5131,7 +5151,7 @@ http://localhost:3000/api/yystopf/ceshi/project_units.json | |||
| <td>是</td> | |||
| <td></td> | |||
| <td>array</td> | |||
| <td>项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑</td> | |||
| <td>项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,wiki:维基,resources:资源库,services:服务</td> | |||
| </tr> | |||
| </tbody></table> | |||
| <h3 id='7447e4874e-2'>返回字段说明:</h3> | |||
| @@ -9302,6 +9322,289 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/3/test.json | |||
| <aside class="success"> | |||
| Success Data. | |||
| </aside> | |||
| <h1 id='traces'>Traces</h1><h2 id='ca438fc3ca'>代码溯源初始化</h2> | |||
| <p>用户同意协议后请求的接口,创建代码溯源的账号</p> | |||
| <blockquote> | |||
| <p>示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST <span class="se">\</span> | |||
| http://localhost:3000/api/traces/trace_users.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">POST /api/traces/trace_users.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http'>HTTP 请求</h3> | |||
| <p><code>POST api/traces/trace_users.json</code></p> | |||
| <blockquote> | |||
| <p>返回的JSON示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> | |||
| </span><span class="nl">"status"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"success"</span><span class="w"> | |||
| </span><span class="p">}</span><span class="w"> | |||
| </span></code></pre></div> | |||
| <aside class="success"> | |||
| Success — a happy kitten is an authenticated kitten! | |||
| </aside> | |||
| <h2 id='bb16c601f1'>代码分析结果列表</h2> | |||
| <p>查询项目下代码分析的结果</p> | |||
| <blockquote> | |||
| <p>示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET <span class="se">\</span> | |||
| http://localhost:3000/api/traces/yystopf/many_branch/task_results.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/traces/:owner/:repo/task_results.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-2'>HTTP 请求</h3> | |||
| <p><code>GET api/traces/:owner/:repo/task_results.json</code></p> | |||
| <h3 id='1f9ac54b15'>请求参数</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| <th>必选</th> | |||
| <th>默认</th> | |||
| <th>类型</th> | |||
| <th>字段说明</th> | |||
| </tr> | |||
| </thead><tbody> | |||
| <tr> | |||
| <td>owner</td> | |||
| <td>是</td> | |||
| <td>否</td> | |||
| <td>string</td> | |||
| <td>项目所有者标识</td> | |||
| </tr> | |||
| <tr> | |||
| <td>repo</td> | |||
| <td>是</td> | |||
| <td>否</td> | |||
| <td>string</td> | |||
| <td>项目标识</td> | |||
| </tr> | |||
| <tr> | |||
| <td>page</td> | |||
| <td>否</td> | |||
| <td>1</td> | |||
| <td>int</td> | |||
| <td>页码</td> | |||
| </tr> | |||
| <tr> | |||
| <td>limit</td> | |||
| <td>否</td> | |||
| <td>15</td> | |||
| <td>int</td> | |||
| <td>每页数量</td> | |||
| </tr> | |||
| </tbody></table> | |||
| <h3 id='90889036d2'>返回字段说明(暂缺)</h3> | |||
| <!-- 参数 | 类型 | 字段说明 | |||
| --------- | ----------- | ----------- | |||
| total_count |int |总数 | | |||
| public_keys.id |int |ID| | |||
| public_keys.name |string|密钥标题| | |||
| public_keys.content |string|密钥内容| | |||
| public_keys.fingerprint |string|密钥标识| | |||
| public_keys.created_time |string|密钥创建时间| --> | |||
| <blockquote> | |||
| <p>返回的JSON示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> | |||
| </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> | |||
| </span><span class="p">{</span><span class="w"> | |||
| </span><span class="nl">"accuracy"</span><span class="p">:</span><span class="w"> </span><span class="s2">"20"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"code_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"C"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"depth"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"detect_flag"</span><span class="p">:</span><span class="w"> </span><span class="s2">"快速-组件级"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"detect_rule"</span><span class="p">:</span><span class="w"> </span><span class="s2">"快速-组件级,2,20,,开源软件,50,10"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"detect_startdate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-05-10 15:59:46 "</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"detect_status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"fail"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"detectflag"</span><span class="p">:</span><span class="w"> </span><span class="s2">"快速-组件级"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"fail_reason"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Invalid package type"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"file_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"many_branch.zip"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"license_process"</span><span class="p">:</span><span class="w"> </span><span class="s2">"100"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"licenseparam"</span><span class="p">:</span><span class="w"> </span><span class="s2">"开源软件"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"package_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"product_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"84727546110"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"project_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"6dbc3e42-5857-4ca4-a54d-58fd9dbf6dc5"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"sim_process"</span><span class="p">:</span><span class="w"> </span><span class="s2">"100"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"similarity_process"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"task_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"15139171-091b-4316-98b1-6068970efa44"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"totalsize"</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"uid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"78"</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"vuln_process"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"vulnlevel"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="w"> | |||
| </span><span class="p">}</span><span class="w"> | |||
| </span><span class="p">]</span><span class="w"> | |||
| </span><span class="p">}</span><span class="w"> | |||
| </span></code></pre></div> | |||
| <aside class="success"> | |||
| Success — a happy kitten is an authenticated kitten! | |||
| </aside> | |||
| <h2 id='32497859e0'>新建分析</h2> | |||
| <p>用户选择仓库分支进行代码分析的接口</p> | |||
| <blockquote> | |||
| <p>示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST <span class="se">\</span> | |||
| http://localhost:3000/api/traces/yystopf/many_branch/tasks.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">POST /api/traces/:owner/:repo/tasks.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-3'>HTTP 请求</h3> | |||
| <p><code>POST api/traces/:owner/:repo/tasks.json</code></p> | |||
| <h3 id='1f9ac54b15-2'>请求参数</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| <th>必选</th> | |||
| <th>默认</th> | |||
| <th>类型</th> | |||
| <th>字段说明</th> | |||
| </tr> | |||
| </thead><tbody> | |||
| <tr> | |||
| <td>owner</td> | |||
| <td>是</td> | |||
| <td>否</td> | |||
| <td>string</td> | |||
| <td>项目所有者标识</td> | |||
| </tr> | |||
| <tr> | |||
| <td>repo</td> | |||
| <td>是</td> | |||
| <td>否</td> | |||
| <td>string</td> | |||
| <td>项目标识</td> | |||
| </tr> | |||
| <tr> | |||
| <td>branch_name</td> | |||
| <td>是</td> | |||
| <td>否</td> | |||
| <td>string</td> | |||
| <td>分支名称</td> | |||
| </tr> | |||
| </tbody></table> | |||
| <blockquote> | |||
| <p>返回的JSON示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> | |||
| </span><span class="nl">"status"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"success"</span><span class="w"> | |||
| </span><span class="p">}</span><span class="w"> | |||
| </span></code></pre></div> | |||
| <aside class="success"> | |||
| Success — a happy kitten is an authenticated kitten! | |||
| </aside> | |||
| <h2 id='7b3a48e274'>重新扫描</h2> | |||
| <p>对代码分析结果进行再次分析</p> | |||
| <blockquote> | |||
| <p>示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET <span class="se">\</span> | |||
| http://localhost:3000/api/traces/yystopf/many_branch/reload_task.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/traces/:owner/:repo/reload_task.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-4'>HTTP 请求</h3> | |||
| <p><code>GET api/traces/:owner/:repo/reload_task.json</code></p> | |||
| <h3 id='1f9ac54b15-3'>请求参数</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| <th>必选</th> | |||
| <th>默认</th> | |||
| <th>类型</th> | |||
| <th>字段说明</th> | |||
| </tr> | |||
| </thead><tbody> | |||
| <tr> | |||
| <td>owner</td> | |||
| <td>是</td> | |||
| <td>否</td> | |||
| <td>string</td> | |||
| <td>项目所有者标识</td> | |||
| </tr> | |||
| <tr> | |||
| <td>repo</td> | |||
| <td>是</td> | |||
| <td>否</td> | |||
| <td>string</td> | |||
| <td>项目标识</td> | |||
| </tr> | |||
| <tr> | |||
| <td>project_id</td> | |||
| <td>是</td> | |||
| <td>否</td> | |||
| <td>string</td> | |||
| <td>代码分析结果里的project_id</td> | |||
| </tr> | |||
| </tbody></table> | |||
| <blockquote> | |||
| <p>返回的JSON示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> | |||
| </span><span class="nl">"status"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"success"</span><span class="w"> | |||
| </span><span class="p">}</span><span class="w"> | |||
| </span></code></pre></div> | |||
| <aside class="success"> | |||
| Success — a happy kitten is an authenticated kitten! | |||
| </aside> | |||
| <h2 id='87775b1430'>下载报告</h2> | |||
| <p>把代码分析的结果下载到本地</p> | |||
| <blockquote> | |||
| <p>示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET <span class="se">\</span> | |||
| http://localhost:3000/api/traces/yystopf/many_branch/task_pdf.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/traces/:owner/:repo/task_pdf.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-5'>HTTP 请求</h3> | |||
| <p><code>GET api/traces/:owner/:repo/task_pdf.json</code></p> | |||
| <h3 id='1f9ac54b15-4'>请求参数</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| <th>必选</th> | |||
| <th>默认</th> | |||
| <th>类型</th> | |||
| <th>字段说明</th> | |||
| </tr> | |||
| </thead><tbody> | |||
| <tr> | |||
| <td>owner</td> | |||
| <td>是</td> | |||
| <td>否</td> | |||
| <td>string</td> | |||
| <td>项目所有者标识</td> | |||
| </tr> | |||
| <tr> | |||
| <td>repo</td> | |||
| <td>是</td> | |||
| <td>否</td> | |||
| <td>string</td> | |||
| <td>项目标识</td> | |||
| </tr> | |||
| <tr> | |||
| <td>task_id</td> | |||
| <td>是</td> | |||
| <td>否</td> | |||
| <td>string</td> | |||
| <td>代码分析结果里的task_id</td> | |||
| </tr> | |||
| </tbody></table> | |||
| <blockquote> | |||
| <p>返回的JSON示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> | |||
| </span><span class="nl">"status"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"success"</span><span class="w"> | |||
| </span><span class="p">}</span><span class="w"> | |||
| </span></code></pre></div> | |||
| <aside class="success"> | |||
| Success — a happy kitten is an authenticated kitten! | |||
| </aside> | |||
| <h1 id='pulls'>Pulls</h1><h2 id='get-a-pull-request'>Get a pull request</h2> | |||
| <p>获取合并请求详情接口</p> | |||
| @@ -0,0 +1,5 @@ | |||
| require 'rails_helper' | |||
| RSpec.describe UserTraceTask, type: :model do | |||
| pending "add some examples to (or delete) #{__FILE__}" | |||
| end | |||