diff --git a/app/libs/trace.rb b/app/libs/trace.rb new file mode 100644 index 000000000..b1c3c4767 --- /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 => exception + raise ex if Rails.env.production? + + puts %Q{\033[33m [warning] gitea config or configuration.yml missing, + please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m} + trace_config = {} + end + + trace_config + end + end +end \ 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 5ca3356b6..903b60c38 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -173,6 +173,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) } @@ -776,6 +777,22 @@ 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 + else + trace_user = TraceUser.new + trace_user.build_self_data + trace_user.build_token + trace_user.save + end + + trace_user.token + end + protected def validate_password_length # 管理员的初始密码是5位 diff --git a/app/services/trace/add_user_service.rb b/app/services/trace/add_user_service.rb new file mode 100644 index 000000000..9c7b12b48 --- /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, 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..841627b50 --- /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, 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..ff6b72810 --- /dev/null +++ b/app/services/trace/client_service.rb @@ -0,0 +1,143 @@ +class Trace::ClientService < ApplicationService + + def post(url, params={}) + puts "[trace][POST] request params: #{params}" + conn.post do |req| + req.url = full_url(url) + req.body = params[:data].to_json + end + end + + def authed_post(token, url, params={}) + puts "[trace][POST] request params: #{params}" + puts "[trace][POST] request token: #{token}" + conn.post do |req| + req.url = full_url(url) + req.body = params[:data].to_json + req.headers['Authorization'] = token + end + end + + def get(url, params={}) + puts "[trace][GET] request params: #{params}" + conn.get do |req| + req.url full_url(url, 'get') + params.each_pair do |key, value| + req.params["#{key}"] = value + end + end + end + + def authed_get(token, url, params={}) + puts "[trace][GET] request params: #{params}" + puts "[trace][GET] request token: #{token}" + conn.get do |req| + req.url full_url(url, 'get') + params.each_pair do |key, value| + req.params["#{key}"] = value + end + req.headers['Authorization'] = token + end + end + + def delete(url, params={}) + puts "[trace][DELETE] request params: #{params}" + conn.delete do |req| + req.url full_url(url) + req.body = params[:data].to_json + end + end + + def authed_delete(token, url, params={}) + puts "[trace][DELETE] request params: #{params}" + puts "[trace][DELETE] request token: #{token}" + conn.delete do |req| + req.url full_url(url) + req.body = params[:data].to_json + req.headers['Authorization'] = token + end + end + + def patch(url, params={}) + puts "[trace][PATCH] request params: #{params}" + conn.patch do |req| + req.url full_url(url) + req.body = params[:data].to_json + end + end + + def authed_patch(token, url, params={}) + puts "[trace][PATCH] request params: #{params}" + puts "[trace][PATCH] request token: #{token}" + conn.patch do |req| + req.url full_url(url) + req.body = params[:data].to_json + req.headers['Authorization'] = token + end + end + + def put(url, params={}) + puts "[trace][PUT] request params: #{params}" + conn.put do |req| + req.url full_url(url) + req.body = params[:data].to_json + end + end + + def authed_put(token, url, params={}) + puts "[trace][PUT] request params: #{params}" + puts "[trace][PUT] request token: #{token}" + conn.put do |req| + req.url full_url(url) + req.body = params[:data].to_json + req.headers['Authorization'] = token + end + end + + private + def conn + @client ||= begin + Faraday.new(url: domain) do |req| + req.request :url_encoded + req.headers['Content-Type'] = 'application/json' + req.adapter Faraday.default_adapter + end + end + + @client + end + + def base_url + Trace.trace_config[:base_url] + end + + def domain + Trace.trace_config[:domain] + end + + def api_url + [domain, base_url].join('') + end + + def full_url(api_rest, action='post') + url = [api_url, api_rest].join('').freeze + url = action === 'get' ? url : URI.escape(url) + url = URI.escape(url) unless url.ascii_only? + puts "[trace] request url: #{url}" + return url + end + + def log_error(status, body) + puts "[trace] status: #{status}" + puts "[trace] body: #{body}" + end + + def render_response(response) + status = response.status + body = JSON.parse(response&.body) + + log_error(status, body) + + return [body["code"], body["Data"], body["Error"]] + end +end \ 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..b245ea733 --- /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, 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..b2c4a0ff6 --- /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, 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/config/configuration.yml.example b/config/configuration.yml.example index b56530128..61e66635a 100644 --- a/config/configuration.yml.example +++ b/config/configuration.yml.example @@ -62,6 +62,10 @@ default: &default write_domain: '' read_domain: '' base_url: '' + + trace: + domain: '' + base_url: '' production: <<: *default diff --git a/db/migrate/20220331031530_create_trace_users.rb b/db/migrate/20220331031530_create_trace_users.rb new file mode 100644 index 000000000..5c8b532ce --- /dev/null +++ b/db/migrate/20220331031530_create_trace_users.rb @@ -0,0 +1,17 @@ +class CreateTraceUsers < ActiveRecord::Migration[5.2] + def change + create_table :trace_users do |t| + t.references :user + t.string :username + t.string :password + t.string :unit + t.string :telnumber + t.string :email + t.string :name + t.text :token + t.datetime :expired_at + + t.timestamps + end + end +end diff --git a/spec/models/trace_user_spec.rb b/spec/models/trace_user_spec.rb new file mode 100644 index 000000000..ddcc25e4d --- /dev/null +++ b/spec/models/trace_user_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe TraceUser, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end