Compare commits

...

156 Commits

Author SHA1 Message Date
yystopf fb23e733d6 Merge branch 'develop' into dev_trustie_server 2021-07-23 17:23:45 +08:00
yystopf 8905f60265 fix: gitea url contain chinese 2021-07-23 17:23:01 +08:00
yystopf c6f2021017 Merge branch 'develop' into dev_trustie_server 2021-07-23 14:53:06 +08:00
yystopf f334864f1b fix: get file extname 2021-07-23 14:50:01 +08:00
yystopf f5e07ab3ec add: remove public key from api 2021-07-23 14:49:54 +08:00
yystopf fcc7736c34 fix some bug pick 2ea0c6e3 add: remove public key from api 2021-07-23 14:49:31 +08:00
jasder 581b147b3c Merge branch 'dev_trustie_server' of https://git.trustie.net/jasder/forgeplus into dev_trustie_server 2021-07-23 14:16:43 +08:00
jasder deebfc3292 fix merge develop branch 2021-07-23 14:16:29 +08:00
yystopf e68c13f1a2 Merge branch 'develop' into dev_trustie_server 2021-07-22 18:30:59 +08:00
yystopf 0db334217e fix 2021-07-22 15:19:53 +08:00
yystopf 32fe6958df fix: create public key return error 2021-07-22 14:53:57 +08:00
yystopf 15eb1f4a17 Merge branch 'develop' into dev_trustie_server 2021-07-21 21:32:38 +08:00
yystopf e4fda9243b fix: create project add login 2021-07-21 09:43:35 +08:00
yystopf 0884a0de1b Merge branch 'develop' into dev_trustie_server 2021-07-16 16:46:28 +08:00
yystopf aeaa5d4366 完成public_keys模块、修复pr查看比较的时候传token,修复无法正确读取仓库图片 2021-07-16 16:45:46 +08:00
yystopf d4b9881f2d fix 2021-07-16 16:42:30 +08:00
yystopf a543c3e08f fix: write image filepath error 2021-07-16 16:10:20 +08:00
viletyy 998381585a add: user public keys controller 2021-07-14 15:38:14 +08:00
viletyy 2ddf1dbd01 add: gitea user keys api 2021-07-14 11:48:52 +08:00
viletyy fd3fab99ae fix: compare code need token 2021-07-14 09:55:12 +08:00
viletyy 193d1b21df Merge branch 'develop' into dev_trustie_server 2021-07-12 18:10:50 +08:00
viletyy de2b54c39e add: compare code return can merge status 2021-07-12 18:10:26 +08:00
viletyy ed8e079595 Merge branch 'develop' into dev_trustie_server 2021-07-12 17:57:51 +08:00
viletyy 4929734a1a fix 2021-07-12 17:57:42 +08:00
viletyy 55a0bcfb82 fix 2021-07-12 17:33:10 +08:00
viletyy 8f1aa3f4b1 fix: merge from develop 2021-07-12 17:28:47 +08:00
yystopf 1c6d8fc2f3 创建合并请求比较代码时返回是否可以创建的信息 2021-07-12 17:27:53 +08:00
viletyy d271a684fa add: compare code return can merge message 2021-07-12 17:24:35 +08:00
jasder b054094798 FIX conflicts 2021-07-12 16:20:14 +08:00
jasder 2d648e516e FIX merge develop branch 2021-07-12 16:19:03 +08:00
jasder 34c3a83df4 fix some bug
FIX 解决私有版本库库不能访问、下载图片的问题
FIX show realname for create project
FIX 解决标签列表和发行版列表中下周zip包、tar包导致的404问题
ADD conflicts file for pull api
2021-07-12 16:16:44 +08:00
jasder 71e039efb8 FIX merge develop branch 2021-07-12 16:14:51 +08:00
jasder 9ac21938e6 pr合并问题 2021-07-12 12:10:06 +08:00
viletyy fa8594d2ab add: merge pr check status 2021-07-12 12:02:34 +08:00
jasder 3614f3e15b FIX 解决私有版本库库不能访问、下载图片的问题 2021-07-09 16:57:11 +08:00
viletyy ff21916f18 fix: merge from develop 2021-07-09 13:48:48 +08:00
viletyy d9162cb3bf fix: merge from develop 2021-07-09 13:47:21 +08:00
jasder e76d475fef FIX show realname for create project 2021-07-06 11:04:00 +08:00
jasder 1392024657 FIX migrate data 2021-07-02 16:08:55 +08:00
viletyy 312fca7e2b fix: update shell simple 2021-07-01 17:55:48 +08:00
vilet.yy d1939116a3 fix: authorize 2021-07-01 13:58:36 +08:00
vilet.yy 2a72fc56a4 fix: copy issue author id 2021-07-01 13:56:15 +08:00
jasder 913bc45a9f Merge branch 'dev_trustie_server' of https://git.trustie.net/jasder/forgeplus into dev_trustie_server 2021-07-01 10:09:28 +08:00
jasder 8131d8cd48 Merge branch 'sync_develop' into dev_trustie_server 2021-07-01 10:08:58 +08:00
jasder 87049b74ef Merge branch 'develop' into sync_develop 2021-07-01 10:06:00 +08:00
jasder f19219a467 FIX 解决标签列表和发行版列表中下周zip包、tar包导致的404问题 2021-06-30 14:30:01 +08:00
vilet.yy 4cc46f4cb4 fix 2021-06-29 18:05:37 +08:00
vilet.yy 8331d849d5 fix: forked projects private set 2021-06-29 17:36:15 +08:00
vilet.yy 0e7f3a8905 fix: project permission and update user lastname 2021-06-29 10:36:58 +08:00
viletyy 259090b8e3 fix 2021-06-28 21:07:10 +08:00
jasder 7e474cab70 Merge branch 'feature/pull_conflict_files' into dev_trustie_server 2021-06-28 10:06:54 +08:00
jasder 01341d4389 FIX pull、 gitea pull model relation bug 2021-06-28 10:04:48 +08:00
jasder 3a475a4674 FIX get conflict files bug with create pr api 2021-06-28 09:59:47 +08:00
jasder 7b27ed71ca FIX 易修详情返回用户操作权限 2021-06-25 18:47:36 +08:00
jasder 83b7b8cd9c Merge branch 'develop' into dev_trustie_server 2021-06-25 18:03:28 +08:00
jasder c298ff02b8 ADD pr冲突文件展示 2021-06-25 18:03:07 +08:00
vilet.yy 6c3c1ce093 fix: issue show permission 2021-06-25 17:54:22 +08:00
jasder 62d1a2378c FIX [更改字段名称]conflicts file for pull api 2021-06-25 17:31:23 +08:00
jasder e111f40c69 fix 修复bug 2021-06-25 16:13:23 +08:00
jasder 8d300e11f9 FIX [bug]conflicts file for pull api 2021-06-24 16:18:34 +08:00
jasder b7dd12927b ADD conflicts file for pull api 2021-06-24 16:08:32 +08:00
vilet.yy 4126ea7b4e fix: some bug from security 2021-06-22 15:54:42 +08:00
jasder 7bb4cf7391 Merge branch 'develop' into dev_trustie_server 2021-06-22 15:15:51 +08:00
jasder 539b832af6 FIX 解决获取平台base url导致的https的问题 2021-06-22 15:15:27 +08:00
jasder 0bfed83bc0 FIX 解决获取平台base url导致的https的问题 2021-06-22 15:05:10 +08:00
jasder 23f7439a8c Merge branch 'develop' into dev_trustie_server 2021-06-22 09:51:46 +08:00
jasder ce8527359c FIX 处理版本库zip、gzip包链接为无效的问题 2021-06-22 09:51:17 +08:00
jasder fff21a1bc8 FIX 处理版本库zip、gzip包链接为无效的问题 2021-06-22 09:39:44 +08:00
vilet.yy 526920f564 fix: version issues count except pull requests count 2021-06-21 18:50:45 +08:00
vilet.yy 2d37df1c00 fix: set cache user nil 2021-06-21 17:12:13 +08:00
vilet.yy 0af08bc967 fix: projects load by project language slowly 2021-06-21 17:05:51 +08:00
vilet.yy ea82a52b7b fix: version issues count 2021-06-21 14:45:41 +08:00
jasder 484f8a854a Merge branch 'develop' into dev_trustie_server 2021-06-18 16:45:12 +08:00
jasder 62bd331876 Merge branch 'sync_develop' into develop 2021-06-18 16:44:57 +08:00
jasder 91e142ba82 FIX code bug 2021-06-18 16:44:37 +08:00
jasder 7bedac263d Merge branch 'develop' into dev_trustie_server 2021-06-18 16:21:21 +08:00
jasder a82b13ecdf Merge branch 'sync_develop' into develop 2021-06-18 16:21:10 +08:00
jasder 855c51a470 FIX 解决在线创建文件错误提示信息不准确的问题 2021-06-18 16:20:50 +08:00
jasder f0b1c9e80b Merge branch 'develop' into dev_trustie_server 2021-06-18 11:03:41 +08:00
jasder dc23be9001 Merge branch 'develop' into dev_trustie_server 2021-06-18 10:54:29 +08:00
jasder e24269c2a7 Merge branch 'develop' into dev_trustie_server 2021-06-17 18:14:19 +08:00
jasder bf390c8366 Merge branch 'develop' into dev_trustie_server 2021-06-11 18:03:35 +08:00
jasder 632a06e575 Merge branch 'develop' into dev_trustie_server 2021-06-08 18:13:16 +08:00
jasder 04c7887319 Merge branch 'sync_develop' into dev_trustie_server 2021-06-08 14:34:29 +08:00
jasder d75b79670d Merge branch 'develop' into dev_trustie_server 2021-06-04 18:51:47 +08:00
jasder 2c5fa8492f Merge branch 'develop' into dev_trustie_server 2021-06-03 17:26:35 +08:00
jasder 6d845eeb3b Merge branch 'develop' into dev_trustie_server 2021-05-26 17:39:54 +08:00
jasder 83e666a387 Merge branch 'develop' into dev_trustie_server 2021-05-24 17:06:54 +08:00
jasder 72b89d4b2b Merge branch 'develop' into dev_trustie_server 2021-05-21 19:26:47 +08:00
jasder 38f6254edc Merge branch 'develop' into dev_trustie_server 2021-05-15 10:20:14 +08:00
jasder 8a4b0ba966 Merge branch 'develop' into dev_trustie_server 2021-05-14 17:34:36 +08:00
jasder 84927c2361 FIX 解决大赛中点击项目跳转到forge平台,保持自动登陆的bug 2021-05-13 11:47:47 +08:00
jasder b568ac4e97 ADD title 2021-05-12 17:48:05 +08:00
jasder 91bbb58d4f FIX delete input readonly 2021-05-12 17:44:45 +08:00
jasder f278b38e6c Merge branch 'trustie_server' into dev_trustie_server 2021-05-12 17:01:59 +08:00
jasder 4023b8980e FIX 完善通过大赛点击项目链接自动注册关联Educoder平台账号的功能 2021-05-12 17:01:30 +08:00
jasder 1c1be18151 Merge branch 'dev_trustie_server' into trustie_server 2021-05-10 14:39:14 +08:00
jasder e5f591e509 Merge branch 'develop' into dev_trustie_server 2021-05-10 14:38:58 +08:00
yystopf 27ee32054b 发布v3.0.3版本 2021-05-08 17:45:23 +08:00
jasder 3e3fd46cad Merge branch 'develop' into dev_trustie_server 2021-05-08 17:02:56 +08:00
jasder 7a752b177d Merge branch 'develop' into dev_trustie_server 2021-05-08 14:23:34 +08:00
jasder abbabfdefd Merge branch 'dev_trustie_server' into trustie_server 2021-04-30 17:13:33 +08:00
jasder edd76b9286 Merge branch 'develop' into dev_trustie_server 2021-04-30 17:13:18 +08:00
jasder a3ca94d433 Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 23:23:55 +08:00
jasder 91a804caf7 Merge branch 'develop' into dev_trustie_server 2021-04-29 23:23:42 +08:00
jasder 663deae21b Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 23:19:34 +08:00
jasder dae5c9690f Merge branch 'develop' into dev_trustie_server 2021-04-29 23:19:17 +08:00
jasder e65df07d79 Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 19:27:55 +08:00
jasder 246b6b52ec Merge branch 'develop' into dev_trustie_server 2021-04-29 19:27:36 +08:00
jasder b9789183e3 Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 19:17:03 +08:00
jasder 7cf2c6021f Merge branch 'develop' into dev_trustie_server 2021-04-29 19:13:12 +08:00
jasder e0f9a3d43d Merge branch 'develop' into dev_trustie_server 2021-04-29 18:50:11 +08:00
jasder c1ef39b262 Merge branch 'develop' into dev_trustie_server 2021-04-29 18:37:35 +08:00
jasder 51643dc02c Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 10:42:12 +08:00
jasder a078c07b59 Merge branch 'develop' into dev_trustie_server 2021-04-29 10:41:59 +08:00
jasder b984790d5c Merge branch 'develop' into trustie_server 2021-04-28 21:17:43 +08:00
jasder 876591100e Merge branch 'develop' into dev_trustie_server 2021-04-28 21:17:36 +08:00
jasder ba9848ebe7 Merge branch 'develop' into dev_trustie_server 2021-04-27 18:24:41 +08:00
jasder 41c621cf55 Merge branch 'develop' into dev_trustie_server 2021-04-26 16:53:05 +08:00
jasder 09ac49dda5 Merge branch 'develop' into dev_trustie_server 2021-04-26 16:46:24 +08:00
jasder 341a810afc Merge branch 'develop' into dev_trustie_server 2021-04-23 17:54:13 +08:00
jasder 2282c52efb FIX update README.md 2021-04-23 17:33:19 +08:00
jasder 34edd78ae7 Merge branch 'develop' into dev_trustie_server 2021-04-23 17:21:34 +08:00
jasder 36fb5a118c Merge branch 'develop' into dev_trustie_server 2021-04-23 14:40:41 +08:00
jasder b756be1d6a Merge branch 'develop' into dev_trustie_server 2021-04-22 18:10:32 +08:00
jasder 348c2244f7 Merge branch 'develop' into dev_trustie_server 2021-04-22 16:45:40 +08:00
jasder 31738fc227 Merge branch 'develop' into dev_trustie_server 2021-04-22 16:43:04 +08:00
jasder a93c98fb7c Merge branch 'trustie_server' into dev_trustie_server 2021-04-22 16:39:03 +08:00
jasder 39193324e9 Merge branch 'develop' into dev_trustie_server 2021-04-22 16:38:58 +08:00
jasder 81743ce3bc Merge branch 'develop' into trustie_server 2021-04-20 19:07:56 +08:00
jasder e9ae536f04 Merge branch 'develop' into trustie_server 2021-04-20 19:06:40 +08:00
jasder 186955fe4a Merge branch 'develop' into trustie_server 2021-04-20 18:58:24 +08:00
jasder 8ce7fd95cb Merge branch 'develop' into trustie_server 2021-04-20 18:37:55 +08:00
jasder 0867e5130f Merge branch 'dev_trustie_server' into trustie_server 2021-04-20 11:37:25 +08:00
jasder db476a1a9b Merge branch 'develop' into dev_trustie_server 2021-04-20 11:37:08 +08:00
jasder fa1fd8a4ba Merge branch 'develop' into trustie_server 2021-04-19 20:39:29 +08:00
jasder 0d7a11f3ab Merge branch 'develop' into dev_trustie_server 2021-04-19 18:41:18 +08:00
jasder 879e45e106 Merge branch 'develop' into trustie_server 2021-04-13 16:40:23 +08:00
jasder b3b0f75e9b Merge branch 'develop' into trustie_server 2021-04-13 10:18:52 +08:00
jasder 5c8e561bd8 Merge branch 'develop' into trustie_server 2021-04-08 18:36:27 +08:00
jasder 2b0c987558 Merge branch 'develop' into trustie_server 2021-04-07 11:35:09 +08:00
jasder 6796805b21 Merge branch 'develop' into trustie_server 2021-04-02 18:58:08 +08:00
jasder 5752f19b2f FIX gug 2021-04-02 18:56:44 +08:00
jasder eb52f05417 集成educoder登陆 2021-04-02 18:46:15 +08:00
vilet.yy 786629dbff fix 2021-04-02 18:41:48 +08:00
vilet.yy 7a00541375 Merge branch 'develop' into hh_develop 2021-04-02 18:41:37 +08:00
vilet.yy 1d832a1723 fix 2021-04-02 18:38:08 +08:00
vilet.yy 80ce40e492 fix 2021-04-02 18:33:31 +08:00
vilet.yy 91f6dae56a fix 2021-04-02 18:24:20 +08:00
vilet.yy 8c5a834b14 Merge branch 'develop' into hh_develop 2021-04-02 18:22:32 +08:00
vilet.yy 57f420848e Merge branch 'develop' into hh_develop 2021-04-02 18:20:41 +08:00
vilet.yy fba58800a7 fix 2021-04-02 18:08:36 +08:00
vilet.yy c4a43c4392 add: need edit user password 2021-04-02 16:44:36 +08:00
vilet.yy 1153bd5ab6 fix: set redirect_uri 2021-04-02 09:43:18 +08:00
vilet.yy f732b0374c fix: ceshi 2021-04-02 09:23:11 +08:00
vilet.yy 0d97d7d4f0 add: educoder third party 2021-04-01 18:01:51 +08:00
85 changed files with 1413 additions and 273 deletions

