From 12cc37443e12e63513f85dc59e112284ec76111d Mon Sep 17 00:00:00 2001 From: yystopf Date: Mon, 9 May 2022 18:12:27 +0800 Subject: [PATCH 01/41] add: trace controller and router --- app/controllers/trace/base_controller.rb | 18 ++++++ app/controllers/trace/projects_controller.rb | 60 +++++++++++++++++++ .../trace/trace_users_controller.rb | 14 +++++ app/services/trace/check_result_service.rb | 8 +-- app/services/trace/check_service.rb | 4 +- config/routes.rb | 14 +++++ 6 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 app/controllers/trace/base_controller.rb create mode 100644 app/controllers/trace/projects_controller.rb create mode 100644 app/controllers/trace/trace_users_controller.rb diff --git a/app/controllers/trace/base_controller.rb b/app/controllers/trace/base_controller.rb new file mode 100644 index 000000000..d3fb52d1c --- /dev/null +++ b/app/controllers/trace/base_controller.rb @@ -0,0 +1,18 @@ +class Trace::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 \ No newline at end of file diff --git a/app/controllers/trace/projects_controller.rb b/app/controllers/trace/projects_controller.rb new file mode 100644 index 000000000..a5adcbbb1 --- /dev/null +++ b/app/controllers/trace/projects_controller.rb @@ -0,0 +1,60 @@ +class Trace::ProjectsController < Trace::BaseController + + before_action :require_login + before_action :load_project + + def tasks + branch_name = params[:branch_name] + [code, data, error] = Trace::CheckService.call(current_user.trace_token, @project, "1", branch_name) + if code == 200 + render_ok + else + render_error(-1, "检测失败 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 + [code, data, error] = Trace::CheckResultService.call(current_user.trace_token, @project, nil, page, limit) + if code == 200 + render :json => {data: data} + else + render_error(-1, "获取检测记录失败 Error:#{error}") + end + rescue Exception => exception + puts exception.message + normal_status(-1, exception.message) + end + + def reload_task + render_error(-1, "project_id错误") if params[:project_id].blank? + [code, data, error] = Trace::ReloadCheckService.call(current_user.trace_token, params[:project_id]) + if code == 200 + render_ok + else + render_error(-1, "重新检测失败 Error:#{error}") + end + rescue Exception => exception + puts exception.message + normal_status(-1, exception.message) + end + + + def task_pdf + render_error(-1, "task_id错误") if params[:task_id].blank? + [code, data, error] = Trace::PdfReportService.call(current_user.trace_token, params[:task_id]) + if code == 200 + render_ok + else + render_error(-1, "下载报告失败 Error:#{error}") + end + rescue Exception => exception + puts exception.message + normal_status(-1, exception.message) + end +end \ No newline at end of file diff --git a/app/controllers/trace/trace_users_controller.rb b/app/controllers/trace/trace_users_controller.rb new file mode 100644 index 000000000..4601c3525 --- /dev/null +++ b/app/controllers/trace/trace_users_controller.rb @@ -0,0 +1,14 @@ +class Trace::TraceUsersController < Trace::BaseController + before_action :require_auth + + 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 \ No newline at end of file diff --git a/app/services/trace/check_result_service.rb b/app/services/trace/check_result_service.rb index f1dd61ab0..9c177b147 100644 --- a/app/services/trace/check_result_service.rb +++ b/app/services/trace/check_result_service.rb @@ -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: "#{project&.owner&.login}-#{project.identifier}", file_name: file_name, pageNum: page_num, pageSize: page_size, diff --git a/app/services/trace/check_service.rb b/app/services/trace/check_service.rb index d31bbcf09..56a70b9a5 100644 --- a/app/services/trace/check_service.rb +++ b/app/services/trace/check_service.rb @@ -17,9 +17,9 @@ class Trace::CheckService < Trace::ClientService 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_name: "#{project&.owner&.login}-#{project&.identifier}", product_type: project&.category&.name, code_type: project&.language&.name, product_desc: project&.description, diff --git a/config/routes.rb b/config/routes.rb index 64dce0e60..836960fe2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -677,6 +677,20 @@ Rails.application.routes.draw do end # Project Area END + namespace :trace 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 + scope module: :helps do resources :faqs, only: [:index] end From c64fa5135b8d2bb80de409021889eafd02c1895e Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 10 May 2022 09:18:49 +0800 Subject: [PATCH 02/41] fix --- app/controllers/trace/projects_controller.rb | 8 ++--- app/services/trace/check_result_service.rb | 2 +- app/services/trace/check_service.rb | 11 ++++--- app/services/trace/client_service.rb | 31 +++++++++++++++++--- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/app/controllers/trace/projects_controller.rb b/app/controllers/trace/projects_controller.rb index a5adcbbb1..160433fe7 100644 --- a/app/controllers/trace/projects_controller.rb +++ b/app/controllers/trace/projects_controller.rb @@ -5,7 +5,7 @@ class Trace::ProjectsController < Trace::BaseController def tasks branch_name = params[:branch_name] - [code, data, error] = Trace::CheckService.call(current_user.trace_token, @project, "1", branch_name) + code, data, error = Trace::CheckService.call(current_user.trace_token, @project, "1", branch_name) if code == 200 render_ok else @@ -20,7 +20,7 @@ class Trace::ProjectsController < Trace::BaseController 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 - [code, data, error] = Trace::CheckResultService.call(current_user.trace_token, @project, nil, page, limit) + code, data, error = Trace::CheckResultService.call(current_user.trace_token, @project, nil, page, limit) if code == 200 render :json => {data: data} else @@ -33,7 +33,7 @@ class Trace::ProjectsController < Trace::BaseController def reload_task render_error(-1, "project_id错误") if params[:project_id].blank? - [code, data, error] = Trace::ReloadCheckService.call(current_user.trace_token, params[:project_id]) + code, data, error = Trace::ReloadCheckService.call(current_user.trace_token, params[:project_id]) if code == 200 render_ok else @@ -47,7 +47,7 @@ class Trace::ProjectsController < Trace::BaseController def task_pdf render_error(-1, "task_id错误") if params[:task_id].blank? - [code, data, error] = Trace::PdfReportService.call(current_user.trace_token, params[:task_id]) + code, data, error = Trace::PdfReportService.call(current_user.trace_token, params[:task_id]) if code == 200 render_ok else diff --git a/app/services/trace/check_result_service.rb b/app/services/trace/check_result_service.rb index 9c177b147..f6a44c882 100644 --- a/app/services/trace/check_result_service.rb +++ b/app/services/trace/check_result_service.rb @@ -19,7 +19,7 @@ class Trace::CheckResultService < Trace::ClientService private def request_params { - product_name: "#{project&.owner&.login}-#{project.identifier}", + product_name: "#{project&.owner&.id}#{project.id}", file_name: file_name, pageNum: page_num, pageSize: page_size, diff --git a/app/services/trace/check_service.rb b/app/services/trace/check_service.rb index 56a70b9a5..cf1fcf133 100644 --- a/app/services/trace/check_service.rb +++ b/app/services/trace/check_service.rb @@ -11,7 +11,7 @@ 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 @@ -19,9 +19,9 @@ class Trace::CheckService < Trace::ClientService def request_params repo = Gitea::Repository::GetService.call(project&.owner, project&.identifier) { - product_name: "#{project&.owner&.login}-#{project&.identifier}", - product_type: project&.category&.name, - code_type: project&.language&.name, + product_name: "#{project&.owner&.id}#{project&.id}", + 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, @@ -32,5 +32,4 @@ class Trace::CheckService < Trace::ClientService def url "/user/check".freeze end -end - +end \ No newline at end of file diff --git a/app/services/trace/client_service.rb b/app/services/trace/client_service.rb index 72ffa8ca2..9423b575d 100644 --- a/app/services/trace/client_service.rb +++ b/app/services/trace/client_service.rb @@ -12,6 +12,18 @@ 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) + 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 +112,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 \ No newline at end of file From 72a32ed8c48f608e9f647e1ee376d6ba9bb00640 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 10 May 2022 15:04:25 +0800 Subject: [PATCH 03/41] rename namespace --- app/controllers/{trace => traces}/base_controller.rb | 0 app/controllers/{trace => traces}/projects_controller.rb | 0 app/controllers/{trace => traces}/trace_users_controller.rb | 0 config/routes.rb | 2 +- 4 files changed, 1 insertion(+), 1 deletion(-) rename app/controllers/{trace => traces}/base_controller.rb (100%) rename app/controllers/{trace => traces}/projects_controller.rb (100%) rename app/controllers/{trace => traces}/trace_users_controller.rb (100%) diff --git a/app/controllers/trace/base_controller.rb b/app/controllers/traces/base_controller.rb similarity index 100% rename from app/controllers/trace/base_controller.rb rename to app/controllers/traces/base_controller.rb diff --git a/app/controllers/trace/projects_controller.rb b/app/controllers/traces/projects_controller.rb similarity index 100% rename from app/controllers/trace/projects_controller.rb rename to app/controllers/traces/projects_controller.rb diff --git a/app/controllers/trace/trace_users_controller.rb b/app/controllers/traces/trace_users_controller.rb similarity index 100% rename from app/controllers/trace/trace_users_controller.rb rename to app/controllers/traces/trace_users_controller.rb diff --git a/config/routes.rb b/config/routes.rb index 836960fe2..9c3fe2ecf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -677,7 +677,7 @@ Rails.application.routes.draw do end # Project Area END - namespace :trace do + namespace :traces do resources :trace_users, only: [:create] scope "/:owner/:repo" do resource :projects, path: '/', only: [:index] do From 17ccf3d57662eb3d6d50a0598986bff724e8d866 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 10 May 2022 15:07:04 +0800 Subject: [PATCH 04/41] rename namespace --- app/controllers/traces/base_controller.rb | 2 +- app/controllers/traces/projects_controller.rb | 2 +- app/controllers/traces/trace_users_controller.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/traces/base_controller.rb b/app/controllers/traces/base_controller.rb index d3fb52d1c..2b857d232 100644 --- a/app/controllers/traces/base_controller.rb +++ b/app/controllers/traces/base_controller.rb @@ -1,4 +1,4 @@ -class Trace::BaseController < ApplicationController +class Traces::BaseController < ApplicationController helper_method :observed_logged_user?, :observed_user diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 160433fe7..7e91a2bc7 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -1,4 +1,4 @@ -class Trace::ProjectsController < Trace::BaseController +class Traces::ProjectsController < Trace::BaseController before_action :require_login before_action :load_project diff --git a/app/controllers/traces/trace_users_controller.rb b/app/controllers/traces/trace_users_controller.rb index 4601c3525..0b738bead 100644 --- a/app/controllers/traces/trace_users_controller.rb +++ b/app/controllers/traces/trace_users_controller.rb @@ -1,4 +1,4 @@ -class Trace::TraceUsersController < Trace::BaseController +class Traces::TraceUsersController < Trace::BaseController before_action :require_auth def create From a0a7f908f4e1f013ba541eff9e360541d14ab049 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 10 May 2022 15:08:42 +0800 Subject: [PATCH 05/41] rename namespace --- app/controllers/traces/projects_controller.rb | 2 +- app/controllers/traces/trace_users_controller.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 7e91a2bc7..6f329b83b 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -1,4 +1,4 @@ -class Traces::ProjectsController < Trace::BaseController +class Traces::ProjectsController < Traces::BaseController before_action :require_login before_action :load_project diff --git a/app/controllers/traces/trace_users_controller.rb b/app/controllers/traces/trace_users_controller.rb index 0b738bead..bf203c646 100644 --- a/app/controllers/traces/trace_users_controller.rb +++ b/app/controllers/traces/trace_users_controller.rb @@ -1,4 +1,4 @@ -class Traces::TraceUsersController < Trace::BaseController +class Traces::TraceUsersController < Traces::BaseController before_action :require_auth def create From 59db914bcc2e9928885a24d082b0f05726e49c33 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 10 May 2022 15:10:01 +0800 Subject: [PATCH 06/41] change route position --- config/routes.rb | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 9c3fe2ecf..097aaf2a7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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 @@ -677,20 +691,6 @@ Rails.application.routes.draw do end # Project Area 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 - scope module: :helps do resources :faqs, only: [:index] end From 2d9bde134a83b1e62d66f0e9b1075ce588f104a8 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 10 May 2022 15:11:04 +0800 Subject: [PATCH 07/41] fix --- app/controllers/traces/trace_users_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/traces/trace_users_controller.rb b/app/controllers/traces/trace_users_controller.rb index bf203c646..70191479e 100644 --- a/app/controllers/traces/trace_users_controller.rb +++ b/app/controllers/traces/trace_users_controller.rb @@ -1,5 +1,5 @@ class Traces::TraceUsersController < Traces::BaseController - before_action :require_auth + before_action :check_auth def create if current_user.trace_token.present? From f31796f344f0be126cd0bc756a9d2a1f3721b277 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 10 May 2022 15:53:14 +0800 Subject: [PATCH 08/41] add: branch valid for tasks --- app/controllers/accounts_controller.rb | 381 ++++++++++++++++++ app/controllers/traces/projects_controller.rb | 15 +- 2 files changed, 390 insertions(+), 6 deletions(-) diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index a837e952f..5b4571d9d 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -1,3 +1,4 @@ +<<<<<<< HEAD class AccountsController < ApplicationController include ApplicationHelper @@ -384,3 +385,383 @@ class AccountsController < ApplicationController end end +======= +class AccountsController < ApplicationController + include ApplicationHelper + + #skip_before_action :check_account, :only => [:logout] + + def index + render json: session + end + + # 其他平台同步注册的用户 + def remote_register + Register::RemoteForm.new(remote_register_params).validate! + username = params[:username]&.gsub(/\s+/, "") + tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username) + email = params[:email]&.gsub(/\s+/, "") + password = params[:password] + platform = (params[:platform] || 'forge')&.gsub(/\s+/, "") + + ActiveRecord::Base.transaction do + result = autologin_register(username, email, password, platform) + if result[:message].blank? + render_ok({user: result[:user]}) + else + render_error(result[:message]) + end + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(-1, e.message) + end + + # 其他平台修改用户的信息,这边同步修改 + def remote_update + ActiveRecord::Base.transaction do + user_params = params[:user_params] + user_extension_params = params[:user_extension_params] + + u = User.find_by(login: params[:old_user_login]) + user_mail = u.try(:mail) + + if u.present? + ue = u.user_extension + u.login = user_params["login"] if user_params["login"] + u.mail = user_params["mail"] if user_params["mail"] + u.lastname = user_params["lastname"] if user_params["lastname"] + + ue.gender = user_extension_params["gender"] + ue.school_id = user_extension_params["school_id"] + ue.location = user_extension_params["location"] + ue.location_city = user_extension_params["location_city"] + ue.identity = user_extension_params["identity"] + ue.technical_title = user_extension_params["technical_title"] + ue.student_id = user_extension_params["student_id"] + ue.description = user_extension_params["description"] + ue.save! + u.save! + + sync_params = {} + + if (user_params["mail"] && user_params["mail"] != user_mail) + sync_params = sync_params.merge(email: user_params["mail"]) + end + + if sync_params.present? + interactor = Gitea::User::UpdateInteractor.call(u.login, sync_params) + if interactor.success? + render_ok + else + render_error(interactor.error) + end + end + end + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(-1, e.message) + end + + # 其他平台同步登录 + def remote_login + @user = User.try_to_login(params[:login], params[:password]) + if @user + successful_authentication(@user) + render_ok({user: {id: @user.id, token: @user.gitea_token}}) + else + render_error("用户不存在") + end + end + + #修改密码 + def remote_password + @user = User.find_by(login: params[:login]) + return render_error("未找到相关用户!") if @user.blank? + + sync_params = { + password: params[:password].to_s, + email: @user.mail + } + + interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params) + if interactor.success? + @user.update_attribute(:password, params[:password]) + render_ok + else + render_error(interactor.error) + end + end + + + + # 用户注册 + # 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用 + # params[:login] 邮箱或者手机号 + # params[:namespace] 登录名 + # params[:code] 验证码 + # code_type 1:注册手机验证码 8:邮箱注册验证码 + # 本地forge注册入口需要重新更改逻辑 + def register + # type只可能是1或者8 + user = nil + begin + Register::Form.new(register_params).validate! + + user = Users::RegisterService.call(register_params) + password = register_params[:password].strip + + # gitea用户注册, email, username, password + interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password}) + if interactor.success? + gitea_user = interactor.result + result = Gitea::User::GenerateTokenService.call(user.login, password) + user.gitea_token = result['sha1'] + user.gitea_uid = gitea_user[:body]['id'] + if user.save! + UserExtension.create!(user_id: user.id) + successful_authentication(user) + render_ok + end + else + tip_exception(-1, interactor.error) + end + rescue Register::BaseForm::EmailError => e + tip_exception(-2, e.message) + rescue Register::BaseForm::LoginError => e + tip_exception(-3, e.message) + rescue Register::BaseForm::PhoneError => e + tip_exception(-4, e.message) + rescue Register::BaseForm::PasswordFormatError => e + tip_exception(-5, e.message) + rescue Register::BaseForm::VerifiCodeError => e + tip_exception(-6, e.message) + rescue Exception => e + Gitea::User::DeleteService.call(user.login) unless user.nil? + uid_logger_error(e.message) + tip_exception(-1, e.message) + end + end + + # 用户登录 + def login + Users::LoginForm.new(account_params).validate! + @user = User.try_to_login(params[:login], params[:password]) + + return normal_status(-2, "错误的账号或密码") if @user.blank? + # user is already in local database + return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked? + + login_control = LimitForbidControl::UserLogin.new(@user) + return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid? + + password_ok = @user.check_password?(params[:password].to_s) + unless password_ok + if login_control.remain_times-1 == 0 + normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") + else + normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会") + end + login_control.increment! + return + end + + successful_authentication(@user) + sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步 + + # session[:user_id] = @user.id + end + + def change_password + @user = User.find_by(login: params[:login]) + return render_error("未找到相关用户!") if @user.blank? + return render_error("旧密码不正确") unless @user.check_password?(params[:old_password]) + + sync_params = { + password: params[:password].to_s, + email: @user.mail, + login_name: @user.login, + source_id: 0 + } + + interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params) + if interactor.success? + @user.update_attribute(:password, params[:password]) + render_ok + else + render_error(interactor.error) + end + end + + # 忘记密码 + def reset_password + begin + code = params[:code] + login_type = phone_mail_type(params[:login].strip) + # 获取验证码 + if login_type == 1 + phone = params[:login] + verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 2).last + user = User.find_by_phone(phone) + else + email = params[:login] + verifi_code = VerificationCode.where(email: email, code: code, code_type: 3).last + user = User.find_by_mail(email) #这里有问题,应该是为email,而不是mail 6.13-hs + end + return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip + return normal_status(-2, "验证码已失效") if !verifi_code&.effective? + return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:new_password] =~ CustomRegexp::PASSWORD + + user.password, user.password_confirmation = params[:new_password], params[:new_password_confirmation] + ActiveRecord::Base.transaction do + user.save! + LimitForbidControl::UserLogin.new(user).clear + end + sucess_status + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + end + + def successful_authentication(user) + uid_logger("Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}") + # Valid user + self.logged_user = user + # generate a key and set cookie if autologin + + set_autologin_cookie(user) + UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip) + user.update_column(:last_login_on, Time.now) + session[:"#{default_yun_session}"] = user.id + Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}") + # 注册完成后有一天的试用申请(先去掉) + # UserDayCertification.create(user_id: user.id, status: 1) + end + + def set_autologin_cookie(user) + token = Token.get_or_create_permanent_login_token(user, "autologin") + sync_user_token_to_trustie(user.login, token.value) + + cookie_options = { + :value => token.value, + :expires => 1.month.from_now, + :path => '/', + :secure => false, + :httponly => true + } + if edu_setting('cookie_domain').present? + cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain')) + end + cookies[autologin_cookie_name] = cookie_options + cookies.signed[:user_id] ||= user.id + + logger.info("cookies is #{cookies} ======> #{cookies.signed[:user_id]} =====> #{cookies[autologin_cookie_name]}") + end + + def logout + Rails.logger.info("########___logout_current_user____________########{current_user.try(:id)}") + UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip) + logout_user + render :json => {status: 1, message: "退出成功!"} + end + + # 检验邮箱是否已被注册及邮箱或者手机号是否合法 + # 参数type为事件类型 1:注册;2:忘记密码;3:绑定 + def valid_email_and_phone + check_mail_and_phone_valid(params[:login], params[:type]) + end + + # 发送验证码 + # params[:login] 手机号或者邮箱号 + # params[:type]为事件通知类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加 + # 发送验证码:send_type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱 + # 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9: 验收手机号有效 + def get_verification_code + code = %W(0 1 2 3 4 5 6 7 8 9) + value = params[:login] + type = params[:type].strip.to_i + login_type = phone_mail_type(value) + send_type = verify_type(login_type, type) + verification_code = code.sample(6).join + + sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}") + tip_exception(501, "请求不合理") if sign != params[:smscode] + + logger.info "########### 验证码:#{verification_code}" + logger.info("########get_verification_code: login_type: #{login_type}, send_type:#{send_type}, ") + + # 记录验证码 + check_verification_code(verification_code, send_type, value) + render_ok + end + + # check user's login or email or phone is used + # params[:value] 手机号或者邮箱号或者登录名 + # params[:type] 为事件类型 1:登录名(login) 2:email(邮箱) 3:phone(手机号) + def check + Register::CheckColumnsForm.new(check_params).validate! + render_ok + end + + private + + # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加 + # login_type 1:手机类型 2:邮箱类型 + def verify_type login_type, type + case type + when 1 + login_type == 1 ? 1 : 8 + when 2 + login_type == 1 ? 2 : 3 + when 3 + login_type == 1 ? 4 : tip_exception('请填写正确的手机号') + when 4 + login_type == 1 ? tip_exception('请填写正确的邮箱') : 5 + when 5 + login_type == 1 ? 9 : tip_exception('请填写正确的手机号') + end + end + + def generate_login(login) + type = phone_mail_type(login.strip) + + if type == 1 + uid_logger("start register by phone: type is #{type}") + pre = 'p' + email = nil + phone = login + else + uid_logger("start register by email: type is #{type}") + pre = 'm' + email = login + phone = nil + end + code = generate_identifier User, 8, pre + + { login: pre + code, email: email, phone: phone } + end + + def user_params + params.require(:user).permit(:login, :email, :phone) + end + + def account_params + params.require(:account).permit(:login, :password) + end + + def check_params + params.permit(:type, :value) + end + + def register_params + params.permit(:login, :namespace, :password, :code) + end + + def remote_register_params + params.permit(:username, :email, :password, :platform) + end + +end +>>>>>>> b62824ad (add: branch valid for tasks) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 6f329b83b..66bfb71b0 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -5,11 +5,14 @@ class Traces::ProjectsController < Traces::BaseController def tasks 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::CheckService.call(current_user.trace_token, @project, "1", branch_name) if code == 200 render_ok else - render_error(-1, "检测失败 Error:#{error}") + render_error("检测失败 Error:#{error}") end rescue Exception => exception puts exception.message @@ -24,7 +27,7 @@ class Traces::ProjectsController < Traces::BaseController if code == 200 render :json => {data: data} else - render_error(-1, "获取检测记录失败 Error:#{error}") + render_error("获取检测记录失败 Error:#{error}") end rescue Exception => exception puts exception.message @@ -32,12 +35,12 @@ class Traces::ProjectsController < Traces::BaseController end def reload_task - render_error(-1, "project_id错误") if params[:project_id].blank? + return render_error("project_id错误") if params[:project_id].blank? code, data, error = Trace::ReloadCheckService.call(current_user.trace_token, params[:project_id]) if code == 200 render_ok else - render_error(-1, "重新检测失败 Error:#{error}") + render_error("重新检测失败 Error:#{error}") end rescue Exception => exception puts exception.message @@ -46,12 +49,12 @@ class Traces::ProjectsController < Traces::BaseController def task_pdf - render_error(-1, "task_id错误") if params[:task_id].blank? + return render_error("task_id错误") if params[:task_id].blank? code, data, error = Trace::PdfReportService.call(current_user.trace_token, params[:task_id]) if code == 200 render_ok else - render_error(-1, "下载报告失败 Error:#{error}") + render_error("下载报告失败 Error:#{error}") end rescue Exception => exception puts exception.message From cf09b28f5ef4ae8bce8cbaa2170c77ae214bb0b6 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 10 May 2022 16:14:27 +0800 Subject: [PATCH 09/41] add: project menu services --- app/controllers/projects_controller.rb | 1 + app/models/project_unit.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 8bc2fb476..2d0f0f5cd 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -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? 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? diff --git a/app/models/project_unit.rb b/app/models/project_unit.rb index cc35a6b28..6ee0f2a8b 100644 --- a/app/models/project_unit.rb +++ b/app/models/project_unit.rb @@ -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} From 5dcee1b4dc486de1706dc56cd2453538869f9e1b Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 10 May 2022 17:10:19 +0800 Subject: [PATCH 10/41] add: traces api document --- app/docs/slate/source/api.html.md | 1 + app/docs/slate/source/includes/_projects.md | 4 +- app/docs/slate/source/includes/_traces.md | 216 ++++++++++++++ public/docs/api.html | 307 +++++++++++++++++++- 4 files changed, 524 insertions(+), 4 deletions(-) create mode 100644 app/docs/slate/source/includes/_traces.md diff --git a/app/docs/slate/source/api.html.md b/app/docs/slate/source/api.html.md index a846317c4..0031a99f4 100644 --- a/app/docs/slate/source/api.html.md +++ b/app/docs/slate/source/api.html.md @@ -16,6 +16,7 @@ includes: - users - projects - repositories + - traces - pulls - issues - organizations diff --git a/app/docs/slate/source/includes/_projects.md b/app/docs/slate/source/includes/_projects.md index d4899a710..08ad6c234 100644 --- a/app/docs/slate/source/includes/_projects.md +++ b/app/docs/slate/source/includes/_projects.md @@ -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:服务 | ### 返回字段说明: diff --git a/app/docs/slate/source/includes/_traces.md b/app/docs/slate/source/includes/_traces.md new file mode 100644 index 000000000..6bdfb950a --- /dev/null +++ b/app/docs/slate/source/includes/_traces.md @@ -0,0 +1,216 @@ +# 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" +} +``` + + +## 代码分析结果列表 +查询项目下代码分析的结果 + +> 示例: + +```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 | 每页数量 | + +### 返回字段说明(暂缺) + + +> 返回的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": "" + } + ] +} +``` + + + + +## 新建分析 +用户选择仓库分支进行代码分析的接口 + +> 示例: + +```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" +} +``` + + +## 重新扫描 +对代码分析结果进行再次分析 + +> 示例: + +```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 | + + +> 返回的JSON示例: + +```json +{ + "status": 0, + "message": "success" +} +``` + + + +## 下载报告 +把代码分析的结果下载到本地 + +> 示例: + +```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" +} +``` + diff --git a/public/docs/api.html b/public/docs/api.html index 45da64400..1fe7bc08e 100644 --- a/public/docs/api.html +++ b/public/docs/api.html @@ -543,6 +543,26 @@ +
  • + Traces + +
  • Pulls
      @@ -4968,7 +4988,7 @@ http://localhost:3000/api/yystopf/ceshi/menu_list | jq menu_name string -导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置 +导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,wiki:维基,services:服务,activity:动态,setting:仓库设置 @@ -5131,7 +5151,7 @@ http://localhost:3000/api/yystopf/ceshi/project_units.json 是 array -项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑 +项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,wiki:维基,resources:资源库,services:服务

      返回字段说明:

      @@ -9302,6 +9322,289 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/3/test.json +

      Traces

      代码溯源初始化

      +

      用户同意协议后请求的接口,创建代码溯源的账号

      + +
      +

      示例:

      +
      +
      curl -X POST \
      +http://localhost:3000/api/traces/trace_users.json
      +
      await octokit.request('POST /api/traces/trace_users.json')
      +

      HTTP 请求

      +

      POST api/traces/trace_users.json

      + +
      +

      返回的JSON示例:

      +
      +
      {
      +    "status": 0,
      +    "message": "success"
      +}
      +
      + +

      代码分析结果列表

      +

      查询项目下代码分析的结果

      + +
      +

      示例:

      +
      +
      curl -X GET \
      +http://localhost:3000/api/traces/yystopf/many_branch/task_results.json
      +
      await octokit.request('GET /api/traces/:owner/:repo/task_results.json')
      +

      HTTP 请求

      +

      GET api/traces/:owner/:repo/task_results.json

      +

      请求参数

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      参数必选默认类型字段说明
      ownerstring项目所有者标识
      repostring项目标识
      page1int页码
      limit15int每页数量
      +

      返回字段说明(暂缺)

      + + +
      +

      返回的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": ""
      +        }
      +    ]
      +}
      +
      + +

      新建分析

      +

      用户选择仓库分支进行代码分析的接口

      + +
      +

      示例:

      +
      +
      curl -X POST \
      +http://localhost:3000/api/traces/yystopf/many_branch/tasks.json
      +
      await octokit.request('POST /api/traces/:owner/:repo/tasks.json')
      +

      HTTP 请求

      +

      POST api/traces/:owner/:repo/tasks.json

      +

      请求参数

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      参数必选默认类型字段说明
      ownerstring项目所有者标识
      repostring项目标识
      branch_namestring分支名称
      + +
      +

      返回的JSON示例:

      +
      +
      {
      +    "status": 0,
      +    "message": "success"
      +}
      +
      + +

      重新扫描

      +

      对代码分析结果进行再次分析

      + +
      +

      示例:

      +
      +
      curl -X GET \
      +http://localhost:3000/api/traces/yystopf/many_branch/reload_task.json
      +
      await octokit.request('GET /api/traces/:owner/:repo/reload_task.json')
      +

      HTTP 请求

      +

      GET api/traces/:owner/:repo/reload_task.json

      +

      请求参数

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      参数必选默认类型字段说明
      ownerstring项目所有者标识
      repostring项目标识
      project_idstring代码分析结果里的project_id
      + +
      +

      返回的JSON示例:

      +
      +
      {
      +    "status": 0,
      +    "message": "success"
      +}
      +
      + +

      下载报告

      +

      把代码分析的结果下载到本地

      + +
      +

      示例:

      +
      +
      curl -X GET \
      +http://localhost:3000/api/traces/yystopf/many_branch/task_pdf.json
      +
      await octokit.request('GET /api/traces/:owner/:repo/task_pdf.json')
      +

      HTTP 请求

      +

      GET api/traces/:owner/:repo/task_pdf.json

      +

      请求参数

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      参数必选默认类型字段说明
      ownerstring项目所有者标识
      repostring项目标识
      task_idstring代码分析结果里的task_id
      + +
      +

      返回的JSON示例:

      +
      +
      {
      +    "status": 0,
      +    "message": "success"
      +}
      +
      +

      Pulls

      Get a pull request

      获取合并请求详情接口

      From 1f13bba52e6a88a3baf5d975b3bd36b583ad9b5f Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 11 May 2022 10:34:35 +0800 Subject: [PATCH 11/41] add: trace user tasks_count --- app/controllers/traces/projects_controller.rb | 3 +++ app/models/trace_user.rb | 25 ++++++++++--------- ...11022334_add_tasks_count_to_trace_users.rb | 5 ++++ 3 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 db/migrate/20220511022334_add_tasks_count_to_trace_users.rb diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 66bfb71b0..1b09bd971 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -5,11 +5,13 @@ class Traces::ProjectsController < Traces::BaseController def tasks branch_name = params[:branch_name] + return render_error("无可用检测次数") if current_user.trace_user&.tasks_count >= 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 + current_user.trace_user.increment!(:tasks_count, 1) render_ok else render_error("检测失败 Error:#{error}") @@ -25,6 +27,7 @@ class Traces::ProjectsController < Traces::BaseController page = params[:page].to_i.zero? ? 1 : params[:page].to_i code, data, error = Trace::CheckResultService.call(current_user.trace_token, @project, nil, page, limit) if code == 200 + current_user.trace_user.update_column(:tasks_count, data[0]["totalsize"]) if data.size > 0 render :json => {data: data} else render_error("获取检测记录失败 Error:#{error}") diff --git a/app/models/trace_user.rb b/app/models/trace_user.rb index e89641565..0e8b3d119 100644 --- a/app/models/trace_user.rb +++ b/app/models/trace_user.rb @@ -2,18 +2,19 @@ # # 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 +# 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 +# tasks_count :integer default("0") # # Indexes # diff --git a/db/migrate/20220511022334_add_tasks_count_to_trace_users.rb b/db/migrate/20220511022334_add_tasks_count_to_trace_users.rb new file mode 100644 index 000000000..035d93a94 --- /dev/null +++ b/db/migrate/20220511022334_add_tasks_count_to_trace_users.rb @@ -0,0 +1,5 @@ +class AddTasksCountToTraceUsers < ActiveRecord::Migration[5.2] + def change + add_column :trace_users, :tasks_count, :integer, default: 0 + end +end From 7750cbe272d0177b46b3b2062b4e7e88eed590df Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 11 May 2022 11:20:18 +0800 Subject: [PATCH 12/41] add: project trace tasks count --- app/controllers/traces/projects_controller.rb | 6 ++--- app/models/trace_user.rb | 25 +++++++++---------- ...11022334_add_tasks_count_to_trace_users.rb | 5 ---- ...31711_add_trace_tasks_count_to_projects.rb | 5 ++++ 4 files changed, 20 insertions(+), 21 deletions(-) delete mode 100644 db/migrate/20220511022334_add_tasks_count_to_trace_users.rb create mode 100644 db/migrate/20220511031711_add_trace_tasks_count_to_projects.rb diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 1b09bd971..812ea535b 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -5,13 +5,13 @@ class Traces::ProjectsController < Traces::BaseController def tasks branch_name = params[:branch_name] - return render_error("无可用检测次数") if current_user.trace_user&.tasks_count >= 5 + return render_error("无可用检测次数") if @project&.trace_tasks_count >= 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 - current_user.trace_user.increment!(:tasks_count, 1) + @project.increment!(:trace_tasks_count, 1) render_ok else render_error("检测失败 Error:#{error}") @@ -27,7 +27,7 @@ class Traces::ProjectsController < Traces::BaseController page = params[:page].to_i.zero? ? 1 : params[:page].to_i code, data, error = Trace::CheckResultService.call(current_user.trace_token, @project, nil, page, limit) if code == 200 - current_user.trace_user.update_column(:tasks_count, data[0]["totalsize"]) if data.size > 0 + @project.update_column(:trace_tasks_count, data[0]["totalsize"]) if data.size > 0 render :json => {data: data} else render_error("获取检测记录失败 Error:#{error}") diff --git a/app/models/trace_user.rb b/app/models/trace_user.rb index 0e8b3d119..e89641565 100644 --- a/app/models/trace_user.rb +++ b/app/models/trace_user.rb @@ -2,19 +2,18 @@ # # 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 -# tasks_count :integer default("0") +# 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 # diff --git a/db/migrate/20220511022334_add_tasks_count_to_trace_users.rb b/db/migrate/20220511022334_add_tasks_count_to_trace_users.rb deleted file mode 100644 index 035d93a94..000000000 --- a/db/migrate/20220511022334_add_tasks_count_to_trace_users.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddTasksCountToTraceUsers < ActiveRecord::Migration[5.2] - def change - add_column :trace_users, :tasks_count, :integer, default: 0 - end -end diff --git a/db/migrate/20220511031711_add_trace_tasks_count_to_projects.rb b/db/migrate/20220511031711_add_trace_tasks_count_to_projects.rb new file mode 100644 index 000000000..fcbeff6b6 --- /dev/null +++ b/db/migrate/20220511031711_add_trace_tasks_count_to_projects.rb @@ -0,0 +1,5 @@ +class AddTraceTasksCountToProjects < ActiveRecord::Migration[5.2] + def change + add_column :projects, :trace_tasks_count, :integer, default: 0 + end +end From 12c961d70d74c6d7a57c7a4c5a738f35d3184bff Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 12 May 2022 09:19:19 +0800 Subject: [PATCH 13/41] fix --- app/controllers/traces/projects_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 812ea535b..a1f4b14db 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -27,7 +27,7 @@ class Traces::ProjectsController < Traces::BaseController page = params[:page].to_i.zero? ? 1 : params[:page].to_i code, data, error = Trace::CheckResultService.call(current_user.trace_token, @project, nil, page, limit) if code == 200 - @project.update_column(:trace_tasks_count, data[0]["totalsize"]) if data.size > 0 + @project.update_column(:trace_tasks_count, data[0]["totalsize"]) if data.is_a?(Array) && data.size > 0 render :json => {data: data} else render_error("获取检测记录失败 Error:#{error}") From 9b3336c0a0ad3aa1bcb1c4b3a50251d72d91cbac Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 12 May 2022 09:26:17 +0800 Subject: [PATCH 14/41] fix: reload task need increment tasks count --- app/controllers/traces/projects_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index a1f4b14db..8bd423878 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -41,6 +41,7 @@ class Traces::ProjectsController < Traces::BaseController return render_error("project_id错误") if params[:project_id].blank? code, data, error = Trace::ReloadCheckService.call(current_user.trace_token, params[:project_id]) if code == 200 + @project.increment!(:trace_tasks_count, 1) render_ok else render_error("重新检测失败 Error:#{error}") From 3eccd6be648afaa0d532670c1d49730d8bc7b22a Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 12 May 2022 09:45:37 +0800 Subject: [PATCH 15/41] add: user has trace user field --- app/controllers/accounts_controller.rb | 381 -------------------- app/views/users/get_user_info.json.jbuilder | 1 + 2 files changed, 1 insertion(+), 381 deletions(-) diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 5b4571d9d..a837e952f 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -1,4 +1,3 @@ -<<<<<<< HEAD class AccountsController < ApplicationController include ApplicationHelper @@ -385,383 +384,3 @@ class AccountsController < ApplicationController end end -======= -class AccountsController < ApplicationController - include ApplicationHelper - - #skip_before_action :check_account, :only => [:logout] - - def index - render json: session - end - - # 其他平台同步注册的用户 - def remote_register - Register::RemoteForm.new(remote_register_params).validate! - username = params[:username]&.gsub(/\s+/, "") - tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username) - email = params[:email]&.gsub(/\s+/, "") - password = params[:password] - platform = (params[:platform] || 'forge')&.gsub(/\s+/, "") - - ActiveRecord::Base.transaction do - result = autologin_register(username, email, password, platform) - if result[:message].blank? - render_ok({user: result[:user]}) - else - render_error(result[:message]) - end - end - rescue Exception => e - uid_logger_error(e.message) - tip_exception(-1, e.message) - end - - # 其他平台修改用户的信息,这边同步修改 - def remote_update - ActiveRecord::Base.transaction do - user_params = params[:user_params] - user_extension_params = params[:user_extension_params] - - u = User.find_by(login: params[:old_user_login]) - user_mail = u.try(:mail) - - if u.present? - ue = u.user_extension - u.login = user_params["login"] if user_params["login"] - u.mail = user_params["mail"] if user_params["mail"] - u.lastname = user_params["lastname"] if user_params["lastname"] - - ue.gender = user_extension_params["gender"] - ue.school_id = user_extension_params["school_id"] - ue.location = user_extension_params["location"] - ue.location_city = user_extension_params["location_city"] - ue.identity = user_extension_params["identity"] - ue.technical_title = user_extension_params["technical_title"] - ue.student_id = user_extension_params["student_id"] - ue.description = user_extension_params["description"] - ue.save! - u.save! - - sync_params = {} - - if (user_params["mail"] && user_params["mail"] != user_mail) - sync_params = sync_params.merge(email: user_params["mail"]) - end - - if sync_params.present? - interactor = Gitea::User::UpdateInteractor.call(u.login, sync_params) - if interactor.success? - render_ok - else - render_error(interactor.error) - end - end - end - end - rescue Exception => e - uid_logger_error(e.message) - tip_exception(-1, e.message) - end - - # 其他平台同步登录 - def remote_login - @user = User.try_to_login(params[:login], params[:password]) - if @user - successful_authentication(@user) - render_ok({user: {id: @user.id, token: @user.gitea_token}}) - else - render_error("用户不存在") - end - end - - #修改密码 - def remote_password - @user = User.find_by(login: params[:login]) - return render_error("未找到相关用户!") if @user.blank? - - sync_params = { - password: params[:password].to_s, - email: @user.mail - } - - interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params) - if interactor.success? - @user.update_attribute(:password, params[:password]) - render_ok - else - render_error(interactor.error) - end - end - - - - # 用户注册 - # 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用 - # params[:login] 邮箱或者手机号 - # params[:namespace] 登录名 - # params[:code] 验证码 - # code_type 1:注册手机验证码 8:邮箱注册验证码 - # 本地forge注册入口需要重新更改逻辑 - def register - # type只可能是1或者8 - user = nil - begin - Register::Form.new(register_params).validate! - - user = Users::RegisterService.call(register_params) - password = register_params[:password].strip - - # gitea用户注册, email, username, password - interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password}) - if interactor.success? - gitea_user = interactor.result - result = Gitea::User::GenerateTokenService.call(user.login, password) - user.gitea_token = result['sha1'] - user.gitea_uid = gitea_user[:body]['id'] - if user.save! - UserExtension.create!(user_id: user.id) - successful_authentication(user) - render_ok - end - else - tip_exception(-1, interactor.error) - end - rescue Register::BaseForm::EmailError => e - tip_exception(-2, e.message) - rescue Register::BaseForm::LoginError => e - tip_exception(-3, e.message) - rescue Register::BaseForm::PhoneError => e - tip_exception(-4, e.message) - rescue Register::BaseForm::PasswordFormatError => e - tip_exception(-5, e.message) - rescue Register::BaseForm::VerifiCodeError => e - tip_exception(-6, e.message) - rescue Exception => e - Gitea::User::DeleteService.call(user.login) unless user.nil? - uid_logger_error(e.message) - tip_exception(-1, e.message) - end - end - - # 用户登录 - def login - Users::LoginForm.new(account_params).validate! - @user = User.try_to_login(params[:login], params[:password]) - - return normal_status(-2, "错误的账号或密码") if @user.blank? - # user is already in local database - return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked? - - login_control = LimitForbidControl::UserLogin.new(@user) - return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid? - - password_ok = @user.check_password?(params[:password].to_s) - unless password_ok - if login_control.remain_times-1 == 0 - normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") - else - normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会") - end - login_control.increment! - return - end - - successful_authentication(@user) - sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步 - - # session[:user_id] = @user.id - end - - def change_password - @user = User.find_by(login: params[:login]) - return render_error("未找到相关用户!") if @user.blank? - return render_error("旧密码不正确") unless @user.check_password?(params[:old_password]) - - sync_params = { - password: params[:password].to_s, - email: @user.mail, - login_name: @user.login, - source_id: 0 - } - - interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params) - if interactor.success? - @user.update_attribute(:password, params[:password]) - render_ok - else - render_error(interactor.error) - end - end - - # 忘记密码 - def reset_password - begin - code = params[:code] - login_type = phone_mail_type(params[:login].strip) - # 获取验证码 - if login_type == 1 - phone = params[:login] - verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 2).last - user = User.find_by_phone(phone) - else - email = params[:login] - verifi_code = VerificationCode.where(email: email, code: code, code_type: 3).last - user = User.find_by_mail(email) #这里有问题,应该是为email,而不是mail 6.13-hs - end - return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip - return normal_status(-2, "验证码已失效") if !verifi_code&.effective? - return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:new_password] =~ CustomRegexp::PASSWORD - - user.password, user.password_confirmation = params[:new_password], params[:new_password_confirmation] - ActiveRecord::Base.transaction do - user.save! - LimitForbidControl::UserLogin.new(user).clear - end - sucess_status - rescue Exception => e - uid_logger_error(e.message) - tip_exception(e.message) - end - end - - def successful_authentication(user) - uid_logger("Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}") - # Valid user - self.logged_user = user - # generate a key and set cookie if autologin - - set_autologin_cookie(user) - UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip) - user.update_column(:last_login_on, Time.now) - session[:"#{default_yun_session}"] = user.id - Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}") - # 注册完成后有一天的试用申请(先去掉) - # UserDayCertification.create(user_id: user.id, status: 1) - end - - def set_autologin_cookie(user) - token = Token.get_or_create_permanent_login_token(user, "autologin") - sync_user_token_to_trustie(user.login, token.value) - - cookie_options = { - :value => token.value, - :expires => 1.month.from_now, - :path => '/', - :secure => false, - :httponly => true - } - if edu_setting('cookie_domain').present? - cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain')) - end - cookies[autologin_cookie_name] = cookie_options - cookies.signed[:user_id] ||= user.id - - logger.info("cookies is #{cookies} ======> #{cookies.signed[:user_id]} =====> #{cookies[autologin_cookie_name]}") - end - - def logout - Rails.logger.info("########___logout_current_user____________########{current_user.try(:id)}") - UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip) - logout_user - render :json => {status: 1, message: "退出成功!"} - end - - # 检验邮箱是否已被注册及邮箱或者手机号是否合法 - # 参数type为事件类型 1:注册;2:忘记密码;3:绑定 - def valid_email_and_phone - check_mail_and_phone_valid(params[:login], params[:type]) - end - - # 发送验证码 - # params[:login] 手机号或者邮箱号 - # params[:type]为事件通知类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加 - # 发送验证码:send_type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱 - # 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9: 验收手机号有效 - def get_verification_code - code = %W(0 1 2 3 4 5 6 7 8 9) - value = params[:login] - type = params[:type].strip.to_i - login_type = phone_mail_type(value) - send_type = verify_type(login_type, type) - verification_code = code.sample(6).join - - sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}") - tip_exception(501, "请求不合理") if sign != params[:smscode] - - logger.info "########### 验证码:#{verification_code}" - logger.info("########get_verification_code: login_type: #{login_type}, send_type:#{send_type}, ") - - # 记录验证码 - check_verification_code(verification_code, send_type, value) - render_ok - end - - # check user's login or email or phone is used - # params[:value] 手机号或者邮箱号或者登录名 - # params[:type] 为事件类型 1:登录名(login) 2:email(邮箱) 3:phone(手机号) - def check - Register::CheckColumnsForm.new(check_params).validate! - render_ok - end - - private - - # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加 - # login_type 1:手机类型 2:邮箱类型 - def verify_type login_type, type - case type - when 1 - login_type == 1 ? 1 : 8 - when 2 - login_type == 1 ? 2 : 3 - when 3 - login_type == 1 ? 4 : tip_exception('请填写正确的手机号') - when 4 - login_type == 1 ? tip_exception('请填写正确的邮箱') : 5 - when 5 - login_type == 1 ? 9 : tip_exception('请填写正确的手机号') - end - end - - def generate_login(login) - type = phone_mail_type(login.strip) - - if type == 1 - uid_logger("start register by phone: type is #{type}") - pre = 'p' - email = nil - phone = login - else - uid_logger("start register by email: type is #{type}") - pre = 'm' - email = login - phone = nil - end - code = generate_identifier User, 8, pre - - { login: pre + code, email: email, phone: phone } - end - - def user_params - params.require(:user).permit(:login, :email, :phone) - end - - def account_params - params.require(:account).permit(:login, :password) - end - - def check_params - params.permit(:type, :value) - end - - def register_params - params.permit(:login, :namespace, :password, :code) - end - - def remote_register_params - params.permit(:username, :email, :password, :platform) - end - -end ->>>>>>> b62824ad (add: branch valid for tasks) diff --git a/app/views/users/get_user_info.json.jbuilder b/app/views/users/get_user_info.json.jbuilder index 95085580e..d60f46ade 100644 --- a/app/views/users/get_user_info.json.jbuilder +++ b/app/views/users/get_user_info.json.jbuilder @@ -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? \ No newline at end of file From 5d771c824bd112ed0da84da0790aada04dac8380 Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 12 May 2022 11:12:34 +0800 Subject: [PATCH 16/41] add: operate permission and request timeout --- app/controllers/traces/projects_controller.rb | 2 ++ app/services/trace/client_service.rb | 1 + 2 files changed, 3 insertions(+) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 8bd423878..191f04e83 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -1,7 +1,9 @@ class Traces::ProjectsController < Traces::BaseController + include OperateProjectAbilityAble before_action :require_login before_action :load_project + before_action :authorizate_user_can_edit_project! def tasks branch_name = params[:branch_name] diff --git a/app/services/trace/client_service.rb b/app/services/trace/client_service.rb index 9423b575d..09aa617e1 100644 --- a/app/services/trace/client_service.rb +++ b/app/services/trace/client_service.rb @@ -18,6 +18,7 @@ class Trace::ClientService < ApplicationService url = URI("#{full_url(url)}") http = Net::HTTP.new(url.host, url.port) request = Net::HTTP::Post.new(url) + request.read_timeout = 1200 request["Authorization"] = token form_data = params[:data].stringify_keys.to_a request.set_form form_data, 'multipart/form-data' From 498ee26f59d2e6f43c218a2d721f9ec3c674d928 Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 12 May 2022 11:14:17 +0800 Subject: [PATCH 17/41] fix --- app/services/trace/client_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/trace/client_service.rb b/app/services/trace/client_service.rb index 09aa617e1..0f1449225 100644 --- a/app/services/trace/client_service.rb +++ b/app/services/trace/client_service.rb @@ -17,8 +17,8 @@ class Trace::ClientService < ApplicationService 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.read_timeout = 1200 request["Authorization"] = token form_data = params[:data].stringify_keys.to_a request.set_form form_data, 'multipart/form-data' From 00fc83235f8b4360140c1695379730438defbb85 Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 12 May 2022 17:11:16 +0800 Subject: [PATCH 18/41] download file use redirect --- app/controllers/traces/projects_controller.rb | 11 ++++++----- .../message_template/project_setting_changed.rb | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 191f04e83..1bf5515dd 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -57,11 +57,12 @@ class Traces::ProjectsController < Traces::BaseController def task_pdf return render_error("task_id错误") if params[:task_id].blank? code, data, error = Trace::PdfReportService.call(current_user.trace_token, params[:task_id]) - if code == 200 - render_ok - else - render_error("下载报告失败 Error:#{error}") - end + domain = Trace.trace_config[:domain] + base_url = Trace.trace_config[:base_url] + url = "/user/pdfreport?task_id=#{params[:task_id]}" + file_path = [domain, api_url, url].join + request.headers["Authorization"] = current_user.trace_token + redirect_to file_path rescue Exception => exception puts exception.message normal_status(-1, exception.message) diff --git a/app/models/message_template/project_setting_changed.rb b/app/models/message_template/project_setting_changed.rb index 0920dfe7a..ab597122a 100644 --- a/app/models/message_template/project_setting_changed.rb +++ b/app/models/message_template/project_setting_changed.rb @@ -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}', '
      ') 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}', '
      ') else From 4dccdfde974d1660afb23e1b7658d488d1f9be46 Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 12 May 2022 17:15:19 +0800 Subject: [PATCH 19/41] fix --- app/controllers/traces/projects_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 1bf5515dd..4945d9c7d 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -60,7 +60,7 @@ class Traces::ProjectsController < Traces::BaseController domain = Trace.trace_config[:domain] base_url = Trace.trace_config[:base_url] url = "/user/pdfreport?task_id=#{params[:task_id]}" - file_path = [domain, api_url, url].join + file_path = [domain, base_url, url].join request.headers["Authorization"] = current_user.trace_token redirect_to file_path rescue Exception => exception From 3d9fe5bba56faaa0de53690c619f5aa81df327a3 Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 12 May 2022 17:52:19 +0800 Subject: [PATCH 20/41] add: download pdf from trace server --- .gitignore | 3 ++- app/controllers/traces/projects_controller.rb | 13 +++++------ app/services/trace/pdf_report_service.rb | 23 ++++++++++++++----- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index fbed31a8e..2eac1d277 100644 --- a/.gitignore +++ b/.gitignore @@ -84,4 +84,5 @@ redis_data/ Dockerfile dump.rdb .tags* -ceshi_user.xlsx \ No newline at end of file +ceshi_user.xlsx +public/trace_task_results \ No newline at end of file diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 4945d9c7d..bd9eb8661 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -56,13 +56,12 @@ class Traces::ProjectsController < Traces::BaseController def task_pdf return render_error("task_id错误") if params[:task_id].blank? - code, data, error = Trace::PdfReportService.call(current_user.trace_token, params[:task_id]) - domain = Trace.trace_config[:domain] - base_url = Trace.trace_config[:base_url] - url = "/user/pdfreport?task_id=#{params[:task_id]}" - file_path = [domain, base_url, url].join - request.headers["Authorization"] = current_user.trace_token - redirect_to file_path + 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) diff --git a/app/services/trace/pdf_report_service.rb b/app/services/trace/pdf_report_service.rb index e91a78b30..244698641 100644 --- a/app/services/trace/pdf_report_service.rb +++ b/app/services/trace/pdf_report_service.rb @@ -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 = URI.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}.zip") + return {code: 200, download_url: "/trace_task_results/#{task_id}.zip"} + 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 From 7fcbbb79225a390f6196fd34e466eb074b0a0319 Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 13 May 2022 13:53:25 +0800 Subject: [PATCH 21/41] fix: remove project tasks_count --- app/controllers/traces/projects_controller.rb | 6 +++--- app/services/trace/pdf_report_service.rb | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index bd9eb8661..a1847d808 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -7,13 +7,13 @@ class Traces::ProjectsController < Traces::BaseController def tasks branch_name = params[:branch_name] - return render_error("无可用检测次数") if @project&.trace_tasks_count >= 5 + # return render_error("无可用检测次数") if @project&.trace_tasks_count >= 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 - @project.increment!(:trace_tasks_count, 1) + # @project.increment!(:trace_tasks_count, 1) render_ok else render_error("检测失败 Error:#{error}") @@ -43,7 +43,7 @@ class Traces::ProjectsController < Traces::BaseController return render_error("project_id错误") if params[:project_id].blank? code, data, error = Trace::ReloadCheckService.call(current_user.trace_token, params[:project_id]) if code == 200 - @project.increment!(:trace_tasks_count, 1) + # @project.increment!(:trace_tasks_count, 1) render_ok else render_error("重新检测失败 Error:#{error}") diff --git a/app/services/trace/pdf_report_service.rb b/app/services/trace/pdf_report_service.rb index 244698641..aa7312739 100644 --- a/app/services/trace/pdf_report_service.rb +++ b/app/services/trace/pdf_report_service.rb @@ -12,11 +12,11 @@ class Trace::PdfReportService < Trace::ClientService end def call - content = URI.open("#{domain}#{base_url}#{url}?task_id#{task_id}", "Authorization" => token) + 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}.zip") - return {code: 200, download_url: "/trace_task_results/#{task_id}.zip"} + 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 From 0e4c0a46c2df885883366076e313f6bb681890ee Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 13 May 2022 13:56:12 +0800 Subject: [PATCH 22/41] fix --- .../20220511031711_add_trace_tasks_count_to_projects.rb | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 db/migrate/20220511031711_add_trace_tasks_count_to_projects.rb diff --git a/db/migrate/20220511031711_add_trace_tasks_count_to_projects.rb b/db/migrate/20220511031711_add_trace_tasks_count_to_projects.rb deleted file mode 100644 index fcbeff6b6..000000000 --- a/db/migrate/20220511031711_add_trace_tasks_count_to_projects.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddTraceTasksCountToProjects < ActiveRecord::Migration[5.2] - def change - add_column :projects, :trace_tasks_count, :integer, default: 0 - end -end From 2c7bb1b5cd5a9c3f1541130b80441c29fd02dab7 Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 13 May 2022 14:00:21 +0800 Subject: [PATCH 23/41] fix: remove project tasks_count --- app/controllers/traces/projects_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index a1847d808..ff4e42627 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -29,7 +29,7 @@ class Traces::ProjectsController < Traces::BaseController page = params[:page].to_i.zero? ? 1 : params[:page].to_i code, data, error = Trace::CheckResultService.call(current_user.trace_token, @project, nil, page, limit) if code == 200 - @project.update_column(:trace_tasks_count, data[0]["totalsize"]) if data.is_a?(Array) && data.size > 0 + # @project.update_column(:trace_tasks_count, data[0]["totalsize"]) if data.is_a?(Array) && data.size > 0 render :json => {data: data} else render_error("获取检测记录失败 Error:#{error}") From 94881dd72a5c5e0ee0d7659ad11e4a96e961d2ad Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 13 May 2022 14:31:59 +0800 Subject: [PATCH 24/41] add: user trace tasks record --- app/controllers/traces/projects_controller.rb | 19 +++++++++++--- app/docs/slate/source/includes/_traces.md | 1 + app/models/project.rb | 1 + app/models/user.rb | 1 + app/models/user_trace_task.rb | 25 +++++++++++++++++++ .../20220513061129_create_user_trace_tasks.rb | 12 +++++++++ spec/models/user_trace_task_spec.rb | 5 ++++ 7 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 app/models/user_trace_task.rb create mode 100644 db/migrate/20220513061129_create_user_trace_tasks.rb create mode 100644 spec/models/user_trace_task_spec.rb diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index ff4e42627..cd6dcd1e0 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -13,7 +13,12 @@ class Traces::ProjectsController < Traces::BaseController 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 - # @project.increment!(:trace_tasks_count, 1) + 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}") @@ -29,7 +34,6 @@ class Traces::ProjectsController < Traces::BaseController page = params[:page].to_i.zero? ? 1 : params[:page].to_i code, data, error = Trace::CheckResultService.call(current_user.trace_token, @project, nil, page, limit) if code == 200 - # @project.update_column(:trace_tasks_count, data[0]["totalsize"]) if data.is_a?(Array) && data.size > 0 render :json => {data: data} else render_error("获取检测记录失败 Error:#{error}") @@ -41,9 +45,18 @@ class Traces::ProjectsController < Traces::BaseController 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 - # @project.increment!(:trace_tasks_count, 1) + 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}") diff --git a/app/docs/slate/source/includes/_traces.md b/app/docs/slate/source/includes/_traces.md index 6bdfb950a..e6aa24b48 100644 --- a/app/docs/slate/source/includes/_traces.md +++ b/app/docs/slate/source/includes/_traces.md @@ -163,6 +163,7 @@ await octokit.request('GET /api/traces/:owner/:repo/reload_task.json') owner |是 | 否 | string | 项目所有者标识 | repo |是 | 否 | string | 项目标识 | project_id|是 | 否| string | 代码分析结果里的project_id | +branch_name|是 | 否| string | 分支名称 | > 返回的JSON示例: diff --git a/app/models/project.rb b/app/models/project.rb index a35fbf387..1edc088f6 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 66aeb6164..bf764c148 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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]) } diff --git a/app/models/user_trace_task.rb b/app/models/user_trace_task.rb new file mode 100644 index 000000000..328cb7c0b --- /dev/null +++ b/app/models/user_trace_task.rb @@ -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 diff --git a/db/migrate/20220513061129_create_user_trace_tasks.rb b/db/migrate/20220513061129_create_user_trace_tasks.rb new file mode 100644 index 000000000..db96ea402 --- /dev/null +++ b/db/migrate/20220513061129_create_user_trace_tasks.rb @@ -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 diff --git a/spec/models/user_trace_task_spec.rb b/spec/models/user_trace_task_spec.rb new file mode 100644 index 000000000..b2542f57a --- /dev/null +++ b/spec/models/user_trace_task_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe UserTraceTask, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end From 9e8c576ff6c5f93a12c8d1893b180c8112ed661e Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 13 May 2022 15:38:04 +0800 Subject: [PATCH 25/41] fix: remove require manager operate --- app/controllers/traces/projects_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index cd6dcd1e0..15d7102eb 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -3,7 +3,7 @@ class Traces::ProjectsController < Traces::BaseController before_action :require_login before_action :load_project - before_action :authorizate_user_can_edit_project! + # before_action :authorizate_user_can_edit_project! def tasks branch_name = params[:branch_name] From 04a733d99f9366164b9ce7710edab3651b58c81d Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 13 May 2022 16:57:41 +0800 Subject: [PATCH 26/41] fix: check user trace tasks count --- app/controllers/traces/projects_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 15d7102eb..fee8fda9e 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -7,7 +7,7 @@ class Traces::ProjectsController < Traces::BaseController def tasks branch_name = params[:branch_name] - # return render_error("无可用检测次数") if @project&.trace_tasks_count >= 5 + 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) From 5a728e7d4d104d2732326ac0e6eed1e948ae8b46 Mon Sep 17 00:00:00 2001 From: yystopf Date: Mon, 16 May 2022 09:58:47 +0800 Subject: [PATCH 27/41] fix: trace user exist and compact tasks create params --- app/controllers/traces/projects_controller.rb | 1 + app/services/trace/check_service.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index fee8fda9e..b3c2ef66a 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -32,6 +32,7 @@ class Traces::ProjectsController < Traces::BaseController 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 => {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 => {data: data} diff --git a/app/services/trace/check_service.rb b/app/services/trace/check_service.rb index cf1fcf133..f12319502 100644 --- a/app/services/trace/check_service.rb +++ b/app/services/trace/check_service.rb @@ -26,7 +26,7 @@ class Trace::CheckService < Trace::ClientService git_url: repo['clone_url'], if_branch: if_branch, branch_tag: branch_tag - } + }.compact end def url From a6efae8b10c993b7ba98de2dc955acbcde857162 Mon Sep 17 00:00:00 2001 From: yystopf Date: Mon, 16 May 2022 10:48:23 +0800 Subject: [PATCH 28/41] fix --- app/services/trace/check_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/trace/check_service.rb b/app/services/trace/check_service.rb index f12319502..a13f6d3be 100644 --- a/app/services/trace/check_service.rb +++ b/app/services/trace/check_service.rb @@ -20,8 +20,8 @@ class Trace::CheckService < Trace::ClientService repo = Gitea::Repository::GetService.call(project&.owner, project&.identifier) { product_name: "#{project&.owner&.id}#{project&.id}", - product_type: project&.project_category&.name, - code_type: project&.project_language&.name, + 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, From 2f4ffe3d8e800c8e1561a93c1c7a71df183d6296 Mon Sep 17 00:00:00 2001 From: yystopf Date: Mon, 16 May 2022 14:25:54 +0800 Subject: [PATCH 29/41] fix: change trace user post valid --- app/controllers/traces/trace_users_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/traces/trace_users_controller.rb b/app/controllers/traces/trace_users_controller.rb index 70191479e..9002a5abd 100644 --- a/app/controllers/traces/trace_users_controller.rb +++ b/app/controllers/traces/trace_users_controller.rb @@ -1,5 +1,5 @@ class Traces::TraceUsersController < Traces::BaseController - before_action :check_auth + # before_action :check_auth def create if current_user.trace_token.present? From acbd0d376ce483f229394d07c05268062f1d438f Mon Sep 17 00:00:00 2001 From: yystopf Date: Mon, 16 May 2022 14:26:21 +0800 Subject: [PATCH 30/41] fix: change trace user post valid --- app/controllers/traces/trace_users_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/traces/trace_users_controller.rb b/app/controllers/traces/trace_users_controller.rb index 9002a5abd..0b28e905a 100644 --- a/app/controllers/traces/trace_users_controller.rb +++ b/app/controllers/traces/trace_users_controller.rb @@ -1,5 +1,5 @@ class Traces::TraceUsersController < Traces::BaseController - # before_action :check_auth + before_action :require_login def create if current_user.trace_token.present? From 77620f77358a402ed257dd144055b5ed512c3079 Mon Sep 17 00:00:00 2001 From: yystopf Date: Mon, 16 May 2022 16:59:25 +0800 Subject: [PATCH 31/41] add: download and import user template xlsx --- .../admins/import_users_controller.rb | 2 +- .../admins/new_import_user_from_excel.rb | 15 ++++ .../admins/import_user_from_excel_service.rb | 71 ++++++++++++++++++ app/views/admins/users/index.html.erb | 4 +- public/导入用户模板.xlsx | Bin 0 -> 9230 bytes 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 app/imports/admins/new_import_user_from_excel.rb create mode 100644 app/services/admins/import_user_from_excel_service.rb create mode 100644 public/导入用户模板.xlsx diff --git a/app/controllers/admins/import_users_controller.rb b/app/controllers/admins/import_users_controller.rb index 5d8a60ce6..4575b08d5 100644 --- a/app/controllers/admins/import_users_controller.rb +++ b/app/controllers/admins/import_users_controller.rb @@ -2,7 +2,7 @@ class Admins::ImportUsersController < Admins::BaseController def create return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile) - result = Admins::ImportUserService.call(params[:file].to_io) + result = Admins::ImportUserFromExcelService.call(params[:file].to_io) render_ok(result) rescue Admins::ImportUserService::Error => ex render_error(ex) diff --git a/app/imports/admins/new_import_user_from_excel.rb b/app/imports/admins/new_import_user_from_excel.rb new file mode 100644 index 000000000..b9a452cf1 --- /dev/null +++ b/app/imports/admins/new_import_user_from_excel.rb @@ -0,0 +1,15 @@ +class Admins::NewImportUserFromExcel < BaseImportXlsx + UserData = Struct.new(:login, :email, :password, :nickname) + + def read_each(&block) + sheet.each_row_streaming(pad_cells: true, offset: 1) do |row| + data = row.map(&method(:cell_value))[0..3] + block.call UserData.new(*data) + end + end + + private + def cell_value(obj) + obj&.cell_value + end +end \ No newline at end of file diff --git a/app/services/admins/import_user_from_excel_service.rb b/app/services/admins/import_user_from_excel_service.rb new file mode 100644 index 000000000..709551c23 --- /dev/null +++ b/app/services/admins/import_user_from_excel_service.rb @@ -0,0 +1,71 @@ +class Admins::ImportUserFromExcelService < ApplicationService + Error = Class.new(StandardError) + + attr_reader :file, :result + + def initialize(file) + @file = file + @result = { success: 0, fail: [] } + end + + def call + raise Error, '文件不存在' if file.blank? + excel = Admins::NewImportUserFromExcel.new(file) + + excel.read_each(&method(:save_user)) + result + rescue ApplicationImport::Error => ex + raise Error, ex.message + end + + private + def save_user(data) + user = find_user(data) + if user.blank? + create_user(data) + result[:success] +=1 + else + fail_data = data.as_json + fail_data[:data] = fail_data.values.join(",") + fail_data[:message] = '用户已存在' + result[:fail] << fail_data + end + + rescue Exception => ex + fail_data = data.as_json + fail_data[:data] = fail_data.values.join(",") + fail_data[:message] = ex.message + result[:fail] << fail_data + end + + def create_user(data) + ActiveRecord::Base.transaction do + username = data.login&.gsub(/\s+/, "") + email = data.email&.gsub(/\s+/, "") + password = data.password + nickname = data.nickname&.gsub(/\s+/, "") + raise Error, "无法使用以下关键词:#{username},请重新命名" if ReversedKeyword.check_exists?(data.login) + Register::RemoteForm.new({username: username, email: email, password: password, platform: 'forge'}).validate! + user = User.new(admin: false, login: username, mail: email, nickname: nickname, platform: 'forge' , type: "User") + user.password = password + user.activate + raise Error, user.errors.full_messages.join(",") unless user.valid? + interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password}) + if interactor.success? + gitea_user = interactor.result + result = Gitea::User::GenerateTokenService.call(username, password) + user.gitea_token = result['sha1'] + user.gitea_uid = gitea_user[:body]['id'] + UserExtension.create!(user_id: user.id) if user.save! + else + raise interactor.error, 'gitea user create error' + end + + user + end + end + + def find_user(data) + User.find_by(login: data.login) + end +end \ No newline at end of file diff --git a/app/views/admins/users/index.html.erb b/app/views/admins/users/index.html.erb index e21a3d665..2f41ffdb6 100644 --- a/app/views/admins/users/index.html.erb +++ b/app/views/admins/users/index.html.erb @@ -31,7 +31,9 @@ <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> <% end %> - <%= javascript_void_link '导入用户', class: 'btn btn-secondary btn-sm', data: { toggle: 'modal', target: '.admin-import-user-modal'} %> + <%= link_to '下载导入模板', "/导入用户模板.xlsx", class: 'btn btn-secondary mr-3' %> + + <%= javascript_void_link '导入用户', class: 'btn btn-secondary', data: { toggle: 'modal', target: '.admin-import-user-modal'} %> diff --git a/public/导入用户模板.xlsx b/public/导入用户模板.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..c538bed63aab06831ab7286e6a1ffe52a0337864 GIT binary patch literal 9230 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 literal 0 HcmV?d00001 From 8ae6a0deb29c0f554f9c4b5ce4f24a68fbdb3f1f Mon Sep 17 00:00:00 2001 From: yystopf Date: Mon, 16 May 2022 17:02:38 +0800 Subject: [PATCH 32/41] fix: some feature about permission --- app/controllers/projects_controller.rb | 2 +- app/controllers/traces/projects_controller.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 2d0f0f5cd..cbe9fc890 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -22,7 +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? + menu.append(menu_hash_by_name("services")) if @project.has_menu_permission("services") && @project.forge? && @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? diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index b3c2ef66a..41200e411 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -3,7 +3,7 @@ class Traces::ProjectsController < Traces::BaseController before_action :require_login before_action :load_project - # before_action :authorizate_user_can_edit_project! + before_action :authorizate_user_can_edit_project!, except: [:task_results] def tasks branch_name = params[:branch_name] From f51ebaad67a8d407c3e2a3a0e8fd945765cb3a60 Mon Sep 17 00:00:00 2001 From: yystopf Date: Mon, 16 May 2022 17:08:52 +0800 Subject: [PATCH 33/41] fix --- app/controllers/projects_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index cbe9fc890..277112265 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -22,7 +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? && @project.member(current_user.id) + menu.append(menu_hash_by_name("services")) if @project.has_menu_permission("services") && @project.forge? && @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? From 4fade5d0b7a88040df4126515c73026ec16cc53d Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 17 May 2022 11:34:08 +0800 Subject: [PATCH 34/41] fix: project trace tasks name rule change --- app/controllers/projects_controller.rb | 2 +- app/controllers/traces/projects_controller.rb | 4 ++-- app/services/trace/check_result_service.rb | 2 +- app/services/trace/check_service.rb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 277112265..68c4e59fb 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -22,7 +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? && @project.member?(current_user.id) + 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? diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 41200e411..4b0d6cf85 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -32,10 +32,10 @@ class Traces::ProjectsController < Traces::BaseController 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 => {data: []} if current_user.trace_user.nil? + 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 => {data: data} + render :json => {left_tasks_count: 5 - @project.user_trace_tasks.size ,data: data} else render_error("获取检测记录失败 Error:#{error}") end diff --git a/app/services/trace/check_result_service.rb b/app/services/trace/check_result_service.rb index f6a44c882..2a673b7ff 100644 --- a/app/services/trace/check_result_service.rb +++ b/app/services/trace/check_result_service.rb @@ -19,7 +19,7 @@ class Trace::CheckResultService < Trace::ClientService private def request_params { - product_name: "#{project&.owner&.id}#{project.id}", + product_name: Digest::MD5.hexdigest.new(project&.id.to_s), file_name: file_name, pageNum: page_num, pageSize: page_size, diff --git a/app/services/trace/check_service.rb b/app/services/trace/check_service.rb index a13f6d3be..9a1cac60c 100644 --- a/app/services/trace/check_service.rb +++ b/app/services/trace/check_service.rb @@ -19,7 +19,7 @@ class Trace::CheckService < Trace::ClientService def request_params repo = Gitea::Repository::GetService.call(project&.owner, project&.identifier) { - product_name: "#{project&.owner&.id}#{project&.id}", + product_name: Digest::MD5.hexdigest.new(project&.id.to_s), product_type: project&.project_category&.name || '其他', code_type: project&.project_language&.name || '其他', product_desc: project&.description, From 077926de181b0bc640c7397c46671d9a53ff46c9 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 17 May 2022 11:39:57 +0800 Subject: [PATCH 35/41] fix --- app/controllers/traces/projects_controller.rb | 2 +- app/services/trace/check_result_service.rb | 2 +- app/services/trace/check_service.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/traces/projects_controller.rb b/app/controllers/traces/projects_controller.rb index 4b0d6cf85..62573a1d8 100644 --- a/app/controllers/traces/projects_controller.rb +++ b/app/controllers/traces/projects_controller.rb @@ -35,7 +35,7 @@ class Traces::ProjectsController < Traces::BaseController 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} + render :json => {left_tasks_count: 5 - @project.user_trace_tasks.size, data: data} else render_error("获取检测记录失败 Error:#{error}") end diff --git a/app/services/trace/check_result_service.rb b/app/services/trace/check_result_service.rb index 2a673b7ff..444462eac 100644 --- a/app/services/trace/check_result_service.rb +++ b/app/services/trace/check_result_service.rb @@ -19,7 +19,7 @@ class Trace::CheckResultService < Trace::ClientService private def request_params { - product_name: Digest::MD5.hexdigest.new(project&.id.to_s), + product_name: Digest::MD5.hexdigest(project&.id.to_s), file_name: file_name, pageNum: page_num, pageSize: page_size, diff --git a/app/services/trace/check_service.rb b/app/services/trace/check_service.rb index 9a1cac60c..b440b0b04 100644 --- a/app/services/trace/check_service.rb +++ b/app/services/trace/check_service.rb @@ -19,7 +19,7 @@ class Trace::CheckService < Trace::ClientService def request_params repo = Gitea::Repository::GetService.call(project&.owner, project&.identifier) { - product_name: Digest::MD5.hexdigest.new(project&.id.to_s), + product_name: Digest::MD5.hexdigest(project&.id.to_s), product_type: project&.project_category&.name || '其他', code_type: project&.project_language&.name || '其他', product_desc: project&.description, From bfd3298cd0111f9c913451e88c3d9b45615a4b05 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 17 May 2022 11:42:43 +0800 Subject: [PATCH 36/41] fix --- app/services/trace/check_result_service.rb | 2 +- app/services/trace/check_service.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/trace/check_result_service.rb b/app/services/trace/check_result_service.rb index 444462eac..ff47d9a39 100644 --- a/app/services/trace/check_result_service.rb +++ b/app/services/trace/check_result_service.rb @@ -19,7 +19,7 @@ class Trace::CheckResultService < Trace::ClientService private def request_params { - product_name: Digest::MD5.hexdigest(project&.id.to_s), + product_name: Digest::MD5.hexdigest(project&.id.to_s)[0...20], file_name: file_name, pageNum: page_num, pageSize: page_size, diff --git a/app/services/trace/check_service.rb b/app/services/trace/check_service.rb index b440b0b04..d1623445b 100644 --- a/app/services/trace/check_service.rb +++ b/app/services/trace/check_service.rb @@ -19,7 +19,7 @@ class Trace::CheckService < Trace::ClientService def request_params repo = Gitea::Repository::GetService.call(project&.owner, project&.identifier) { - product_name: Digest::MD5.hexdigest(project&.id.to_s), + 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, From 9cd18397f7a7ddeec987fc9851d661171b294698 Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 18 May 2022 10:11:09 +0800 Subject: [PATCH 37/41] fix: import user login length required --- app/libs/custom_regexp.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/libs/custom_regexp.rb b/app/libs/custom_regexp.rb index 25c3ae988..72184630a 100644 --- a/app/libs/custom_regexp.rb +++ b/app/libs/custom_regexp.rb @@ -1,7 +1,7 @@ module CustomRegexp PHONE = /1\d{10}/ EMAIL = /\A[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+\z/ - LOGIN = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾 + LOGIN = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]{4,15}/ #只含有数字、字母、下划线不能以下划线开头和结尾 LASTNAME = /\A[a-zA-Z0-9\u4e00-\u9fa5]+\z/ NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/ PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/ From ca3c56452917b968d0b302728686757e20708657 Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 18 May 2022 11:03:39 +0800 Subject: [PATCH 38/41] fix: not found user return 404 --- app/controllers/owners_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/owners_controller.rb b/app/controllers/owners_controller.rb index 067fe4da1..863f8aa3a 100644 --- a/app/controllers/owners_controller.rb +++ b/app/controllers/owners_controller.rb @@ -11,6 +11,8 @@ class OwnersController < ApplicationController end def show + return render_not_found unless @user.present? + @owner = Owner.find_by(login: params[:id]) || Owner.find_by(id: params[:id]) # return render_not_found unless @owner.present? # 组织 From e237fd46f7d151a3162f806a6042dae03abad34e Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 18 May 2022 11:37:23 +0800 Subject: [PATCH 39/41] fix: not found user return 404 --- app/controllers/owners_controller.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/controllers/owners_controller.rb b/app/controllers/owners_controller.rb index 863f8aa3a..28a5210d5 100644 --- a/app/controllers/owners_controller.rb +++ b/app/controllers/owners_controller.rb @@ -11,10 +11,8 @@ class OwnersController < ApplicationController end def show - return render_not_found unless @user.present? - @owner = Owner.find_by(login: params[:id]) || Owner.find_by(id: params[:id]) - # return render_not_found unless @owner.present? + return render_not_found unless @owner.present? # 组织 if @owner.is_a?(Organization) return render_forbidden("没有查看组织的权限") if org_limited_condition || org_privacy_condition From 83e43f0c9792010817828abcc117294e2e287303 Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 20 May 2022 11:43:22 +0800 Subject: [PATCH 40/41] add: new readme delay function --- app/helpers/repositories_helper.rb | 39 +++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index b8bfc31cd..9fd45249c 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -87,6 +87,42 @@ module RepositoriesHelper end end + # author hui.he + def new_readme_render_decode64_content(str, owner, repo, ref) + path = [owner&.login, repo&.identifier, 'tree', ref].join("/") + return nil if str.blank? + content = Base64.decode64(str).force_encoding('UTF-8') + s_regex = /\[.*?\]\((.*?)\)/ + src_regex = /src=\"(.*?)\"/ + ss = content.to_s.scan(s_regex) + ss_src = content.to_s.scan(src_regex) + total_sources = ss + ss_src + total_sources.uniq! + total_sources.each do |s| + begin + s_content = s[0] + # 链接直接跳过不做替换 + next if s_content.starts_with?('http://') || s_content.starts_with?('https://') || s_content.starts_with?('mailto:') + # 路径替换 + if s_content.starts_with?('./') || s_content.starts_with?("../") || s_content.starts_with?("/") + s_content = File.expand_path(s_content, path) + s_content = s_content.split("#{Rails.root}/")[1] + content = content.gsub(s[0], "/#{s_content}") + else + # 图片资源替换 + s_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{s_content}&ref=#{ref}"].join + content = content.gsub(s[0], s_content) + end + rescue + next + end + end + + return content + rescue + return str + 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") @@ -102,7 +138,8 @@ module RepositoriesHelper Rails.logger.info("entry===#{entry["type"]} #{entry["name"]}") content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] Rails.logger.info("content===#{content}") - readme_render_decode64_content(content, owner, repo, ref) + # readme_render_decode64_content(content, owner, repo, ref) + new_readme_render_decode64_content(content, owner, repo, ref) else file_type = File.extname(entry['name'].to_s)[1..-1] if image_type?(file_type) From 779c86108a547da22ef3cb2148906c49cbea196f Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 20 May 2022 17:00:02 +0800 Subject: [PATCH 41/41] fix: readme relative delay and replace_content --- app/controllers/repositories_controller.rb | 3 +- app/helpers/repositories_helper.rb | 30 +++++++++++++------ .../repositories/_simple_entry.json.jbuilder | 7 +++-- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 272e121a0..a2ab33b23 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -225,7 +225,8 @@ class RepositoriesController < ApplicationController @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") + @readme['replace_content'] = readme_decode64_content(@readme, @owner, @repository, params[:ref], @path) + render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha", "replace_content") rescue render json: nil end diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index 9fd45249c..1897f3ae0 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -88,8 +88,8 @@ module RepositoriesHelper end # author hui.he - def new_readme_render_decode64_content(str, owner, repo, ref) - path = [owner&.login, repo&.identifier, 'tree', ref].join("/") + def new_readme_render_decode64_content(str, owner, repo, ref, readme_path, readme_name) + file_path = readme_path.include?('/') ? readme_path.gsub("/#{readme_name}", '') : readme_path.gsub("#{readme_name}", '') return nil if str.blank? content = Base64.decode64(str).force_encoding('UTF-8') s_regex = /\[.*?\]\((.*?)\)/ @@ -103,15 +103,19 @@ module RepositoriesHelper s_content = s[0] # 链接直接跳过不做替换 next if s_content.starts_with?('http://') || s_content.starts_with?('https://') || s_content.starts_with?('mailto:') - # 路径替换 - if s_content.starts_with?('./') || s_content.starts_with?("../") || s_content.starts_with?("/") + ext = File.extname(s_content)[1..-1] + + if image_type?(ext) || download_type(ext) + s_content = File.expand_path(s_content, file_path) + s_content = s_content.split("#{Rails.root}/")[1] + # content = content.gsub(s[0], "/#{s_content}") + s_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{s_content}&ref=#{ref}"].join + content = content.gsub(s[0], s_content) + else + path = [owner&.login, repo&.identifier, 'tree', ref, file_path].join("/") s_content = File.expand_path(s_content, path) s_content = s_content.split("#{Rails.root}/")[1] content = content.gsub(s[0], "/#{s_content}") - else - # 图片资源替换 - s_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{s_content}&ref=#{ref}"].join - content = content.gsub(s[0], s_content) end rescue next @@ -133,13 +137,21 @@ module RepositoriesHelper date.to_time.strftime("%Y-%m-%d %H:%M") end + def readme_decode64_content(entry, owner, repo, ref, path=nil) + Rails.logger.info("entry===#{entry["type"]} #{entry["name"]}") + content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] + Rails.logger.info("content===#{content}") + # readme_render_decode64_content(content, owner, repo, ref) + new_readme_render_decode64_content(content, owner, repo, ref, entry['path'], entry['name']) + end + def decode64_content(entry, owner, repo, ref, path=nil) if is_readme?(entry['type'], entry['name']) Rails.logger.info("entry===#{entry["type"]} #{entry["name"]}") content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] Rails.logger.info("content===#{content}") # readme_render_decode64_content(content, owner, repo, ref) - new_readme_render_decode64_content(content, owner, repo, ref) + return Base64.decode64(content).force_encoding('UTF-8') else file_type = File.extname(entry['name'].to_s)[1..-1] if image_type?(file_type) diff --git a/app/views/repositories/_simple_entry.json.jbuilder b/app/views/repositories/_simple_entry.json.jbuilder index 9d0998c82..3a0d16e28 100644 --- a/app/views/repositories/_simple_entry.json.jbuilder +++ b/app/views/repositories/_simple_entry.json.jbuilder @@ -8,7 +8,10 @@ if @project.forge? json.path entry['path'] json.type entry['type'] json.size entry['size'] - + is_readme = is_readme?(entry['type'], entry['name']) + if is_readme + json.replace_content readme_decode64_content(entry, @owner, @repository, @ref, @path) + end json.content direct_download ? nil : decode64_content(entry, @owner, @repository, @ref, @path) json.target entry['target'] @@ -24,7 +27,7 @@ if @project.forge? json.direct_download direct_download json.image_type image_type - json.is_readme_file is_readme?(entry['type'], entry['name']) + json.is_readme_file is_readme json.commit do json.partial! 'last_commit', latest_commit: entry['latest_commit'] end