| @@ -134,3 +134,5 @@ gem 'jwt' | |||
| gem 'doorkeeper' | |||
| 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,弹试用申请弹框 | |||
| def require_login | |||
| #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? | |||
| end | |||
| @@ -266,11 +269,11 @@ class ApplicationController < ActionController::Base | |||
| 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? | |||
| url = URI.encode(params[:download_url].to_s.gsub("http:", "https:")) | |||
| 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('&', '?') | |||
| request_url = [domain, api_url, url, "?ref=#{params[:ref]}&access_token=#{current_user&.gitea_token}"].join | |||
| response = Faraday.get(request_url) | |||
| @@ -6,9 +6,14 @@ class CompareController < ApplicationController | |||
| end | |||
| 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_limit = page_limit <=0 ? 15 : page_limit | |||
| @page_offset = (@page_size -1) * @page_limit | |||
| @@ -18,15 +18,15 @@ module Acceleratorable | |||
| end | |||
| def accelerator_domain | |||
| Gitea.gitea_config[:accelerator]["domain"] | |||
| GiteaService.gitea_config[:accelerator]["domain"] | |||
| end | |||
| def accelerator_username | |||
| Gitea.gitea_config[:accelerator]["access_key_id"] | |||
| GiteaService.gitea_config[:accelerator]["access_key_id"] | |||
| end | |||
| def config_accelerator? | |||
| Gitea.gitea_config[:accelerator].present? | |||
| GiteaService.gitea_config[:accelerator].present? | |||
| end | |||
| 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)) | |||
| if interactor.success? | |||
| Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########" | |||
| user.update_column(:is_sync_pwd, true) | |||
| true | |||
| else | |||
| 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, | |||
| @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 | |||
| # 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 | |||
| 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 | |||
| 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) | |||
| @@ -176,6 +181,7 @@ class PullRequestsController < ApplicationController | |||
| @issue_assign_to = @issue.get_assign_user | |||
| @gitea_pull = Gitea::PullRequest::GetService.call(@owner.login, | |||
| @repository.identifier, @pull_request.gitea_number, current_user&.gitea_token) | |||
| @last_review = @pull_request.issue.reviews.take | |||
| end | |||
| def pr_merge | |||
| @@ -9,7 +9,7 @@ class RepositoriesController < ApplicationController | |||
| before_action :load_repository | |||
| before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive] | |||
| before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror] | |||
| before_action :get_ref, only: %i[entries sub_entries top_counts file archive] | |||
| before_action :get_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_statistics, only: %i[top_counts] | |||
| @@ -54,7 +54,7 @@ class RepositoriesController < ApplicationController | |||
| else | |||
| @entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call | |||
| @entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : [] | |||
| @path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/" | |||
| @path = GiteaService.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/" | |||
| end | |||
| end | |||
| @@ -99,7 +99,7 @@ class RepositoriesController < ApplicationController | |||
| end | |||
| end | |||
| 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) | |||
| if interactor.success? | |||
| result = interactor.result | |||
| @@ -222,7 +222,7 @@ class RepositoriesController < ApplicationController | |||
| else | |||
| result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token) | |||
| end | |||
| @path = Gitea.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/" | |||
| @path = GiteaService.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) | |||
| @readme['replace_content'] = readme_decode64_content(@readme, @owner, @repository, params[:ref], @path) | |||
| @@ -240,8 +240,8 @@ class RepositoriesController < ApplicationController | |||
| end | |||
| 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])}" | |||
| file_path = [domain, api_url, archive_url].join | |||
| @@ -253,8 +253,8 @@ class RepositoriesController < ApplicationController | |||
| end | |||
| 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])}" | |||
| 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 | |||
| curl -X GET \ | |||
| http://localhost:3000/api/yystopf/ceshi/webhooks.json | |||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks.json | |||
| ``` | |||
| ```javascript | |||
| await octokit.request('GET /api/yystopf/ceshi/webhooks.json') | |||
| await octokit.request('GET /api/v1/yystopf/ceshi/webhooks.json') | |||
| ``` | |||
| ### 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|地址| | |||
| |http_method |string|请求方式| | |||
| |is_active |bool |是否激活| | |||
| |type |string|类型| | |||
| |last_status |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", | |||
| "http_method": "", | |||
| "is_active": true, | |||
| "type": "dingtalk", | |||
| "last_status": "succeed", | |||
| "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", | |||
| "http_method": "GET", | |||
| "is_active": true, | |||
| "type": "gitea", | |||
| "last_status": "succeed", | |||
| "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", | |||
| "http_method": "POST", | |||
| "is_active": true, | |||
| "type": "gitea", | |||
| "last_status": "waiting", | |||
| "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", | |||
| "http_method": "POST", | |||
| "is_active": true, | |||
| "type": "gitea", | |||
| "last_status": "fail", | |||
| "create_time": "2021-07-26 16:58:23" | |||
| } | |||
| @@ -1200,15 +1195,15 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks.json') | |||
| ```shell | |||
| curl -X GET \ | |||
| http://localhost:3000/api/yystopf/ceshi/webhooks/3/edit.json | |||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks/3.json | |||
| ``` | |||
| ```javascript | |||
| await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json') | |||
| await octokit.request('GET /api/v1/yystopf/ceshi/webhooks/3.json') | |||
| ``` | |||
| ### 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| | |||
| |http_method |string|请求方式| | |||
| |secret| |string|密钥| | |||
| |is_active |bool |是否激活| | |||
| |type |string|类型| | |||
| |last_status |string|最后一次推送的状态, waiting 等待,fail 失败,succeed 成功| | |||
| |active |bool |是否激活| | |||
| |branch_filter |string|分支过滤| | |||
| |events |string|触发条件| | |||
| |create_time |string|创建时间| | |||
| |create_at |string|创建时间| | |||
| 参数| 含义| | |||
| --------- | ------- | ------- | | |||
| |create|创建分支或标签| | |||
| |delete|分支或标签删除| | |||
| |fork|仓库被fork| | |||
| |push|git仓库推送| | |||
| |issue|疑修已打开、已关闭、已重新打开或编辑| | |||
| |issue_assign|疑修被指派| | |||
| |issue_label|疑修标签被更新或删除| | |||
| |issue_milestone|疑修被收入里程碑| | |||
| |issue_comment|疑修评论| | |||
| |pull_request|合并请求| | |||
| |pull_request_assign|合并请求被指派| | |||
| |pull_request_label|合并请求被贴上标签| | |||
| |pull_request_milestone|合并请求被记录于里程碑中| | |||
| |pull_request_comment|合并请求被评论| | |||
| |pull_request_review_approved|合并请求被批准| | |||
| |pull_request_review_rejected|合并请求被拒绝| | |||
| |pull_request_review_comment|合并请求被提出审查意见| | |||
| |pull_request_sync|合并请求被同步| | |||
| |repository|创建或删除仓库| | |||
| |release|版本发布| | |||
| > 返回的JSON示例: | |||
| @@ -1266,31 +1246,15 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json') | |||
| "http_method": "GET", | |||
| "content_type": "form", | |||
| "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": "*", | |||
| "events": [ | |||
| "create", | |||
| "delete", | |||
| "fork", | |||
| "issues", | |||
| "issue_assign", | |||
| "issue_label", | |||
| "issue_milestone", | |||
| "issue_comment", | |||
| "push", | |||
| "pull_request", | |||
| "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 | |||
| curl -X POST \ | |||
| http://localhost:3000/api/yystopf/ceshi/webhooks.json | |||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks.json | |||
| ``` | |||
| ```javascript | |||
| await octokit.request('POST /api/yystopf/ceshi/webhooks.json') | |||
| await octokit.request('POST /api/v1/yystopf/ceshi/webhooks.json') | |||
| ``` | |||
| ### 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 |用户登录名 | | |||
| |repo |是| | string |项目标识identifier | | |||
| |webhook.url |是| | string |目标url | | |||
| |webhook.type |否| | string |类型| | |||
| |webhook.http_method |是| | string | http方法, POST和GET | | |||
| |webhook.content_type |是| | string | POST Content Type | | |||
| |webhook.secret |否| | string |密钥文本| | |||
| @@ -1335,24 +1298,11 @@ await octokit.request('POST /api/yystopf/ceshi/webhooks.json') | |||
| --------- | ------- | ------- | | |||
| |create|创建分支或标签| | |||
| |delete|分支或标签删除| | |||
| |fork|仓库被fork| | |||
| |push|git仓库推送| | |||
| |issue|疑修已打开、已关闭、已重新打开或编辑| | |||
| |issue_assign|疑修被指派| | |||
| |issue_label|疑修标签被更新或删除| | |||
| |issue_milestone|疑修被收入里程碑| | |||
| |issue_comment|疑修评论| | |||
| |pull_request|合并请求| | |||
| |pull_request_assign|合并请求被指派| | |||
| |pull_request_label|合并请求被贴上标签| | |||
| |pull_request_milestone|合并请求被记录于里程碑中| | |||
| |pull_request_comment|合并请求被评论| | |||
| |pull_request_review_approved|合并请求被批准| | |||
| |pull_request_review_rejected|合并请求被拒绝| | |||
| |pull_request_review_comment|合并请求被提出审查意见| | |||
| |pull_request_sync|合并请求被同步| | |||
| |repository|创建或删除仓库| | |||
| |release|版本发布| | |||
| > 请求的JSON示例: | |||
| @@ -1385,15 +1335,22 @@ await octokit.request('POST /api/yystopf/ceshi/webhooks.json') | |||
| ```json | |||
| { | |||
| "id": 18, | |||
| "type": "gitea", | |||
| "id": 68, | |||
| "content_type": "json", | |||
| "url": "http://localhost:10000", | |||
| "http_method": "GET", | |||
| "url": "http://127.0.0.1:3000", | |||
| "events": [ | |||
| "push" | |||
| "create", | |||
| "delete", | |||
| "push", | |||
| "pull_request", | |||
| "pull_request_assign", | |||
| "pull_request_review_approved", | |||
| "pull_request_review_rejected" | |||
| ], | |||
| "active": true, | |||
| "create_time": "2021-07-26 18:53:43" | |||
| "branch_filter": "*", | |||
| "created_at": "2022-06-23 15:52" | |||
| } | |||
| ``` | |||
| <aside class="success"> | |||
| @@ -1407,15 +1364,15 @@ await octokit.request('POST /api/yystopf/ceshi/webhooks.json') | |||
| ```shell | |||
| curl -X PATCH \ | |||
| http://localhost:3000/api/yystopf/ceshi/webhooks/7.json | |||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks/7.json | |||
| ``` | |||
| ```javascript | |||
| await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json') | |||
| await octokit.request('PATCH /api/v1/yystopf/ceshi/webhooks/7.json') | |||
| ``` | |||
| ### 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 | | |||
| |id |是| | string |webhook id | | |||
| |webhook.url |是| | string |目标url | | |||
| |webhook.type |否| | string |类型| | |||
| |webhook.http_method |是| | string | http方法, POST和GET | | |||
| |webhook.content_type |是| | string | POST Content Type | | |||
| |webhook.secret |否| | string |密钥文本| | |||
| @@ -1438,24 +1394,11 @@ await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json') | |||
| --------- | ------- | ------- | | |||
| |create|创建分支或标签| | |||
| |delete|分支或标签删除| | |||
| |fork|仓库被fork| | |||
| |push|git仓库推送| | |||
| |issue|疑修已打开、已关闭、已重新打开或编辑| | |||
| |issue_assign|疑修被指派| | |||
| |issue_label|疑修标签被更新或删除| | |||
| |issue_milestone|疑修被收入里程碑| | |||
| |issue_comment|疑修评论| | |||
| |pull_request|合并请求| | |||
| |pull_request_assign|合并请求被指派| | |||
| |pull_request_label|合并请求被贴上标签| | |||
| |pull_request_milestone|合并请求被记录于里程碑中| | |||
| |pull_request_comment|合并请求被评论| | |||
| |pull_request_review_approved|合并请求被批准| | |||
| |pull_request_review_rejected|合并请求被拒绝| | |||
| |pull_request_review_comment|合并请求被提出审查意见| | |||
| |pull_request_sync|合并请求被同步| | |||
| |repository|创建或删除仓库| | |||
| |release|版本发布| | |||
| > 请求的JSON示例: | |||
| @@ -1478,8 +1421,22 @@ await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.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"> | |||
| @@ -1494,15 +1451,15 @@ await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json') | |||
| ```shell | |||
| curl -X DELETE \ | |||
| http://localhost:3000/api/yystopf/ceshi/webhooks/7.json | |||
| http://localhost:3000/api/v1/yystopf/ceshi/webhooks/7.json | |||
| ``` | |||
| ```javascript | |||
| await octokit.request('DELETE /api/yystopf/ceshi/webhooks/7.json') | |||
| await octokit.request('DELETE /api/v1/yystopf/ceshi/webhooks/7.json') | |||
| ``` | |||
| ### 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 | |||
| 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 | |||
| await octokit.request('GET /api/yystopf/ceshi/webhooks/3/tasks.json') | |||
| await octokit.request('GET /api/v1/yystopf/ceshi/webhooks/3/hooktasks.json') | |||
| ``` | |||
| ### 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 | |||
| { | |||
| "total_count": 6, | |||
| "tasks": [ | |||
| "hooktasks": [ | |||
| { | |||
| "id": 20, | |||
| "type": "gitea", | |||
| @@ -1744,15 +1701,15 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks/3/tasks.json') | |||
| ```shell | |||
| 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 | |||
| await octokit.request('POST /api/yystopf/ceshi/webhooks/3/test.json') | |||
| await octokit.request('POST /api/v1/yystopf/ceshi/webhooks/3/tests.json') | |||
| ``` | |||
| ### 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. | |||
| </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 | |||
| def gitea_domain | |||
| Gitea.gitea_config[:domain] | |||
| GiteaService.gitea_config[:domain] | |||
| end | |||
| def find_user_by_login_or_mail(identifier) | |||
| @@ -103,7 +103,7 @@ module RepositoriesHelper | |||
| end | |||
| end | |||
| # author hui.he | |||
| # author hui.he | |||
| 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? | |||
| @@ -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? | |||
| 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 = s_content.split("#{Rails.root}/")[1] | |||
| # content = content.gsub(s[0], "/#{s_content}") | |||
| @@ -131,7 +130,7 @@ module RepositoriesHelper | |||
| 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}") | |||
| content = content.gsub('('+s[0]+')', '('+"/#{s_content}"+')') | |||
| end | |||
| rescue | |||
| next | |||
| @@ -44,8 +44,8 @@ module Gitea | |||
| 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 | |||
| @@ -37,7 +37,7 @@ class Ci::Drone::Server | |||
| private | |||
| def gitea_url | |||
| Gitea.gitea_config[:domain] | |||
| GiteaService.gitea_config[:domain] | |||
| end | |||
| def database_username | |||
| @@ -1,4 +1,4 @@ | |||
| module Gitea | |||
| module GiteaService | |||
| class << self | |||
| def gitea_config | |||
| gitea_config = {} | |||
| @@ -69,6 +69,7 @@ class Issue < ApplicationRecord | |||
| has_many :issue_tags, through: :issue_tags_relates | |||
| has_many :issue_times, dependent: :destroy | |||
| has_many :issue_depends, dependent: :destroy | |||
| has_many :reviews, dependent: :destroy | |||
| scope :issue_includes, ->{includes(:user)} | |||
| scope :issue_many_includes, ->{includes(journals: :user)} | |||
| scope :issue_issue, ->{where(issue_classify: [nil,"issue"])} | |||
| @@ -12,11 +12,13 @@ | |||
| # parent_id :integer | |||
| # comments_count :integer default("0") | |||
| # reply_id :integer | |||
| # review_id :integer | |||
| # | |||
| # Indexes | |||
| # | |||
| # index_journals_on_created_on (created_on) | |||
| # index_journals_on_journalized_id (journalized_id) | |||
| # index_journals_on_review_id (review_id) | |||
| # index_journals_on_user_id (user_id) | |||
| # 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 | |||
| def access_key_secret | |||
| Gitea.gitea_config[:access_key_secret] | |||
| GiteaService.gitea_config[:access_key_secret] | |||
| end | |||
| def api_url(url) | |||
| @@ -56,7 +56,7 @@ class Gitea::Accelerator::BaseService < ApplicationService | |||
| end | |||
| def accelerator | |||
| Gitea.gitea_config[:accelerator] | |||
| GiteaService.gitea_config[:accelerator] | |||
| end | |||
| def render_status(response) | |||
| @@ -96,11 +96,11 @@ class Gitea::ClientService < ApplicationService | |||
| end | |||
| def base_url | |||
| Gitea.gitea_config[:base_url] | |||
| GiteaService.gitea_config[:base_url] | |||
| end | |||
| def domain | |||
| Gitea.gitea_config[:domain] | |||
| GiteaService.gitea_config[:domain] | |||
| end | |||
| def api_url | |||
| @@ -14,8 +14,8 @@ class Gitea::User::DeleteService < Gitea::ClientService | |||
| private | |||
| 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 | |||
| @@ -17,7 +17,7 @@ class Gitea::User::UpdateService < Gitea::ClientService | |||
| # source_id integer($int64) | |||
| # 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 | |||
| @params = params | |||
| @edit_username = edit_username | |||
| @@ -63,7 +63,7 @@ class Repositories::CreateService < ApplicationService | |||
| end | |||
| 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 | |||
| 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.comments_count @issue.journals.parent_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.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__}" | |||
| # Put your resource owner authentication logic here. | |||
| # 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 | |||
| resource_owner_from_credentials do |routes| | |||
| @@ -21,7 +21,7 @@ Doorkeeper.configure do | |||
| admin_authenticator do | |||
| 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 | |||
| end | |||
| end | |||
| @@ -242,8 +242,8 @@ Doorkeeper.configure do | |||
| # For more information go to | |||
| # 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. | |||
| # 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]) | |||
| { | |||
| iss: 'My App', | |||
| iss: 'GitLink', | |||
| iat: Time.current.utc.to_i, | |||
| # @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 | |||
| def draw(routes_name) | |||
| instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb"))) | |||
| end | |||
| draw :api | |||
| use_doorkeeper | |||
| require 'sidekiq/web' | |||
| require 'sidekiq/cron/web' | |||
| @@ -22,6 +28,9 @@ Rails.application.routes.draw do | |||
| get 'oauth/register', to: 'oauth#register' | |||
| post 'oauth/auto_register', to: 'oauth#auto_register' | |||
| get 'oauth2', to: 'oauth2#show' | |||
| post 'oauth2', to: 'oauth2#create' | |||
| resources :edu_settings | |||
| scope '/api' do | |||
| @@ -547,6 +556,7 @@ Rails.application.routes.draw do | |||
| post :refuse_merge | |||
| get :files | |||
| get :commits | |||
| resources :reviews, only: [:create] | |||
| end | |||
| collection do | |||
| 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 | |||
| def remote_repository_url(username, identifier) | |||
| [Gitea.gitea_config[:domain], '/', username, '/', identifier, ".git"].join("") | |||
| [GiteaService.gitea_config[:domain], '/', username, '/', identifier, ".git"].join("") | |||
| end | |||
| 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 | |||