1
.gitignore vendored
View File

@ -74,6 +74,7 @@ vendor/bundle/
/log /log
/public/admin /public/admin
/mysql_data /mysql_data
/public/repo/
.generators .generators

View File

@ -329,7 +329,6 @@ class ApplicationController < ActionController::Base
User.current = user User.current = user
end end
end end
# if !User.current.logged? && Rails.env.development? # if !User.current.logged? && Rails.env.development?
# User.current = User.find 1 # User.current = User.find 1
# end # end
@ -771,7 +770,7 @@ class ApplicationController < ActionController::Base
end end
def base_url def base_url
request.base_url Rails.application.config_for(:configuration)['platform_url'] || request.base_url
end end
def convert_image! def convert_image!

View File

@ -6,26 +6,48 @@ class CompareController < ApplicationController
end end
def show def show
load_compare_params
compare compare
@merge_status, @merge_message = get_merge_message
end end
private private
def get_merge_message
if @base.blank? || @head.blank?
return -2, "请选择分支"
else
if @head.include?(":")
fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take
return -2, "请选择正确的仓库" unless fork_project.present?
@exist_pullrequest = @project.pull_requests.where(is_original: true, head: @head.to_s.split(":")[1], base: @base, status: 0, fork_project_id: fork_project.id).take
else
@exist_pullrequest = @project.pull_requests.where(is_original: false, head: @base, base: @head, status: 0).take
end
if @exist_pullrequest.present?
return -2, "在这些分支之间的合并请求已存在:<a href='/projects/#{@owner.login}/#{@project.identifier}/pulls/#{@exist_pullrequest.id}/Messagecount'>#{@exist_pullrequest.try(:title)}</a>"
else
if @compare_result["Commits"].blank? && @compare_result["Diff"].blank?
return -2, "分支内容相同,无需创建合并请求"
end
end
end
return 0, "可以合并"
end
def compare def compare
base, head = compare_params
# TODO: 处理fork的项目向源项目发送PR的base、head参数问题 # TODO: 处理fork的项目向源项目发送PR的base、head参数问题
@compare_result ||= @compare_result ||=
head.include?(":") ? gitea_compare(base, head) : gitea_compare(head, base) @head.include?(":") ? gitea_compare(@base, @head) : gitea_compare(@head, @base)
end end
def compare_params def load_compare_params
base = Addressable::URI.unescape(params[:base]) @base = Addressable::URI.unescape(params[:base])
head = params[:head].include?('json') ? params[:head]&.split('.json')[0] : params[:head] @head = params[:head].include?('json') ? params[:head]&.split('.json')[0] : params[:head]
[base, head]
end end
def gitea_compare(base, head) def gitea_compare(base, head)
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, base, head) Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, base, head, current_user.gitea_token)
end end
end end

View File

@ -1,13 +1,17 @@
module RegisterHelper module RegisterHelper
extend ActiveSupport::Concern extend ActiveSupport::Concern
def autologin_register(username, email, password, platform= 'forge') def autologin_register(username, email, password, platform= 'forge', need_edit_info = false)
result = {message: nil, user: nil} result = {message: nil, user: nil}
user = User.new(admin: false, login: username, mail: email, type: "User") user = User.new(admin: false, login: username, mail: email, type: "User")
user.password = password user.password = password
user.platform = platform user.platform = platform
user.activate if need_edit_info
user.need_edit_info
else
user.activate
end
return unless user.valid? return unless user.valid?
@ -27,4 +31,31 @@ module RegisterHelper
result result
end end
def autosync_register_trustie(username, password, email, lastname="")
config = Rails.application.config_for(:configuration).symbolize_keys!
api_host = config[:sync_url]
return if api_host.blank?
url = "#{api_host}/api/v1/users/common"
sync_json = {
"mail": email,
"password": password,
"login": username,
"lastname": lastname
}.compact
uri = URI.parse(url)
if api_host
http = Net::HTTP.new(uri.hostname, uri.port)
if api_host.include?("https://")
http.use_ssl = true
end
http.send_request('POST', uri.path, sync_json.to_json, {'Content-Type' => 'application/json'})
end
end
end end

View File

@ -3,6 +3,7 @@ class IssuesController < ApplicationController
before_action :load_project before_action :load_project
before_action :set_user before_action :set_user
before_action :check_issue_permission before_action :check_issue_permission
before_action :operate_issue_permission, only:[:create, :update, :destroy, :clean, :series_update, :copy]
before_action :check_project_public, only: [:index ,:show, :copy, :index_chosen, :close_issue] before_action :check_project_public, only: [:index ,:show, :copy, :index_chosen, :close_issue]
before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue] before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue]
@ -230,7 +231,7 @@ class IssuesController < ApplicationController
end end
def show def show
@user_permission = current_user.present? && current_user.logged? && (!@issue.is_lock || @project.member?(current_user) || current_user.admin? || @issue.user == current_user) @user_permission = current_user.present? && current_user.logged? && (@project.member?(current_user) || current_user.admin? || @issue.user == current_user)
@issue_attachments = @issue.attachments @issue_attachments = @issue.attachments
@issue_user = @issue.user @issue_user = @issue.user
@issue_assign_to = @issue.get_assign_user @issue_assign_to = @issue.get_assign_user
@ -303,7 +304,7 @@ class IssuesController < ApplicationController
if issue_ids.present? if issue_ids.present?
if update_hash.blank? if update_hash.blank?
normal_status(-1, "请选择批量更新内容") normal_status(-1, "请选择批量更新内容")
elsif Issue.where(id: issue_ids).update_all(update_hash) elsif Issue.where(id: issue_ids)&.update(update_hash)
normal_status(0, "批量更新成功") normal_status(0, "批量更新成功")
else else
normal_status(-1, "批量更新失败") normal_status(-1, "批量更新失败")
@ -315,6 +316,7 @@ class IssuesController < ApplicationController
def copy def copy
@new_issue = @issue.dup @new_issue = @issue.dup
@new_issue.author_id = current_user.id
if @new_issue.save if @new_issue.save
issue_tags = @issue.issue_tags.pluck(:id) issue_tags = @issue.issue_tags.pluck(:id)
if issue_tags.present? if issue_tags.present?
@ -412,6 +414,10 @@ class IssuesController < ApplicationController
end end
end end
def operate_issue_permission
return render_forbidden("您没有权限进行此操作.") unless current_user.admin? || @project.member?(current_user)
end
def export_issues(issues) def export_issues(issues)
@table_columns = %w(ID 类型 标题 描述 状态 指派给 优先级 标签 发布人 创建时间 里程碑 开始时间 截止时间 完成度 分类 金额 属于) @table_columns = %w(ID 类型 标题 描述 状态 指派给 优先级 标签 发布人 创建时间 里程碑 开始时间 截止时间 完成度 分类 金额 属于)
@export_issues = [] @export_issues = []

View File

@ -2,6 +2,7 @@ class Oauth::BaseController < ActionController::Base
include RenderHelper include RenderHelper
include LoginHelper include LoginHelper
include ControllerRescueHandler include ControllerRescueHandler
include LoggerHelper
# include LaboratoryHelper # include LaboratoryHelper
skip_before_action :verify_authenticity_token skip_before_action :verify_authenticity_token
@ -11,6 +12,18 @@ class Oauth::BaseController < ActionController::Base
end end
private private
def tip_exception(status = -1, message)
raise Educoder::TipException.new(status, message)
end
def tip_show_exception(status = -2, message)
raise Educoder::TipException.new(status, message)
end
def tip_show(exception)
uid_logger("Tip show status is #{exception.status}, message is #{exception.message}")
render json: exception.tip_json
end
def session_user_id def session_user_id
# session[:user_id] # session[:user_id]
@ -48,4 +61,13 @@ class Oauth::BaseController < ActionController::Base
Rails.logger.info("[wechat] set session unionid: #{unionid}") Rails.logger.info("[wechat] set session unionid: #{unionid}")
session[:unionid] = unionid session[:unionid] = unionid
end end
def session_edulogin
session[:edulogin]
end
def set_session_edulogin(login)
Rails.logger.info("[educoder] set sesstion edulogin: #{login}")
session[:edulogin] = login
end
end end

View File

@ -1,4 +1,6 @@
class Oauth::EducoderController < Oauth::BaseController class Oauth::EducoderController < Oauth::BaseController
include RegisterHelper
def bind def bind
begin begin
login = params[:login] login = params[:login]
@ -32,4 +34,41 @@ class Oauth::EducoderController < Oauth::BaseController
render_error(ex.message) render_error(ex.message)
end end
end end
# 需要educoder那边设置回调地址
def create
begin
code = params['code'].to_s.strip
tip_exception("code不能为空") if code.blank?
new_user = false
result = EducoderOauth::Service.access_token(code)
result = EducoderOauth::Service.user_info(result[:access_token])
# 存在该用户
open_user = OpenUsers::Educoder.find_by(uid: result['login'])
if open_user.present? && open_user.user.present?
successful_authentication(open_user.user)
else
if current_user.blank? || !current_user.logged?
new_user = true
login = User.generate_login('E')
reg_result = autologin_register(login,"#{login}@forge.com", "Ec#{login}2021#", 'educoder', true)
if reg_result[:message].blank?
open_user = OpenUsers::Educoder.create!(user_id: reg_result[:user][:id], uid: result['login'], extra: result)
autosync_register_trustie(login, "Ec#{login}2021#", "#{login}@forge.com")
successful_authentication(open_user.user)
else
render_error(reg_result[:message])
end
else
OpenUsers::Educoder.create!(user: current_user, uid: result['login'], extra: result)
end
end
redirect_to root_path(new_user: new_user)
rescue Exception => ex
render_error(ex.message)
end
end
end end

View File

@ -61,6 +61,7 @@ class OauthController < ApplicationController
login = params[:login] login = params[:login]
email = params[:mail] email = params[:mail]
password = params[:password] password = params[:password]
lastname = params[:lastname]
callback_url = params[:callback_url] callback_url = params[:callback_url]
platform = params[:plathform] || 'educoder' platform = params[:plathform] || 'educoder'
@ -72,8 +73,11 @@ class OauthController < ApplicationController
if result[:message].blank? if result[:message].blank?
logger.info "[Oauth educoer] ====auto_register success" logger.info "[Oauth educoer] ====auto_register success"
user = User.find result[:user][:id] user = User.find result[:user][:id]
successful_authentication(user) user.update_column(:lastname, params[:lastname])
autosync_register_trustie(login, password, email, lastname)
OpenUsers::Educoder.create!(user: user, uid: user.login) OpenUsers::Educoder.create!(user: user, uid: user.login)
successful_authentication(user)
render json: { callback_url: callback_url } render json: { callback_url: callback_url }
# redirect_to callback_url # redirect_to callback_url

View File

