| @@ -134,3 +134,5 @@ gem 'jwt' | |||||
| gem 'doorkeeper' | gem 'doorkeeper' | ||||
| gem 'doorkeeper-jwt' | gem 'doorkeeper-jwt' | ||||
| gem 'gitea-client', '~> 0.8.2' | |||||
| @@ -0,0 +1,18 @@ | |||||
| class Api::V1::BaseController < ApplicationController | |||||
| include Api::ProjectHelper | |||||
| include Api::UserHelper | |||||
| before_action :doorkeeper_authorize! | |||||
| skip_before_action :user_setup | |||||
| protected | |||||
| def current_user | |||||
| User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token | |||||
| end | |||||
| def require_manager_above | |||||
| @project = load_project | |||||
| return render_forbidden unless current_user.admin? && @project.manager?(current_user) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,55 @@ | |||||
| class Api::V1::Projects::WebhooksController < Api::V1::BaseController | |||||
| before_action :require_manager_above | |||||
| before_action :find_webhook, only: [:show, :update, :destroy, :tests, :hooktasks] | |||||
| def index | |||||
| # @result_object = Api::V1::Projects::Webhooks::ListService.call(@project, current_user&.gitea_token) | |||||
| @webhooks = @project.webhooks | |||||
| @webhooks = kaminari_paginate(@webhooks) | |||||
| end | |||||
| def create | |||||
| @result_object = Api::V1::Projects::Webhooks::CreateService.call(@project, webhook_params, current_user&.gitea_token) | |||||
| end | |||||
| def show | |||||
| @result_object = Api::V1::Projects::Webhooks::GetService.call(@project, params[:id], current_user&.gitea_token) | |||||
| end | |||||
| def update | |||||
| @result_object = Api::V1::Projects::Webhooks::UpdateService.call(@project, params[:id], webhook_params, current_user&.gitea_token) | |||||
| end | |||||
| def destroy | |||||
| @result_object = Api::V1::Projects::Webhooks::DeleteService.call(@project, params[:id], current_user&.gitea_token) | |||||
| if @result_object | |||||
| return render_ok | |||||
| else | |||||
| return render_error('删除失败!') | |||||
| end | |||||
| end | |||||
| def tests | |||||
| @result_object = Api::V1::Projects::Webhooks::TestsService.call(@project, params[:id], current_user&.gitea_token) | |||||
| if @result_object | |||||
| return render_ok | |||||
| else | |||||
| return render_error('推送失败!') | |||||
| end | |||||
| end | |||||
| def hooktasks | |||||
| @hooktasks = @webhook.tasks.where(is_delivered: true).order("delivered desc") | |||||
| @hooktasks = kaminari_paginate(@hooktasks) | |||||
| end | |||||
| private | |||||
| def webhook_params | |||||
| params.require(:webhook).permit(:active, :branch_filter, :http_method, :url, :content_type, :secret, events: []) | |||||
| end | |||||
| def find_webhook | |||||
| @webhook = Gitea::Webhook.find_by_id(params[:id]) | |||||
| return render_not_found unless @webhook.present? | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,11 @@ | |||||
| class Api::V1::ProjectsController < Api::V1::BaseController | |||||
| before_action :load_project, only: [:show] | |||||
| def index | |||||
| render_ok | |||||
| end | |||||
| def show | |||||
| @result_object = Api::V1::Projects::GetService.call(@project, current_user.gitea_token) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,13 @@ | |||||
| class Api::V1::Users::ProjectsController < Api::V1::BaseController | |||||
| before_action :load_observe_user | |||||
| def index | |||||
| @object_results = Api::V1::Users::Projects::ListService.call(@observe_user, query_params, current_user) | |||||
| @projects = kaminari_paginate(@object_results) | |||||
| end | |||||
| private | |||||
| def query_params | |||||
| params.permit(:category, :is_public, :project_type, :sort_by, :sort_direction, :search) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,6 @@ | |||||
| class Api::V1::UsersController < Api::V1::BaseController | |||||
| def index | |||||
| render_ok | |||||
| end | |||||
| end | |||||
| @@ -170,7 +170,10 @@ class ApplicationController < ActionController::Base | |||||
| # 未授权的捕捉407,弹试用申请弹框 | # 未授权的捕捉407,弹试用申请弹框 | ||||
| def require_login | def require_login | ||||
| #6.13 -hs | #6.13 -hs | ||||
| if request.headers["Authorization"].present? | |||||
| tip_exception(401, "请登录后再操作!") unless valid_doorkeeper_token? | |||||
| User.current = User.find_by(id: @doorkeeper_token.resource_owner_id) if @doorkeeper_token.present? | |||||
| end | |||||
| tip_exception(401, "请登录后再操作") unless User.current.logged? | tip_exception(401, "请登录后再操作") unless User.current.logged? | ||||
| end | end | ||||
| @@ -266,11 +269,11 @@ class ApplicationController < ActionController::Base | |||||
| end | end | ||||
| end | end | ||||
| if !User.current.logged? && Rails.env.development? | |||||
| user = User.find 1 | |||||
| User.current = user | |||||
| start_user_session(user) | |||||
| end | |||||
| # if !User.current.logged? && Rails.env.development? | |||||
| # user = User.find 1 | |||||
| # User.current = user | |||||
| # start_user_session(user) | |||||
| # end | |||||
| # 测试版前端需求 | # 测试版前端需求 | ||||
| @@ -33,8 +33,8 @@ class AttachmentsController < ApplicationController | |||||
| normal_status(-1, "参数缺失") if params[:download_url].blank? | normal_status(-1, "参数缺失") if params[:download_url].blank? | ||||
| url = URI.encode(params[:download_url].to_s.gsub("http:", "https:")) | url = URI.encode(params[:download_url].to_s.gsub("http:", "https:")) | ||||
| if url.starts_with?(base_url) | if url.starts_with?(base_url) | ||||
| domain = Gitea.gitea_config[:domain] | |||||
| api_url = Gitea.gitea_config[:base_url] | |||||
| domain = GiteaService.gitea_config[:domain] | |||||
| api_url = GiteaService.gitea_config[:base_url] | |||||
| url = url.split(base_url)[1].gsub("api", "repos").gsub('?filepath=', '/').gsub('&', '?') | url = url.split(base_url)[1].gsub("api", "repos").gsub('?filepath=', '/').gsub('&', '?') | ||||
| request_url = [domain, api_url, url, "?ref=#{params[:ref]}&access_token=#{current_user&.gitea_token}"].join | request_url = [domain, api_url, url, "?ref=#{params[:ref]}&access_token=#{current_user&.gitea_token}"].join | ||||
| response = Faraday.get(request_url) | response = Faraday.get(request_url) | ||||
| @@ -6,9 +6,14 @@ class CompareController < ApplicationController | |||||
| end | end | ||||
| def show | def show | ||||
| load_compare_params | |||||
| compare | |||||
| @merge_status, @merge_message = get_merge_message | |||||
| if params[:type] == "sha" | |||||
| load_compare_params | |||||
| @compare_result ||= gitea_compare(@base, @head) | |||||
| else | |||||
| load_compare_params | |||||
| compare | |||||
| @merge_status, @merge_message = get_merge_message | |||||
| end | |||||
| @page_size = page_size <= 0 ? 1 : page_size | @page_size = page_size <= 0 ? 1 : page_size | ||||
| @page_limit = page_limit <=0 ? 15 : page_limit | @page_limit = page_limit <=0 ? 15 : page_limit | ||||
| @page_offset = (@page_size -1) * @page_limit | @page_offset = (@page_size -1) * @page_limit | ||||
| @@ -18,15 +18,15 @@ module Acceleratorable | |||||
| end | end | ||||
| def accelerator_domain | def accelerator_domain | ||||
| Gitea.gitea_config[:accelerator]["domain"] | |||||
| GiteaService.gitea_config[:accelerator]["domain"] | |||||
| end | end | ||||
| def accelerator_username | def accelerator_username | ||||
| Gitea.gitea_config[:accelerator]["access_key_id"] | |||||
| GiteaService.gitea_config[:accelerator]["access_key_id"] | |||||
| end | end | ||||
| def config_accelerator? | def config_accelerator? | ||||
| Gitea.gitea_config[:accelerator].present? | |||||
| GiteaService.gitea_config[:accelerator].present? | |||||
| end | end | ||||
| def is_foreign_url?(clone_addr) | def is_foreign_url?(clone_addr) | ||||
| @@ -0,0 +1,20 @@ | |||||
| module Api::ProjectHelper | |||||
| extend ActiveSupport::Concern | |||||
| def load_project | |||||
| namespace = params[:owner] | |||||
| repo = params[:repo] | |||||
| @project, @owner = Project.find_with_namespace(namespace, repo) | |||||
| if @project | |||||
| logger.info "###########:project not founded" | |||||
| @project | |||||
| else | |||||
| logger.info "###########:project not found" | |||||
| @project = nil | |||||
| render_not_found and return | |||||
| end | |||||
| @project | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,19 @@ | |||||
| module Api::UserHelper | |||||
| extend ActiveSupport::Concern | |||||
| def load_observe_user | |||||
| username = params[:owner] | |||||
| @observe_user = User.find_by(login: username) | |||||
| if @observe_user | |||||
| logger.info "###########observe_user not founded" | |||||
| @observe_user | |||||
| else | |||||
| logger.info "###########observe_user not found" | |||||
| @observe_user = nil | |||||
| render_not_found and return | |||||
| end | |||||
| @observe_user | |||||
| end | |||||
| end | |||||
| @@ -116,6 +116,7 @@ module LoginHelper | |||||
| interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params.merge(hash)) | interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params.merge(hash)) | ||||
| if interactor.success? | if interactor.success? | ||||
| Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########" | Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########" | ||||
| user.update_column(:is_sync_pwd, true) | |||||
| true | true | ||||
| else | else | ||||
| Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea fail!: #{interactor.error}" | Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea fail!: #{interactor.error}" | ||||
| @@ -5,7 +5,16 @@ module Repository::LanguagesPercentagable | |||||
| result = Gitea::Repository::Languages::ListService.call(@owner.login, | result = Gitea::Repository::Languages::ListService.call(@owner.login, | ||||
| @repository.identifier, current_user&.gitea_token) | @repository.identifier, current_user&.gitea_token) | ||||
| result[:status] === :success ? hash_transform_precentagable(result[:body]) : nil | |||||
| @transform_language = result[:status] === :success ? hash_transform_precentagable(result[:body]) : nil | |||||
| update_project_language(@transform_language) unless @transform_language.nil? | |||||
| @transform_language | |||||
| end | |||||
| def update_project_language(language) | |||||
| db_language = ProjectLanguage.find_or_create_by!(name: language.keys.first.downcase.upcase_first) | |||||
| @project.update_column(:project_language_id, db_language.id) | |||||
| rescue | |||||
| return | |||||
| end | end | ||||
| # hash eq:{"JavaScript": 301681522,"Ruby": 1444004,"Roff": 578781} | # hash eq:{"JavaScript": 301681522,"Ruby": 1444004,"Roff": 578781} | ||||
| @@ -0,0 +1,39 @@ | |||||
| class Oauth2Controller < ActionController::Base | |||||
| layout 'doorkeeper/application' | |||||
| include LoginHelper | |||||
| def show | |||||
| client_id = params[:call_url].split("client_id=")[1].split("&redirect_uri")[0] | |||||
| @call_url = request.fullpath.split('call_url=').last | |||||
| @app = Doorkeeper::Application.find_by(uid: client_id) | |||||
| end | |||||
| def create | |||||
| if params[:login].blank? | |||||
| @error = {msg: '邮箱地址或用户名不能为空', id: 'login'} | |||||
| elsif params[:password].blank? | |||||
| @error = {msg: '请输入密码', id: 'password'} | |||||
| else | |||||
| @user = User.try_to_login(params[:login], params[:password]) | |||||
| return @error = {msg: '账号或密码错误', id: 'login'} if @user.blank? | |||||
| return @error = {msg: '违反平台使用规范,账号已被锁定', id: 'login'} if @user.locked? | |||||
| login_control = LimitForbidControl::UserLogin.new(@user) | |||||
| return @error = {msg: "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码", id: 'account'} if login_control.forbid? | |||||
| password_ok = @user.check_password?(params[:password].to_s) | |||||
| unless password_ok | |||||
| if login_control.remain_times-1 == 0 | |||||
| @error = {msg: "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码", id: 'account'} | |||||
| else | |||||
| @error = {msg: "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会", id: 'account'} | |||||
| end | |||||
| login_control.increment! | |||||
| return | |||||
| end | |||||
| login_control.clear | |||||
| redirect_to params[:call_url] + "&auth=" + @user.login | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -56,7 +56,12 @@ class PullRequestsController < ApplicationController | |||||
| end | end | ||||
| def create | def create | ||||
| # return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user) | |||||
| if params[:fork_project_id].present? | |||||
| fork_project= Project.find_by(id: params[:fork_project_id]) | |||||
| return normal_status(-1, "您不是源项目开发者,没有权限,请联系源项目管理员.") unless fork_project && fork_project.operator?(current_user) | |||||
| else | |||||
| return normal_status(-1, "您不是项目开发者,没有权限,请联系项目管理员.") unless @project.operator?(current_user) | |||||
| end | |||||
| ActiveRecord::Base.transaction do | ActiveRecord::Base.transaction do | ||||
| Issues::CreateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate! | Issues::CreateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate! | ||||
| @pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params) | @pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params) | ||||
| @@ -176,6 +181,7 @@ class PullRequestsController < ApplicationController | |||||
| @issue_assign_to = @issue.get_assign_user | @issue_assign_to = @issue.get_assign_user | ||||
| @gitea_pull = Gitea::PullRequest::GetService.call(@owner.login, | @gitea_pull = Gitea::PullRequest::GetService.call(@owner.login, | ||||
| @repository.identifier, @pull_request.gitea_number, current_user&.gitea_token) | @repository.identifier, @pull_request.gitea_number, current_user&.gitea_token) | ||||
| @last_review = @pull_request.issue.reviews.take | |||||
| end | end | ||||
| def pr_merge | def pr_merge | ||||
| @@ -9,7 +9,7 @@ class RepositoriesController < ApplicationController | |||||
| before_action :load_repository | before_action :load_repository | ||||
| before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive] | before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive] | ||||
| before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror] | before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror] | ||||
| before_action :get_ref, only: %i[entries sub_entries top_counts file archive] | |||||
| before_action :get_ref, only: %i[entries sub_entries top_counts files archive] | |||||
| before_action :get_latest_commit, only: %i[entries sub_entries top_counts] | before_action :get_latest_commit, only: %i[entries sub_entries top_counts] | ||||
| before_action :get_statistics, only: %i[top_counts] | before_action :get_statistics, only: %i[top_counts] | ||||
| @@ -54,7 +54,7 @@ class RepositoriesController < ApplicationController | |||||
| else | else | ||||
| @entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call | @entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call | ||||
| @entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : [] | @entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : [] | ||||
| @path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/" | |||||
| @path = GiteaService.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/" | |||||
| end | end | ||||
| end | end | ||||
| @@ -99,7 +99,7 @@ class RepositoriesController < ApplicationController | |||||
| end | end | ||||
| end | end | ||||
| else | else | ||||
| @path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/" | |||||
| @path = GiteaService.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/" | |||||
| interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref) | interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref) | ||||
| if interactor.success? | if interactor.success? | ||||
| result = interactor.result | result = interactor.result | ||||
| @@ -222,7 +222,7 @@ class RepositoriesController < ApplicationController | |||||
| else | else | ||||
| result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token) | result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token) | ||||
| end | end | ||||
| @path = Gitea.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/" | |||||
| @path = GiteaService.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/" | |||||
| @readme = result[:status] === :success ? result[:body] : nil | @readme = result[:status] === :success ? result[:body] : nil | ||||
| @readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path) | @readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path) | ||||
| @readme['replace_content'] = readme_decode64_content(@readme, @owner, @repository, params[:ref], @path) | @readme['replace_content'] = readme_decode64_content(@readme, @owner, @repository, params[:ref], @path) | ||||
| @@ -240,8 +240,8 @@ class RepositoriesController < ApplicationController | |||||
| end | end | ||||
| def archive | def archive | ||||
| domain = Gitea.gitea_config[:domain] | |||||
| api_url = Gitea.gitea_config[:base_url] | |||||
| domain = GiteaService.gitea_config[:domain] | |||||
| api_url = GiteaService.gitea_config[:base_url] | |||||
| archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{Addressable::URI.escape(params[:archive])}" | archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{Addressable::URI.escape(params[:archive])}" | ||||
| file_path = [domain, api_url, archive_url].join | file_path = [domain, api_url, archive_url].join | ||||
| @@ -253,8 +253,8 @@ class RepositoriesController < ApplicationController | |||||
| end | end | ||||
| def raw | def raw | ||||
| domain = Gitea.gitea_config[:domain] | |||||
| api_url = Gitea.gitea_config[:base_url] | |||||
| domain = GiteaService.gitea_config[:domain] | |||||
| api_url = GiteaService.gitea_config[:base_url] | |||||
| url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{Addressable::URI.escape(params[:filepath])}?ref=#{Addressable::URI.escape(params[:ref])}" | url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{Addressable::URI.escape(params[:filepath])}?ref=#{Addressable::URI.escape(params[:ref])}" | ||||
| file_path = [domain, api_url, url].join | file_path = [domain, api_url, url].join | ||||
| @@ -0,0 +1,20 @@ | |||||
| class ReviewsController < ApplicationController | |||||
| before_action :require_login | |||||
| before_action :load_project | |||||
| before_action :load_pull_request | |||||
| def create | |||||
| return render_forbidden('您不是审查人员,无法进行审查!') if current_user&.id != @pull_request.issue.assigned_to_id | |||||
| @journal, @review = Api::V1::Projects::PullRequests::Reviews::CreateService.call(@project, @pull_request, review_params, current_user) | |||||
| end | |||||
| private | |||||
| def review_params | |||||
| params.require(:review).permit(:content, :commit_id, :status) | |||||
| end | |||||
| def load_pull_request | |||||
| @pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id]) | |||||
| end | |||||
| end | |||||
| @@ -1115,15 +1115,15 @@ await octokit.request('GET /api/yystopf/csfjkkj/contributors.json') | |||||
| ```shell | ```shell | ||||
| curl -X GET \ | curl -X GET \ | ||||
| http://localhost:3000/api/yystopf/ceshi/webhooks.json | |||||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks.json | |||||
| ``` | ``` | ||||
| ```javascript | ```javascript | ||||
| await octokit.request('GET /api/yystopf/ceshi/webhooks.json') | |||||
| await octokit.request('GET /api/v1/yystopf/ceshi/webhooks.json') | |||||
| ``` | ``` | ||||
| ### HTTP 请求 | ### HTTP 请求 | ||||
| `GET /api/:owner/:repo/webhooks.json` | |||||
| `GET /api/v1/:owner/:repo/webhooks.json` | |||||
| ### 请求参数: | ### 请求参数: | ||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | 参数 | 必选 | 默认 | 类型 | 字段说明 | ||||
| @@ -1139,7 +1139,6 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks.json') | |||||
| |url |string|地址| | |url |string|地址| | ||||
| |http_method |string|请求方式| | |http_method |string|请求方式| | ||||
| |is_active |bool |是否激活| | |is_active |bool |是否激活| | ||||
| |type |string|类型| | |||||
| |last_status |string|最后一次推送的状态| | |last_status |string|最后一次推送的状态| | ||||
| |create_time |string|创建时间| | |create_time |string|创建时间| | ||||
| @@ -1155,7 +1154,6 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks.json') | |||||
| "url": "https://oapi.dingtalk.com/robot/send?access_token=7e1e19d0eddb6a5e33c5c2c4e66f4c88f9437184b9ed2c2653194c6374c7d513", | "url": "https://oapi.dingtalk.com/robot/send?access_token=7e1e19d0eddb6a5e33c5c2c4e66f4c88f9437184b9ed2c2653194c6374c7d513", | ||||
| "http_method": "", | "http_method": "", | ||||
| "is_active": true, | "is_active": true, | ||||
| "type": "dingtalk", | |||||
| "last_status": "succeed", | "last_status": "succeed", | ||||
| "create_time": "2021-07-12 10:50:07" | "create_time": "2021-07-12 10:50:07" | ||||
| }, | }, | ||||
| @@ -1164,7 +1162,6 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks.json') | |||||
| "url": "http://localhost:3000", | "url": "http://localhost:3000", | ||||
| "http_method": "GET", | "http_method": "GET", | ||||
| "is_active": true, | "is_active": true, | ||||
| "type": "gitea", | |||||
| "last_status": "succeed", | "last_status": "succeed", | ||||
| "create_time": "2021-07-26 10:03:45" | "create_time": "2021-07-26 10:03:45" | ||||
| }, | }, | ||||
| @@ -1173,7 +1170,6 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks.json') | |||||
| "url": "http://localhost:10081", | "url": "http://localhost:10081", | ||||
| "http_method": "POST", | "http_method": "POST", | ||||
| "is_active": true, | "is_active": true, | ||||
| "type": "gitea", | |||||
| "last_status": "waiting", | "last_status": "waiting", | ||||
| "create_time": "2021-07-26 16:56:53" | "create_time": "2021-07-26 16:56:53" | ||||
| }, | }, | ||||
| @@ -1182,7 +1178,6 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks.json') | |||||
| "url": "http://localhost:3001", | "url": "http://localhost:3001", | ||||
| "http_method": "POST", | "http_method": "POST", | ||||
| "is_active": true, | "is_active": true, | ||||
| "type": "gitea", | |||||
| "last_status": "fail", | "last_status": "fail", | ||||
| "create_time": "2021-07-26 16:58:23" | "create_time": "2021-07-26 16:58:23" | ||||
| } | } | ||||
| @@ -1200,15 +1195,15 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks.json') | |||||
| ```shell | ```shell | ||||
| curl -X GET \ | curl -X GET \ | ||||
| http://localhost:3000/api/yystopf/ceshi/webhooks/3/edit.json | |||||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3.json | |||||
| ``` | ``` | ||||
| ```javascript | ```javascript | ||||
| await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json') | |||||
| await octokit.request('GET /api/v1/yystopf/ceshi/webhooks/3.json') | |||||
| ``` | ``` | ||||
| ### HTTP 请求 | ### HTTP 请求 | ||||
| `GET /api/:owner/:repo/webhooks/:id/edit.json` | |||||
| `GET /api/v1/:owner/:repo/webhooks/:id.json` | |||||
| ### 请求参数: | ### 请求参数: | ||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | 参数 | 必选 | 默认 | 类型 | 字段说明 | ||||
| @@ -1226,36 +1221,21 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json') | |||||
| |content_type |string|POST Content Type| | |content_type |string|POST Content Type| | ||||
| |http_method |string|请求方式| | |http_method |string|请求方式| | ||||
| |secret| |string|密钥| | |secret| |string|密钥| | ||||
| |is_active |bool |是否激活| | |||||
| |type |string|类型| | |||||
| |last_status |string|最后一次推送的状态, waiting 等待,fail 失败,succeed 成功| | |||||
| |active |bool |是否激活| | |||||
| |branch_filter |string|分支过滤| | |branch_filter |string|分支过滤| | ||||
| |events |string|触发条件| | |events |string|触发条件| | ||||
| |create_time |string|创建时间| | |||||
| |create_at |string|创建时间| | |||||
| 参数| 含义| | 参数| 含义| | ||||
| --------- | ------- | ------- | | --------- | ------- | ------- | | ||||
| |create|创建分支或标签| | |create|创建分支或标签| | ||||
| |delete|分支或标签删除| | |delete|分支或标签删除| | ||||
| |fork|仓库被fork| | |||||
| |push|git仓库推送| | |push|git仓库推送| | ||||
| |issue|疑修已打开、已关闭、已重新打开或编辑| | |||||
| |issue_assign|疑修被指派| | |||||
| |issue_label|疑修标签被更新或删除| | |||||
| |issue_milestone|疑修被收入里程碑| | |||||
| |issue_comment|疑修评论| | |||||
| |pull_request|合并请求| | |pull_request|合并请求| | ||||
| |pull_request_assign|合并请求被指派| | |pull_request_assign|合并请求被指派| | ||||
| |pull_request_label|合并请求被贴上标签| | |||||
| |pull_request_milestone|合并请求被记录于里程碑中| | |||||
| |pull_request_comment|合并请求被评论| | |||||
| |pull_request_review_approved|合并请求被批准| | |pull_request_review_approved|合并请求被批准| | ||||
| |pull_request_review_rejected|合并请求被拒绝| | |pull_request_review_rejected|合并请求被拒绝| | ||||
| |pull_request_review_comment|合并请求被提出审查意见| | |||||
| |pull_request_sync|合并请求被同步| | |||||
| |repository|创建或删除仓库| | |||||
| |release|版本发布| | |||||
| > 返回的JSON示例: | > 返回的JSON示例: | ||||
| @@ -1266,31 +1246,15 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json') | |||||
| "http_method": "GET", | "http_method": "GET", | ||||
| "content_type": "form", | "content_type": "form", | ||||
| "url": "http://localhost:3000", | "url": "http://localhost:3000", | ||||
| "secret": "123456", | |||||
| "last_status": "succeed", | |||||
| "is_active": true, | |||||
| "type": "gitea", | |||||
| "create_time": "2021-07-26 10:03:45", | |||||
| "active": true, | |||||
| "create_at": "2021-07-26 10:03", | |||||
| "branch_filter": "*", | "branch_filter": "*", | ||||
| "events": [ | "events": [ | ||||
| "create", | "create", | ||||
| "delete", | "delete", | ||||
| "fork", | |||||
| "issues", | |||||
| "issue_assign", | |||||
| "issue_label", | |||||
| "issue_milestone", | |||||
| "issue_comment", | |||||
| "push", | "push", | ||||
| "pull_request", | "pull_request", | ||||
| "pull_request_assign", | "pull_request_assign", | ||||
| "pull_request_label", | |||||
| "pull_request_milestone", | |||||
| "pull_request_comment", | |||||
| "pull_request_review", | |||||
| "pull_request_sync", | |||||
| "repository", | |||||
| "release" | |||||
| ] | ] | ||||
| } | } | ||||
| ``` | ``` | ||||
| @@ -1305,15 +1269,15 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json') | |||||
| ```shell | ```shell | ||||
| curl -X POST \ | curl -X POST \ | ||||
| http://localhost:3000/api/yystopf/ceshi/webhooks.json | |||||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks.json | |||||
| ``` | ``` | ||||
| ```javascript | ```javascript | ||||
| await octokit.request('POST /api/yystopf/ceshi/webhooks.json') | |||||
| await octokit.request('POST /api/v1/yystopf/ceshi/webhooks.json') | |||||
| ``` | ``` | ||||
| ### HTTP 请求 | ### HTTP 请求 | ||||
| `POST /api/:owner/:repo/webhooks.json` | |||||
| `POST /api/v1/:owner/:repo/webhooks.json` | |||||
| ### 请求参数: | ### 请求参数: | ||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | 参数 | 必选 | 默认 | 类型 | 字段说明 | ||||
| @@ -1321,7 +1285,6 @@ await octokit.request('POST /api/yystopf/ceshi/webhooks.json') | |||||
| |owner |是| | string |用户登录名 | | |owner |是| | string |用户登录名 | | ||||
| |repo |是| | string |项目标识identifier | | |repo |是| | string |项目标识identifier | | ||||
| |webhook.url |是| | string |目标url | | |webhook.url |是| | string |目标url | | ||||
| |webhook.type |否| | string |类型| | |||||
| |webhook.http_method |是| | string | http方法, POST和GET | | |webhook.http_method |是| | string | http方法, POST和GET | | ||||
| |webhook.content_type |是| | string | POST Content Type | | |webhook.content_type |是| | string | POST Content Type | | ||||
| |webhook.secret |否| | string |密钥文本| | |webhook.secret |否| | string |密钥文本| | ||||
| @@ -1335,24 +1298,11 @@ await octokit.request('POST /api/yystopf/ceshi/webhooks.json') | |||||
| --------- | ------- | ------- | | --------- | ------- | ------- | | ||||
| |create|创建分支或标签| | |create|创建分支或标签| | ||||
| |delete|分支或标签删除| | |delete|分支或标签删除| | ||||
| |fork|仓库被fork| | |||||
| |push|git仓库推送| | |push|git仓库推送| | ||||
| |issue|疑修已打开、已关闭、已重新打开或编辑| | |||||
| |issue_assign|疑修被指派| | |||||
| |issue_label|疑修标签被更新或删除| | |||||
| |issue_milestone|疑修被收入里程碑| | |||||
| |issue_comment|疑修评论| | |||||
| |pull_request|合并请求| | |pull_request|合并请求| | ||||
| |pull_request_assign|合并请求被指派| | |pull_request_assign|合并请求被指派| | ||||
| |pull_request_label|合并请求被贴上标签| | |||||
| |pull_request_milestone|合并请求被记录于里程碑中| | |||||
| |pull_request_comment|合并请求被评论| | |||||
| |pull_request_review_approved|合并请求被批准| | |pull_request_review_approved|合并请求被批准| | ||||
| |pull_request_review_rejected|合并请求被拒绝| | |pull_request_review_rejected|合并请求被拒绝| | ||||
| |pull_request_review_comment|合并请求被提出审查意见| | |||||
| |pull_request_sync|合并请求被同步| | |||||
| |repository|创建或删除仓库| | |||||
| |release|版本发布| | |||||
| > 请求的JSON示例: | > 请求的JSON示例: | ||||
| @@ -1385,15 +1335,22 @@ await octokit.request('POST /api/yystopf/ceshi/webhooks.json') | |||||
| ```json | ```json | ||||
| { | { | ||||
| "id": 18, | |||||
| "type": "gitea", | |||||
| "id": 68, | |||||
| "content_type": "json", | "content_type": "json", | ||||
| "url": "http://localhost:10000", | |||||
| "http_method": "GET", | |||||
| "url": "http://127.0.0.1:3000", | |||||
| "events": [ | "events": [ | ||||
| "push" | |||||
| "create", | |||||
| "delete", | |||||
| "push", | |||||
| "pull_request", | |||||
| "pull_request_assign", | |||||
| "pull_request_review_approved", | |||||
| "pull_request_review_rejected" | |||||
| ], | ], | ||||
| "active": true, | "active": true, | ||||
| "create_time": "2021-07-26 18:53:43" | |||||
| "branch_filter": "*", | |||||
| "created_at": "2022-06-23 15:52" | |||||
| } | } | ||||
| ``` | ``` | ||||
| <aside class="success"> | <aside class="success"> | ||||
| @@ -1407,15 +1364,15 @@ await octokit.request('POST /api/yystopf/ceshi/webhooks.json') | |||||
| ```shell | ```shell | ||||
| curl -X PATCH \ | curl -X PATCH \ | ||||
| http://localhost:3000/api/yystopf/ceshi/webhooks/7.json | |||||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks/7.json | |||||
| ``` | ``` | ||||
| ```javascript | ```javascript | ||||
| await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json') | |||||
| await octokit.request('PATCH /api/v1/yystopf/ceshi/webhooks/7.json') | |||||
| ``` | ``` | ||||
| ### HTTP 请求 | ### HTTP 请求 | ||||
| `PATCH /api/:owner/:repo/webhooks/:id.json` | |||||
| `PATCH /api/v1/:owner/:repo/webhooks/68.json` | |||||
| ### 请求参数: | ### 请求参数: | ||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | 参数 | 必选 | 默认 | 类型 | 字段说明 | ||||
| @@ -1424,7 +1381,6 @@ await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json') | |||||
| |repo |是| | string |项目标识identifier | | |repo |是| | string |项目标识identifier | | ||||
| |id |是| | string |webhook id | | |id |是| | string |webhook id | | ||||
| |webhook.url |是| | string |目标url | | |webhook.url |是| | string |目标url | | ||||
| |webhook.type |否| | string |类型| | |||||
| |webhook.http_method |是| | string | http方法, POST和GET | | |webhook.http_method |是| | string | http方法, POST和GET | | ||||
| |webhook.content_type |是| | string | POST Content Type | | |webhook.content_type |是| | string | POST Content Type | | ||||
| |webhook.secret |否| | string |密钥文本| | |webhook.secret |否| | string |密钥文本| | ||||
| @@ -1438,24 +1394,11 @@ await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json') | |||||
| --------- | ------- | ------- | | --------- | ------- | ------- | | ||||
| |create|创建分支或标签| | |create|创建分支或标签| | ||||
| |delete|分支或标签删除| | |delete|分支或标签删除| | ||||
| |fork|仓库被fork| | |||||
| |push|git仓库推送| | |push|git仓库推送| | ||||
| |issue|疑修已打开、已关闭、已重新打开或编辑| | |||||
| |issue_assign|疑修被指派| | |||||
| |issue_label|疑修标签被更新或删除| | |||||
| |issue_milestone|疑修被收入里程碑| | |||||
| |issue_comment|疑修评论| | |||||
| |pull_request|合并请求| | |pull_request|合并请求| | ||||
| |pull_request_assign|合并请求被指派| | |pull_request_assign|合并请求被指派| | ||||
| |pull_request_label|合并请求被贴上标签| | |||||
| |pull_request_milestone|合并请求被记录于里程碑中| | |||||
| |pull_request_comment|合并请求被评论| | |||||
| |pull_request_review_approved|合并请求被批准| | |pull_request_review_approved|合并请求被批准| | ||||
| |pull_request_review_rejected|合并请求被拒绝| | |pull_request_review_rejected|合并请求被拒绝| | ||||
| |pull_request_review_comment|合并请求被提出审查意见| | |||||
| |pull_request_sync|合并请求被同步| | |||||
| |repository|创建或删除仓库| | |||||
| |release|版本发布| | |||||
| > 请求的JSON示例: | > 请求的JSON示例: | ||||
| @@ -1478,8 +1421,22 @@ await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json') | |||||
| ```json | ```json | ||||
| { | { | ||||
| "status": 0, | |||||
| "message": "success" | |||||
| "id": 68, | |||||
| "content_type": "json", | |||||
| "http_method": "GET", | |||||
| "url": "http://127.0.0.1:3000", | |||||
| "events": [ | |||||
| "create", | |||||
| "delete", | |||||
| "push", | |||||
| "pull_request", | |||||
| "pull_request_assign", | |||||
| "pull_request_review_approved", | |||||
| "pull_request_review_rejected" | |||||
| ], | |||||
| "active": true, | |||||
| "branch_filter": "*", | |||||
| "created_at": "2022-06-23 15:52" | |||||
| } | } | ||||
| ``` | ``` | ||||
| <aside class="success"> | <aside class="success"> | ||||
| @@ -1494,15 +1451,15 @@ await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json') | |||||
| ```shell | ```shell | ||||
| curl -X DELETE \ | curl -X DELETE \ | ||||
| http://localhost:3000/api/yystopf/ceshi/webhooks/7.json | |||||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks/7.json | |||||
| ``` | ``` | ||||
| ```javascript | ```javascript | ||||
| await octokit.request('DELETE /api/yystopf/ceshi/webhooks/7.json') | |||||
| await octokit.request('DELETE /api/v1/yystopf/ceshi/webhooks/7.json') | |||||
| ``` | ``` | ||||
| ### HTTP 请求 | ### HTTP 请求 | ||||
| `DELETE /api/:owner/:repo/webhooks/:id.json` | |||||
| `DELETE /api/v1/:owner/:repo/webhooks/:id.json` | |||||
| ### 请求参数: | ### 请求参数: | ||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | 参数 | 必选 | 默认 | 类型 | 字段说明 | ||||
| @@ -1532,15 +1489,15 @@ await octokit.request('DELETE /api/yystopf/ceshi/webhooks/7.json') | |||||
| ```shell | ```shell | ||||
| curl -X GET \ | curl -X GET \ | ||||
| http://localhost:3000/api/yystopf/ceshi/webhooks/3/tasks.json | |||||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3/hooktasks.json | |||||
| ``` | ``` | ||||
| ```javascript | ```javascript | ||||
| await octokit.request('GET /api/yystopf/ceshi/webhooks/3/tasks.json') | |||||
| await octokit.request('GET /api/v1/yystopf/ceshi/webhooks/3/hooktasks.json') | |||||
| ``` | ``` | ||||
| ### HTTP 请求 | ### HTTP 请求 | ||||
| `GET /api/:owner/:repo/webhooks/:id/tasks.json` | |||||
| `GET /api/v1/:owner/:repo/webhooks/:id/hooktasks.json` | |||||
| ### 请求参数: | ### 请求参数: | ||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | 参数 | 必选 | 默认 | 类型 | 字段说明 | ||||
| @@ -1568,7 +1525,7 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks/3/tasks.json') | |||||
| ```json | ```json | ||||
| { | { | ||||
| "total_count": 6, | "total_count": 6, | ||||
| "tasks": [ | |||||
| "hooktasks": [ | |||||
| { | { | ||||
| "id": 20, | "id": 20, | ||||
| "type": "gitea", | "type": "gitea", | ||||
| @@ -1744,15 +1701,15 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks/3/tasks.json') | |||||
| ```shell | ```shell | ||||
| curl -X POST \ | curl -X POST \ | ||||
| http://localhost:3000/api/yystopf/ceshi/webhooks/3/test.json | |||||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3/tests.json | |||||
| ``` | ``` | ||||
| ```javascript | ```javascript | ||||
| await octokit.request('POST /api/yystopf/ceshi/webhooks/3/test.json') | |||||
| await octokit.request('POST /api/v1/yystopf/ceshi/webhooks/3/tests.json') | |||||
| ``` | ``` | ||||
| ### HTTP 请求 | ### HTTP 请求 | ||||
| `POST /api/:owner/:repo/webhooks/:id/test.json` | |||||
| `POST /api/v1/:owner/:repo/webhooks/:id/tests.json` | |||||
| ### 请求参数: | ### 请求参数: | ||||
| 参数 | 必选 | 默认 | 类型 | 字段说明 | 参数 | 必选 | 默认 | 类型 | 字段说明 | ||||
| @@ -47,6 +47,105 @@ await octokit.request('GET /api/users/me.json') | |||||
| Success Data. | Success Data. | ||||
| </aside> | </aside> | ||||
| ## 用户项目列表 | |||||
| 获取用户项目列表 | |||||
| > 示例: | |||||
| ```shell | |||||
| curl -X GET http://localhost:3000/api/v1/:login/projects.json | |||||
| ``` | |||||
| ```javascript | |||||
| await octokit.request('GET /api/v1/:login/projects.json') | |||||
| ``` | |||||
| ### HTTP 请求 | |||||
| `GET api/v1/yystopf/projects.json` | |||||
| ### 请求字段说明: | |||||
| 参数 | 类型 | 字段说明 | |||||
| --------- | ----------- | ----------- | |||||
| |login | string | 用户的用户名| | |||||
| |category | string | 归属项目,默认为全部项目, join: 参与项目, created: 创建项目, manage: 管理项目, watched: 关注项目, forked: 复刻项目 | | |||||
| |is_public | boolean | 公/私有项目,true为公开项目,false为私有项目| | |||||
| |project_type | string | 项目类型,common为托管项目, mirror为镜像项目, sync_mirror为同步镜像项目| | |||||
| |sort_by | string | 项目的排序字段,比如 created_on, updated_on等| | |||||
| |sort_direction | string | 排序的类型,desc 倒序,asc 正序| | |||||
| |limit | integer | 每页个数 | | |||||
| |page | integer | 页码 | | |||||
| ### 返回字段说明: | |||||
| 参数 | 类型 | 字段说明 | |||||
| --------- | ----------- | ----------- | |||||
| |total_count | integer | 项目总数 | | |||||
| |projects.owner.id | integer | 项目拥有者id | | |||||
| |projects.owner.type | string | 项目拥有者类型,User 用户,Organization 组织 | | |||||
| |projects.owner.name | string | 项目拥有者名称| | |||||
| |projects.owner.login | string | 项目拥有者用户名 | | |||||
| |projects.owner.image_url | string | 项目拥有者头像地址 | | |||||
| |type | string | 项目类型,common 托管项目,mirror 镜像项目, sync 同步镜像项目 | | |||||
| |description | string | 项目描述 | | |||||
| |forked_count | integer | 项目复刻数量 | | |||||
| |forked_from_project_id | integer | 项目复刻来源项目 | | |||||
| |identifier | string | 项目标识 | | |||||
| |issues_count | integer | 项目issues数量| | |||||
| |pull_requests_count | integer | 项目合并请求数量 | | |||||
| |invite_code | string | 项目邀请码| | |||||
| |website | string | 项目网址| | |||||
| |platform | string | 项目平台 | | |||||
| |name | string | 项目名称| | |||||
| |open_devops | boolean | 项目是否开启工作流 | | |||||
| |praises_count | integer | 项目点赞数量| | |||||
| |is_public | boolean | 项目是否公开| | |||||
| |status | integer | 项目状态| | |||||
| |watchers_count | integer | 项目关注数量| | |||||
| |ignore_id | integer | 项目ignoreID| | |||||
| |license_id | integer | 项目许可证ID| | |||||
| |project_category_id | integer | 项目分类ID| | |||||
| |project_language_id | integer | 项目语言ID| | |||||
| > 返回的JSON示例: | |||||
| ```json | |||||
| "total_count": 1, | |||||
| "projects": [ | |||||
| { | |||||
| "owner": { | |||||
| "id": 2, | |||||
| "type": "User", | |||||
| "name": "heh", | |||||
| "login": "yystopf", | |||||
| "image_url": "system/lets/letter_avatars/2/H/188_239_142/120.png" | |||||
| }, | |||||
| "type": "common", | |||||
| "description": null, | |||||
| "forked_count": 1, | |||||
| "forked_from_project_id": null, | |||||
| "identifier": "hahahah", | |||||
| "issues_count": 5, | |||||
| "pull_requests_count": 3, | |||||
| "invite_code": "8zfKtM", | |||||
| "website": null, | |||||
| "platform": "forge", | |||||
| "name": "hahahah", | |||||
| "open_devops": false, | |||||
| "praises_count": 0, | |||||
| "is_public": true, | |||||
| "status": 1, | |||||
| "watchers_count": 0, | |||||
| "ignore_id": null, | |||||
| "license_id": null, | |||||
| "project_category_id": null, | |||||
| "project_language_id": null | |||||
| } | |||||
| ] | |||||
| ``` | |||||
| <aside class="success"> | |||||
| Success Data. | |||||
| </aside> | |||||
| ## 用户消息列表 | ## 用户消息列表 | ||||
| 获取用户消息列表 | 获取用户消息列表 | ||||
| @@ -30,7 +30,7 @@ module ProjectsHelper | |||||
| end | end | ||||
| def gitea_domain | def gitea_domain | ||||
| Gitea.gitea_config[:domain] | |||||
| GiteaService.gitea_config[:domain] | |||||
| end | end | ||||
| def find_user_by_login_or_mail(identifier) | def find_user_by_login_or_mail(identifier) | ||||
| @@ -103,7 +103,7 @@ module RepositoriesHelper | |||||
| end | end | ||||
| end | end | ||||
| # author hui.he | |||||
| # author hui.he | |||||
| def new_readme_render_decode64_content(str, owner, repo, ref, readme_path, readme_name) | 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}", '') | file_path = readme_path.include?('/') ? readme_path.gsub("/#{readme_name}", '') : readme_path.gsub("#{readme_name}", '') | ||||
| return nil if str.blank? | return nil if str.blank? | ||||
| @@ -120,8 +120,7 @@ module RepositoriesHelper | |||||
| # 链接直接跳过不做替换 | # 链接直接跳过不做替换 | ||||
| next if s_content.starts_with?('http://') || s_content.starts_with?('https://') || s_content.starts_with?('mailto:') || s_content.blank? | next if s_content.starts_with?('http://') || s_content.starts_with?('https://') || s_content.starts_with?('mailto:') || s_content.blank? | ||||
| ext = File.extname(s_content)[1..-1] | ext = File.extname(s_content)[1..-1] | ||||
| if (image_type?(ext) || download_type(ext)) && !s_content.to_s.end_with?('/') | |||||
| if (image_type?(ext) || download_type(ext)) && !ext.blank? | |||||
| s_content = File.expand_path(s_content, file_path) | s_content = File.expand_path(s_content, file_path) | ||||
| s_content = s_content.split("#{Rails.root}/")[1] | s_content = s_content.split("#{Rails.root}/")[1] | ||||
| # content = content.gsub(s[0], "/#{s_content}") | # content = content.gsub(s[0], "/#{s_content}") | ||||
| @@ -131,7 +130,7 @@ module RepositoriesHelper | |||||
| path = [owner&.login, repo&.identifier, 'tree', ref, file_path].join("/") | path = [owner&.login, repo&.identifier, 'tree', ref, file_path].join("/") | ||||
| s_content = File.expand_path(s_content, path) | s_content = File.expand_path(s_content, path) | ||||
| s_content = s_content.split("#{Rails.root}/")[1] | s_content = s_content.split("#{Rails.root}/")[1] | ||||
| content = content.gsub(s[0], "/#{s_content}") | |||||
| content = content.gsub('('+s[0]+')', '('+"/#{s_content}"+')') | |||||
| end | end | ||||
| rescue | rescue | ||||
| next | next | ||||
| @@ -44,8 +44,8 @@ module Gitea | |||||
| def token | def token | ||||
| { | { | ||||
| username: Gitea.gitea_config[:access_key_id], | |||||
| password: Gitea.gitea_config[:access_key_secret] | |||||
| username: GiteaService.gitea_config[:access_key_id], | |||||
| password: GiteaService.gitea_config[:access_key_secret] | |||||
| } | } | ||||
| end | end | ||||
| end | end | ||||
| @@ -37,7 +37,7 @@ class Ci::Drone::Server | |||||
| private | private | ||||
| def gitea_url | def gitea_url | ||||
| Gitea.gitea_config[:domain] | |||||
| GiteaService.gitea_config[:domain] | |||||
| end | end | ||||
| def database_username | def database_username | ||||
| @@ -1,4 +1,4 @@ | |||||
| module Gitea | |||||
| module GiteaService | |||||
| class << self | class << self | ||||
| def gitea_config | def gitea_config | ||||
| gitea_config = {} | gitea_config = {} | ||||
| @@ -69,6 +69,7 @@ class Issue < ApplicationRecord | |||||
| has_many :issue_tags, through: :issue_tags_relates | has_many :issue_tags, through: :issue_tags_relates | ||||
| has_many :issue_times, dependent: :destroy | has_many :issue_times, dependent: :destroy | ||||
| has_many :issue_depends, dependent: :destroy | has_many :issue_depends, dependent: :destroy | ||||
| has_many :reviews, dependent: :destroy | |||||
| scope :issue_includes, ->{includes(:user)} | scope :issue_includes, ->{includes(:user)} | ||||
| scope :issue_many_includes, ->{includes(journals: :user)} | scope :issue_many_includes, ->{includes(journals: :user)} | ||||
| scope :issue_issue, ->{where(issue_classify: [nil,"issue"])} | scope :issue_issue, ->{where(issue_classify: [nil,"issue"])} | ||||
| @@ -12,11 +12,13 @@ | |||||
| # parent_id :integer | # parent_id :integer | ||||
| # comments_count :integer default("0") | # comments_count :integer default("0") | ||||
| # reply_id :integer | # reply_id :integer | ||||
| # review_id :integer | |||||
| # | # | ||||
| # Indexes | # Indexes | ||||
| # | # | ||||
| # index_journals_on_created_on (created_on) | # index_journals_on_created_on (created_on) | ||||
| # index_journals_on_journalized_id (journalized_id) | # index_journals_on_journalized_id (journalized_id) | ||||
| # index_journals_on_review_id (review_id) | |||||
| # index_journals_on_user_id (user_id) | # index_journals_on_user_id (user_id) | ||||
| # journals_journalized_id (journalized_id,journalized_type) | # journals_journalized_id (journalized_id,journalized_type) | ||||
| # | # | ||||
| @@ -0,0 +1,27 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: reviews | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # issue_id :integer | |||||
| # reviewer_id :integer | |||||
| # content :text(65535) | |||||
| # commit_id :string(255) | |||||
| # status :integer default("0") | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_reviews_on_issue_id (issue_id) | |||||
| # index_reviews_on_reviewer_id (reviewer_id) | |||||
| # | |||||
| class Review < ApplicationRecord | |||||
| belongs_to :issue | |||||
| belongs_to :reviewer, class_name: 'User', foreign_key: :reviewer_id | |||||
| has_one :journal, dependent: :destroy | |||||
| enum status: {common: 0, approved: 1, rejected: 2} | |||||
| end | |||||
| @@ -0,0 +1,48 @@ | |||||
| class Api::V1::Projects::GetService < ApplicationService | |||||
| attr_reader :project, :token, :owner, :repo | |||||
| attr_accessor :gitea_data, :gitea_branch_tag_count | |||||
| def initialize(project, token=nil) | |||||
| @project = project | |||||
| @owner = project&.owner.login | |||||
| @repo = project&.identifier | |||||
| @token = token | |||||
| end | |||||
| def call | |||||
| $gitea_client.token = token unless token.blank? | |||||
| load_gitea_data | |||||
| load_gitea_branch_tag_count | |||||
| $gitea_client.token = nil unless token.blank? | |||||
| result_object | |||||
| rescue | |||||
| raise Error, "服务器错误,请联系系统管理员!" | |||||
| end | |||||
| private | |||||
| def result_object | |||||
| { | |||||
| full_name: "#{owner}/#{repo}", | |||||
| owner: project&.owner, | |||||
| ssh_url: gitea_data["ssh_url"], | |||||
| clone_url: gitea_data["clone_url"], | |||||
| size: gitea_data["size"], | |||||
| default_branch: gitea_data["default_branch"], | |||||
| empty: gitea_data["empty"], | |||||
| branch_count: gitea_branch_tag_count["branch_count"], | |||||
| tag_count: gitea_branch_tag_count["tag_count"], | |||||
| } | |||||
| end | |||||
| def load_gitea_data | |||||
| @gitea_data = $gitea_client.get_repos_by_owner_repo(owner, repo) | |||||
| end | |||||
| def load_gitea_branch_tag_count | |||||
| @gitea_branch_tag_count = $gitea_client.get_repos_branch_tag_count_by_owner_repo(owner, repo) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,40 @@ | |||||
| class Api::V1::Projects::PullRequests::Reviews::CreateService < ApplicationService | |||||
| include ActiveModel::Model | |||||
| attr_reader :project, :pull_request, :issue, :status, :commit_id, :content, :current_user | |||||
| attr_accessor :review, :journal | |||||
| validates :status, inclusion: { in: %w(common approved rejected), message: '请输入正确的Type'} | |||||
| def initialize(project, pull_request, params, current_user) | |||||
| @project = project | |||||
| @pull_request = pull_request | |||||
| @issue = pull_request&.issue | |||||
| @status = params[:status] | |||||
| @commit_id = params[:commit_id] | |||||
| @content = params[:content] | |||||
| @current_user = current_user | |||||
| end | |||||
| def call | |||||
| raise Error, errors.full_messages.join(", ") unless valid? | |||||
| ActiveRecord::Base.transaction do | |||||
| create_review | |||||
| create_journal | |||||
| end | |||||
| return @journal, @review | |||||
| rescue | |||||
| raise Error, '服务器错误,请联系系统管理员!' | |||||
| end | |||||
| private | |||||
| def create_review | |||||
| @review = issue.reviews.create!(status: status, content: content, commit_id: commit_id, reviewer_id: @current_user.id) | |||||
| end | |||||
| def create_journal | |||||
| @journal = issue.journals.create!(notes: content, user_id: @current_user.id, review_id: @review.id) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,60 @@ | |||||
| class Api::V1::Projects::Webhooks::CreateService < ApplicationService | |||||
| include ActiveModel::Model | |||||
| attr_reader :project, :token, :owner, :repo, :active, :branch_filter, :content_type, :url, :http_method, :secret, :events | |||||
| attr_accessor :gitea_data | |||||
| validates :url, format: { with: URI::regexp(%w[http https]), message: "请输入正确的地址" } | |||||
| validates :active, inclusion: {in: [true, false]} | |||||
| validates :http_method, inclusion: { in: %w(POST GET), message: "请输入正确的请求方式"} | |||||
| validates :content_type, inclusion: { in: %w(json form), message: "请输入正确的Content Type"} | |||||
| def initialize(project, params, token=nil) | |||||
| @project = project | |||||
| @owner = project&.owner.login | |||||
| @repo = project&.identifier | |||||
| @active = params[:active] | |||||
| @branch_filter = params[:branch_filter] | |||||
| @content_type = params[:content_type] | |||||
| @url = params[:url] | |||||
| @http_method = params[:http_method] | |||||
| @secret = params[:secret] | |||||
| @events = params[:events] | |||||
| @token = token | |||||
| end | |||||
| def call | |||||
| raise Error, errors.full_messages.join(",") unless valid? | |||||
| begin | |||||
| $gitea_client.token = token unless token.blank? | |||||
| excute_data_to_gitea | |||||
| $gitea_client.token = nil unless token.blank? | |||||
| gitea_data | |||||
| rescue | |||||
| raise Error, "服务器错误,请联系系统管理员!" | |||||
| end | |||||
| end | |||||
| private | |||||
| def request_body | |||||
| { | |||||
| active: active, | |||||
| branch_filter: branch_filter, | |||||
| config: { | |||||
| content_type: content_type, | |||||
| url: url, | |||||
| http_method: http_method, | |||||
| secret: secret | |||||
| }, | |||||
| events: events || [], | |||||
| type: 'gitea', | |||||
| } | |||||
| end | |||||
| def excute_data_to_gitea | |||||
| @gitea_data = $gitea_client.post_repos_hooks_by_owner_repo(owner, repo, {body: request_body.to_json}) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,30 @@ | |||||
| class Api::V1::Projects::Webhooks::DeleteService < ApplicationService | |||||
| attr_reader :project, :id, :token, :owner, :repo | |||||
| attr_accessor :gitea_data | |||||
| def initialize(project, id, token=nil) | |||||
| @project = project | |||||
| @id = id | |||||
| @owner = project&.owner.login | |||||
| @repo = project&.identifier | |||||
| @token = token | |||||
| end | |||||
| def call | |||||
| $gitea_client.token = token unless token.blank? | |||||
| excute_data_to_gitea | |||||
| $gitea_client.token = nil unless token.blank? | |||||
| gitea_data | |||||
| rescue | |||||
| raise Error, "服务器错误,请联系系统管理员!" | |||||
| end | |||||
| private | |||||
| def excute_data_to_gitea | |||||
| @gitea_data = $gitea_client.delete_repos_hooks_by_owner_repo_id(owner, repo, id) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,30 @@ | |||||
| class Api::V1::Projects::Webhooks::GetService < ApplicationService | |||||
| attr_reader :project, :id, :token, :owner, :repo | |||||
| attr_accessor :gitea_data | |||||
| def initialize(project, id, token=nil) | |||||
| @project = project | |||||
| @id = id | |||||
| @owner = project&.owner.login | |||||
| @repo = project&.identifier | |||||
| @token = token | |||||
| end | |||||
| def call | |||||
| $gitea_client.token = token unless token.blank? | |||||
| load_gitea_data | |||||
| $gitea_client.token = nil unless token.blank? | |||||
| gitea_data | |||||
| rescue | |||||
| raise Error, "服务器错误,请联系系统管理员!" | |||||
| end | |||||
| private | |||||
| def load_gitea_data | |||||
| @gitea_data = $gitea_client.get_repos_hooks_by_owner_repo_id(owner, repo, id) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,30 @@ | |||||
| class Api::V1::Projects::Webhooks::ListService < ApplicationService | |||||
| attr_reader :project, :id, :token, :owner, :repo | |||||
| attr_accessor :gitea_data | |||||
| def initialize(project, id, token=nil) | |||||
| @project = project | |||||
| @id = id | |||||
| @owner = project&.owner.login | |||||
| @repo = project&.identifier | |||||
| @token = token | |||||
| end | |||||
| def call | |||||
| $gitea_client.token = token unless token.blank? | |||||
| load_gitea_data | |||||
| $gitea_client.token = nil unless token.blank? | |||||
| gitea_data | |||||
| rescue | |||||
| raise Error, "服务器错误,请联系系统管理员!" | |||||
| end | |||||
| private | |||||
| def load_gitea_data | |||||
| @gitea_data = $gitea_client.get_repos_hooks_hooktasks_by_owner_repo(owner, repo, id) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,29 @@ | |||||
| class Api::V1::Projects::Webhooks::ListService < ApplicationService | |||||
| attr_reader :project, :token, :owner, :repo | |||||
| attr_accessor :gitea_data | |||||
| def initialize(project, token=nil) | |||||
| @project = project | |||||
| @owner = project&.owner.login | |||||
| @repo = project&.identifier | |||||
| @token = token | |||||
| end | |||||
| def call | |||||
| $gitea_client.token = token unless token.blank? | |||||
| load_gitea_data | |||||
| $gitea_client.token = nil unless token.blank? | |||||
| gitea_data | |||||
| rescue | |||||
| raise Error, "服务器错误,请联系系统管理员!" | |||||
| end | |||||
| private | |||||
| def load_gitea_data | |||||
| @gitea_data = $gitea_client.get_repos_hooks_by_owner_repo(owner, repo) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,30 @@ | |||||
| class Api::V1::Projects::Webhooks::TestsService < ApplicationService | |||||
| attr_reader :project, :id, :token, :owner, :repo | |||||
| attr_accessor :gitea_data | |||||
| def initialize(project, id, token=nil) | |||||
| @project = project | |||||
| @id = id | |||||
| @owner = project&.owner.login | |||||
| @repo = project&.identifier | |||||
| @token = token | |||||
| end | |||||
| def call | |||||
| $gitea_client.token = token unless token.blank? | |||||
| excute_data_to_gitea | |||||
| $gitea_client.token = nil unless token.blank? | |||||
| gitea_data | |||||
| rescue | |||||
| raise Error, "服务器错误,请联系系统管理员!" | |||||
| end | |||||
| private | |||||
| def excute_data_to_gitea | |||||
| @gitea_data = $gitea_client.post_repos_hooks_tests_by_owner_repo_id(owner, repo, id) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,61 @@ | |||||
| class Api::V1::Projects::Webhooks::UpdateService < ApplicationService | |||||
| include ActiveModel::Model | |||||
| attr_reader :project, :id, :token, :owner, :repo, :active, :branch_filter, :content_type, :url, :http_method, :secret, :events | |||||
| attr_accessor :gitea_data | |||||
| validates :url, format: { with: URI::regexp(%w[http https]), message: "请输入正确的地址" } | |||||
| validates :active, inclusion: {in: [true, false]} | |||||
| validates :http_method, inclusion: { in: %w(POST GET), message: "请输入正确的请求方式"} | |||||
| validates :content_type, inclusion: { in: %w(json form), message: "请输入正确的Content Type"} | |||||
| def initialize(project, id, params, token=nil) | |||||
| @project = project | |||||
| @id = id | |||||
| @owner = project&.owner.login | |||||
| @repo = project&.identifier | |||||
| @active = params[:active] | |||||
| @branch_filter = params[:branch_filter] | |||||
| @content_type = params[:content_type] | |||||
| @url = params[:url] | |||||
| @http_method = params[:http_method] | |||||
| @secret = params[:secret] | |||||
| @events = params[:events] | |||||
| @token = token | |||||
| end | |||||
| def call | |||||
| raise Error, errors.full_messages.join(",") unless valid? | |||||
| begin | |||||
| $gitea_client.token = token unless token.blank? | |||||
| excute_data_to_gitea | |||||
| $gitea_client.token = nil unless token.blank? | |||||
| gitea_data | |||||
| rescue | |||||
| raise Error, "服务器错误,请联系系统管理员!" | |||||
| end | |||||
| end | |||||
| private | |||||
| def request_body | |||||
| { | |||||
| active: active, | |||||
| branch_filter: branch_filter, | |||||
| config: { | |||||
| content_type: content_type, | |||||
| url: url, | |||||
| http_method: http_method, | |||||
| secret: secret | |||||
| }, | |||||
| events: events || [], | |||||
| type: 'gitea', | |||||
| } | |||||
| end | |||||
| def excute_data_to_gitea | |||||
| @gitea_data = $gitea_client.patch_repos_hooks_by_owner_repo_id(owner, repo, id, {body: request_body.to_json}) | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,86 @@ | |||||
| class Api::V1::Users::Projects::ListService < ApplicationService | |||||
| include ActiveModel::Model | |||||
| attr_reader :observe_user, :category, :is_public, :project_type, :sort_by, :sort_direction, :search, :current_user | |||||
| attr_accessor :queried_projects | |||||
| validates :category, inclusion: {in: %w(all join created manage watched forked), message: "请输入正确的Category"} | |||||
| validates :is_public, inclusion: {in: [true, false], message: '请输入正确的IsPublic'}, allow_nil: true | |||||
| validates :project_type, inclusion: {in: %w(common mirror sync_mirror), message: '请输入正确的ProjectType'}, allow_nil: true | |||||
| validates :sort_by, inclusion: {in: Project.column_names, message: '请输入正确的SortBy'} | |||||
| validates :sort_direction, inclusion: {in: %w(asc desc), message: '请输入正确的SortDirection'} | |||||
| def initialize(observe_user, params, current_user=nil) | |||||
| @observe_user = observe_user | |||||
| @category = params[:category] || 'all' | |||||
| @is_public = params[:is_public] | |||||
| @project_type = params[:project_type] | |||||
| @sort_by = params[:sort_by] || 'updated_on' | |||||
| @sort_direction = params[:sort_direction] || 'desc' | |||||
| @search = params[:search] | |||||
| @current_user = current_user | |||||
| end | |||||
| def call | |||||
| raise Error, errors.full_messages.join(", ") unless valid? | |||||
| begin | |||||
| project_query_data | |||||
| queried_projects | |||||
| rescue | |||||
| raise Error, "服务器错误,请联系系统管理员!" | |||||
| end | |||||
| end | |||||
| private | |||||
| def project_query_data | |||||
| if current_user.admin? | |||||
| projects = Project | |||||
| else | |||||
| projects = Project.visible | |||||
| end | |||||
| case category | |||||
| when 'join' | |||||
| normal_projects = projects.where.not(user_id: observe_user.id).members_projects(observe_user.id).to_sql | |||||
| org_projects = projects.joins(team_projects: [team: :team_users]).where(team_users: {user_id: observe_user.id}).to_sql | |||||
| projects = Project.from("( #{normal_projects} UNION #{org_projects} ) AS projects").distinct | |||||
| when 'created' | |||||
| projects = projects.where(user_id: observe_user.id) | |||||
| when 'manage' | |||||
| normal_projects = projects.joins(members: :roles).where(members: {user_id: observe_user.id}, roles: {name: 'Manager'}).to_sql | |||||
| org_projects = projects.joins(team_projects: [team: :team_users]).where(team_users: {user_id: observe_user.id}, teams: {authorize: %w(owner admin)}).to_sql | |||||
| projects = Project.from("( #{normal_projects} UNION #{org_projects} ) AS projects").distinct | |||||
| when 'watched' | |||||
| projects = projects.where.not(user_id: observe_user.id).joins(:watchers).where(watchers: {watchable_type: "Project", user_id: observe_user.id}) | |||||
| when 'forked' | |||||
| fork_ids = observe_user.fork_users.select(:id, :fork_project_id).pluck(:fork_project_id) | |||||
| projects = projects.where(id: fork_ids) | |||||
| else | |||||
| normal_projects = projects.members_projects(observe_user.id).to_sql | |||||
| org_projects = projects.joins(team_projects: [team: :team_users]).where(team_users: {user_id: observe_user.id}).to_sql | |||||
| projects = Project.from("( #{ normal_projects} UNION #{ org_projects } ) AS projects").distinct | |||||
| end | |||||
| unless is_public.nil? | |||||
| if is_public | |||||
| projects = projects.visible | |||||
| else | |||||
| projects = projects.is_private | |||||
| end | |||||
| end | |||||
| projects = projects.with_project_type(project_type) | |||||
| q = projects.ransack(name_or_identifier_cont: search) | |||||
| scope = q.result.includes(:project_category, :project_language,:owner, :repository, :has_pinned_users) | |||||
| scope = scope.order("projects.#{sort_by} #{sort_direction}") | |||||
| @queried_projects = scope | |||||
| end | |||||
| end | |||||
| @@ -81,7 +81,7 @@ class Educoder::ClientService < ApplicationService | |||||
| end | end | ||||
| def access_key_secret | def access_key_secret | ||||
| Gitea.gitea_config[:access_key_secret] | |||||
| GiteaService.gitea_config[:access_key_secret] | |||||
| end | end | ||||
| def api_url(url) | def api_url(url) | ||||
| @@ -56,7 +56,7 @@ class Gitea::Accelerator::BaseService < ApplicationService | |||||
| end | end | ||||
| def accelerator | def accelerator | ||||
| Gitea.gitea_config[:accelerator] | |||||
| GiteaService.gitea_config[:accelerator] | |||||
| end | end | ||||
| def render_status(response) | def render_status(response) | ||||
| @@ -96,11 +96,11 @@ class Gitea::ClientService < ApplicationService | |||||
| end | end | ||||
| def base_url | def base_url | ||||
| Gitea.gitea_config[:base_url] | |||||
| GiteaService.gitea_config[:base_url] | |||||
| end | end | ||||
| def domain | def domain | ||||
| Gitea.gitea_config[:domain] | |||||
| GiteaService.gitea_config[:domain] | |||||
| end | end | ||||
| def api_url | def api_url | ||||
| @@ -14,8 +14,8 @@ class Gitea::User::DeleteService < Gitea::ClientService | |||||
| private | private | ||||
| def token | def token | ||||
| { | { | ||||
| username: Gitea.gitea_config[:access_key_id], | |||||
| password: Gitea.gitea_config[:access_key_secret] | |||||
| username: GiteaService.gitea_config[:access_key_id], | |||||
| password: GiteaService.gitea_config[:access_key_secret] | |||||
| } | } | ||||
| end | end | ||||
| @@ -17,7 +17,7 @@ class Gitea::User::UpdateService < Gitea::ClientService | |||||
| # source_id integer($int64) | # source_id integer($int64) | ||||
| # website string | # website string | ||||
| def initialize(edit_username, params={}, token={username: Gitea.gitea_config[:access_key_id], password: Gitea.gitea_config[:access_key_secret]}) | |||||
| def initialize(edit_username, params={}, token={username: GiteaService.gitea_config[:access_key_id], password: GiteaService.gitea_config[:access_key_secret]}) | |||||
| @token = token | @token = token | ||||
| @params = params | @params = params | ||||
| @edit_username = edit_username | @edit_username = edit_username | ||||
| @@ -63,7 +63,7 @@ class Repositories::CreateService < ApplicationService | |||||
| end | end | ||||
| def remote_repository_url | def remote_repository_url | ||||
| [Gitea.gitea_config[:domain], '/', user.login, '/', params[:identifier], ".git"].join("") | |||||
| [GiteaService.gitea_config[:domain], '/', user.login, '/', params[:identifier], ".git"].join("") | |||||
| end | end | ||||
| def repository_params | def repository_params | ||||
| @@ -0,0 +1,10 @@ | |||||
| if project.present? | |||||
| json.type project.project_type | |||||
| json.(project, | |||||
| :description, :forked_count, :forked_from_project_id, :identifier, | |||||
| :issues_count, :pull_requests_count, :invite_code, :website, :platform, | |||||
| :name, :open_devops, :praises_count, :is_public, :status, :watchers_count, | |||||
| :ignore_id, :license_id, :project_category_id, :project_language_id) | |||||
| else | |||||
| json.nil! | |||||
| end | |||||
| @@ -0,0 +1,5 @@ | |||||
| json.owner do | |||||
| json.partial! "api/v1/users/simple_user", user: @result_object[:owner] | |||||
| end | |||||
| json.(@result_object, :full_name, :ssh_url, :clone_url, :default_branch, :empty, :branch_count, :tag_count) | |||||
| json.partial! "api/v1/projects/simple_detail", project: @project | |||||
| @@ -0,0 +1,3 @@ | |||||
| json.(webhook, :id, :url, :http_method, :is_active) | |||||
| json.last_status webhook.last_status | |||||
| json.create_time Time.at(webhook.created_unix).strftime("%Y-%m-%d %H:%M:%S") | |||||
| @@ -0,0 +1,8 @@ | |||||
| json.id webhook["id"] | |||||
| json.content_type webhook['config']['content_type'] | |||||
| json.http_method webhook['config']['http_method'] | |||||
| json.url webhook['config']['url'] | |||||
| json.events webhook['events'] | |||||
| json.active webhook['active'] | |||||
| json.branch_filter webhook['branch_filter'] | |||||
| json.created_at format_time(webhook['created_at'].to_time) | |||||
| @@ -0,0 +1 @@ | |||||
| json.partial! "api/v1/projects/webhooks/simple_gitea_detail", webhook: @result_object | |||||
| @@ -0,0 +1,6 @@ | |||||
| json.total_count @hooktasks.total_count | |||||
| json.hooktasks @hooktasks.each do |task| | |||||
| json.(task, :id, :event_type, :type, :uuid, :is_succeed, :is_delivered, :payload_content, :request_content) | |||||
| json.response_content task.response_content_json | |||||
| json.delivered_time Time.at(task.delivered*10**-9).strftime("%Y-%m-%d %H:%M:%S") | |||||
| end | |||||
| @@ -0,0 +1,4 @@ | |||||
| json.total_count @webhooks.total_count | |||||
| json.webhooks @webhooks do |webhook| | |||||
| json.partial! "api/v1/projects/webhooks/simple_detail", webhook: webhook | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| json.partial! "api/v1/projects/webhooks/simple_gitea_detail", webhook: @result_object | |||||
| @@ -0,0 +1 @@ | |||||
| json.partial! "api/v1/projects/webhooks/simple_gitea_detail", webhook: @result_object | |||||
| @@ -0,0 +1,9 @@ | |||||
| if user.present? | |||||
| json.id user.id | |||||
| json.type user.type | |||||
| json.name user.real_name | |||||
| json.login user.login | |||||
| json.image_url url_to_avatar(user) | |||||
| else | |||||
| json.nil! | |||||
| end | |||||
| @@ -0,0 +1,8 @@ | |||||
| json.total_count @projects.total_count | |||||
| json.projects @projects do |project| | |||||
| json.owner do | |||||
| json.partial! "api/v1/users/simple_user", user: project.owner | |||||
| end | |||||
| json.partial! "api/v1/projects/simple_detail", project: project | |||||
| end | |||||
| @@ -0,0 +1,141 @@ | |||||
| <!DOCTYPE html> | |||||
| <html> | |||||
| <head> | |||||
| <title>GitLink oauth2 认证</title> | |||||
| <meta charset="utf-8"> | |||||
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||||
| <%= javascript_include_tag :application, 'data-turbolinks-track': 'reload' %> | |||||
| <%= stylesheet_link_tag "doorkeeper/application" %> | |||||
| <%= csrf_meta_tags %> | |||||
| <%= yield(:css) if content_for?(:css) %> | |||||
| <style> | |||||
| body { | |||||
| margin: 0; | |||||
| color: rgba(0, 0, 0, .65); | |||||
| font-size: 14px; | |||||
| font-family: -apple-system, BlinkMacSystemFont, Segoe UI, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol; | |||||
| font-variant: tabular-nums; | |||||
| line-height: 1.5; | |||||
| background-color: #fff; | |||||
| -webkit-font-feature-settings: "tnum"; | |||||
| font-feature-settings: "tnum"; | |||||
| background: url(https://ali-cdn.educoder.net/react/build/static/media/beijintulogontwo.41076faf.png) center center / 100% 100% no-repeat fixed; | |||||
| height: 100%; | |||||
| width: 100%; | |||||
| position: absolute; | |||||
| top: 0px; | |||||
| bottom: 0px; | |||||
| min-height: 100%; | |||||
| padding-top: 40px; | |||||
| } | |||||
| #container { | |||||
| max-width: 500px; | |||||
| } | |||||
| .mt-20 { | |||||
| margin-top: 20px; | |||||
| } | |||||
| .login-form { | |||||
| margin-top: 10px; | |||||
| } | |||||
| .error { | |||||
| color: #ee4a1f; | |||||
| text-align: left; | |||||
| margin-bottom: 0px; | |||||
| min-height: 20px; | |||||
| } | |||||
| .app-name { | |||||
| color: #459be6; | |||||
| } | |||||
| .logo-wraper { | |||||
| text-align: center; | |||||
| } | |||||
| .auth-desc { | |||||
| margin: 20px; | |||||
| font-size: 20px; | |||||
| } | |||||
| .w { | |||||
| position: relative; | |||||
| width: 100%; | |||||
| max-width: 350px; | |||||
| margin: 0px auto; | |||||
| } | |||||
| .btn-login { | |||||
| width: 100%; | |||||
| text-align: center; | |||||
| color: #fff !important; | |||||
| display: block; | |||||
| background: #459be6; | |||||
| border-radius: 4px; | |||||
| letter-spacing: 2px; | |||||
| cursor: pointer; | |||||
| } | |||||
| input { | |||||
| font-family: "Monospaced Number", "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif; | |||||
| -webkit-box-sizing: border-box; | |||||
| box-sizing: border-box; | |||||
| margin: 0; | |||||
| padding: 0; | |||||
| list-style: none; | |||||
| position: relative; | |||||
| display: inline-block; | |||||
| padding: 4px 11px; | |||||
| width: 100%; | |||||
| height: 38px; | |||||
| font-size: 14px; | |||||
| line-height: 1.5; | |||||
| color: rgba(0, 0, 0, 0.65); | |||||
| width: 100%; | |||||
| background-color: #fff; | |||||
| height: 45px; | |||||
| padding: 5px; | |||||
| background-image: none; | |||||
| border: 1px solid #d9d9d9; | |||||
| border-radius: 4px; | |||||
| -webkit-transition: all .3s; | |||||
| -o-transition: all .3s; | |||||
| transition: all .3s; | |||||
| margin-top: 10px; | |||||
| } | |||||
| .reg { | |||||
| text-align: center; | |||||
| margin-top: 20px; | |||||
| } | |||||
| .reg-link { | |||||
| font-size: 18px; | |||||
| color: #999; | |||||
| } | |||||
| </style> | |||||
| </head> | |||||
| <body> | |||||
| <header class="page-header" role="banner"> | |||||
| <div class="logo-wraper"> | |||||
| <img src="https://www.gitlink.org.cn/images/avatars/LaboratorySetting/1nav?t=1638344455" style="cursor: pointer;width: 80px;"> | |||||
| </div> | |||||
| </header> | |||||
| <div id="container"> | |||||
| <%- if flash[:notice].present? %> | |||||
| <div class="alert alert-info"> | |||||
| <%= flash[:notice] %> | |||||
| </div> | |||||
| <% end -%> | |||||
| <%= yield %> | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,25 @@ | |||||
| <main role="main"> | |||||
| <p class="auth-desc"> | |||||
| 申请使用<strong class="app-name"> GitLink </strong>账号登录 | |||||
| <strong class="app-name"><%= @app&.name %></strong> | |||||
| </p> | |||||
| <div class="actions"> | |||||
| <div class="w"> | |||||
| <%= form_tag oauth2_path, method: :post, authenticity_token: true, remote: true, class: 'login-form' do %> | |||||
| <%= hidden_field_tag :client_id, @app.uid %> | |||||
| <%= hidden_field_tag :call_url, @call_url %> | |||||
| <p id="account_error" class='error'></p> | |||||
| <%= text_field_tag :login, '', placeholder: '请输入邮箱地址/用户名' %> | |||||
| <p id="login_error" class='error'></p> | |||||
| <%= password_field_tag :password, '', placeholder: '请输入密码'%> | |||||
| <p id="password_error" class='error'></p> | |||||
| <%= submit_tag '授权登录', class: "btn btn-login btn-lg btn-block mt-20" %> | |||||
| <% end %> | |||||
| <div class="reg"> | |||||
| <%= link_to "注 册", '/register', class: 'reg-link' %> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </main> | |||||
| @@ -7,6 +7,20 @@ json.commits_count @gitea_pull["commit_num"] | |||||
| json.files_count @gitea_pull["changed_files"] | json.files_count @gitea_pull["changed_files"] | ||||
| json.comments_count @issue.journals.parent_journals.size | json.comments_count @issue.journals.parent_journals.size | ||||
| json.comments_total_count @issue.get_journals_size | json.comments_total_count @issue.get_journals_size | ||||
| json.assign_user do | |||||
| json.partial! 'users/user_simple', user: @issue_assign_to | |||||
| end | |||||
| json.author do | |||||
| json.partial! 'users/user_simple', user: @issue_user | |||||
| end | |||||
| if @last_review.present? | |||||
| json.last_review do | |||||
| json.(@last_review, :id, :commit_id, :content, :status) | |||||
| json.created_at format_time(@last_review.created_at) | |||||
| end | |||||
| end | |||||
| json.pull_request do | json.pull_request do | ||||
| json.extract! @pull_request, :id,:base, :head, :status,:fork_project_id, :is_original | json.extract! @pull_request, :id,:base, :head, :status,:fork_project_id, :is_original | ||||
| @@ -0,0 +1,10 @@ | |||||
| json.issue do | |||||
| json.partial! 'pull_requests/detail', issue: @pull_request.issue | |||||
| end | |||||
| json.journal_id @journal.id | |||||
| json.journal_notes @journal.notes | |||||
| json.review_id @review.id | |||||
| json.commit_id @review.commit_id | |||||
| json.content @review.content | |||||
| json.status @review.status | |||||
| json.created_at format_time(@review.created_at) | |||||
| @@ -10,7 +10,7 @@ Doorkeeper.configure do | |||||
| # raise "Please configure doorkeeper resource_owner_authenticator block located in #{__FILE__}" | # raise "Please configure doorkeeper resource_owner_authenticator block located in #{__FILE__}" | ||||
| # Put your resource owner authentication logic here. | # Put your resource owner authentication logic here. | ||||
| # Example implementation: | # Example implementation: | ||||
| User.find_by(id: session[:www_user_id]) || redirect_to(new_user_session_url) | |||||
| User.find_by(login: params[:auth]) || redirect_to("/oauth2?call_url=#{request.fullpath}") | |||||
| end | end | ||||
| resource_owner_from_credentials do |routes| | resource_owner_from_credentials do |routes| | ||||
| @@ -21,7 +21,7 @@ Doorkeeper.configure do | |||||
| admin_authenticator do | admin_authenticator do | ||||
| user = User.find_by_id(session[:www_user_id]) | user = User.find_by_id(session[:www_user_id]) | ||||
| unless user #&& user.admin_or_business? | |||||
| unless user && user.admin_or_business? | |||||
| redirect_to root_url | redirect_to root_url | ||||
| end | end | ||||
| end | end | ||||
| @@ -242,8 +242,8 @@ Doorkeeper.configure do | |||||
| # For more information go to | # For more information go to | ||||
| # https://doorkeeper.gitbook.io/guides/ruby-on-rails/scopes | # https://doorkeeper.gitbook.io/guides/ruby-on-rails/scopes | ||||
| # | # | ||||
| # default_scopes :public | |||||
| # optional_scopes :write, :update | |||||
| default_scopes :public | |||||
| optional_scopes :write, :update | |||||
| # Allows to restrict only certain scopes for grant_type. | # Allows to restrict only certain scopes for grant_type. | ||||
| # By default, all the scopes will be available for all the grant types. | # By default, all the scopes will be available for all the grant types. | ||||
| @@ -516,7 +516,7 @@ Doorkeeper::JWT.configure do | |||||
| user = User.find(opts[:resource_owner_id]) | user = User.find(opts[:resource_owner_id]) | ||||
| { | { | ||||
| iss: 'My App', | |||||
| iss: 'GitLink', | |||||
| iat: Time.current.utc.to_i, | iat: Time.current.utc.to_i, | ||||
| # @see JWT reserved claims - https://tools.ietf.org/html/draft-jones-json-web-token-07#page-7 | # @see JWT reserved claims - https://tools.ietf.org/html/draft-jones-json-web-token-07#page-7 | ||||
| @@ -0,0 +1,11 @@ | |||||
| require 'gitea-client' | |||||
| config = Rails.application.config_for(:configuration).symbolize_keys! | |||||
| gitea_config = config[:gitea].symbolize_keys! | |||||
| $gitea_client = Gitea::Api::Client.new({ | |||||
| domain: gitea_config[:domain], | |||||
| base_url: gitea_config[:base_url], | |||||
| username: gitea_config[:username], | |||||
| password: gitea_config[:password] | |||||
| }) | |||||
| @@ -1,5 +1,11 @@ | |||||
| Rails.application.routes.draw do | Rails.application.routes.draw do | ||||
| def draw(routes_name) | |||||
| instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb"))) | |||||
| end | |||||
| draw :api | |||||
| use_doorkeeper | use_doorkeeper | ||||
| require 'sidekiq/web' | require 'sidekiq/web' | ||||
| require 'sidekiq/cron/web' | require 'sidekiq/cron/web' | ||||
| @@ -22,6 +28,9 @@ Rails.application.routes.draw do | |||||
| get 'oauth/register', to: 'oauth#register' | get 'oauth/register', to: 'oauth#register' | ||||
| post 'oauth/auto_register', to: 'oauth#auto_register' | post 'oauth/auto_register', to: 'oauth#auto_register' | ||||
| get 'oauth2', to: 'oauth2#show' | |||||
| post 'oauth2', to: 'oauth2#create' | |||||
| resources :edu_settings | resources :edu_settings | ||||
| scope '/api' do | scope '/api' do | ||||
| @@ -547,6 +556,7 @@ Rails.application.routes.draw do | |||||
| post :refuse_merge | post :refuse_merge | ||||
| get :files | get :files | ||||
| get :commits | get :commits | ||||
| resources :reviews, only: [:create] | |||||
| end | end | ||||
| collection do | collection do | ||||
| post :check_can_merge | post :check_can_merge | ||||
| @@ -0,0 +1,36 @@ | |||||
| defaults format: :json do | |||||
| namespace :api do | |||||
| namespace :v1 do | |||||
| scope ':owner' do | |||||
| resource :users, path: '/', only: [:show, :update, :edit, :destroy] | |||||
| scope module: :users do | |||||
| resources :projects, only: [:index] | |||||
| end | |||||
| scope ':repo' do | |||||
| # projects | |||||
| resource :projects, path: '/', only: [:show, :update, :edit, :destroy] | |||||
| # projects文件夹下的 | |||||
| scope module: :projects do | |||||
| resources :issues | |||||
| resources :pull_requests | |||||
| resources :versions | |||||
| resources :release_versions | |||||
| resources :webhooks do | |||||
| member do | |||||
| post :tests | |||||
| get :hooktasks | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| resources :projects, only: [:index] | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,15 @@ | |||||
| class CreateReviews < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :reviews do |t| | |||||
| t.references :issue | |||||
| t.references :reviewer | |||||
| t.text :content | |||||
| t.string :commit_id | |||||
| t.integer :status, default: 0 | |||||
| t.timestamps | |||||
| end | |||||
| add_reference :journals, :review | |||||
| end | |||||
| end | |||||
| @@ -128,7 +128,7 @@ namespace :sync_data_to_gitea do | |||||
| end | end | ||||
| def remote_repository_url(username, identifier) | def remote_repository_url(username, identifier) | ||||
| [Gitea.gitea_config[:domain], '/', username, '/', identifier, ".git"].join("") | |||||
| [GiteaService.gitea_config[:domain], '/', username, '/', identifier, ".git"].join("") | |||||
| end | end | ||||
| def generate_identifier | def generate_identifier | ||||
| @@ -0,0 +1,5 @@ | |||||
| require 'rails_helper' | |||||
| RSpec.describe Review, type: :model do | |||||
| pending "add some examples to (or delete) #{__FILE__}" | |||||
| end | |||||