@ -5,7 +5,7 @@ class ProjectsController < ApplicationController
include Acceleratorable include Acceleratorable
before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users recommend about menu_list] before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users recommend about menu_list]
before_action :load_project, except: %i[index group_type_list migrate create recommend] before_action :load_repository, except: %i[index group_type_list migrate create recommend]
before_action :authorizate_user_can_edit_project!, only: %i[update] before_action :authorizate_user_can_edit_project!, only: %i[update]
before_action :project_public?, only: %i[fork_users praise_users watch_users] before_action :project_public?, only: %i[fork_users praise_users watch_users]
@ -116,10 +116,11 @@ class ProjectsController < ApplicationController
Projects::UpdateForm.new(validate_params).validate! Projects::UpdateForm.new(validate_params).validate!
private = params[:private] || false private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : params[:private] || false
new_project_params = project_params.except(:private).merge(is_public: !private) new_project_params = project_params.except(:private).merge(is_public: !private)
@project.update_attributes!(new_project_params) @project.update_attributes!(new_project_params)
@project.forked_projects.update_all(is_public: @project.is_public)
gitea_params = { gitea_params = {
private: private, private: private,
default_branch: @project.default_branch, default_branch: @project.default_branch,
@ -144,6 +145,7 @@ class ProjectsController < ApplicationController
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
Gitea::Repository::DeleteService.new(@project.owner, @project.identifier).call Gitea::Repository::DeleteService.new(@project.owner, @project.identifier).call
@project.destroy! @project.destroy!
@project.forked_projects.update_all(forked_from_project_id: nil)
render_ok render_ok
end end
else else

View File

@ -0,0 +1,64 @@
class PublicKeysController < ApplicationController
before_action :require_login
before_action :find_public_key, only: [:destroy]
def index
@public_keys = current_user.public_keys
@public_keys = kaminari_paginate(@public_keys)
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def create
return render_error("参数错误") if public_key_params.blank?
return render_ok({status: 10002, message: "请输入密钥"}) if public_key_params[:key].blank?
return render_ok({status: 10001, message: "请输入标题"}) if public_key_params[:title].blank?
@gitea_response = Gitea::User::Keys::CreateService.call(current_user.gitea_token, public_key_params)
if @gitea_response[0] == 201
@public_key = @gitea_response[2]
else
return render_error("创建ssh key失败") if @gitea_response[2].blank?
return render_ok({status: 10002, message: "密钥格式不正确"}) if @gitea_response[2]["message"].starts_with?("Invalid key content")
exist_public_key = Gitea::PublicKey.find_by(content: public_key_params[:key])
return render_ok({status: 10002, message: "密钥已被占用"}) if @gitea_response[2]["message"].starts_with?("Key content has been used as non-deploy key") && exist_public_key.present? && exist_public_key&.owner_id != current_user.gitea_uid
return render_ok({status: 10002, message: "密钥已存在,请勿重复添加"}) if @gitea_response[2]["message"].starts_with?("Key content has been used as non-deploy key")
@public_key = nil
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def destroy
return render_not_found unless @public_key.present?
result = Gitea::User::Keys::DeleteService.call(current_user.gitea_token, @public_key.id)
if result[0] == 204
render_ok
else
render_error
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
private
def page
params[:page].to_i.zero? ? 1 : params[:page].to_i
end
def limit
limit = params[:limit] || params[:per_page]
limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i
end
def public_key_params
params.require(:public_key).permit(:key, :title)
end
def find_public_key
@public_key = current_user.public_keys.find_by_id(params[:id])
end
end

View File

@ -56,7 +56,7 @@ class PullRequestsController < ApplicationController
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
@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)
if @gitea_pull_request[:status] == :success if @gitea_pull_request[:status] == :success
@pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"]) @pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"])
render_ok render_ok
else else
render_error("create pull request error: #{@gitea_pull_request[:status]}") render_error("create pull request error: #{@gitea_pull_request[:status]}")
@ -91,7 +91,7 @@ class PullRequestsController < ApplicationController
if @issue.update_attributes(@issue_params) if @issue.update_attributes(@issue_params)
if @pull_request.update_attributes(@local_params.compact) if @pull_request.update_attributes(@local_params.compact)
gitea_pull = Gitea::PullRequest::UpdateService.call(@owner.login, @repository.identifier, gitea_pull = Gitea::PullRequest::UpdateService.call(@owner.login, @repository.identifier,
@pull_request.gpid, @requests_params, current_user.gitea_token) @pull_request.gitea_number, @requests_params, current_user.gitea_token)
if gitea_pull[:status] === :success if gitea_pull[:status] === :success
if params[:issue_tag_ids].present? if params[:issue_tag_ids].present?
@ -139,7 +139,7 @@ class PullRequestsController < ApplicationController
@issue_user = @issue.user @issue_user = @issue.user
@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.gpid, current_user&.gitea_token) @repository.identifier, @pull_request.gitea_number, current_user&.gitea_token)
end end
def pr_merge def pr_merge
@ -150,9 +150,16 @@ class PullRequestsController < ApplicationController
else else
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
result = PullRequests::MergeService.call(@owner, @repository, @pull_request, current_user, params) @gitea_pull = Gitea::PullRequest::GetService.call(@owner.login, @repository.identifier, @pull_request.gitea_number, current_user&.gitea_token)
if result.status == 200 && @pull_request.merge! if @gitea_pull["merged_by"].present?
success_condition = true
else
result = PullRequests::MergeService.call(@owner, @repository, @pull_request, current_user, params)
success_condition = result.status == 200
end
if success_condition && @pull_request.merge!
@pull_request.project_trend_status! @pull_request.project_trend_status!
@issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id) @issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id)
normal_status(1, "合并成功") normal_status(1, "合并成功")
@ -191,12 +198,12 @@ class PullRequestsController < ApplicationController
def files def files
@files_result = Gitea::PullRequest::FilesService.call(@owner.login, @project.identifier, @pull_request.gpid, current_user&.gitea_token) @files_result = Gitea::PullRequest::FilesService.call(@owner.login, @project.identifier, @pull_request.gitea_number, current_user&.gitea_token)
# render json: @files_result # render json: @files_result
end end
def commits def commits
@commits_result = Gitea::PullRequest::CommitsService.call(@owner.login, @project.identifier, @pull_request.gpid, current_user&.gitea_token) @commits_result = Gitea::PullRequest::CommitsService.call(@owner.login, @project.identifier, @pull_request.gitea_number, current_user&.gitea_token)
# render json: @commits_result # render json: @commits_result
end end

View File

@ -5,9 +5,9 @@ class RepositoriesController < ApplicationController
before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror] before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror]
before_action :load_repository before_action :load_repository
before_action :authorizate!, except: [:sync_mirror, :tags, :commit] 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] before_action :get_ref, only: %i[entries sub_entries top_counts file 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]
@ -192,6 +192,19 @@ class RepositoriesController < ApplicationController
render json: languages_precentagable render json: languages_precentagable
end end
def archive
domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url]
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{params[:archive]}"
file_path = [domain, api_url, archive_url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
return render_not_found if !request.format.zip? && !request.format.gzip?
redirect_to file_path
end
private private
def find_project def find_project
@ -266,7 +279,7 @@ class RepositoriesController < ApplicationController
# uploadPushInfo # uploadPushInfo
end end
def create_new_pr(params) def create_new_pr(params)
if params[:new_branch].present? && params[:new_branch] != params[:branch] if params[:new_branch].present? && params[:new_branch] != params[:branch]
local_params = { local_params = {
@ -303,7 +316,7 @@ class RepositoriesController < ApplicationController
local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id)) local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id))
if local_requests.save if local_requests.save
gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call
if gitea_request[:status] == :success && local_requests.update_attributes(gpid: gitea_request["body"]["number"]) if gitea_request[:status] == :success && local_requests.update_attributes(gitea_number: gitea_request["body"]["number"])
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create") local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
end end
end end

View File

@ -4,7 +4,7 @@ class SettingsController < ApplicationController
get_add_menu get_add_menu
get_common_menu get_common_menu
get_personal_menu get_personal_menu
get_third_party
end end
private private
@ -40,6 +40,14 @@ class SettingsController < ApplicationController
end end
end end
def get_third_party
@third_party = []
@third_party << {
name: 'educoder',
url: EducoderOauth.oauth_url
}
end
def get_site_url(key, value) def get_site_url(key, value)
key.to_s === "url" ? append_http(reset_site_url(value)) : reset_site_url(value) key.to_s === "url" ? append_http(reset_site_url(value)) : reset_site_url(value)
end end

View File

@ -267,7 +267,7 @@ class UsersController < ApplicationController
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params) interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params)
if interactor.success? if interactor.success?
user.update!(password: params[:password], mail: params[:email], status: User::STATUS_EDIT_INFO) user.update!(password: params[:password], mail: params[:email], status: User::STATUS_ACTIVE)
render_ok render_ok
else else
render_error(interactor.error) render_error(interactor.error)

View File

@ -25,17 +25,13 @@ class VersionsController < ApplicationController
end end
def show def show
version_issues = @version.issues.issue_includes version_issues = @version.issues.issue_issue.issue_includes
status_type = params[:status_type] || "1" status_type = params[:status_type] || "1"
# @close_issues_size = version_issues.where(status_id: 5).size # @close_issues_size = version_issues.where(status_id: 5).size
# @open_issues_size = version_issues.size - @close_issues_size # @open_issues_size = version_issues.size - @close_issues_size
if status_type.to_s == "1" #表示开启中的
version_issues = version_issues.where.not(status_id: 5)
else
version_issues = version_issues.where(status_id: 5)
end
version_issues = version_issues.where(author_id: params[:author_id]) if params[:author_id].present? && params[:author_id].to_s != "all" version_issues = version_issues.where(author_id: params[:author_id]) if params[:author_id].present? && params[:author_id].to_s != "all"
version_issues = version_issues.where(assigned_to_id: params[:assigned_to_id]) if params[:assigned_to_id].present? && params[:assigned_to_id].to_s != "all" version_issues = version_issues.where(assigned_to_id: params[:assigned_to_id]) if params[:assigned_to_id].present? && params[:assigned_to_id].to_s != "all"
version_issues = version_issues.where(tracker_id: params[:tracker_id]) if params[:tracker_id].present? && params[:tracker_id].to_s != "all" version_issues = version_issues.where(tracker_id: params[:tracker_id]) if params[:tracker_id].present? && params[:tracker_id].to_s != "all"
@ -47,10 +43,26 @@ class VersionsController < ApplicationController
version_issues = version_issues.joins(:issue_tags).where(issue_tags: {id: params[:issue_tag_id].to_i}) if params[:issue_tag_id].present? && params[:issue_tag_id].to_s != "all" version_issues = version_issues.joins(:issue_tags).where(issue_tags: {id: params[:issue_tag_id].to_i}) if params[:issue_tag_id].present? && params[:issue_tag_id].to_s != "all"
version_issues = version_issues.reorder("#{order_name} #{order_type}") version_issues = version_issues.reorder("#{order_name} #{order_type}")
has_filter_params = (params[:author_id].present? && params[:author_id].to_s != "all") ||
(params[:assigned_to_id].present? && params[:assigned_to_id].to_s != "all") ||
(params[:tracker_id].present? && params[:tracker_id].to_s != "all") ||
(params[:status_id].present? && params[:status_id].to_s != "all") ||
(params[:priority_id].present? && params[:priority_id].to_s != "all") ||
(params[:fixed_version_id].present? && params[:fixed_version_id].to_s != "all") ||
(params[:done_ratio].present? && params[:done_ratio].to_s != "all") ||
(params[:issue_type].present? && params[:issue_type].to_s != "all") ||
(params[:issue_tag_id].present? && params[:issue_tag_id].to_s != "all")
@version_close_issues_size = has_filter_params ? version_issues.closed.size : @version.issues.issue_issue.issue_includes.closed.size
@version_issues_size = has_filter_params ? version_issues.size : @version.issues.issue_issue.issue_includes.size
if status_type.to_s == "1" #表示开启中的
version_issues = version_issues.where.not(status_id: 5)
else
version_issues = version_issues.where(status_id: 5)
end
@page = params[:page] || 1 @page = params[:page] || 1
@limit = params[:limit] || 15 @limit = params[:limit] || 15
@version_issues_size = version_issues.size # @version_issues_size = version_issues.size
@version_issues = version_issues.page(@page).per(@limit) @version_issues = version_issues.page(@page).per(@limit)
end end

View File

@ -12,6 +12,7 @@ toc_footers:
includes: includes:
- licenses - licenses
- gitignores - gitignores
- public_keys
- users - users
- projects - projects
- repositories - repositories

View File

@ -0,0 +1,158 @@
<!--
* @Date: 2021-07-14 15:10:29
* @LastEditors: viletyy
* @LastEditTime: 2021-07-14 15:37:23
* @FilePath: /forgeplus/app/docs/slate/source/includes/_public_keys.md
-->
# PublicKeys
## public_keys列表
获取public_keys列表支持分页
> 示例:
```shell
curl -X GET \
http://localhost:3000/api/public_keys.json
```
```javascript
await octokit.request('GET /api/public_keys.json')
```
### HTTP 请求
`GET api/public_keys.json`
### 请求参数
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
page |否| 1 | int | 页码 |
limit |否| 15 | int | 每页数量 |
### 返回字段说明
参数 | 类型 | 字段说明
--------- | ----------- | -----------
total_count |int |总数 |
public_keys.id |int |ID|
public_keys.name |string|密钥标题|
public_keys.content |string|密钥内容|
public_keys.fingerprint |string|密钥标识|
public_keys.created_time |string|密钥创建时间|
> 返回的JSON示例:
```json
{
"total_count": 1,
"public_keys": [
{
"id": 16,
"name": "xxx",
"content": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDe5ETOTB5PcmcYJkIhfF7+mxmJQDCLg7/LnMoKHpKoo/jYUnFU9OjfsxVo3FTNUvh2475WXMAur5KsFoNKjK9+JHxvoXyJKmyVPWgXU/NRxQyaWPnPLPK8qPRF5ksJE6feBOqtsdxsvBiHs2r1NX/U26Ecnpr6avudD0cmyrEfbYMWbupLrhsd39dswPT73f3W5jc7B9Y47Ioiv8UOju3ABt1+kpuAjaaVC6VtUQoEFiZb1y33yBnyePya7dvFyApyD4ILyyIG2rtZWK7l53YFnwZDuFsTWjEEEQD0U4FBSFdH5wtwx0WQLMSNyTtaFBSG0kJ+uiQQIrxlvikcm63df7zbC3/rWLPsKgW122Zt966dcpFqiCiJNDKZPPw3qpg8TBL6X+qIZ+FxVEk/16/zScpyEfoxQp0GvgxI7hPLErmfkC5tMsib8MAXYBNyvJXna0vg/wOaNNIaI4SAH9Ksh3f/TtalYVjp6WxIwVBfnbq51WnmlnEXePtX6XjAGL+GbF2VQ1nv/IzrY09tNbTV6wQsrSIP3VDzYQxdJ1rdsVNMoJB0H2Pu0NdcSz53Wx45N+myD0QnE05ss+zDp5StY90OYsx2aCo6qAA8Qn2jUjdta7MQWwkPfKrta4tTQ0XbWMjx4/E1+l3J5liwZkl2XOGOwhfXdRsBjaEziZ18kQ== yystopf@163.com",
"fingerprint": "SHA256:cU8AK/+roqUUyiaYXIdS2Nj4+Rb2p6rqWSeRDc+aqKM",
"created_unix": 1626246596,
"created_time": "2021/07/14 15:09"
}
]
}
```
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>
## 创建public_key
创建public_key
> 示例:
```shell
curl -X POST \
http://localhost:3000/api/public_keys.json
```
```javascript
await octokit.request('POST /api/public_keys.json')
```
### HTTP 请求
`POST api/public_keys.json`
### 请求参数
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
key |是 | 否 | string | 密钥 |
title |是 | 否 | string | 密钥标题 |
> 请求的JSON示例
```json
{
"public_key": {
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDe5ETOTB5PcmcYJkIhfF7+mxmJQDCLg7/LnMoKHpKoo/jYUnFU9OjfsxVo3FTNUvh2475WXMAur5KsFoNKjK9+JHxvoXyJKmyVPWgXU/NRxQyaWPnPLPK8qPRF5ksJE6feBOqtsdxsvBiHs2r1NX/U26Ecnpr6avudD0cmyrEfbYMWbupLrhsd39dswPT73f3W5jc7B9Y47Ioiv8UOju3ABt1+kpuAjaaVC6VtUQoEFiZb1y33yBnyePya7dvFyApyD4ILyyIG2rtZWK7l53YFnwZDuFsTWjEEEQD0U4FBSFdH5wtwx0WQLMSNyTtaFBSG0kJ+uiQQIrxlvikcm63df7zbC3/rWLPsKgW122Zt966dcpFqiCiJNDKZPPw3qpg8TBL6X+qIZ+FxVEk/16/zScpyEfoxQp0GvgxI7hPLErmfkC5tMsib8MAXYBNyvJXna0vg/wOaNNIaI4SAH9Ksh3f/TtalYVjp6WxIwVBfnbq51WnmlnEXePtX6XjAGL+GbF2VQ1nv/IzrY09tNbTV6wQsrSIP3VDzYQxdJ1rdsVNMoJB0H2Pu0NdcSz53Wx45N+myD0QnE05ss+zDp5StY90OYsx2aCo6qAA8Qn2jUjdta7MQWwkPfKrta4tTQ0XbWMjx4/E1+l3J5liwZkl2XOGOwhfXdRsBjaEziZ18kQ== yystopf@163.com",
"title": "xxx"
}
}
```
### 返回字段说明
参数 | 类型 | 字段说明
--------- | ----------- | -----------
total_count |int |总数 |
id |int |ID|
name |string|密钥标题|
content |string|密钥内容|
fingerprint |string|密钥标识|
created_time |string|密钥创建时间|
> 返回的JSON示例:
```json
{
"id": 17,
"name": "xxx",
"content": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDe5ETOTB5PcmcYJkIhfF7+mxmJQDCLg7/LnMoKHpKoo/jYUnFU9OjfsxVo3FTNUvh2475WXMAur5KsFoNKjK9+JHxvoXyJKmyVPWgXU/NRxQyaWPnPLPK8qPRF5ksJE6feBOqtsdxsvBiHs2r1NX/U26Ecnpr6avudD0cmyrEfbYMWbupLrhsd39dswPT73f3W5jc7B9Y47Ioiv8UOju3ABt1+kpuAjaaVC6VtUQoEFiZb1y33yBnyePya7dvFyApyD4ILyyIG2rtZWK7l53YFnwZDuFsTWjEEEQD0U4FBSFdH5wtwx0WQLMSNyTtaFBSG0kJ+uiQQIrxlvikcm63df7zbC3/rWLPsKgW122Zt966dcpFqiCiJNDKZPPw3qpg8TBL6X+qIZ+FxVEk/16/zScpyEfoxQp0GvgxI7hPLErmfkC5tMsib8MAXYBNyvJXna0vg/wOaNNIaI4SAH9Ksh3f/TtalYVjp6WxIwVBfnbq51WnmlnEXePtX6XjAGL+GbF2VQ1nv/IzrY09tNbTV6wQsrSIP3VDzYQxdJ1rdsVNMoJB0H2Pu0NdcSz53Wx45N+myD0QnE05ss+zDp5StY90OYsx2aCo6qAA8Qn2jUjdta7MQWwkPfKrta4tTQ0XbWMjx4/E1+l3J5liwZkl2XOGOwhfXdRsBjaEziZ18kQ== yystopf@163.com",
"fingerprint": "SHA256:cU8AK/+roqUUyiaYXIdS2Nj4+Rb2p6rqWSeRDc+aqKM",
"created_time": "2021/07/14 15:26"
}
```
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>
## 删除public_key
删除public_key
> 示例:
```shell
curl -X DELETE \
http://localhost:3000/api/public_keys/:id.json
```
```javascript
await octokit.request('DELETE /api/public_keys/:id.json')
```
### HTTP 请求
`DELETE api/public_keys/:id.json`
### 请求参数
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
id |是 | 否 | int | 密钥ID |
> 返回的JSON示例:
```json
{
"status": 0,
"message": "success"
}
```
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>

View File

@ -13,12 +13,12 @@ module ProjectsHelper
end end
end end
def render_zip_url(project, archive_name) def render_zip_url(owner, repository, archive)
[gitea_domain, project.owner.login, project.identifier, "archive", "#{archive_name}.zip"].join('/') [base_url, archive_repositories_path(owner&.login, repository, "#{archive}.zip")].join
end end
def render_tar_url(project, archive_name) def render_tar_url(owner, repository, archive)
[gitea_domain, project.owner.login, project.identifier, "archive", "#{archive_name}.tar.gz"].join('/') [base_url, archive_repositories_path(owner&.login, repository, "#{archive}.tar.gz")].join
end end
def render_http_url(project) def render_http_url(project)

View File

@ -10,12 +10,12 @@ module RepositoriesHelper
end end
def download_type(str) def download_type(str)
default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb png jpg gif tif psd svg RData rdata doc docx mpp vsdx dot) default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb png jpg gif tif psd svg RData rdata doc docx mpp vsdx dot otf eot ttf woff woff2)
default_type.include?(str&.downcase) default_type.include?(str&.downcase)
end end
def image_type?(str) def image_type?(str)
default_type = %w(png jpg gif tif psd svg) default_type = %w(png jpg gif tif psd svg gif bmp webp jpeg)
default_type.include?(str&.downcase) default_type.include?(str&.downcase)
end end
@ -81,9 +81,47 @@ module RepositoriesHelper
content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, entry['path'], ref: ref)['content'] content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, entry['path'], ref: ref)['content']
readme_render_decode64_content(content, path) readme_render_decode64_content(content, path)
else else
file_type = entry['name'].to_s.split(".").last file_type = File.extname(entry['name'].to_s)[1..-1]
return entry['content'] if download_type(file_type) if download_type(file_type)
return entry['content'].nil? ? Gitea::Repository::Entries::GetService.call(owner, repo.identifier, entry['path'], ref: ref)['content'] : entry['content']
end
render_decode64_content(entry['content']) render_decode64_content(entry['content'])
end end
end end
def base64_to_image(path, content)
# generate to https://git.trusite.net/pawm36ozq/-/raw/branch/master/entrn.png"
content = Base64.decode64(content)
File.open(path, 'wb') { |f| f.write(content) }
end
def render_download_image_url(dir_path, file_path, content)
full_path = file_path.starts_with?("/") ? [dir_path, file_path].join("") : [dir_path, file_path].join("/")
file_name = full_path.split("/")[-1]
# 用户名/项目标识/文件路径
dir_path = generate_dir_path(full_path.split("/"+file_name)[0])
file_path = [dir_path, file_name].join('/')
puts "##### render_download_image_url file_path: #{file_path}"
base64_to_image(file_path, content)
file_path = file_path[6..-1]
File.join(base_url, file_path)
end
def generate_dir_path(dir_path)
# tmp_dir_path
# eg: jasder/forgeplus/raw/branch/ref
dir_path = ["public", tmp_dir, dir_path].join('/')
puts "#### dir_path: #{dir_path}"
unless Dir.exists?(dir_path)
FileUtils.mkdir_p(dir_path) ##不成功这里会抛异常
end
dir_path
end
def tmp_dir
"repo"
end
end end

View File

@ -24,8 +24,14 @@ module Gitea
def run def run
Contents::CreateForm.new(valid_params).validate! Contents::CreateForm.new(valid_params).validate!
response = Gitea::Repository::Entries::CreateService.new(token, owner, @params[:identifier], @params[:filepath], file_params).call result = Gitea::Repository::Entries::CreateService.call(token,
render_result(response) owner, @params[:identifier], @params[:filepath], file_params)
if result[:status] == :success
@result = result[:body]
else
fail!(result[:message])
end
rescue Exception => exception rescue Exception => exception
Rails.logger.info "Exception ===========> #{exception.message}" Rails.logger.info "Exception ===========> #{exception.message}"
fail!(exception.message) fail!(exception.message)
@ -56,7 +62,7 @@ module Gitea
file_params = {} file_params = {}
file_params = file_params.merge(branch: @params[:branch]) unless @params[:branch].blank? file_params = file_params.merge(branch: @params[:branch]) unless @params[:branch].blank?
file_params = file_params.merge(new_branch: @params[:new_branch]) unless @params[:new_branch].blank? file_params = file_params.merge(new_branch: @params[:new_branch]) unless @params[:new_branch].blank?
file_params = file_params.merge(content: Base64.encode64(@params[:content])) file_params = file_params.merge(content: Base64.encode64(@params[:content] || ""))
file_params = file_params.merge(message: @params[:message]) unless @params[:message].blank? file_params = file_params.merge(message: @params[:message]) unless @params[:message].blank?
file_params = file_params.merge(committer: @params[:committer]) file_params = file_params.merge(committer: @params[:committer])
file_params file_params

View File

@ -2,6 +2,7 @@ class ResetUserCacheJob < ApplicationJob
queue_as :cache queue_as :cache
def perform(user) def perform(user)
return if user.nil?
Cache::UserFollowCountService.new(user).reset Cache::UserFollowCountService.new(user).reset
Cache::UserIssueCountService.new(user).reset Cache::UserIssueCountService.new(user).reset
Cache::UserProjectCountService.new(user).reset Cache::UserProjectCountService.new(user).reset

View File

@ -0,0 +1,18 @@
module EducoderOauth
class << self
attr_accessor :client_id, :client_secret, :base_url, :redirect_uri
def logger
@_logger ||= STDOUT
end
def logger=(l)
@_logger = l
end
def oauth_url
"#{base_url}/oauth2?call_url=/oauth/authorize?client_id=#{client_id}&redirect_uri=#{URI.encode_www_form_component(redirect_uri)}&response_type=code"
end
end
end

View File

@ -0,0 +1,37 @@
require 'oauth2'
module EducoderOauth::Service
module_function
def request(method, url, params)
begin
Rails.logger.info("[EducoderOauth] [#{method.to_s.upcase}] #{url} || #{params}")
client = Faraday.new(url: EducoderOauth.base_url)
response = client.public_send(method, url, params)
result = JSON.parse(response.body)
Rails.logger.info("[EducoderOauth] [#{response.status}] #{result}")
result
rescue Exception => e
raise Educoder::TipException.new(e.message)
end
end
def access_token(code)
begin
Rails.logger.info("[EducoderOauth] [code] #{code} ")
Rails.logger.info("[EducoderOauth] [redirect_uri] #{EducoderOauth.redirect_uri} ")
client = OAuth2::Client.new(EducoderOauth.client_id, EducoderOauth.client_secret, site: EducoderOauth.base_url)
result = client.auth_code.get_token(code, redirect_uri: EducoderOauth.redirect_uri).to_hash
return result
rescue Exception => e
raise Educoder::TipException.new(e.message)
end
end
def user_info(access_token)
request(:get, '/api/users/info.json', {access_token: access_token})
end
end

View File

@ -1,19 +1,26 @@
# == Schema Information # == Schema Information
# #
# Table name: applied_messages # Table name: forge_applied_messages
# #
# id :integer not null, primary key # id :integer not null, primary key
# user_id :integer # user_id :integer
# applied_id :integer
# applied_type :string(255) # applied_type :string(255)
# applied_id :integer
# viewed :integer default("0") # viewed :integer default("0")
# status :integer default("0") # status :integer default("0")
# created_at :datetime not null
# updated_at :datetime not null
# name :string(255) # name :string(255)
# applied_user_id :integer # applied_user_id :integer
# role :integer # role :integer
# project_id :integer # project_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_forge_applied_messages_on_applied_type_and_applied_id (applied_type,applied_id)
# index_forge_applied_messages_on_applied_user_id (applied_user_id)
# index_forge_applied_messages_on_project_id (project_id)
# index_forge_applied_messages_on_user_id (user_id)
# #
class AppliedMessage < ApplicationRecord class AppliedMessage < ApplicationRecord

View File

@ -1,14 +1,19 @@
# == Schema Information # == Schema Information
# #
# Table name: applied_projects # Table name: forge_applied_projects
# #
# id :integer not null, primary key # id :integer not null, primary key
# project_id :integer not null # project_id :integer
# user_id :integer not null # user_id :integer
# role :integer default("0") # role :integer default("0")
# status :integer default("0") # status :integer default("0")
# created_at :datetime # created_at :datetime not null
# updated_at :datetime # updated_at :datetime not null
#
# Indexes
#
# index_forge_applied_projects_on_project_id (project_id)
# index_forge_applied_projects_on_user_id (user_id)
# #
class AppliedProject < ApplicationRecord class AppliedProject < ApplicationRecord

View File

@ -1,41 +1,42 @@
# == Schema Information # == Schema Information
# #
# Table name: attachments # Table name: attachments
# #
# id :integer not null, primary key # id :integer not null, primary key
# container_id :integer # container_id :integer
# container_type :string(30) # container_type :string(30)
# filename :string(255) default(""), not null # filename :string(255) default(""), not null
# disk_filename :string(255) default(""), not null # disk_filename :string(255) default(""), not null
# filesize :integer default("0"), not null # filesize :integer default("0"), not null
# content_type :string(255) default("") # content_type :string(255) default("")
# digest :string(60) default(""), not null # digest :string(60) default(""), not null
# downloads :integer default("0"), not null # downloads :integer default("0"), not null
# author_id :integer default("0"), not null # author_id :integer default("0"), not null
# created_on :datetime # created_on :datetime
# description :text(65535) # description :text(65535)
# disk_directory :string(255) # disk_directory :string(255)
# attachtype :integer default("1") # attachtype :integer default("1")
# is_public :integer default("1") # is_public :integer default("1")
# copy_from :integer # copy_from :string(255)
# quotes :integer default("0") # quotes :integer default("0")
# is_publish :integer default("1") # is_publish :integer default("1")
# publish_time :datetime # publish_time :datetime
# resource_bank_id :integer # resource_bank_id :integer
# unified_setting :boolean default("1") # unified_setting :boolean default("1")
# cloud_url :string(255) default("") # cloud_url :string(255) default("")
# course_second_category_id :integer default("0") # course_second_category_id :integer default("0")
# delay_publish :boolean default("0") # delay_publish :boolean default("0")
# # link :string(255)
# Indexes # clone_id :integer
# #
# index_attachments_on_author_id (author_id) # Indexes
# index_attachments_on_container_id_and_container_type (container_id,container_type) #
# index_attachments_on_course_second_category_id (course_second_category_id) # index_attachments_on_author_id (author_id)
# index_attachments_on_created_on (created_on) # index_attachments_on_clone_id (clone_id)
# index_attachments_on_is_public (is_public) # index_attachments_on_container_id_and_container_type (container_id,container_type)
# index_attachments_on_quotes (quotes) # index_attachments_on_created_on (created_on)
# #
class Attachment < ApplicationRecord class Attachment < ApplicationRecord

View File

@ -39,17 +39,15 @@
# business :boolean default("0") # business :boolean default("0")
# profile_completed :boolean default("0") # profile_completed :boolean default("0")
# laboratory_id :integer # laboratory_id :integer
# platform :string(255) default("0")
# gitea_token :string(255)
# gitea_uid :integer
# is_shixun_marker :boolean default("0") # is_shixun_marker :boolean default("0")
# admin_visitable :boolean default("0")
# collaborator :boolean default("0")
# gitea_uid :integer
# is_sync_pwd :boolean default("1") # is_sync_pwd :boolean default("1")
# watchers_count :integer default("0") # watchers_count :integer default("0")
# devops_step :integer default("0") # devops_step :integer default("0")
# sponsor_certification :integer default("0") # gitea_token :string(255)
# sponsor_num :integer default("0") # platform :string(255)
# sponsored_num :integer default("0")
# award_time :datetime
# #
# Indexes # Indexes
# #
@ -57,8 +55,9 @@
# index_users_on_homepage_engineer (homepage_engineer) # index_users_on_homepage_engineer (homepage_engineer)
# index_users_on_homepage_teacher (homepage_teacher) # index_users_on_homepage_teacher (homepage_teacher)
# index_users_on_laboratory_id (laboratory_id) # index_users_on_laboratory_id (laboratory_id)
# index_users_on_login (login) # index_users_on_login (login) UNIQUE
# index_users_on_mail (mail) # index_users_on_mail (mail) UNIQUE
# index_users_on_phone (phone) UNIQUE
# index_users_on_type (type) # index_users_on_type (type)
# #

View File

@ -65,7 +65,7 @@ module ProjectOperable
if owner.is_a?(User) if owner.is_a?(User)
managers.exists?(user_id: user.id) managers.exists?(user_id: user.id)
elsif owner.is_a?(Organization) elsif owner.is_a?(Organization)
managers.exists?(user_id: user.id) || owner.is_only_admin?(user.id) managers.exists?(user_id: user.id) || owner.is_owner?(user.id) || owner.is_only_admin?(user.id)
else else
false false
end end
@ -94,7 +94,7 @@ module ProjectOperable
end end
def operator?(user) def operator?(user)
user.admin? || !reporter?(user) user.admin? || (member?(user.id) && !reporter?(user))
end end
def set_developer_role(member, role_name) def set_developer_role(member, role_name)

View File

@ -1,4 +1,6 @@
class Gitea::Base < Gitea::Database class Gitea::Base < ApplicationRecord
self.abstract_class = true db_config = Rails.configuration.database_configuration[Rails.env]["gitea_server"]
raise 'gitea database config missing' if db_config.blank?
establish_connection db_config
end end

View File

@ -0,0 +1,9 @@
class Gitea::PublicKey < Gitea::Base
self.inheritance_column = nil # FIX The single-table inheritance mechanism failed
# establish_connection :gitea_db
self.table_name = "public_key"
belongs_to :user, class_name: '::User', foreign_key: :gitea_uid, primary_key: :owner_id, optional: true
end

44
app/models/gitea/pull.rb Normal file
View File

@ -0,0 +1,44 @@
# == Schema Information
#
# Table name: pull_request
#
# id :integer not null, primary key
# type :integer
# status :integer
# conflicted_files :text(65535)
# commits_ahead :integer
# commits_behind :integer
# changed_protected_files :text(65535)
# issue_id :integer
# index :integer
# head_repo_id :integer
# base_repo_id :integer
# head_branch :string(255)
# base_branch :string(255)
# merge_base :string(40)
# has_merged :boolean
# merged_commit_id :string(40)
# merger_id :integer
# merged_unix :integer
#
# Indexes
#
# IDX_pull_request_base_repo_id (base_repo_id)
# IDX_pull_request_has_merged (has_merged)
# IDX_pull_request_head_repo_id (head_repo_id)
# IDX_pull_request_issue_id (issue_id)
# IDX_pull_request_merged_unix (merged_unix)
# IDX_pull_request_merger_id (merger_id)
#
class Gitea::Pull < Gitea::Base
self.inheritance_column = nil # FIX The single-table inheritance mechanism failed
# establish_connection :gitea_db
self.table_name = "pull_request"
serialize :conflicted_files, Array
belongs_to :pull_request, class_name: '::PullRequest', foreign_key: :id, primary_key: :gitea_id, optional: true
end

View File

@ -10,6 +10,7 @@
# sync_course :boolean default("0") # sync_course :boolean default("0")
# sync_subject :boolean default("0") # sync_subject :boolean default("0")
# sync_shixun :boolean default("0") # sync_shixun :boolean default("0")
# is_local :boolean default("0")
# #
# Indexes # Indexes
# #

View File

@ -7,7 +7,6 @@
# content :text(65535) # content :text(65535)
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# is_secret :boolean default("0")
# #
class License < ApplicationRecord class License < ApplicationRecord

View File

@ -11,7 +11,6 @@
# course_group_id :integer default("0") # course_group_id :integer default("0")
# is_collect :integer default("1") # is_collect :integer default("1")
# graduation_group_id :integer default("0") # graduation_group_id :integer default("0")
# is_apply_signature :boolean default("0")
# #
# Indexes # Indexes
# #

View File

@ -39,17 +39,15 @@
# business :boolean default("0") # business :boolean default("0")
# profile_completed :boolean default("0") # profile_completed :boolean default("0")
# laboratory_id :integer # laboratory_id :integer
# platform :string(255) default("0")
# gitea_token :string(255)
# gitea_uid :integer
# is_shixun_marker :boolean default("0") # is_shixun_marker :boolean default("0")
# admin_visitable :boolean default("0")
# collaborator :boolean default("0")
# gitea_uid :integer
# is_sync_pwd :boolean default("1") # is_sync_pwd :boolean default("1")
# watchers_count :integer default("0") # watchers_count :integer default("0")
# devops_step :integer default("0") # devops_step :integer default("0")
# sponsor_certification :integer default("0") # gitea_token :string(255)
# sponsor_num :integer default("0") # platform :string(255)
# sponsored_num :integer default("0")
# award_time :datetime
# #
# Indexes # Indexes
# #
@ -57,8 +55,9 @@
# index_users_on_homepage_engineer (homepage_engineer) # index_users_on_homepage_engineer (homepage_engineer)
# index_users_on_homepage_teacher (homepage_teacher) # index_users_on_homepage_teacher (homepage_teacher)
# index_users_on_laboratory_id (laboratory_id) # index_users_on_laboratory_id (laboratory_id)
# index_users_on_login (login) # index_users_on_login (login) UNIQUE
# index_users_on_mail (mail) # index_users_on_mail (mail) UNIQUE
# index_users_on_phone (phone) UNIQUE
# index_users_on_type (type) # index_users_on_type (type)
# #

View File

@ -1,79 +1,79 @@
# == Schema Information # == Schema Information
# #
# Table name: projects # Table name: projects
# #
# id :integer not null, primary key # id :integer not null, primary key
# name :string(255) default(""), not null # name :string(255) default(""), not null
# description :text(4294967295) # description :text(4294967295)
# homepage :string(255) default("") # homepage :string(255) default("")
# is_public :boolean default("1"), not null # is_public :boolean default("1"), not null
# parent_id :integer # parent_id :integer
# created_on :datetime # created_on :datetime
# updated_on :datetime # updated_on :datetime
# identifier :string(255) # identifier :string(255)
# status :integer default("1"), not null # status :integer default("1"), not null
# lft :integer # lft :integer
# rgt :integer # rgt :integer
# inherit_members :boolean default("0"), not null # inherit_members :boolean default("0"), not null
# project_type :integer default("0") # project_type :integer default("0")
# hidden_repo :boolean default("0"), not null # hidden_repo :boolean default("0"), not null
# attachmenttype :integer default("1") # attachmenttype :integer default("1")
# user_id :integer # user_id :integer
# dts_test :integer default("0") # dts_test :integer default("0")
# enterprise_name :string(255) # enterprise_name :string(255)
# organization_id :integer # organization_id :integer
# project_new_type :integer # project_new_type :integer
# gpid :integer # gpid :integer
# forked_from_project_id :integer # forked_from_project_id :integer
# forked_count :integer default("0") # forked_count :integer default("0")
# publish_resource :integer default("0") # publish_resource :integer default("0")
# visits :integer default("0") # visits :integer default("0")
# hot :integer default("0") # hot :integer default("0")
# invite_code :string(255) # invite_code :string(255)
# qrcode :string(255) # qrcode :string(255)
# qrcode_expiretime :integer default("0") # qrcode_expiretime :integer default("0")
# script :text(65535) # script :text(65535)
# training_status :integer default("0") # training_status :integer default("0")
# rep_identifier :string(255) # rep_identifier :string(255)
# project_category_id :integer # project_category_id :integer
# project_language_id :integer # project_language_id :integer
# license_id :integer # praises_count :integer default("0")
# ignore_id :integer # watchers_count :integer default("0")
# praises_count :integer default("0") # issues_count :integer default("0")
# watchers_count :integer default("0") # pull_requests_count :integer default("0")
# issues_count :integer default("0") # language :string(255)
# pull_requests_count :integer default("0") # versions_count :integer default("0")
# language :string(255) # issue_tags_count :integer default("0")
# versions_count :integer default("0") # closed_issues_count :integer default("0")
# issue_tags_count :integer default("0") # open_devops :boolean default("0")
# closed_issues_count :integer default("0") # gitea_webhook_id :integer
# open_devops :boolean default("0") # open_devops_count :integer default("0")
# gitea_webhook_id :integer # recommend :boolean default("0")
# open_devops_count :integer default("0") # platform :integer default("0")
# recommend :boolean default("0") # license_id :integer
# platform :integer default("0") # ignore_id :integer
# default_branch :string(255) default("master") # default_branch :string(255) default("master")
# website :string(255) # website :string(255)
# order_index :integer default("0") # lesson_url :string(255)
# lesson_url :string(255) #
# # Indexes
# Indexes #
# # index_projects_on_forked_from_project_id (forked_from_project_id)
# index_projects_on_forked_from_project_id (forked_from_project_id) # index_projects_on_identifier (identifier)
# index_projects_on_identifier (identifier) # index_projects_on_invite_code (invite_code)
# index_projects_on_invite_code (invite_code) # index_projects_on_is_public (is_public)
# index_projects_on_is_public (is_public) # index_projects_on_lft (lft)
# index_projects_on_lft (lft) # index_projects_on_license_id (license_id)
# index_projects_on_name (name) # index_projects_on_name (name)
# index_projects_on_platform (platform) # index_projects_on_platform (platform)
# index_projects_on_project_type (project_type) # index_projects_on_project_category_id (project_category_id)
# index_projects_on_recommend (recommend) # index_projects_on_project_language_id (project_language_id)
# index_projects_on_rgt (rgt) # index_projects_on_project_type (project_type)
# index_projects_on_status (status) # index_projects_on_recommend (recommend)
# index_projects_on_updated_on (updated_on) # index_projects_on_rgt (rgt)
# # index_projects_on_status (status)
# index_projects_on_updated_on (updated_on)
#
class Project < ApplicationRecord class Project < ApplicationRecord
@ -98,10 +98,12 @@ class Project < ApplicationRecord
belongs_to :organization_extension, foreign_key: :user_id, primary_key: :organization_id, optional: true, counter_cache: :num_projects belongs_to :organization_extension, foreign_key: :user_id, primary_key: :organization_id, optional: true, counter_cache: :num_projects
belongs_to :project_category, optional: true , :counter_cache => true belongs_to :project_category, optional: true , :counter_cache => true
belongs_to :project_language, optional: true , :counter_cache => true belongs_to :project_language, optional: true , :counter_cache => true
belongs_to :forked_from_project, class_name: 'Project', optional: true, foreign_key: :forked_from_project_id
has_many :project_trends, dependent: :destroy has_many :project_trends, dependent: :destroy
has_many :watchers, as: :watchable, dependent: :destroy has_many :watchers, as: :watchable, dependent: :destroy
has_many :fork_users, dependent: :destroy has_many :fork_users, dependent: :destroy
has_many :forked_users, class_name: 'ForkUser', foreign_key: :fork_project_id, dependent: :destroy has_many :forked_users, class_name: 'ForkUser', foreign_key: :fork_project_id, dependent: :destroy
has_many :forked_projects, class_name: 'Project', foreign_key: :forked_from_project_id
has_one :project_educoder, dependent: :destroy has_one :project_educoder, dependent: :destroy
has_one :project_score, dependent: :destroy has_one :project_score, dependent: :destroy

View File

@ -8,11 +8,6 @@
# projects_count :integer default("0") # projects_count :integer default("0")
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# ancestry :string(255)
#
# Indexes
#
# index_project_categories_on_ancestry (ancestry)
# #
class ProjectCategory < ApplicationRecord class ProjectCategory < ApplicationRecord

View File

@ -37,6 +37,7 @@ class PullRequest < ApplicationRecord
has_many :pull_request_tags, foreign_key: :pull_request_id has_many :pull_request_tags, foreign_key: :pull_request_id
has_many :project_trends, as: :trend, dependent: :destroy has_many :project_trends, as: :trend, dependent: :destroy
has_many :attachments, as: :container, dependent: :destroy has_many :attachments, as: :container, dependent: :destroy
has_one :gitea_pull, foreign_key: :id, primary_key: :gitea_id, class_name: 'Gitea::Pull'
scope :merged_and_closed, ->{where.not(status: 0)} scope :merged_and_closed, ->{where.not(status: 0)}
scope :opening, -> {where(status: 0)} scope :opening, -> {where(status: 0)}
@ -53,8 +54,10 @@ class PullRequest < ApplicationRecord
Project.find_by(id: self.fork_project_id) Project.find_by(id: self.fork_project_id)
end end
def bind_gitea_pull_request!(gitea_pull_number) def bind_gitea_pull_request!(gitea_pull_number, gitea_pull_id)
update_column(:gpid, gitea_pull_number) update_columns(
gitea_number: gitea_pull_number,
gitea_id: gitea_pull_id)
end end
def merge! def merge!
@ -67,19 +70,26 @@ class PullRequest < ApplicationRecord
# TODO: sync educoder platform repo's for update some statistics count # TODO: sync educoder platform repo's for update some statistics count
def self.update_some_count def self.update_some_count
PullRequest.includes(:user, :project).select(:id, :user_id, :gpid, :project_id, :fork_project_id).each do |pr| PullRequest.includes(:user, :project).select(:id, :user_id, :gitea_number, :project_id, :fork_project_id).each do |pr|
puts pr.id puts pr.id
next if pr.gpid.blank? next if pr.gitea_number.blank?
project = pr.project project = pr.project
next if project.blank? next if project.blank?
user = project.owner user = project.owner
next if pr.gpid === 6 || pr.gpid === 7 next if pr.gitea_number === 6 || pr.gitea_number === 7
files_result = Gitea::PullRequest::FilesService.call(user.login, project.identifier, pr.gpid) files_result = Gitea::PullRequest::FilesService.call(user.login, project.identifier, pr.gitea_number)
pr.update_column(:files_count, files_result['NumFiles']) unless files_result.blank? pr.update_column(:files_count, files_result['NumFiles']) unless files_result.blank?
commits_result = Gitea::PullRequest::CommitsService.call(user.login, project.identifier, pr.gpid) commits_result = Gitea::PullRequest::CommitsService.call(user.login, project.identifier, pr.gitea_number)
pr.update_column(:commits_count, commits_result.size) unless commits_result.blank? pr.update_column(:commits_count, commits_result.size) unless commits_result.blank?
end end
end end
def conflict_files
file_names = self&.gitea_pull&.conflicted_files
return [] if file_names.blank?
JSON.parse file_names
end
end end

View File

@ -27,7 +27,6 @@
# #
# Indexes # Indexes
# #
# index_repositories_on_identifier (identifier)
# index_repositories_on_project_id (project_id) # index_repositories_on_project_id (project_id)
# index_repositories_on_user_id (user_id) # index_repositories_on_user_id (user_id)
# #

View File

@ -1,19 +1,19 @@
# == Schema Information # == Schema Information
# #
# Table name: tokens # Table name: tokens
# #
# id :integer not null, primary key # id :integer not null, primary key
# user_id :integer default("0"), not null # user_id :integer default("0"), not null
# action :string(30) default(""), not null # action :string(30) default(""), not null
# value :string(40) default(""), not null # value :string(40) default(""), not null
# created_on :datetime not null # created_on :datetime not null
# #
# Indexes # Indexes
# #
# index_tokens_on_user_id (user_id) # index_tokens_on_user_id (user_id)
# tokens_value (value) UNIQUE # tokens_value (value) UNIQUE
# #
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -76,7 +76,7 @@ class Token < ActiveRecord::Base
# Returns the active user who owns the key for the given action # Returns the active user who owns the key for the given action
def self.find_active_user(action, key, validity_days=nil) def self.find_active_user(action, key, validity_days=nil)
user = find_user(action, key, validity_days) user = find_user(action, key, validity_days)
if user && user.active? if user && (user.active? || user.need_edit_info?)
user user
end end
end end

View File

@ -39,17 +39,15 @@
# business :boolean default("0") # business :boolean default("0")
# profile_completed :boolean default("0") # profile_completed :boolean default("0")
# laboratory_id :integer # laboratory_id :integer
# platform :string(255) default("0")
# gitea_token :string(255)
# gitea_uid :integer
# is_shixun_marker :boolean default("0") # is_shixun_marker :boolean default("0")
# admin_visitable :boolean default("0")
# collaborator :boolean default("0")
# gitea_uid :integer
# is_sync_pwd :boolean default("1") # is_sync_pwd :boolean default("1")
# watchers_count :integer default("0") # watchers_count :integer default("0")
# devops_step :integer default("0") # devops_step :integer default("0")
# sponsor_certification :integer default("0") # gitea_token :string(255)
# sponsor_num :integer default("0") # platform :string(255)
# sponsored_num :integer default("0")
# award_time :datetime
# #
# Indexes # Indexes
# #
@ -57,8 +55,9 @@
# index_users_on_homepage_engineer (homepage_engineer) # index_users_on_homepage_engineer (homepage_engineer)
# index_users_on_homepage_teacher (homepage_teacher) # index_users_on_homepage_teacher (homepage_teacher)
# index_users_on_laboratory_id (laboratory_id) # index_users_on_laboratory_id (laboratory_id)
# index_users_on_login (login) # index_users_on_login (login) UNIQUE
# index_users_on_mail (mail) # index_users_on_mail (mail) UNIQUE
# index_users_on_phone (phone) UNIQUE
# index_users_on_type (type) # index_users_on_type (type)
# #
@ -84,6 +83,7 @@ class User < Owner
STATUS_ACTIVE = 1 STATUS_ACTIVE = 1
STATUS_REGISTERED = 2 STATUS_REGISTERED = 2
STATUS_LOCKED = 3 STATUS_LOCKED = 3
STATUS_EDIT_INFO = 4
# tpi tpm权限控制 # tpi tpm权限控制
EDU_ADMIN = 1 # 超级管理员 EDU_ADMIN = 1 # 超级管理员
@ -170,9 +170,10 @@ class User < Owner
accepts_nested_attributes_for :is_pinned_projects accepts_nested_attributes_for :is_pinned_projects
has_many :issues, dependent: :destroy, foreign_key: :author_id has_many :issues, dependent: :destroy, foreign_key: :author_id
has_many :pull_requests, dependent: :destroy has_many :pull_requests, dependent: :destroy
has_many :public_keys, class_name: "Gitea::PublicKey",primary_key: :gitea_uid, foreign_key: :owner_id, dependent: :destroy
# Groups and active users # Groups and active users
scope :active, lambda { where(status: STATUS_ACTIVE) } scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) }
scope :like, lambda { |keywords| scope :like, lambda { |keywords|
sql = "CONCAT(lastname, firstname) LIKE :search OR nickname LIKE :search OR login LIKE :search OR mail LIKE :search OR nickname LIKE :search" sql = "CONCAT(lastname, firstname) LIKE :search OR nickname LIKE :search OR login LIKE :search OR mail LIKE :search OR nickname LIKE :search"
where(sql, :search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank? where(sql, :search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank?
@ -186,7 +187,7 @@ class User < Owner
:show_email, :show_location, :show_department, :show_email, :show_location, :show_department,
:technical_title, :province, :city, :custom_department, to: :user_extension, allow_nil: true :technical_title, :province, :city, :custom_department, to: :user_extension, allow_nil: true
before_save :update_hashed_password before_save :update_hashed_password, :set_lastname
after_create do after_create do
SyncTrustieJob.perform_later("user", 1) if allow_sync_to_trustie? SyncTrustieJob.perform_later("user", 1) if allow_sync_to_trustie?
end end
@ -410,6 +411,10 @@ class User < Owner
status == STATUS_LOCKED status == STATUS_LOCKED
end end
def need_edit_info?
status == STATUS_EDIT_INFO
end
def activate def activate
self.status = STATUS_ACTIVE self.status = STATUS_ACTIVE
end end
@ -422,6 +427,10 @@ class User < Owner
self.status = STATUS_LOCKED self.status = STATUS_LOCKED
end end
def need_edit_info
self.status = STATUS_EDIT_INFO
end
def activate! def activate!
update_attribute(:status, STATUS_ACTIVE) update_attribute(:status, STATUS_ACTIVE)
end end
@ -434,6 +443,10 @@ class User < Owner
update_attribute(:status, STATUS_LOCKED) update_attribute(:status, STATUS_LOCKED)
end end
def need_edit_info!
update_attribute(:status, STATUS_EDIT_INFO)
end
# 课程用户身份 # 课程用户身份
def course_identity(course) def course_identity(course)
if !logged? if !logged?
@ -779,6 +792,10 @@ class User < Owner
self.laboratory = Laboratory.current if laboratory_id.blank? self.laboratory = Laboratory.current if laboratory_id.blank?
end end
def set_lastname
self.lastname = self.nickname if changes[:nickname].present?
end
end end

View File

@ -12,7 +12,9 @@
# #
# Indexes # Indexes
# #
# index_user_actions_on_ip (ip) # index_user_actions_on_ip (ip)
# index_user_actions_on_user_id (user_id)
# index_user_actions_on_user_id_and_action_type (user_id,action_type)
# #
class UserAction < ApplicationRecord class UserAction < ApplicationRecord

View File

@ -10,10 +10,13 @@
# updated_at :datetime not null # updated_at :datetime not null
# register_status :integer default("0") # register_status :integer default("0")
# action_status :integer default("0") # action_status :integer default("0")
# is_delete :boolean default("0")
# user_id :integer
# #
# Indexes # Indexes
# #
# index_user_agents_on_ip (ip) UNIQUE # index_user_agents_on_ip (ip)
# index_user_agents_on_user_id (user_id)
# #
class UserAgent < ApplicationRecord class UserAgent < ApplicationRecord

View File

@ -22,6 +22,9 @@
# school_id :integer # school_id :integer
# description :string(255) default("") # description :string(255) default("")
# department_id :integer # department_id :integer
# honor :text(65535)
# edu_background :integer
# edu_entry_year :integer
# province :string(255) # province :string(255)
# city :string(255) # city :string(255)
# custom_department :string(255) # custom_department :string(255)

View File

@ -46,11 +46,11 @@ class Cache::PlatformProjectLanguagesCountService < ApplicationService
def reset_platform_project_language_count_by_key def reset_platform_project_language_count_by_key
return if key.nil? return if key.nil?
$redis_cache.hset(platform_project_language_count_key, key, Project.joins(:project_language).where(project_languages: {name: key}).count) $redis_cache.hset(platform_project_language_count_key, key, ProjectLanguage.where(name: key).projects_count)
end end
def reset_platform_project_language_count def reset_platform_project_language_count
Project.joins(:project_language).group("project_languages.name").count.each do |k, v| ProjectLanguage.where.not(projects_count: 0).group("project_languages.name").sum(:projects_count).each do |k, v|
$redis_cache.hset(platform_project_language_count_key, k, v) $redis_cache.hset(platform_project_language_count_key, k, v)
end end
end end

View File

@ -108,6 +108,7 @@ class Gitea::ClientService < ApplicationService
def full_url(api_rest, action='post') def full_url(api_rest, action='post')
url = [api_url, api_rest].join('').freeze url = [api_url, api_rest].join('').freeze
url = action === 'get' ? url : URI.escape(url) url = action === 'get' ? url : URI.escape(url)
url = URI.escape(url) unless url.ascii_only?
puts "[gitea] request url: #{url}" puts "[gitea] request url: #{url}"
return url return url
end end
@ -214,6 +215,14 @@ class Gitea::ClientService < ApplicationService
[body, message] [body, message]
end end
def json_parse!(body)
return nil unless body.present?
body = JSON.parse(body)
body, message = fix_body(body)
body
end
def log_error(status, body) def log_error(status, body)
puts "[gitea] status: #{status}" puts "[gitea] status: #{status}"
puts "[gitea] body: #{body&.force_encoding('UTF-8')}" puts "[gitea] body: #{body&.force_encoding('UTF-8')}"

View File

@ -8,7 +8,7 @@ class Gitea::PullRequest::CloseService < Gitea::PullRequest::UpdateService
# number: number of pull request # number: number of pull request
# token: token of gitea user # token: token of gitea user
# eq: # eq:
# Gitea::PullRequest::CloseService.call(owner.login, repo.identifier, pull.gpid, pull.base, current_user.gitea_token) # Gitea::PullRequest::CloseService.call(owner.login, repo.identifier, pull.gitea_number, pull.base, current_user.gitea_token)
def initialize(owner, repo, number, base,token=nil) def initialize(owner, repo, number, base,token=nil)
colse_pull_params = Hash.new.merge(base: base, state: 'closed').compact colse_pull_params = Hash.new.merge(base: base, state: 'closed').compact

View File

@ -3,7 +3,7 @@ class Gitea::PullRequest::GetService < Gitea::ClientService
attr_reader :owner, :repo, :number, :token attr_reader :owner, :repo, :number, :token
#eq: #eq:
# Gitea::PullRequest::GetService.call(user.login, repository.identifier, pull.gpid, user.gitea_token) # Gitea::PullRequest::GetService.call(user.login, repository.identifier, pull.gitea_number, user.gitea_token)
def initialize(owner, repo, number, token=nil) def initialize(owner, repo, number, token=nil)
@owner = owner @owner = owner
@repo = repo @repo = repo

View File

@ -8,7 +8,7 @@ class Gitea::PullRequest::OpenService < Gitea::PullRequest::UpdateService
# number: number of pull request # number: number of pull request
# token: token of gitea user # token: token of gitea user
# eq: # eq:
# Gitea::PullRequest::OpenService.new(owner.login, repo.identifier, pr.gpid, pr.base, current_user.gitea_token) # Gitea::PullRequest::OpenService.new(owner.login, repo.identifier, pr.gitea_number, pr.base, current_user.gitea_token)
def initialize(owner, repo, number, base, token=nil) def initialize(owner, repo, number, base, token=nil)
open_pull_params = Hash.new.merge(base: base, state: 'open').compact open_pull_params = Hash.new.merge(base: base, state: 'open').compact

View File

@ -0,0 +1,40 @@
class Gitea::Repository::ArchiveService < Gitea::ClientService
attr_reader :owner, :repo, :archive, :token
def initialize(owner, repo, archive, token=nil)
@owner = owner
@repo = repo
@archive = archive
@token = token
end
def call
response = get(url, params)
response_payload(response)
end
private
def params
Hash.new.merge(token: token)
end
def url
"/repos/#{owner}/#{repo}/archive/#{archive}".freeze
end
def response_payload(response)
status = response.status
body = response&.body
log_error(status, body)
status_payload(status, body)
end
def status_payload(status, body)
case status
when 200 then success
when 404 then error("你操作的链接不存在!")
else error("系统错误!")
end
end
end

View File

@ -30,8 +30,7 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService
def call def call
response = post(url, params) response = post(url, params)
response_payload(response)
render_201_response(response)
end end
private private
@ -43,4 +42,21 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService
"/repos/#{owner}/#{repo_name}/contents/#{filepath}".freeze "/repos/#{owner}/#{repo_name}/contents/#{filepath}".freeze
end end
def response_payload(response)
status = response.status
body = response&.body
log_error(status, body)
status_payload(status, body)
end
def status_payload(status, body)
case status
when 201 then success(json_parse!(body))
when 403 then error("你没有权限操作!")
when 404 then error("你操作的链接不存在!")
when 422 then error("#{filepath}文件已存在,不能重复创建!")
else error("系统错误!")
end
end
end end

View File

@ -0,0 +1,21 @@
class Gitea::User::Keys::CreateService < Gitea::ClientService
attr_reader :token, :params
def initialize(token, params)
@token = token
@params = params
end
def call
response = post(url, request_params)
render_response(response)
end
private
def request_params
Hash.new.merge({token: token, data: params})
end
def url
'/user/keys'.freeze
end
end

View File

@ -0,0 +1,23 @@
class Gitea::User::Keys::DeleteService < Gitea::ClientService
attr_reader :token, :key_id
def initialize(token, key_id)
@token = token
@key_id = key_id
end
def call
response = delete(url, params)
render_response(response)
end
private
def params
Hash.new.merge(token: token)
end
def url
"/user/keys/#{key_id}".freeze
end
end

View File

@ -0,0 +1,22 @@
class Gitea::User::Keys::GetService < Gitea::ClientService
attr_reader :token, :key_id
def initialize(token, key_id)
@token = token
@key_id = key_id
end
def call
response = get(url, params)
render_response(response)
end
private
def params
Hash.new.merge({token: token})
end
def url
"/user/keys/#{key_id}".freeze
end
end

View File

@ -0,0 +1,26 @@
class Gitea::User::Keys::ListService < Gitea::ClientService
attr_reader :token, :page, :limit, :fingerprint
def initialize(token, page, limit, fingerprint="")
@token = token
@page = page
@limit = limit
@fingerprint = fingerprint
end
def call
response = get(url, params)
render_response(response)
end
private
def params
Hash.new.merge({token: token, fingerprint: fingerprint, page: page, limit: limit})
end
def url
'/user/keys'.freeze
end
end

View File

@ -8,6 +8,7 @@ class Projects::CreateService < ApplicationService
def call def call
Rails.logger.info("#############__________project_params______###########{project_params}") Rails.logger.info("#############__________project_params______###########{project_params}")
raise Error, "user_id不正确." unless authroize_user_id_success
@project = Project.new(project_params) @project = Project.new(project_params)
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
@ -27,6 +28,10 @@ class Projects::CreateService < ApplicationService
private private
def authroize_user_id_success
(user.id == params[:user_id].to_i) || (user.organizations.find_by_id(params[:user_id]).present?)
end
def project_params def project_params
{ {
name: params[:name], name: params[:name],

View File

@ -8,6 +8,8 @@ class Projects::MigrateService < ApplicationService
end end
def call def call
raise Error, "user_id不正确." unless authroize_user_id_success
@project = Project.new(project_params) @project = Project.new(project_params)
if @project.save! if @project.save!
ProjectUnit.init_types(@project.id, project.project_type) ProjectUnit.init_types(@project.id, project.project_type)
@ -24,6 +26,9 @@ class Projects::MigrateService < ApplicationService
end end
private private
def authroize_user_id_success
(user.id == params[:user_id].to_i) || (user.organizations.find_by_id(params[:user_id]).present?)
end
def project_params def project_params
{ {

View File

@ -23,7 +23,7 @@ class PullRequests::CloseService < ApplicationService
def close_gitea_pull def close_gitea_pull
Gitea::PullRequest::CloseService.call(@owner.login, @repo.identifier, Gitea::PullRequest::CloseService.call(@owner.login, @repo.identifier,
@pull.gpid, @pull.base, current_user.gitea_token) @pull.gitea_number, @pull.base, current_user.gitea_token)
end end
def update_pull_status! def update_pull_status!

View File

@ -22,7 +22,7 @@ class PullRequests::MergeService < ApplicationService
def gitea_pull_merge! def gitea_pull_merge!
result = Gitea::PullRequest::MergeService.call(@current_user.gitea_token, @owner.login, result = Gitea::PullRequest::MergeService.call(@current_user.gitea_token, @owner.login,
@repo.identifier, @pull.gpid, gitea_merge_pull_params) @repo.identifier, @pull.gitea_number, gitea_merge_pull_params)
@status, @message = result @status, @message = result
end end

View File

@ -23,7 +23,7 @@ class PullRequests::OpenService < ApplicationService
def open_gitea_pull def open_gitea_pull
Gitea::PullRequest::OpenService.call(@owner.login, @repo.identifier, Gitea::PullRequest::OpenService.call(@owner.login, @repo.identifier,
@pull.gpid, @pull.base, @current_user.gitea_token) @pull.gitea_number, @pull.base, @current_user.gitea_token)
end end
def update_pull_status! def update_pull_status!

View File

@ -83,3 +83,5 @@ json.diff do
end end
end end
json.status @merge_status
json.message @merge_message

View File

@ -1,14 +1,19 @@
<div class="indexPanel"> <div class="indexPanel">
<p class="indexTitle">完善信息,进入比赛</p> <p class="indexTitle">平台已检测到您的如下信息,完善即可进入比赛</p>
<div class="indexInfos"> <div class="indexInfos">
<%= form_tag('', method: :post, id: 'oauth_form', class: 'form-inline search-form flex-1', remote: true) do %> <%= form_tag('', method: :post, id: 'oauth_form', class: 'form-inline search-form flex-1', remote: true) do %>
<%= hidden_field_tag 'callback_url', params[:callback_url] %> <%= hidden_field_tag 'callback_url', params[:callback_url] %>
<div class="indexInfo"> <div class="indexInfo">
<span>用户名:</span> <span>登录名:</span>
<%= text_field_tag :login, params[:login], placeholder: '请输入用户名', readonly: true, id: 'login' %> <%= text_field_tag :login, params[:login], placeholder: '请输入登录名', readonly: true, id: 'login' %>
<p class="checkInfo loginCheck"><span></span></p> <p class="checkInfo loginCheck"><span></span></p>
</div> </div>
<div class="indexInfo">
<span>用户名称:</span>
<%= text_field_tag :lastname, params[:lastname], placeholder: '登录平台后显示的用户名称', maxlength: 40, id: 'lastname' %>
<p class="checkInfo lastnameCheck"><span></span></p>
</div>
<div class="indexInfo"> <div class="indexInfo">
<span>邮箱:</span> <span>邮箱:</span>
<%= text_field_tag :mail, params[:mail], placeholder: '请输入绑定邮箱', maxlength: 40, id: 'email' %> <%= text_field_tag :mail, params[:mail], placeholder: '请输入绑定邮箱', maxlength: 40, id: 'email' %>
@ -16,7 +21,7 @@
</div> </div>
<div class="indexInfo"> <div class="indexInfo">
<span>密码:</span> <span>密码:</span>
<%= password_field_tag :password, '', placeholder: '输入账号密码', id: 'password' %> <%= password_field_tag :password, '', placeholder: '输入EduCoder账号密码或新的密码',maxlength: 15, id: 'password' %>
<p class="checkInfo passwordCheck"><span></span></p> <p class="checkInfo passwordCheck"><span></span></p>
</div> </div>
<div class="indexBtn"> <div class="indexBtn">
@ -29,6 +34,7 @@
function submitdata(){ function submitdata(){
var login = $("#login").val(); var login = $("#login").val();
var email = $("#email").val(); var email = $("#email").val();
var lastname = $("#lastname").val();
var password = $("#password").val(); var password = $("#password").val();
if(!login){ if(!login){
@ -37,6 +43,12 @@
}else{ }else{
$(".loginCheck span").html(""); $(".loginCheck span").html("");
} }
if(!lastname){
$(".lastnameCheck span").html("请输入用户名称");
return;
}else{
$(".lastnameCheck span").html("");
}
if(!email){ if(!email){
$(".emailCheck span").html("请输入绑定的邮箱"); $(".emailCheck span").html("请输入绑定的邮箱");
return; return;

View File

@ -2,6 +2,6 @@ json.total_count @owners.size
json.owners @owners.each do |owner| json.owners @owners.each do |owner|
json.id owner.id json.id owner.id
json.type owner.type json.type owner.type
json.name owner.login json.name owner&.show_real_name
json.avatar_url url_to_avatar(owner) json.avatar_url url_to_avatar(owner)
end end

View File

@ -4,8 +4,8 @@ json.array! @branches do |branch|
json.user_can_merge branch['user_can_merge'] json.user_can_merge branch['user_can_merge']
json.protected branch['protected'] json.protected branch['protected']
json.http_url render_http_url(@project) json.http_url render_http_url(@project)
json.zip_url render_zip_url(@project, branch['name']) json.zip_url render_zip_url(@owner, @repository, branch['name'])
json.tar_url render_tar_url(@project, branch['name']) json.tar_url render_tar_url(@owner, @repository, branch['name'])
json.last_commit do json.last_commit do
json.sha branch['commit']['id'] json.sha branch['commit']['id']
json.message branch['commit']['message'] json.message branch['commit']['message']

View File

@ -1 +1,2 @@
json.extract! @project, :id, :name,:identifier json.extract! @project, :id, :name,:identifier
json.login @project&.owner.login

View File

@ -0,0 +1,8 @@
if @public_key.present?
json.status 0
json.id @public_key["id"]
json.name @public_key["title"]
json.content @public_key["key"]
json.fingerprint @public_key["fingerprint"]
json.created_time @public_key["created_at"].to_time.strftime("%Y/%m/%d %H:%M")
end

View File

@ -0,0 +1,5 @@
json.total_count @public_keys.total_count
json.public_keys @public_keys do |public_key|
json.(public_key, :id, :name, :content, :fingerprint, :created_unix)
json.created_time Time.at(public_key.created_unix).strftime("%Y/%m/%d %H:%M")
end

View File

@ -32,3 +32,5 @@ json.issue do
json.version @issue.version.try(:name) json.version @issue.version.try(:name)
json.issue_tags @issue.get_issue_tags json.issue_tags @issue.get_issue_tags
end end
json.conflict_files @pull_request.conflict_files

View File

@ -1,6 +1,6 @@
if @project.forge? if @project.forge?
file_name = entry['name'] file_name = entry['name']
file_type = file_name.to_s.split(".").last file_type = File.extname(file_name.to_s)[1..-1]
direct_download = download_type(file_type) direct_download = download_type(file_type)
image_type = image_type?(file_type) image_type = image_type?(file_type)
json.name file_name json.name file_name
@ -11,7 +11,16 @@ if @project.forge?
json.content decode64_content(entry, @owner, @repository, @ref) json.content decode64_content(entry, @owner, @repository, @ref)
json.target entry['target'] json.target entry['target']
json.download_url entry['download_url']
download_url =
if image_type
dir_path = [@owner.login, @repository.identifier, "raw/branch", @ref].join('/')
render_download_image_url(dir_path, entry['path'], decode64_content(entry, @owner, @repository, @ref))
else
entry['download_url']
end
json.download_url download_url
json.direct_download direct_download json.direct_download direct_download
json.image_type image_type json.image_type image_type
json.is_readme_file is_readme?(entry['type'], entry['name']) json.is_readme_file is_readme?(entry['type'], entry['name'])

View File

@ -42,8 +42,9 @@ if @project.forge?
#json.tags_count @tags_count #json.tags_count @tags_count
#json.branches_count @branches_count #json.branches_count @branches_count
json.commits_count @commits_count json.commits_count @commits_count
json.zip_url render_zip_url(@project, @ref) # json.zip_url archive_repositories_path(@owner&.login, @repository, @ref)
json.tar_url render_tar_url(@project, @ref) json.zip_url render_zip_url(@owner, @repository, @ref)
json.tar_url render_tar_url(@owner, @repository, @ref)
json.entries do json.entries do
json.array! @entries do |entry| json.array! @entries do |entry|
json.name entry['name'] json.name entry['name']

View File

@ -2,8 +2,8 @@ json.array! @tags do |tag|
if tag.present? if tag.present?
json.name tag['name'] json.name tag['name']
json.id tag['id'] json.id tag['id']
json.zipball_url tag['zipball_url'] json.zipball_url render_zip_url(@owner, @repository, tag['name'])
json.tarball_url tag['tarball_url'] json.tarball_url render_tar_url(@owner, @repository, tag['name'])
json.commit do json.commit do
json.sha tag['commit']['sha'] json.sha tag['commit']['sha']
end end

View File

@ -56,4 +56,5 @@ json.setting do
end end
json.common @common json.common @common
json.third_party @third_party
end end

View File

@ -9,8 +9,9 @@ json.is_teacher @user.user_extension&.teacher?
json.user_identity @user.identity json.user_identity @user.identity
json.tidding_count 0 json.tidding_count 0
json.user_phone_binded @user.phone.present? json.user_phone_binded @user.phone.present?
json.need_edit_info @user.need_edit_info?
# json.phone @user.phone # json.phone @user.phone
# json.email @user.mail json.email @user.mail
json.profile_completed @user.profile_completed? json.profile_completed @user.profile_completed?
json.professional_certification @user.professional_certification json.professional_certification @user.professional_certification
json.devops_step @user.devops_step json.devops_step @user.devops_step

View File

@ -14,8 +14,8 @@ json.releases do
json.name re["name"] json.name re["name"]
json.body re["body"] json.body re["body"]
json.url re["url"] json.url re["url"]
json.tarball_url re["tarball_url"] json.tarball_url render_tar_url(@owner, @repository, re["tag_name"])
json.zipball_url re["zipball_url"] json.zipball_url render_zip_url(@owner, @repository, re["tag_name"])
json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定") json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定")
json.created_at format_time(version.created_at.to_s.to_time) json.created_at format_time(version.created_at.to_s.to_time)
json.published_at format_time(version.created_at.to_s.to_time) json.published_at format_time(version.created_at.to_s.to_time)
@ -30,8 +30,8 @@ json.releases do
json.name re["name"] json.name re["name"]
json.body re["body"] json.body re["body"]
json.url re["url"] json.url re["url"]
json.tarball_url re["tarball_url"] json.tarball_url render_tar_url(@owner, @repository, re["tag_name"])
json.zipball_url re["zipball_url"] json.zipball_url render_zip_url(@owner, @repository, re["tag_name"])
json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定") json.draft re["draft"] ? "草稿" : (re["prerelease"] ? "预发行" : "稳定")
json.created_at format_time(version.created_at.to_s.to_time) json.created_at format_time(version.created_at.to_s.to_time)
json.published_at format_time(version.created_at.to_s.to_time) json.published_at format_time(version.created_at.to_s.to_time)

View File

@ -7,8 +7,8 @@ json.versions do
json.array! @versions.each.to_a do |version| json.array! @versions.each.to_a do |version|
json.extract! version, :id, :name, :description, :effective_date,:status,:percent json.extract! version, :id, :name, :description, :effective_date,:status,:percent
json.open_issues_count (version.issues_count - version.closed_issues_count) json.open_issues_count (version.issues.issue_issue.size - version.issues.issue_issue.closed.size)
json.close_issues_count version.closed_issues_count json.close_issues_count version.issues.issue_issue.closed.size
json.created_at format_time(version.created_on) json.created_at format_time(version.created_on)
json.updated_at format_time(version.updated_on) json.updated_at format_time(version.updated_on)
json.user_name version.version_user.try(:show_real_name) json.user_name version.version_user.try(:show_real_name)

View File

@ -1,7 +1,7 @@
json.partial! "commons/success" json.partial! "commons/success"
json.issues_count @version.issues_count json.issues_count @version_issues_size
json.open_issues_count @version.issues_count - @version.closed_issues_count json.open_issues_count @version_issues_size - @version_close_issues_size
json.close_issues_count @version.closed_issues_count json.close_issues_count @version_close_issues_size
json.limit @limit json.limit @limit
json.user_name @version.version_user.try(:show_real_name) json.user_name @version.version_user.try(:show_real_name)
json.user_login @version.version_user.try(:login) json.user_login @version.version_user.try(:login)

View File

@ -1,6 +1,7 @@
default: &default default: &default
# 用户登入的时候设置/登出的时候清空 # 用户登入的时候设置/登出的时候清空
autologin_cookie_name: 'autologin_trustie' autologin_cookie_name: 'autologin_trustie'
platform_url: 'http://localhost:3000'
#附件上传路径 #附件上传路径
@ -43,6 +44,11 @@ default: &default
cate_id: '-1' cate_id: '-1'
callback_url: 'callback_url' callback_url: 'callback_url'
signature_key: 'test12345678' signature_key: 'test12345678'
educoder:
client_id: 'e9ce4d5ba1698d6f7d01d8ee2959776c7a6d743ebe94da2341e288fd2fbf60aa'
client_secret: '6ff84dd75eddd859c5bd0e7a791b58bc5ad1ba4fbb30bc9db37cb0baf9f33012'
base_url: 'https://test-data.educoder.net'
redirect_uri: 'https://testforgeplus.trustie.net/api/auth/educoder/callback'
gitea: gitea:
access_key_id: '' access_key_id: ''

View File

@ -17,6 +17,13 @@ default: &default
username: root username: root
password: 123456 password: 123456
# socket: /var/run/mysqld/mysqld.sock # socket: /var/run/mysqld/mysqld.sock
gitea_server:
aadapter: mysql2
database: gitea_development
host: 127.0.0.1
username: root
password: "123456"
encoding: utf8
development: development:
<<: *default <<: *default

View File

@ -0,0 +1,16 @@
oauth_config = {}
begin
config = Rails.application.config_for(:configuration)
oauth_config = config.dig('oauth', 'educoder')
raise 'oauth educoder config missing' if oauth_config.blank?
rescue => ex
raise ex if Rails.env.production?
puts %Q{\033[33m [warning] wechat oauth config or configuration.yml missing,
please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
end
EducoderOauth.client_id = oauth_config['client_id']
EducoderOauth.client_secret = oauth_config['client_secret']
EducoderOauth.base_url = oauth_config['base_url']
EducoderOauth.redirect_uri = oauth_config['redirect_uri']

View File

@ -4,5 +4,5 @@
# Rails.application.config.session_store :active_record_store # Rails.application.config.session_store :active_record_store
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
Rails.application.config.session_store :cache_store, :expire_after => 24.hours, :httponly => false, :secure => false, key: '_educoder_session', domain: :all Rails.application.config.session_store :cache_store, :expire_after => 24.hours, :httponly => true, :secure => false, key: '_educoder_session', domain: :all

View File

@ -71,6 +71,8 @@ Rails.application.routes.draw do
# end # end
end end
resources :public_keys, only: [:index, :create, :destroy]
resources :statistic, only: [:index] do resources :statistic, only: [:index] do
collection do collection do
get :platform_profile get :platform_profile
@ -346,6 +348,7 @@ Rails.application.routes.draw do
get '/auth/qq/callback', to: 'oauth/qq#create' get '/auth/qq/callback', to: 'oauth/qq#create'
get '/auth/wechat/callback', to: 'oauth/wechat#create' get '/auth/wechat/callback', to: 'oauth/wechat#create'
get '/auth/educoder/callback', to: 'oauth/educoder#create'
resource :bind_user, only: [:create] resource :bind_user, only: [:create]
resources :hot_keywords, only: [:index] resources :hot_keywords, only: [:index]
@ -416,7 +419,6 @@ Rails.application.routes.draw do
member do member do
get :files get :files
get :detail get :detail
get :archive
get :entries get :entries
match :sub_entries, :via => [:get, :put] match :sub_entries, :via => [:get, :put]
get :commits get :commits
@ -431,6 +433,7 @@ Rails.application.routes.draw do
get 'commits/:sha', to: 'repositories#commit', as: 'commit' get 'commits/:sha', to: 'repositories#commit', as: 'commit'
get 'readme' get 'readme'
get 'languages' get 'languages'
get 'archive/:archive', to: 'repositories#archive', as: "archive", constraints: { archive: /.+/, format: /(zip|gzip)/ }
end end
end end

View File

@ -0,0 +1,7 @@
class AddProjectLanguageIndexToProjects < ActiveRecord::Migration[5.2]
def change
add_index :projects, :project_category_id
add_index :projects, :project_language_id
add_index :projects, :license_id
end
end

View File

@ -0,0 +1,22 @@
class ChangeColumnsNameFromPullRequests < ActiveRecord::Migration[5.2]
def change
rename_column :pull_requests, :pull_request_id, :gitea_id
rename_column :pull_requests, :gpid, :gitea_number
PullRequest.find_each do |pr|
next if pr.gitea_number.blank?
project = pr.project
next if project.blank?
owner = project&.owner
gitea_pull = Gitea::PullRequest::GetService.call(owner.login, project.identifier, pr.gitea_number, owner&.gitea_token)
next if gitea_pull.blank?
pr.update_column(:gitea_id, gitea_pull["id"])
end
end
end

View File

@ -0,0 +1,26 @@
namespace :sync_projects_by_forked_project do
desc "sync projects is_public by forked project"
task is_public: :environment do
count = 0
Project.where.not(forked_from_project_id: nil).group(:forked_from_project_id).count.each do |k, _|
project = Project.find_by_id(k)
need_update_forked_projects = Project.where(forked_from_project_id: k)
need_update_forked_projects.update_all(is_public: project&.is_public)
need_update_forked_repositories = Repository.where(project_id: need_update_forked_projects.ids)
need_update_forked_repositories.update_all(hidden: !project&.is_public)
count +=need_update_forked_projects.size
end
puts "共同步了#{count}个项目"
end
task destroy: :environment do
count = 0
Project.where.not(forked_from_project_id: nil).find_each do |project|
if project.forked_from_project.nil?
project.update(forked_from_project_id: nil)
count +=1
end
end
puts "共同步了#{count}个项目"
end
end

View File

@ -325,6 +325,20 @@
</li> </li>
</ul> </ul>
</li> </li>
<li>
<a href="#publickeys" class="toc-h1 toc-link" data-title="PublicKeys">PublicKeys</a>
<ul class="toc-list-h2">
<li>
<a href="#public_keys" class="toc-h2 toc-link" data-title="public_keys列表">public_keys列表</a>
</li>
<li>
<a href="#public_key" class="toc-h2 toc-link" data-title="创建public_key">创建public_key</a>
</li>
<li>
<a href="#public_key-2" class="toc-h2 toc-link" data-title="删除public_key">删除public_key</a>
</li>
</ul>
</li>
<li> <li>
<a href="#users" class="toc-h1 toc-link" data-title="Users">Users</a> <a href="#users" class="toc-h1 toc-link" data-title="Users">Users</a>
<ul class="toc-list-h2"> <ul class="toc-list-h2">
@ -626,6 +640,251 @@ http://localhost:3000/api/ignores.json
<aside class="success"> <aside class="success">
Success — a happy kitten is an authenticated kitten! Success — a happy kitten is an authenticated kitten!
</aside> </aside>
<!--
* @Date: 2021-07-14 15:10:29
* @LastEditors: viletyy
* @LastEditTime: 2021-07-14 15:37:23
* @FilePath: /forgeplus/app/docs/slate/source/includes/_public_keys.md
-->
<h1 id='publickeys'>PublicKeys</h1><h2 id='public_keys'>public_keys列表</h2>
<p>获取public_keys列表支持分页</p>
<blockquote>
<p>示例:</p>
</blockquote>
<div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET <span class="se">\</span>
http://localhost:3000/api/public_keys.json
</code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/public_keys.json</span><span class="dl">'</span><span class="p">)</span>
</code></pre></div><h3 id='http'>HTTP 请求</h3>
<p><code>GET api/public_keys.json</code></p>
<h3 id='1f9ac54b15'>请求参数</h3>
<table><thead>
<tr>
<th>参数</th>
<th>必选</th>
<th>默认</th>
<th>类型</th>
<th>字段说明</th>
</tr>
</thead><tbody>
<tr>
<td>page</td>
<td></td>
<td>1</td>
<td>int</td>
<td>页码</td>
</tr>
<tr>
<td>limit</td>
<td></td>
<td>15</td>
<td>int</td>
<td>每页数量</td>
</tr>
</tbody></table>
<h3 id='b302a98fa6'>返回字段说明</h3>
<table><thead>
<tr>
<th>参数</th>
<th>类型</th>
<th>字段说明</th>
</tr>
</thead><tbody>
<tr>
<td>total_count</td>
<td>int</td>
<td>总数</td>
</tr>
<tr>
<td>public_keys.id</td>
<td>int</td>
<td>ID</td>
</tr>
<tr>
<td>public_keys.name</td>
<td>string</td>
<td>密钥标题</td>
</tr>
<tr>
<td>public_keys.content</td>
<td>string</td>
<td>密钥内容</td>
</tr>
<tr>
<td>public_keys.fingerprint</td>
<td>string</td>
<td>密钥标识</td>
</tr>
<tr>
<td>public_keys.created_time</td>
<td>string</td>
<td>密钥创建时间</td>
</tr>
</tbody></table>
<blockquote>
<p>返回的JSON示例:</p>
</blockquote>
<div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w">
</span><span class="nl">"total_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
</span><span class="nl">"public_keys"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">16</span><span class="p">,</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx"</span><span class="p">,</span><span class="w">
</span><span class="nl">"content"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDe5ETOTB5PcmcYJkIhfF7+mxmJQDCLg7/LnMoKHpKoo/jYUnFU9OjfsxVo3FTNUvh2475WXMAur5KsFoNKjK9+JHxvoXyJKmyVPWgXU/NRxQyaWPnPLPK8qPRF5ksJE6feBOqtsdxsvBiHs2r1NX/U26Ecnpr6avudD0cmyrEfbYMWbupLrhsd39dswPT73f3W5jc7B9Y47Ioiv8UOju3ABt1+kpuAjaaVC6VtUQoEFiZb1y33yBnyePya7dvFyApyD4ILyyIG2rtZWK7l53YFnwZDuFsTWjEEEQD0U4FBSFdH5wtwx0WQLMSNyTtaFBSG0kJ+uiQQIrxlvikcm63df7zbC3/rWLPsKgW122Zt966dcpFqiCiJNDKZPPw3qpg8TBL6X+qIZ+FxVEk/16/zScpyEfoxQp0GvgxI7hPLErmfkC5tMsib8MAXYBNyvJXna0vg/wOaNNIaI4SAH9Ksh3f/TtalYVjp6WxIwVBfnbq51WnmlnEXePtX6XjAGL+GbF2VQ1nv/IzrY09tNbTV6wQsrSIP3VDzYQxdJ1rdsVNMoJB0H2Pu0NdcSz53Wx45N+myD0QnE05ss+zDp5StY90OYsx2aCo6qAA8Qn2jUjdta7MQWwkPfKrta4tTQ0XbWMjx4/E1+l3J5liwZkl2XOGOwhfXdRsBjaEziZ18kQ== yystopf@163.com"</span><span class="p">,</span><span class="w">
</span><span class="nl">"fingerprint"</span><span class="p">:</span><span class="w"> </span><span class="s2">"SHA256:cU8AK/+roqUUyiaYXIdS2Nj4+Rb2p6rqWSeRDc+aqKM"</span><span class="p">,</span><span class="w">
</span><span class="nl">"created_unix"</span><span class="p">:</span><span class="w"> </span><span class="mi">1626246596</span><span class="p">,</span><span class="w">
</span><span class="nl">"created_time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2021/07/14 15:09"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div>
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>
<h2 id='public_key'>创建public_key</h2>
<p>创建public_key</p>
<blockquote>
<p>示例:</p>
</blockquote>
<div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST <span class="se">\</span>
http://localhost:3000/api/public_keys.json
</code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">POST /api/public_keys.json</span><span class="dl">'</span><span class="p">)</span>
</code></pre></div><h3 id='http-2'>HTTP 请求</h3>
<p><code>POST api/public_keys.json</code></p>
<h3 id='1f9ac54b15-2'>请求参数</h3>
<table><thead>
<tr>
<th>参数</th>
<th>必选</th>
<th>默认</th>
<th>类型</th>
<th>字段说明</th>
</tr>
</thead><tbody>
<tr>
<td>key</td>
<td></td>
<td></td>
<td>string</td>
<td>密钥</td>
</tr>
<tr>
<td>title</td>
<td></td>
<td></td>
<td>string</td>
<td>密钥标题</td>
</tr>
</tbody></table>
<blockquote>
<p>请求的JSON示例
<code>json
{
&quot;public_key&quot;: {
&quot;key&quot;: &quot;ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDe5ETOTB5PcmcYJkIhfF7+mxmJQDCLg7/LnMoKHpKoo/jYUnFU9OjfsxVo3FTNUvh2475WXMAur5KsFoNKjK9+JHxvoXyJKmyVPWgXU/NRxQyaWPnPLPK8qPRF5ksJE6feBOqtsdxsvBiHs2r1NX/U26Ecnpr6avudD0cmyrEfbYMWbupLrhsd39dswPT73f3W5jc7B9Y47Ioiv8UOju3ABt1+kpuAjaaVC6VtUQoEFiZb1y33yBnyePya7dvFyApyD4ILyyIG2rtZWK7l53YFnwZDuFsTWjEEEQD0U4FBSFdH5wtwx0WQLMSNyTtaFBSG0kJ+uiQQIrxlvikcm63df7zbC3/rWLPsKgW122Zt966dcpFqiCiJNDKZPPw3qpg8TBL6X+qIZ+FxVEk/16/zScpyEfoxQp0GvgxI7hPLErmfkC5tMsib8MAXYBNyvJXna0vg/wOaNNIaI4SAH9Ksh3f/TtalYVjp6WxIwVBfnbq51WnmlnEXePtX6XjAGL+GbF2VQ1nv/IzrY09tNbTV6wQsrSIP3VDzYQxdJ1rdsVNMoJB0H2Pu0NdcSz53Wx45N+myD0QnE05ss+zDp5StY90OYsx2aCo6qAA8Qn2jUjdta7MQWwkPfKrta4tTQ0XbWMjx4/E1+l3J5liwZkl2XOGOwhfXdRsBjaEziZ18kQ== yystopf@163.com&quot;,
&quot;title&quot;: &quot;xxx&quot;
}
}
</code></p>
</blockquote>
<h3 id='b302a98fa6-2'>返回字段说明</h3>
<table><thead>
<tr>
<th>参数</th>
<th>类型</th>
<th>字段说明</th>
</tr>
</thead><tbody>
<tr>
<td>total_count</td>
<td>int</td>
<td>总数</td>
</tr>
<tr>
<td>id</td>
<td>int</td>
<td>ID</td>
</tr>
<tr>
<td>name</td>
<td>string</td>
<td>密钥标题</td>
</tr>
<tr>
<td>content</td>
<td>string</td>
<td>密钥内容</td>
</tr>
<tr>
<td>fingerprint</td>
<td>string</td>
<td>密钥标识</td>
</tr>
<tr>
<td>created_time</td>
<td>string</td>
<td>密钥创建时间</td>
</tr>
</tbody></table>
<blockquote>
<p>返回的JSON示例:</p>
</blockquote>
<div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w">
</span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">17</span><span class="p">,</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx"</span><span class="p">,</span><span class="w">
</span><span class="nl">"content"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDe5ETOTB5PcmcYJkIhfF7+mxmJQDCLg7/LnMoKHpKoo/jYUnFU9OjfsxVo3FTNUvh2475WXMAur5KsFoNKjK9+JHxvoXyJKmyVPWgXU/NRxQyaWPnPLPK8qPRF5ksJE6feBOqtsdxsvBiHs2r1NX/U26Ecnpr6avudD0cmyrEfbYMWbupLrhsd39dswPT73f3W5jc7B9Y47Ioiv8UOju3ABt1+kpuAjaaVC6VtUQoEFiZb1y33yBnyePya7dvFyApyD4ILyyIG2rtZWK7l53YFnwZDuFsTWjEEEQD0U4FBSFdH5wtwx0WQLMSNyTtaFBSG0kJ+uiQQIrxlvikcm63df7zbC3/rWLPsKgW122Zt966dcpFqiCiJNDKZPPw3qpg8TBL6X+qIZ+FxVEk/16/zScpyEfoxQp0GvgxI7hPLErmfkC5tMsib8MAXYBNyvJXna0vg/wOaNNIaI4SAH9Ksh3f/TtalYVjp6WxIwVBfnbq51WnmlnEXePtX6XjAGL+GbF2VQ1nv/IzrY09tNbTV6wQsrSIP3VDzYQxdJ1rdsVNMoJB0H2Pu0NdcSz53Wx45N+myD0QnE05ss+zDp5StY90OYsx2aCo6qAA8Qn2jUjdta7MQWwkPfKrta4tTQ0XbWMjx4/E1+l3J5liwZkl2XOGOwhfXdRsBjaEziZ18kQ== yystopf@163.com"</span><span class="p">,</span><span class="w">
</span><span class="nl">"fingerprint"</span><span class="p">:</span><span class="w"> </span><span class="s2">"SHA256:cU8AK/+roqUUyiaYXIdS2Nj4+Rb2p6rqWSeRDc+aqKM"</span><span class="p">,</span><span class="w">
</span><span class="nl">"created_time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2021/07/14 15:26"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div>
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>
<h2 id='public_key-2'>删除public_key</h2>
<p>删除public_key</p>
<blockquote>
<p>示例:</p>
</blockquote>
<div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> DELETE <span class="se">\</span>
http://localhost:3000/api/public_keys/:id.json
</code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">DELETE /api/public_keys/:id.json</span><span class="dl">'</span><span class="p">)</span>
</code></pre></div><h3 id='http-3'>HTTP 请求</h3>
<p><code>DELETE api/public_keys/:id.json</code></p>
<h3 id='1f9ac54b15-3'>请求参数</h3>
<table><thead>
<tr>
<th>参数</th>
<th>必选</th>
<th>默认</th>
<th>类型</th>
<th>字段说明</th>
</tr>
</thead><tbody>
<tr>
<td>id</td>
<td></td>
<td></td>
<td>int</td>
<td>密钥ID</td>
</tr>
</tbody></table>
<blockquote>
<p>返回的JSON示例:</p>
</blockquote>
<div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w">
</span><span class="nl">"status"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w">
</span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"success"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div>
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>
<!-- <!--
* @Date: 2021-03-01 10:35:21 * @Date: 2021-03-01 10:35:21
* @LastEditors: viletyy * @LastEditors: viletyy