Change
This commit is contained in:
commit
e1c49c0ba8
179
README.md
179
README.md
|
@ -531,17 +531,18 @@ curl -X POST http://localhost:3000/api/repositories/1244/sync_mirror | jq
|
|||
|
||||
#### 项目详情
|
||||
```
|
||||
GET api/projects/:id
|
||||
GET /api/:namespace_id/:id
|
||||
```
|
||||
*示例*
|
||||
```
|
||||
curl -X GET http://localhost:3000/api/projects/3263 | jq
|
||||
curl -X GET http://localhost:3000/api/jasder/jasder_test | jq
|
||||
```
|
||||
*请求参数说明:*
|
||||
|
||||
|参数名|必选|类型|说明|
|
||||
|-|-|-|-|
|
||||
|id |是|int |项目id |
|
||||
|namespace_id |是|string |用户登录名 |
|
||||
|id |是|string |项目标识identifier |
|
||||
|
||||
|
||||
*返回参数说明:*
|
||||
|
@ -570,6 +571,50 @@ curl -X GET http://localhost:3000/api/projects/3263 | jq
|
|||
```
|
||||
---
|
||||
|
||||
#### 项目详情(简版)
|
||||
```
|
||||
GET /api/:namespace_id/:id/simple
|
||||
```
|
||||
*示例*
|
||||
```
|
||||
curl -X GET http://localhost:3000/api/jasder/jasder_test/simple | jq
|
||||
```
|
||||
*请求参数说明:*
|
||||
|
||||
|参数名|必选|类型|说明|
|
||||
|-|-|-|-|
|
||||
|id |是|int |项目id |
|
||||
|
||||
|
||||
*返回参数说明:*
|
||||
|
||||
|参数名|类型|说明|
|
||||
|-|-|-|
|
||||
|id |int |id |
|
||||
|name |string|项目名称|
|
||||
|identifier |string|项目标识|
|
||||
|is_public |boolean|项目是否公开, true:公开,false:私有|
|
||||
|description |string|项目简介|
|
||||
|repo_id |int|仓库id|
|
||||
|repo_identifier|string|仓库标识|
|
||||
|
||||
|
||||
返回值
|
||||
```
|
||||
{
|
||||
"identifier": "jasder_test",
|
||||
"name": "jasder的测试项目",
|
||||
"id": 4967,
|
||||
"type": 0,
|
||||
"author": {
|
||||
"login": "jasder",
|
||||
"name": "姓名",
|
||||
"image_url": "avatars/User/b"
|
||||
}
|
||||
}
|
||||
```
|
||||
---
|
||||
|
||||
#### 编辑仓库信息
|
||||
```
|
||||
GET /api/repositories/:id/edit.json
|
||||
|
@ -897,13 +942,13 @@ curl -X POST http://localhost:3000/api/projects/3297/forks | jq
|
|||
|
||||
#### 获取代码目录列表
|
||||
```
|
||||
POST /api/repositories/:id/entries.json
|
||||
POST /api/:namespace_id/:project_id/repository/entries
|
||||
```
|
||||
*示例*
|
||||
```
|
||||
curl -X GET \
|
||||
-d "ref=develop" \
|
||||
http://localhost:3000//api/repositories/3687/entries.json | jq
|
||||
http://localhost:3000//api/jasder/jasder_test/repository/entries | jq
|
||||
```
|
||||
*请求参数说明:*
|
||||
|
||||
|
@ -1320,11 +1365,11 @@ http://localhost:3000/api/projects | jq
|
|||
|
||||
### 获取分支列表
|
||||
```
|
||||
GET /api/projects/:id/branches
|
||||
GET /api/:namespace_id/:id/branches
|
||||
```
|
||||
*示例*
|
||||
```
|
||||
curl -X GET http://localhost:3000/api/projects/4797/branches | jq
|
||||
curl -X GET http://localhost:3000/api/jasder/jasder_test/branches | jq
|
||||
```
|
||||
*请求参数说明:*
|
||||
|
||||
|
@ -1487,18 +1532,19 @@ http://localhost:3000/api/repositories/5836/tags.json | jq
|
|||
|
||||
## 仓库详情
|
||||
```
|
||||
GET /api/repositories/:id
|
||||
GET /api/:namespace_id/:project_id/repository
|
||||
```
|
||||
*示例*
|
||||
```
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/repositories/23.json | jq
|
||||
http://192.168.2.230:3000/api/jasder/forgeplus/repository | jq
|
||||
```
|
||||
*请求参数说明:*
|
||||
|
||||
|参数名|必选|类型|说明|
|
||||
|-|-|-|-|
|
||||
|id |是|string |项目id |
|
||||
|namespace_id |是|string |用户登录名 |
|
||||
|project_id |是|string |项目标识identifier |
|
||||
|
||||
|
||||
*返回参数说明:*
|
||||
|
@ -2357,6 +2403,51 @@ http://localhost:3000/api//api/repositories/3868/delete_file | jq
|
|||
### DevOps相关api
|
||||
---
|
||||
|
||||
#### 获取devops流程步骤(判断devops是否初始化)
|
||||
```
|
||||
GET /api/users/devops
|
||||
```
|
||||
|
||||
*示例*
|
||||
```
|
||||
curl -X GET \
|
||||
-d "project_id=5988" \
|
||||
https://localhost:3000/api/users/devops.json | jq
|
||||
```
|
||||
|
||||
*请求参数说明:*
|
||||
|
||||
|参数名|必选|类型|说明|
|
||||
|-|-|-|-|
|
||||
|project_id |是|string |项目id或者项目的标识identifier|
|
||||
|
||||
*返回参数说明:*
|
||||
|
||||
|参数名|类型|说明|
|
||||
|-|-|-|
|
||||
|step |int|初始化devops流程步骤; 0: 标识未开启devops,1: 标识用户已填写了云服务器相关信息,但并未开启认证, 2: 标识用户已开启了CI服务端的认证, 3: 标识用户已经授权并获取了CI服务的token|
|
||||
|account |string|你的云服务器帐号|
|
||||
|ip |string|你的云服务器帐号ip|
|
||||
|secret |string|你的云服务器登录密码|
|
||||
|authenticate_url |string|devops授权认证地址, 只有填写了服务器相关信息后才会有该地址|
|
||||
|get_drone_token_url |string|获取CI服务端token地址, 只有认证成功后才会有该地址|
|
||||
|
||||
返回值
|
||||
```json
|
||||
{
|
||||
"step": 0,
|
||||
"cloud_account": {
|
||||
"id": 1,
|
||||
"account": "xxx",
|
||||
"ip": "xxx.xxx.xxx.x",
|
||||
"secret": "11111",
|
||||
"authenticate_url": "http://localhost:3000/login",
|
||||
"get_drone_token_url": "http://localhost:3000/account"
|
||||
}
|
||||
}
|
||||
```
|
||||
---
|
||||
|
||||
#### 初始化DevOps流程
|
||||
```
|
||||
POST /api/dev_ops/cloud_accounts
|
||||
|
@ -2399,6 +2490,72 @@ https://localhost:3000/api/dev_ops/cloud_accounts.json | jq
|
|||
```
|
||||
---
|
||||
|
||||
#### 用户认证CI服务端后,需要调用该接口进行更新devlops流程状态
|
||||
```
|
||||
PUT /api/users/devops_authenticate
|
||||
```
|
||||
*示例*
|
||||
```
|
||||
curl -X PUT \
|
||||
-d "project_id=5988" \
|
||||
http://localhost:3000/api/users/devops_authenticate.json | jq
|
||||
```
|
||||
*请求参数说明:*
|
||||
|
||||
|参数名|必选|类型|说明|
|
||||
|-|-|-|-|
|
||||
|project_id |是|string |项目id或者项目的标识identifier|
|
||||
|
||||
|
||||
*返回参数说明:*
|
||||
|
||||
|参数名|类型|说明|
|
||||
|-|-|-|
|
||||
|status |int|0:成功, -1: 失败|
|
||||
|
||||
```
|
||||
{
|
||||
"status": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
---
|
||||
|
||||
#### 激活项目
|
||||
```
|
||||
POST /api/dev_ops/cloud_accounts/:id/activate
|
||||
```
|
||||
*示例*
|
||||
```
|
||||
curl -X POST \
|
||||
-d "id=1" \
|
||||
-d "project_id=4844" \
|
||||
-d "drone_token=xxxxxxxxxx" \
|
||||
http://localhost:3000/api/dev_ops/cloud_accounts/1/activate.json | jq
|
||||
```
|
||||
*请求参数说明:*
|
||||
|
||||
|参数名|必选|类型|说明|
|
||||
|-|-|-|-|
|
||||
|project_id |是|int |project's id or identifier |
|
||||
|id |是|int |cloud_account's id |
|
||||
|drone_token |否|string |CI端用户的token值,只有当用户第一次激活时,才需要填写该值 |
|
||||
|
||||
|
||||
*返回参数说明:*
|
||||
|
||||
|参数名|类型|说明|
|
||||
|-|-|-|
|
||||
|status |int|0:成功, -1: 失败|
|
||||
|
||||
```
|
||||
{
|
||||
"status": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
---
|
||||
|
||||
#### 获取仓库的.trustie-pipeline.yml
|
||||
```
|
||||
GET /api/dev_ops/builds/get_trustie_pipeline
|
||||
|
@ -2429,9 +2586,11 @@ http://localhost:3000/api/dev_ops/builds/get_trustie_pipeline.json | jq
|
|||
{
|
||||
"name": ".trustie-pipeline.yml",
|
||||
"path": ".trustie-pipeline.yml",
|
||||
"sha": "548sfefsafef48sf485s4f",
|
||||
"content": "..jsaf"
|
||||
}
|
||||
```
|
||||
---
|
||||
|
||||
#### 获取语言列表
|
||||
```
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
html{margin:0px;padding: 0px;font-size: 14px;font-family: "微软雅黑","宋体";}
|
||||
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.IndexContent{
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background-image: url('/images/oauth/backImg.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.indexLogo{
|
||||
width:80px;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
.indexPanel{
|
||||
width: 580px;
|
||||
min-height: 400px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 2px 10px 5px rgba(0,0,0,0.05);
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.indexTitle{
|
||||
height: 75px;
|
||||
line-height: 75px;
|
||||
font-size: 18px;
|
||||
color:#333;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.indexInfo{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.indexInfos{
|
||||
padding:40px 60px;
|
||||
}
|
||||
.indexInfo > span{
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.indexInfo input{
|
||||
width: 100%;
|
||||
height:40px;
|
||||
border-radius: 2px;
|
||||
border:1px solid #eee;
|
||||
margin-top: 5px;
|
||||
padding:0px 0px 0px 8px;
|
||||
outline: none;
|
||||
}
|
||||
.indexInfo .checkInfo{
|
||||
height: 15px;
|
||||
color: red;
|
||||
}
|
||||
.indexBtn{
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.indexSubmit{
|
||||
width: 50%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
background-color: #1890FF;
|
||||
border:none;
|
||||
color: #fff;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
|
@ -13,24 +13,12 @@ class AccountsController < ApplicationController
|
|||
password = params[:password]
|
||||
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
|
||||
|
||||
@user = User.new(admin: false, login: username, mail: email, type: "User")
|
||||
@user.password = password
|
||||
@user.platform = platform
|
||||
@user.activate
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password})
|
||||
if interactor.success?
|
||||
gitea_user = interactor.result
|
||||
result = Gitea::User::GenerateTokenService.new(username, password).call
|
||||
@user.gitea_token = result['sha1']
|
||||
@user.gitea_uid = gitea_user['id']
|
||||
if @user.save!
|
||||
UserExtension.create!(user_id: @user.id)
|
||||
render_ok({user: {id: @user.id, token: @user.gitea_token}})
|
||||
end
|
||||
result = autologin_register(username, email, password, platform)
|
||||
if result[:message].blank?
|
||||
render_ok({user: result[:user]})
|
||||
else
|
||||
render_error(interactor.error)
|
||||
render_error(result[:message])
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
|
|
|
@ -9,7 +9,8 @@ class ApplicationController < ActionController::Base
|
|||
include GitHelper
|
||||
include LoggerHelper
|
||||
include LoginHelper
|
||||
|
||||
include RegisterHelper
|
||||
|
||||
protect_from_forgery prepend: true, unless: -> { request.format.json? }
|
||||
|
||||
before_action :check_sign
|
||||
|
@ -728,11 +729,6 @@ class ApplicationController < ActionController::Base
|
|||
render_not_found("未找到’#{project}’相关的项目") unless @project
|
||||
end
|
||||
|
||||
def find_project_with_identifier
|
||||
@project = Project.find_by_identifier! params[:id]
|
||||
render_not_found("未找到’#{params[:id]}’相关的项目") unless @project
|
||||
end
|
||||
|
||||
def find_project_with_id
|
||||
@project = Project.find(params[:project_id] || params[:id])
|
||||
rescue Exception => e
|
||||
|
@ -744,9 +740,30 @@ class ApplicationController < ActionController::Base
|
|||
interactor.success? ? render_ok : render_error(interactor.error)
|
||||
end
|
||||
|
||||
# devops 权限验证
|
||||
def devops_authorize!
|
||||
render_forbidden unless @project.owner?(current_user)
|
||||
# projects
|
||||
def load_project
|
||||
namespace = params[:owner]
|
||||
id = params[:repo] || params[:id]
|
||||
|
||||
@project = Project.find_with_namespace(namespace, id)
|
||||
|
||||
if @project and current_user.can_read_project?(@project)
|
||||
logger.info "###########: has project and can read project"
|
||||
@project
|
||||
elsif current_user.is_a?(AnonymousUser)
|
||||
logger.info "###########:This is AnonymousUser"
|
||||
@project = nil if !@project.is_public?
|
||||
render_forbidden and return
|
||||
else
|
||||
logger.info "###########:project not found"
|
||||
@project = nil
|
||||
render_not_found and return
|
||||
end
|
||||
@project
|
||||
end
|
||||
|
||||
def load_repository
|
||||
@repository ||= load_project.repository
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
class Ci::BaseController < ApplicationController
|
||||
before_action :require_login
|
||||
end
|
|
@ -0,0 +1,58 @@
|
|||
class Ci::BuildsController < Ci::BaseController
|
||||
include RepositoriesHelper
|
||||
|
||||
before_action :find_project, :find_cloud_account
|
||||
before_action :find_cloud_account, except: :get_trustie_pipeline
|
||||
before_action :ci_authorize!
|
||||
|
||||
def index
|
||||
result = Ci::Drone::API.new(@cloud_account.drone_token, @cloud_account.drone_url, @project.owner.login, @project.identifier).builds
|
||||
|
||||
render json: result
|
||||
end
|
||||
|
||||
def detail
|
||||
result = Ci::Drone::API.new(@cloud_account.drone_token, @cloud_account.drone_url, @project.owner.login, @project.identifier, number: params[:number]).build
|
||||
|
||||
render json: result
|
||||
end
|
||||
|
||||
def restart
|
||||
result = Ci::Drone::API.new(@cloud_account.drone_token, @cloud_account.drone_url, @project.owner.login, @project.identifier, number: params[:number]).restart
|
||||
|
||||
render json: result
|
||||
end
|
||||
|
||||
def delete
|
||||
result = Ci::Drone::API.new(@cloud_account.drone_token, @cloud_account.drone_url, @project.owner.login, @project.identifier, number: params[:number]).stop
|
||||
render json: result
|
||||
end
|
||||
|
||||
def logs
|
||||
result = Ci::Drone::API.new(@cloud_account.drone_token, @cloud_account.drone_url, @project.owner.login, @project.identifier, build: params[:number], stage: params[:stage], step: params[:step]).logs
|
||||
|
||||
render json: result
|
||||
end
|
||||
|
||||
# get .trustie-pipeline.yml file
|
||||
def get_trustie_pipeline
|
||||
file_path_uri = URI.parse('.trustie-pipeline.yml')
|
||||
interactor = Repositories::EntriesInteractor.call(@project.owner, @project.identifier, file_path_uri, ref: params[:ref] || "master")
|
||||
if interactor.success?
|
||||
file = interactor.result
|
||||
return render json: {} if file[:status]
|
||||
|
||||
json = {name: file['name'], path: file['path'], sha: file['sha'], content: render_decode64_content(file['content'])}
|
||||
render json: json
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_project
|
||||
@project = Project.find params[:project_id]
|
||||
end
|
||||
|
||||
def find_cloud_account
|
||||
@cloud_account = @project.ci_cloud_account
|
||||
end
|
||||
end
|
|
@ -1,21 +1,21 @@
|
|||
class DevOps::CloudAccountsController < ApplicationController
|
||||
before_action :require_login
|
||||
before_action :find_project
|
||||
before_action :devops_authorize!
|
||||
class Ci::CloudAccountsController < Ci::BaseController
|
||||
include Devopsable
|
||||
|
||||
before_action :auto_load_project
|
||||
before_action :ci_authorize!
|
||||
before_action :find_cloud_account, only: %i[activate]
|
||||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
DevOps::CreateCloudAccountForm.new(devops_params).validate!
|
||||
Ci::CreateCloudAccountForm.new(devops_params).validate!
|
||||
|
||||
# 1. 保存华为云服务器帐号
|
||||
create_params = devops_params.merge(ip_num: IPAddr.new(devops_params[:ip_num]).to_i, secret: DevOps::CloudAccount.encrypted_secret(devops_params[:secret]))
|
||||
create_params = devops_params.merge(ip_num: IPAddr.new(devops_params[:ip_num]).to_i, secret: Ci::CloudAccount.encrypted_secret(devops_params[:secret]))
|
||||
if cloud_account = @project.dev_ops_cloud_account
|
||||
return render_error('该仓库已绑定了云帐号.')
|
||||
else
|
||||
cloud_account = DevOps::CloudAccount.new(create_params)
|
||||
cloud_account = Ci::CloudAccount.new(create_params)
|
||||
cloud_account.user = current_user
|
||||
cloud_account.repo_id = @project.repository.id
|
||||
cloud_account.project_id = @project.id
|
||||
cloud_account.save!
|
||||
end
|
||||
|
||||
|
@ -34,15 +34,15 @@ class DevOps::CloudAccountsController < ApplicationController
|
|||
logger.info "######### rpc_secret: #{rpc_secret}"
|
||||
|
||||
# 3. 创建drone server
|
||||
drone_server_cmd = DevOps::Drone::Server.new(oauth.client_id, oauth.client_secret, cloud_account.drone_host, rpc_secret).generate_cmd
|
||||
drone_server_cmd = Ci::Drone::Server.new(oauth.client_id, oauth.client_secret, cloud_account.drone_host, rpc_secret).generate_cmd
|
||||
logger.info "######### drone_server_cmd: #{drone_server_cmd}"
|
||||
|
||||
# 4. 创建drone client
|
||||
drone_client_cmd = DevOps::Drone::Client.new(oauth.client_id, cloud_account.drone_ip, rpc_secret).generate_cmd
|
||||
drone_client_cmd = Ci::Drone::Client.new(oauth.client_id, cloud_account.drone_ip, rpc_secret).generate_cmd
|
||||
logger.info "######### drone_client_cmd: #{drone_client_cmd}"
|
||||
|
||||
# 5. 登录远程服务器,启动drone服务
|
||||
result = DevOps::Drone::Start.new(cloud_account.account, cloud_account.visible_secret, cloud_account.drone_ip, drone_server_cmd, drone_client_cmd).run
|
||||
result = Ci::Drone::Start.new(cloud_account.account, cloud_account.visible_secret, cloud_account.drone_ip, drone_server_cmd, drone_client_cmd).run
|
||||
logger.info "######### result: #{result}"
|
||||
|
||||
|
||||
|
@ -50,6 +50,7 @@ class DevOps::CloudAccountsController < ApplicationController
|
|||
logger.info "######### redirect_url: #{redirect_url}"
|
||||
|
||||
if result && !result.blank?
|
||||
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
||||
render_ok(redirect_url: redirect_url)
|
||||
else
|
||||
render_error('激活失败, 请检查你的云服务器信息是否正确.')
|
||||
|
@ -60,12 +61,28 @@ class DevOps::CloudAccountsController < ApplicationController
|
|||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def activate
|
||||
result =
|
||||
if current_user.devops_has_token?
|
||||
# 已有drone_token的,直接激活项目
|
||||
Ci::Drone::API.new(@cloud_account.drone_token, @cloud_account.drone_url, @project.owner.login, @project.identifier).activate
|
||||
else
|
||||
# 没有token,说明是第一次激活devops, 需要用户填写token值
|
||||
return render_error('请先在CI服务端做用户认证.') if !current_user.devops_verified?
|
||||
Ci::Drone::API.new(params[:drone_token], @cloud_account.drone_url, @project.owner.login, @project.identifier).activate
|
||||
end
|
||||
|
||||
if result
|
||||
set_drone_token!(current_user, @cloud_account, params[:drone_token])
|
||||
@project.update_column(:open_devops, true)
|
||||
render_ok
|
||||
else
|
||||
render_error("激活失败,请检查你的token值是否正确.")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def devops_params
|
||||
params.permit(:account, :secret, :ip_num, :project_id)
|
||||
end
|
||||
|
||||
def find_project
|
||||
@project = Project.find params[:project_id]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
class Ci::LanguagesController < Ci::BaseController
|
||||
# TODO 需要开启权限认证,只有该项目devops初始化成功后才能获取语言列表
|
||||
before_action :find_langugae, only: :show
|
||||
|
||||
def index
|
||||
@languages = Ci::Language.by_usage_amount_desc
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def common
|
||||
@languages = Ci::Language.six_common
|
||||
end
|
||||
|
||||
private
|
||||
def find_langugae
|
||||
@language = Ci::Language.find params[:id]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
module Devopsable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
end
|
||||
|
||||
# ci 权限验证
|
||||
def ci_authorize!
|
||||
render_forbidden unless @project.owner?(current_user)
|
||||
end
|
||||
|
||||
def auto_load_project
|
||||
@project = Project.find_by(id: params[:project_id]) || Project.find_by(identifier: params[:project_id])
|
||||
render_not_found('未找到相关的项目') if @project.blank?
|
||||
end
|
||||
|
||||
# TODO 暂时限制项目拥有者才有权限操作
|
||||
def limit_owner_can_devops!(user)
|
||||
return if @project.owner? user
|
||||
render_forbidden
|
||||
end
|
||||
|
||||
def find_cloud_account
|
||||
@cloud_account = Ci::CloudAccount.find params[:id]
|
||||
end
|
||||
|
||||
def set_drone_token!(user, cloud_account, drone_token)
|
||||
return if user.devops_has_token?
|
||||
cloud_account.update_column(:drone_token, drone_token)
|
||||
user.set_drone_step!(User::DEVOPS_HAS_TOKEN)
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@ module OperateProjectAbilityAble
|
|||
end
|
||||
|
||||
def authorizate_user_can_edit_repo!
|
||||
return if @repo.project.manager?(current_user) || current_user.admin?
|
||||
return if @repository.project.manager?(current_user) || current_user.admin?
|
||||
render_forbidden('你没有权限操作.')
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
module RegisterHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def autologin_register(username, email, password, platform= '')
|
||||
result = {message: nil, user: nil}
|
||||
|
||||
user = User.new(admin: false, login: username, mail: email, type: "User")
|
||||
user.password = password
|
||||
user.platform = platform
|
||||
user.activate
|
||||
|
||||
interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password})
|
||||
if interactor.success?
|
||||
gitea_user = interactor.result
|
||||
result = Gitea::User::GenerateTokenService.new(username, password).call
|
||||
user.gitea_token = result['sha1']
|
||||
user.gitea_uid = gitea_user['id']
|
||||
if user.save!
|
||||
UserExtension.create!(user_id: user.id)
|
||||
result[:user] = {id: user.id, token: user.gitea_token}
|
||||
end
|
||||
else
|
||||
result[:message] = interactor.error
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
end
|
|
@ -1,59 +0,0 @@
|
|||
class DevOps::BuildsController < ApplicationController
|
||||
include RepositoriesHelper
|
||||
|
||||
before_action :require_login
|
||||
before_action :find_project
|
||||
before_action :devops_authorize!
|
||||
|
||||
def index
|
||||
cloud_account = @project.dev_ops_cloud_account
|
||||
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @project.owner.login, @project.identifier).builds
|
||||
|
||||
render json: result
|
||||
end
|
||||
|
||||
def detail
|
||||
cloud_account = @project.dev_ops_cloud_account
|
||||
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @project.owner.login, @project.identifier, number: params[:number]).build
|
||||
|
||||
render json: result
|
||||
end
|
||||
|
||||
def restart
|
||||
cloud_account = @project.dev_ops_cloud_account
|
||||
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @project.owner.login, @project.identifier, number: params[:number]).restart
|
||||
|
||||
render json: result
|
||||
end
|
||||
|
||||
def delete
|
||||
cloud_account = @project.dev_ops_cloud_account
|
||||
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @project.owner.login, @project.identifier, number: params[:number]).stop
|
||||
render json: result
|
||||
end
|
||||
|
||||
def logs
|
||||
cloud_account = @project.dev_ops_cloud_account
|
||||
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @project.owner.login, @project.identifier, build: params[:number], stage: params[:stage], step: params[:step]).logs
|
||||
|
||||
render json: result
|
||||
end
|
||||
|
||||
# get .trustie-pipeline.yml file
|
||||
def get_trustie_pipeline
|
||||
file_path_uri = URI.parse('.trustie-pipeline.yml')
|
||||
interactor = Repositories::EntriesInteractor.call(@project.owner, @project.identifier, file_path_uri, ref: params[:ref] || "master")
|
||||
if interactor.success?
|
||||
file = interactor.result
|
||||
return render json: {} if file[:status]
|
||||
|
||||
json = {name: file['name'], path: file['path'], content: render_decode64_content(file['content'])}
|
||||
render json: json
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_project
|
||||
@project = Project.find params[:project_id]
|
||||
end
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
class DevOps::LanguagesController < ApplicationController
|
||||
before_action :require_login
|
||||
before_action :find_langugae, only: :show
|
||||
|
||||
def index
|
||||
@languages = DevOps::Language.by_usage_amount_desc
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def common
|
||||
@languages = DevOps::Language.six_common
|
||||
end
|
||||
|
||||
private
|
||||
def find_langugae
|
||||
@language = DevOps::Language.find params[:id]
|
||||
end
|
||||
end
|
|
@ -1,5 +1,6 @@
|
|||
class ForksController < ApplicationController
|
||||
before_action :require_login, :find_project_with_id
|
||||
before_action :require_login
|
||||
before_action :load_project
|
||||
before_action :authenticate_project!, :authenticate_user!
|
||||
|
||||
def create
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class IssueTagsController < ApplicationController
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :find_project_with_id
|
||||
before_action :set_project
|
||||
before_action :load_repository
|
||||
before_action :set_user
|
||||
before_action :check_issue_permission, except: :index
|
||||
before_action :set_issue_tag, only: [:edit, :update, :destroy]
|
||||
|
||||
|
@ -38,12 +38,12 @@ class IssueTagsController < ApplicationController
|
|||
begin
|
||||
issue_tag = IssueTag.new(tag_params.merge(project_id: @project.id, user_id: current_user.id))
|
||||
if issue_tag.save
|
||||
gitea_tag = Gitea::Labels::CreateService.new(current_user, @repository.try(:identifier), tag_params).call
|
||||
if gitea_tag && issue_tag.update_attributes(gid: gitea_tag["id"], gitea_url: gitea_tag["url"])
|
||||
normal_status(0, "标签创建成功")
|
||||
else
|
||||
normal_status(-1, "标签创建失败")
|
||||
end
|
||||
# gitea_tag = Gitea::Labels::CreateService.new(current_user, @repository.try(:identifier), tag_params).call
|
||||
# if gitea_tag && issue_tag.update_attributes(gid: gitea_tag["id"], gitea_url: gitea_tag["url"])
|
||||
# normal_status(0, "标签创建成功")
|
||||
# else
|
||||
# normal_status(-1, "标签创建失败")
|
||||
# end
|
||||
else
|
||||
normal_status(-1, "标签创建失败")
|
||||
end
|
||||
|
@ -79,12 +79,12 @@ class IssueTagsController < ApplicationController
|
|||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
if @issue_tag.update_attributes(tag_params)
|
||||
gitea_tag = Gitea::Labels::UpdateService.new(current_user, @repository.try(:identifier),@issue_tag.try(:gid), tag_params).call
|
||||
if gitea_tag
|
||||
normal_status(0, "标签更新成功")
|
||||
else
|
||||
normal_status(-1, "标签更新失败")
|
||||
end
|
||||
# gitea_tag = Gitea::Labels::UpdateService.new(current_user, @repository.try(:identifier),@issue_tag.try(:gid), tag_params).call
|
||||
# if gitea_tag
|
||||
# normal_status(0, "标签更新成功")
|
||||
# else
|
||||
# normal_status(-1, "标签更新失败")
|
||||
# end
|
||||
else
|
||||
normal_status(-1, "标签更新失败")
|
||||
end
|
||||
|
@ -103,12 +103,12 @@ class IssueTagsController < ApplicationController
|
|||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
if @issue_tag.destroy
|
||||
issue_tag = Gitea::Labels::DeleteService.new(@user, @repository.try(:identifier), @issue_tag.try(:gid)).call
|
||||
if issue_tag
|
||||
normal_status(0, "标签删除成功")
|
||||
else
|
||||
normal_status(-1, "标签删除失败")
|
||||
end
|
||||
# issue_tag = Gitea::Labels::DeleteService.new(@user, @repository.try(:identifier), @issue_tag.try(:gid)).call
|
||||
# if issue_tag
|
||||
# normal_status(0, "标签删除成功")
|
||||
# else
|
||||
# normal_status(-1, "标签删除失败")
|
||||
# end
|
||||
else
|
||||
normal_status(-1, "标签删除失败")
|
||||
end
|
||||
|
@ -121,13 +121,8 @@ class IssueTagsController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
def set_project
|
||||
# @project = Project.find_by_identifier! params[:project_id]
|
||||
@repository = @project.repository
|
||||
def set_user
|
||||
@user = @project.owner
|
||||
normal_status(-1, "项目不存在") unless @project.present?
|
||||
normal_status(-1, "仓库不存在") unless @repository.present?
|
||||
normal_status(-1, "用户不存在") unless @user.present?
|
||||
end
|
||||
|
||||
def check_issue_permission
|
||||
|
@ -143,4 +138,4 @@ class IssueTagsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class IssuesController < ApplicationController
|
||||
before_action :require_login, except: [:index, :show, :index_chosen]
|
||||
before_action :find_project_with_id
|
||||
before_action :set_project_and_user
|
||||
before_action :load_project
|
||||
before_action :set_user
|
||||
before_action :check_issue_permission
|
||||
before_action :check_project_public, only: [:index ,:show, :copy, :index_chosen, :close_issue]
|
||||
|
||||
|
@ -16,7 +16,7 @@ class IssuesController < ApplicationController
|
|||
@user_admin_or_member = current_user.present? && current_user.logged? && (current_user.admin || @project.member?(current_user))
|
||||
issues = @project.issues.issue_issue.issue_index_includes
|
||||
issues = issues.where(is_private: false) unless @user_admin_or_member
|
||||
|
||||
|
||||
@all_issues_size = issues.size
|
||||
@open_issues_size = issues.where.not(status_id: 5).size
|
||||
@close_issues_size = issues.where(status_id: 5).size
|
||||
|
@ -383,11 +383,8 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
|
||||
private
|
||||
def set_project_and_user
|
||||
# @project = Project.find_by_identifier(params[:project_id]) || (Project.find params[:project_id]) || (Project.find params[:id])
|
||||
def set_user
|
||||
@user = @project&.owner
|
||||
# normal_status(-1, "项目不存在") unless @project.present?
|
||||
normal_status(-1, "用户不存在") unless @user.present?
|
||||
end
|
||||
|
||||
def check_project_public
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class MembersController < ApplicationController
|
||||
before_action :require_login
|
||||
before_action :find_project_with_id
|
||||
before_action :load_project
|
||||
before_action :find_user_with_id, only: %i[create remove change_role]
|
||||
before_action :operate!, except: %i[index]
|
||||
before_action :check_member_exists!, only: %i[create]
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
class Oauth::EducoderController < Oauth::BaseController
|
||||
def bind
|
||||
begin
|
||||
login = params[:login]
|
||||
callback_url = params[:callback_url]
|
||||
token = params[:token]
|
||||
|
||||
::OauthEducoderForm.new({login: login, token: token, callback_url: callback_url}).validate!
|
||||
|
||||
open_user= OpenUsers::Educoder.find_by(uid: login)
|
||||
|
||||
if open_user.present? && open_user.user.present? && open_user.user.email_binded?
|
||||
if current_user != open_user.user
|
||||
logout_user
|
||||
successful_authentication(open_user.user)
|
||||
end
|
||||
redirect_to callback_url
|
||||
else
|
||||
if current_user.blank? || !current_user.logged?
|
||||
user = User.find_by(login: login)
|
||||
if user
|
||||
successful_authentication(user)
|
||||
OpenUsers::Educoder.create!(user: user, uid: user.login)
|
||||
|
||||
redirect_to callback_url
|
||||
else
|
||||
redirect_to oauth_register_path(login: login, callback_url: callback_url)
|
||||
end
|
||||
else
|
||||
# forge平台已登录
|
||||
OpenUsers::Educoder.create!(user: current_user, uid: login)
|
||||
redirect_to callback_url
|
||||
end
|
||||
end
|
||||
rescue WechatOauth::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,6 @@
|
|||
class OauthController < ApplicationController
|
||||
layout "oauth_register", only: [:register]
|
||||
|
||||
DEFAULT_PASSWORD = "a12345678"
|
||||
TOKEN_CALL_BACK = "/oauth/get_token_callback"
|
||||
USER_INFO = "/oauth/userinfo"
|
||||
|
@ -51,4 +53,35 @@ class OauthController < ApplicationController
|
|||
|
||||
def get_token_callback
|
||||
end
|
||||
|
||||
def register
|
||||
end
|
||||
|
||||
def auto_register
|
||||
login = params[:login]
|
||||
email = params[:mail]
|
||||
password = params[:password]
|
||||
callback_url = params[:callback_url]
|
||||
platform = params[:plathform] || 'educoder'
|
||||
|
||||
if User.where(mail: email).exists?
|
||||
render_error("该邮箱已使用过.") and return
|
||||
end
|
||||
|
||||
result = autologin_register(login, email, password, platform)
|
||||
logger.info "[Oauth educoer] =====#{result}"
|
||||
if result[:message].blank?
|
||||
logger.info "[Oauth educoer] ====auto_register success"
|
||||
user = User.find result[:user][:id]
|
||||
successful_authentication(user)
|
||||
OpenUsers::Educoder.create!(user: user, uid: user.login)
|
||||
|
||||
render_ok({callback_url: callback_url})
|
||||
# redirect_to callback_url
|
||||
else
|
||||
logger.info "[Oauth educoer] ====auto_register failed."
|
||||
render :action => "auto_register"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class ProjectTrendsController < ApplicationController
|
||||
before_action :find_project_with_id
|
||||
before_action :load_repository
|
||||
before_action :check_project_public
|
||||
|
||||
def index
|
||||
|
@ -44,4 +44,4 @@ class ProjectTrendsController < ApplicationController
|
|||
normal_status(-1, "您没有权限")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
class Projects::BaseController < ApplicationController
|
||||
include PaginateHelper
|
||||
|
||||
before_action :require_login, :check_auth
|
||||
before_action :load_project
|
||||
before_action :load_repository
|
||||
|
||||
end
|
||||
|
|
|
@ -2,8 +2,8 @@ class ProjectsController < ApplicationController
|
|||
include ApplicationHelper
|
||||
include OperateProjectAbilityAble
|
||||
include ProjectsHelper
|
||||
before_action :require_login, except: %i[index branches group_type_list simple]
|
||||
before_action :find_project_with_id, only: %i[show branches update destroy fork_users praise_users watch_users]
|
||||
before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users]
|
||||
before_action :load_project, except: %i[index group_type_list migrate create]
|
||||
before_action :authorizate_user_can_edit_project!, only: %i[update]
|
||||
before_action :project_public?, only: %i[fork_users praise_users watch_users]
|
||||
|
||||
|
@ -100,8 +100,7 @@ class ProjectsController < ApplicationController
|
|||
end
|
||||
|
||||
def simple
|
||||
project = Project.includes(:owner, :repository).select(:id, :name, :identifier, :user_id, :project_type, :open_devops).find params[:id]
|
||||
json_response(project)
|
||||
json_response(@project)
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class PullRequestsController < ApplicationController
|
||||
before_action :require_login, except: [:index, :show]
|
||||
before_action :find_project_with_id
|
||||
before_action :set_repository
|
||||
before_action :load_repository
|
||||
before_action :set_user, only: [:new, :get_branches]
|
||||
before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos]
|
||||
# before_action :get_relatived, only: [:edit]
|
||||
include TagChosenHelper
|
||||
|
@ -238,12 +238,8 @@ class PullRequestsController < ApplicationController
|
|||
|
||||
|
||||
private
|
||||
|
||||
def set_repository
|
||||
@repository = @project.repository
|
||||
def set_user
|
||||
@user = @project.owner
|
||||
normal_status(-1, "仓库不存在") unless @repository.present?
|
||||
normal_status(-1, "用户不存在") unless @user.present?
|
||||
end
|
||||
|
||||
def find_pull_request
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
class RepositoriesController < ApplicationController
|
||||
include ApplicationHelper
|
||||
include OperateProjectAbilityAble
|
||||
|
||||
before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror]
|
||||
before_action :find_project_with_includes, only: :show
|
||||
before_action :find_project, except: [:tags, :commit, :sync_mirror, :show]
|
||||
before_action :load_repository
|
||||
before_action :authorizate!, except: [:sync_mirror, :tags, :commit]
|
||||
before_action :find_repository_by_id, only: %i[commit sync_mirror tags]
|
||||
before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror]
|
||||
before_action :get_ref, only: %i[entries sub_entries top_counts]
|
||||
before_action :get_latest_commit, only: %i[entries sub_entries top_counts]
|
||||
|
@ -56,18 +55,18 @@ class RepositoriesController < ApplicationController
|
|||
end
|
||||
|
||||
def commit
|
||||
@commit = Gitea::Repository::Commits::GetService.new(@repo.user.login, @repo.identifier, params[:sha], current_user.gitea_token).call
|
||||
@commit = Gitea::Repository::Commits::GetService.new(@repository.user.login, @repository.identifier, params[:sha], current_user.gitea_token).call
|
||||
end
|
||||
|
||||
def tags
|
||||
@tags = Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @repo.user.login, @repo.identifier, {page: params[:page], limit: params[:limit]}).call
|
||||
@tags = Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @project.owner.login, @project.identifier, {page: params[:page], limit: params[:limit]}).call
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def create_file
|
||||
interactor = Gitea::CreateFileInteractor.call(current_user, content_params)
|
||||
interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @project.owner.login, content_params)
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
create_new_pr(params)
|
||||
|
@ -77,7 +76,7 @@ class RepositoriesController < ApplicationController
|
|||
end
|
||||
|
||||
def update_file
|
||||
interactor = Gitea::UpdateFileInteractor.call(current_user, params.merge(identifier: @project.identifier))
|
||||
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @project.owner.login, params.merge(identifier: @project.identifier))
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
create_new_pr(params)
|
||||
|
@ -88,7 +87,7 @@ class RepositoriesController < ApplicationController
|
|||
end
|
||||
|
||||
def delete_file
|
||||
interactor = Gitea::DeleteFileInteractor.call(current_user, params.merge(identifier: @project.identifier))
|
||||
interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @project.owner.login, params.merge(identifier: @project.identifier))
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
render_result(1, "文件删除成功")
|
||||
|
@ -102,10 +101,10 @@ class RepositoriesController < ApplicationController
|
|||
end
|
||||
|
||||
def sync_mirror
|
||||
return render_error("正在镜像中..") if @repo.mirror.waiting?
|
||||
return render_error("正在镜像中..") if @repository.mirror.waiting?
|
||||
|
||||
@repo.sync_mirror!
|
||||
SyncMirroredRepositoryJob.perform_later(@repo.id, current_user.id)
|
||||
@repository.sync_mirror!
|
||||
SyncMirroredRepositoryJob.perform_later(@repository.id, current_user.id)
|
||||
render_ok
|
||||
end
|
||||
|
||||
|
|
|
@ -12,11 +12,11 @@ class SyncForgeController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# def create
|
||||
# def create
|
||||
# ActiveRecord::Base.transaction do
|
||||
# params.permit!
|
||||
# sync_params = params[:sync_params]
|
||||
# project_user = User.where(login: sync_params[:owner_login])&.first
|
||||
# project_user = User.where(login: sync_params[:owner_login])&.first
|
||||
# #以前已同步的项目,那么肯定存在仓库
|
||||
# SyncLog.sync_log("=================begin_to_sync_forge: project_identifier: #{sync_params[:identifier]}========")
|
||||
# user_projects = Project.where(user_id: project_user.id)
|
||||
|
@ -38,7 +38,7 @@ class SyncForgeController < ApplicationController
|
|||
# check_sync_project(project, sync_params)
|
||||
# else #新建项目
|
||||
# SyncLog.sync_log("=================begin_to_create_new_project========")
|
||||
|
||||
|
||||
# project_params = {
|
||||
# repository_name: sync_params[:identifier],
|
||||
# user_id: project_user.id,
|
||||
|
@ -53,7 +53,7 @@ class SyncForgeController < ApplicationController
|
|||
# new_project_score = ProjectScore.create(score_params)
|
||||
# SyncLog.sync_log("=================new_project_score:#{new_project_score.try(:id)}========")
|
||||
# end
|
||||
|
||||
|
||||
# SyncRepositoryJob.perform_later(sync_params[:owner_login], sync_params[:identifier], sync_params[:repository], get_sudomain) if sync_params[:repository].present?
|
||||
# check_new_project(project, sync_params)
|
||||
# else
|
||||
|
@ -115,7 +115,7 @@ class SyncForgeController < ApplicationController
|
|||
# SyncLog.sync_log("=================sync_user_failed====#{e}")
|
||||
# end
|
||||
|
||||
# private
|
||||
# private
|
||||
|
||||
# def check_sync_project(project,sync_params)
|
||||
# begin
|
||||
|
@ -125,8 +125,8 @@ class SyncForgeController < ApplicationController
|
|||
# # end
|
||||
|
||||
# SyncLog.sync_log("----begin_to_check_sync_project----project_id:#{project.id}---------------")
|
||||
# change_project_score(project, sync_params[:project_score], sync_params[:repository]) if sync_params[:repository].present? #更新project_score
|
||||
# change_project_issues(project, sync_params[:issues],project.id, gitea_main)
|
||||
# change_project_score(project, sync_params[:project_score], sync_params[:repository]) if sync_params[:repository].present? #更新project_score
|
||||
# change_project_issues(project, sync_params[:issues],project.id, gitea_main)
|
||||
# change_project_members(project, sync_params[:members],gitea_main)
|
||||
# change_project_versions(project, sync_params[:project_versions],gitea_main)
|
||||
# change_project_watchers(project, sync_params[:project_watchers],gitea_main)
|
||||
|
@ -134,7 +134,7 @@ class SyncForgeController < ApplicationController
|
|||
# rescue => e
|
||||
# SyncLog.sync_log("=========check_sync_project_errors:#{e}===================")
|
||||
# end
|
||||
|
||||
|
||||
# end
|
||||
|
||||
# def check_new_project(project,sync_params)
|
||||
|
@ -167,7 +167,7 @@ class SyncForgeController < ApplicationController
|
|||
# parent_id: project.id
|
||||
# }
|
||||
# SyncProjectsJob.perform_later(sync_projects_params,gitea_main)
|
||||
|
||||
|
||||
# SyncLog.sync_log("***6. end_to_sync_parises---------------")
|
||||
# end
|
||||
# end
|
||||
|
@ -189,7 +189,7 @@ class SyncForgeController < ApplicationController
|
|||
# end
|
||||
# end
|
||||
# pre_project_score.save! if change_num > 0 #如果 project_score有变化则更新
|
||||
# else
|
||||
# else
|
||||
# ProjectScore.create!(project_scores.merge(project_id: project.id))
|
||||
# end
|
||||
# SyncLog.sync_log("***1. end_to_sync_project_score---------------")
|
||||
|
@ -206,7 +206,7 @@ class SyncForgeController < ApplicationController
|
|||
# SyncLog.sync_log("***2--01. forge_issue_ids-#{forge_issue_ids.size.to_i}--------------")
|
||||
# if forge_issue_ids.size.to_i <= old_issues_params[:count].to_i
|
||||
# diff_issue_ids = old_issues_params[:ids] - forge_issue_ids
|
||||
|
||||
|
||||
# if diff_issue_ids.size == 0 #issue数量一样,判断评论是否有增减
|
||||
# forge_journal_ids = Journal.select([:id, :journalized_id, :journalized_type]).where(journalized_id: forge_issue_ids).pluck(:id)
|
||||
# diff_journal_ids = old_issues_params[:journals][:ids] - forge_journal_ids
|
||||
|
@ -241,10 +241,10 @@ class SyncForgeController < ApplicationController
|
|||
# # }
|
||||
# # SyncLog.sync_log("***2--03. sync_projects_params_groups-#{sync_projects_params}--------------")
|
||||
# # SyncProjectsJob.perform_later(sync_projects_params, gitea_main)
|
||||
|
||||
|
||||
# end
|
||||
# end
|
||||
|
||||
|
||||
# # SyncProjectsJob.perform_later(sync_projects_params, gitea_main) if sync_projects_params.present?
|
||||
# SyncLog.sync_log("***2. end_to_syncissues---------------")
|
||||
# rescue Exception => e
|
||||
|
@ -265,7 +265,7 @@ class SyncForgeController < ApplicationController
|
|||
# parent_id: project.id
|
||||
# }
|
||||
# SyncProjectsJob.perform_later(sync_projects_params,gitea_main)
|
||||
|
||||
|
||||
# end
|
||||
# end
|
||||
# SyncLog.sync_log("***5. begin_to_sync_watchers---------------")
|
||||
|
@ -285,7 +285,7 @@ class SyncForgeController < ApplicationController
|
|||
# }
|
||||
# SyncProjectsJob.perform_later(sync_projects_params,gitea_main)
|
||||
# end
|
||||
|
||||
|
||||
# SyncLog.sync_log("***4. end_to_sync_versions---------------")
|
||||
# end
|
||||
# end
|
||||
|
@ -304,7 +304,7 @@ class SyncForgeController < ApplicationController
|
|||
# }
|
||||
# SyncProjectsJob.perform_later(sync_projects_params,gitea_main)
|
||||
# end
|
||||
|
||||
|
||||
# SyncLog.sync_log("***3. end_to_sync_members---------------")
|
||||
# end
|
||||
# end
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
class UsersController < ApplicationController
|
||||
include Devopsable
|
||||
|
||||
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users]
|
||||
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users]
|
||||
before_action :require_login, only: %i[me list]
|
||||
before_action :require_login, only: %i[me list devops_authenticate devops]
|
||||
before_action :auto_load_project, only: %i[devops devops_authenticate]
|
||||
skip_before_action :check_sign, only: [:attachment_show]
|
||||
|
||||
def list
|
||||
|
@ -177,7 +179,7 @@ class UsersController < ApplicationController
|
|||
def trustie_projects
|
||||
user_id = User.select(:id, :login).where(login: params[:login])&.first&.id
|
||||
projects = Project.visible
|
||||
|
||||
|
||||
projects = projects.joins(:members).where(members: { user_id: user_id })
|
||||
|
||||
search = params[:search].to_s.strip
|
||||
|
@ -212,6 +214,19 @@ class UsersController < ApplicationController
|
|||
render_ok
|
||||
end
|
||||
|
||||
def devops
|
||||
@user = current_user
|
||||
limit_owner_can_devops!(user)
|
||||
@cloud_account = @user.dev_ops_cloud_account
|
||||
end
|
||||
|
||||
# devops 认证
|
||||
def devops_authenticate
|
||||
limit_owner_can_devops!(current_user)
|
||||
current_user.set_drone_step!(User::DEVOPS_VERIFIED)
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
def load_user
|
||||
@user = User.find_by_login(params[:id]) || User.find_by(id: params[:id])
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class VersionReleasesController < ApplicationController
|
||||
before_action :find_project_with_id
|
||||
before_action :set_user_and_project
|
||||
before_action :load_repository
|
||||
before_action :set_user
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :find_version , only: [:edit, :update, :destroy]
|
||||
|
||||
|
@ -78,14 +78,14 @@ class VersionReleasesController < ApplicationController
|
|||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
version_params = releases_params
|
||||
|
||||
|
||||
if @version.update_attributes!(version_params)
|
||||
create_attachments(params[:attachment_ids], @version) if params[:attachment_ids].present?
|
||||
git_version_release = Gitea::Versions::UpdateService.new(@user.gitea_token, @user.try(:login), @repository.try(:identifier), version_params, @version.try(:version_gid)).call
|
||||
unless git_version_release
|
||||
raise Error, "更新失败"
|
||||
end
|
||||
|
||||
|
||||
normal_status(0, "更新成功")
|
||||
else
|
||||
normal_status(-1, "更新失败")
|
||||
|
@ -123,14 +123,8 @@ class VersionReleasesController < ApplicationController
|
|||
|
||||
|
||||
private
|
||||
|
||||
def set_user_and_project
|
||||
# @project = Project.find_by_id(params[:project_id])
|
||||
@repository = @project.repository #项目的仓库
|
||||
@user = @project.owner
|
||||
unless @user.present? && @project.present? && @repository.present?
|
||||
normal_status(-1, "仓库不存在")
|
||||
end
|
||||
def set_user
|
||||
@user = @repository.user
|
||||
end
|
||||
|
||||
def find_version
|
||||
|
@ -140,7 +134,7 @@ class VersionReleasesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def releases_params
|
||||
def releases_params
|
||||
{
|
||||
body: params[:body],
|
||||
draft: params[:draft] || false,
|
||||
|
@ -151,7 +145,7 @@ class VersionReleasesController < ApplicationController
|
|||
}
|
||||
end
|
||||
|
||||
def create_attachments(attachment_ids, target)
|
||||
def create_attachments(attachment_ids, target)
|
||||
attachment_ids.each do |id|
|
||||
attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id)
|
||||
unless attachment.blank?
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class VersionsController < ApplicationController
|
||||
before_action :require_login, except: [:index, :show]
|
||||
before_action :find_project_with_id
|
||||
before_action :load_repository
|
||||
before_action :check_issue_permission, except: [:show, :index]
|
||||
before_action :set_version, only: [:edit, :update, :destroy, :show,:update_status]
|
||||
|
||||
|
@ -166,4 +166,4 @@ class VersionsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class DevOps::CreateCloudAccountForm
|
||||
class Ci::CreateCloudAccountForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :project_id, :ip_num, :account, :secret
|
|
@ -0,0 +1,36 @@
|
|||
class OauthEducoderForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :login, :token, :callback_url
|
||||
|
||||
validates :login, presence: true
|
||||
validates :token, presence: true
|
||||
validates :callback_url, presence: true
|
||||
|
||||
validate :check_callback_url!
|
||||
validate :check_auth!
|
||||
|
||||
def check_auth!
|
||||
Rails.logger.info "====login: #{login} ====token: #{token} ==== callback_url: #{callback_url}"
|
||||
secret = OauthEducoder.config[:access_key_secret]
|
||||
Rails.logger.info "==== secret: #{secret}"
|
||||
before_raw_pay_load = Digest::SHA1.hexdigest("#{login}#{secret}#{Time.now.to_i/60-1}")
|
||||
now_raw_pay_load = Digest::SHA1.hexdigest("#{login}#{secret}#{Time.now.to_i/60}")
|
||||
|
||||
Rails.logger.info "==== before_raw_pay_load: #{before_raw_pay_load}"
|
||||
Rails.logger.info "==== now_raw_pay_load: #{now_raw_pay_load}"
|
||||
Rails.logger.info "==== token: #{token}"
|
||||
|
||||
if token != now_raw_pay_load && token != before_raw_pay_load
|
||||
raise '你的请求无效值无效.'
|
||||
end
|
||||
end
|
||||
|
||||
def check_callback_url!
|
||||
request_host = URI.parse(callback_url).host
|
||||
callback_url = OauthEducoder.config[:callback_url_host]
|
||||
|
||||
raise 'callback_url参数无效.' if request_host != callback_url
|
||||
end
|
||||
|
||||
end
|
|
@ -1,15 +1,15 @@
|
|||
module Gitea
|
||||
class CreateFileInteractor
|
||||
def self.call(user, params={})
|
||||
interactor = new(user, params)
|
||||
def self.call(token, owner, params={})
|
||||
interactor = new(token, owner, params)
|
||||
interactor.run
|
||||
interactor
|
||||
end
|
||||
|
||||
attr_reader :error, :result
|
||||
|
||||
def initialize(user, params)
|
||||
@user = user
|
||||
def initialize(token, owner, params)
|
||||
@owner = owner
|
||||
@params = params
|
||||
end
|
||||
|
||||
|
@ -23,7 +23,7 @@ module Gitea
|
|||
|
||||
def run
|
||||
Contents::CreateForm.new(valid_params).validate!
|
||||
response = Gitea::Repository::Entries::CreateService.new(user, @params[:identifier], @params[:filepath], file_params).call
|
||||
response = Gitea::Repository::Entries::CreateService.new(token, owner, @params[:identifier], @params[:filepath], file_params).call
|
||||
render_result(response)
|
||||
rescue Exception => exception
|
||||
Rails.logger.info "Exception ===========> #{exception.message}"
|
||||
|
@ -33,7 +33,7 @@ module Gitea
|
|||
|
||||
private
|
||||
|
||||
attr_reader :params, :user
|
||||
attr_reader :params, :owner, :token
|
||||
|
||||
def fail!(error)
|
||||
@error = error
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
module Gitea
|
||||
class DeleteFileInteractor
|
||||
def self.call(user, params={})
|
||||
interactor = new(user, params)
|
||||
def self.call(token, owner, params={})
|
||||
interactor = new(token, owner, params)
|
||||
interactor.run
|
||||
interactor
|
||||
end
|
||||
|
||||
attr_reader :error, :result
|
||||
|
||||
def initialize(user, params)
|
||||
@user = user
|
||||
def initialize(token, owner, params)
|
||||
@token = token
|
||||
@owner = owner
|
||||
@params = params
|
||||
end
|
||||
|
||||
|
@ -23,7 +24,7 @@ module Gitea
|
|||
|
||||
def run
|
||||
Contents::DeleteForm.new(valid_params).validate!
|
||||
response = Gitea::Repository::Entries::DeleteService.new(user, @params[:identifier], @params[:filepath], file_params).call
|
||||
response = Gitea::Repository::Entries::DeleteService.new(token, owner, @params[:identifier], @params[:filepath], file_params).call
|
||||
render_result(response)
|
||||
rescue Exception => exception
|
||||
fail!(exception.message)
|
||||
|
@ -31,7 +32,7 @@ module Gitea
|
|||
|
||||
private
|
||||
|
||||
attr_reader :params, :user
|
||||
attr_reader :params, :owner, :token
|
||||
|
||||
def fail!(error)
|
||||
puts "[exception]: error"
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
module Gitea
|
||||
class UpdateFileInteractor
|
||||
def self.call(user, params={})
|
||||
interactor = new(user, params)
|
||||
def self.call(token, owner, params={})
|
||||
interactor = new(token, owner, params)
|
||||
interactor.run
|
||||
interactor
|
||||
end
|
||||
|
||||
attr_reader :error, :result
|
||||
|
||||
def initialize(user, params)
|
||||
@user = user
|
||||
def initialize(token, owner, params)
|
||||
@owner = owner
|
||||
@token = token
|
||||
@params = params
|
||||
end
|
||||
|
||||
|
@ -23,7 +24,7 @@ module Gitea
|
|||
|
||||
def run
|
||||
Contents::UpdateForm.new(valid_params).validate!
|
||||
response = Gitea::Repository::Entries::UpdateService.new(user, @params[:identifier], @params[:filepath], file_params).call
|
||||
response = Gitea::Repository::Entries::UpdateService.new(token, owner, @params[:identifier], @params[:filepath], file_params).call
|
||||
render_result(response)
|
||||
rescue Exception => exception
|
||||
fail!(exception.message)
|
||||
|
@ -31,7 +32,7 @@ module Gitea
|
|||
|
||||
private
|
||||
|
||||
attr_reader :params, :user
|
||||
attr_reader :params, :owner, :token
|
||||
|
||||
def fail!(error)
|
||||
puts "[exception]: error"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class DevOps::Drone::API < DevOps::Drone::Request
|
||||
class Ci::Drone::API < Ci::Drone::Request
|
||||
attr_reader :drone_token, :endpoint, :owner, :repo, :options
|
||||
|
||||
# drone_token:
|
|
@ -1,4 +1,4 @@
|
|||
class DevOps::Drone::Ci
|
||||
class Ci::Drone::Ci
|
||||
attr_reader :host, :username, :password, :gitea_username
|
||||
|
||||
# host: drone server's ip
|
||||
|
@ -20,6 +20,6 @@ class DevOps::Drone::Ci
|
|||
|
||||
private
|
||||
def cmd
|
||||
"cd ..; cd var/lib/drone/; sqlite3 database.sqlite; .dump; select user_hash from users where user_login=#{gitea_username} "
|
||||
"cd ..; cd var/lib/drone/; sqlite3 database.sqlite; .dump; select user_hash from users where user_login=#{gitea_username};"
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
class DevOps::Drone::Client
|
||||
class Ci::Drone::Client
|
||||
attr_reader :client_id, :drone_ip, :rpc_secret
|
||||
|
||||
# client_id: user's client_id from oauth
|
|
@ -1,4 +1,4 @@
|
|||
class DevOps::Drone::Error < StandardError
|
||||
class Ci::Drone::Error < StandardError
|
||||
attr_reader :code
|
||||
|
||||
def initialize(code, message)
|
|
@ -0,0 +1,108 @@
|
|||
class Ci::Drone::Request
|
||||
# Converts the response body to an ObjectifiedHash.
|
||||
def self.parse(body)
|
||||
body = decode(body)
|
||||
|
||||
if body.is_a? Hash
|
||||
ObjectifiedHash.new body
|
||||
elsif body.is_a? Array
|
||||
body.collect! { |e| ObjectifiedHash.new(e) }
|
||||
elsif body == true
|
||||
body
|
||||
else
|
||||
raise Error::Parsing.new "Couldn't parse a response body"
|
||||
end
|
||||
end
|
||||
|
||||
# Decodes a JSON response into Ruby object.
|
||||
def self.decode(response)
|
||||
begin
|
||||
JSON.load response
|
||||
rescue JSON::ParserError
|
||||
raise Error::Parsing.new "The response is not a valid JSON"
|
||||
end
|
||||
end
|
||||
|
||||
def get(endpoint, path, options={})
|
||||
validate_request_params!(endpoint)
|
||||
request(:get, endpoint, path, options)
|
||||
end
|
||||
|
||||
def post(endpoint, path, options={})
|
||||
validate_request_params!(endpoint)
|
||||
request(:post, endpoint, path, options)
|
||||
end
|
||||
|
||||
def put(endpoint, path, options={})
|
||||
validate_request_params!(endpoint)
|
||||
request(:put, endpoint, path, options)
|
||||
end
|
||||
|
||||
def patch(endpoint, path, options={})
|
||||
validate_request_params!(endpoint)
|
||||
request(:patch, endpoint, path, options)
|
||||
end
|
||||
|
||||
def delete(endpoint, path, options={})
|
||||
validate_request_params!(endpoint)
|
||||
request(:delete, endpoint, path, options)
|
||||
end
|
||||
|
||||
private
|
||||
def request(method, endpoint, path, **params)
|
||||
Rails.logger.info("[drone] request: #{method} #{path} #{params.except(:drone_token).inspect}")
|
||||
|
||||
client ||= begin
|
||||
Faraday.new(url: endpoint) do |req|
|
||||
req.request :url_encoded
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.response :logger # 显示日志
|
||||
req.adapter Faraday.default_adapter
|
||||
req.authorization :Bearer, params[:drone_token]
|
||||
req.headers['Authorization']
|
||||
end
|
||||
end
|
||||
response = client.public_send(method, path) do |req|
|
||||
req.body = params.except(:drone_token).to_json
|
||||
end
|
||||
|
||||
json_response(response)
|
||||
end
|
||||
|
||||
# Checks the response code for common errors.
|
||||
# Returns parsed response for successful requests.
|
||||
def validate(response)
|
||||
# case response.code
|
||||
# when 400; raise Error::BadRequest.new error_message(response)
|
||||
# when 401; raise Error::Unauthorized.new error_message(response)
|
||||
# when 403; raise Error::Forbidden.new error_message(response)
|
||||
# when 404; raise Error::NotFound.new error_message(response)
|
||||
# when 405; raise Error::MethodNotAllowed.new error_message(response)
|
||||
# when 406; raise Error::DataNotAccepted.new error_message(response)
|
||||
# when 409; raise Error::Conflict.new error_message(response)
|
||||
# when 500; raise Error::InternalServerError.new error_message(response)
|
||||
# when 502; raise Error::BadGateway.new error_message(response)
|
||||
# when 503; raise Error::ServiceUnavailable.new error_message(response)
|
||||
# end
|
||||
|
||||
response.parsed_response
|
||||
end
|
||||
|
||||
# Checks a base_uri and params for requests.
|
||||
def validate_request_params!(endpoint)
|
||||
raise "Please set an endpoint to API" unless endpoint
|
||||
end
|
||||
|
||||
def error_message(response)
|
||||
"Server responded with code #{response.code}, message: #{response.parsed_response.message}. " \
|
||||
"Request URI: #{response.request.base_uri}#{response.request.path}"
|
||||
end
|
||||
|
||||
def json_response(response)
|
||||
result = JSON.parse(response.body)
|
||||
status = response.status
|
||||
Rails.logger.info("[drone] response:#{status} #{result.inspect}")
|
||||
|
||||
response.status != 200 ? result.merge!(status: response.status) : result
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
class DevOps::Drone::Server
|
||||
class Ci::Drone::Server
|
||||
attr_reader :client_id, :client_secret, :drone_host, :rpc_secret
|
||||
|
||||
# client_id: user's client_id from oauth
|
||||
|
@ -18,7 +18,8 @@ class DevOps::Drone::Server
|
|||
def generate_cmd
|
||||
"service docker start; docker rm -f `docker ps -qa`; docker run \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /var/lib/drone:/data \
|
||||
-e DRONE_DATABASE_DRIVER=mysql \
|
||||
-e DRONE_DATABASE_DATASOURCE=#{database_username}:#{database_password}@#{database_host}:3306/drone?parseTime=true \
|
||||
-e DRONE_GITEA_SERVER=#{gitea_url} \
|
||||
-e DRONE_GITEA_CLIENT_ID=#{client_id} \
|
||||
-e DRONE_GITEA_CLIENT_SECRET=#{client_secret} \
|
||||
|
@ -37,4 +38,24 @@ class DevOps::Drone::Server
|
|||
def gitea_url
|
||||
Gitea.gitea_config[:domain]
|
||||
end
|
||||
|
||||
def database_username
|
||||
database_config[Rails.env]["username"]
|
||||
end
|
||||
|
||||
def database_password
|
||||
database_config[Rails.env]["password"]
|
||||
end
|
||||
|
||||
def database_host
|
||||
database_config[Rails.env]["host"]
|
||||
end
|
||||
|
||||
def database
|
||||
database_config[Rails.env]["database"]
|
||||
end
|
||||
|
||||
def database_config
|
||||
Rails.configuration.database_configuration
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
class DevOps::Drone::Start
|
||||
class Ci::Drone::Start
|
||||
attr_reader :drone_username, :drone_password, :drone_host, :drone_server_cmd, :drone_client_cmd
|
||||
|
||||
# drone_username="XXXX" 云服务器登录用户名
|
|
@ -1,108 +0,0 @@
|
|||
class DevOps::Drone::Request
|
||||
# Converts the response body to an ObjectifiedHash.
|
||||
def self.parse(body)
|
||||
body = decode(body)
|
||||
|
||||
if body.is_a? Hash
|
||||
ObjectifiedHash.new body
|
||||
elsif body.is_a? Array
|
||||
body.collect! { |e| ObjectifiedHash.new(e) }
|
||||
elsif body == true
|
||||
body
|
||||
else
|
||||
raise Error::Parsing.new "Couldn't parse a response body"
|
||||
end
|
||||
end
|
||||
|
||||
# Decodes a JSON response into Ruby object.
|
||||
def self.decode(response)
|
||||
begin
|
||||
JSON.load response
|
||||
rescue JSON::ParserError
|
||||
raise Error::Parsing.new "The response is not a valid JSON"
|
||||
end
|
||||
end
|
||||
|
||||
def get(endpoint, path, options={})
|
||||
validate_request_params!(endpoint)
|
||||
request(:get, endpoint, path, options)
|
||||
end
|
||||
|
||||
def post(endpoint, path, options={})
|
||||
validate_request_params!(endpoint)
|
||||
request(:post, endpoint, path, options)
|
||||
end
|
||||
|
||||
def put(endpoint, path, options={})
|
||||
validate_request_params!(endpoint)
|
||||
request(:put, endpoint, path, options)
|
||||
end
|
||||
|
||||
def patch(endpoint, path, options={})
|
||||
validate_request_params!(endpoint)
|
||||
request(:patch, endpoint, path, options)
|
||||
end
|
||||
|
||||
def delete(endpoint, path, options={})
|
||||
validate_request_params!(endpoint)
|
||||
request(:delete, endpoint, path, options)
|
||||
end
|
||||
|
||||
private
|
||||
def request(method, endpoint, path, **params)
|
||||
Rails.logger.info("[drone] request: #{method} #{path} #{params.except(:drone_token).inspect}")
|
||||
|
||||
client ||= begin
|
||||
Faraday.new(url: endpoint) do |req|
|
||||
req.request :url_encoded
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.response :logger # 显示日志
|
||||
req.adapter Faraday.default_adapter
|
||||
req.authorization :Bearer, params[:drone_token]
|
||||
req.headers['Authorization']
|
||||
end
|
||||
end
|
||||
response = client.public_send(method, path) do |req|
|
||||
req.body = params.except(:drone_token).to_json
|
||||
end
|
||||
|
||||
json_response(response)
|
||||
end
|
||||
|
||||
# Checks the response code for common errors.
|
||||
# Returns parsed response for successful requests.
|
||||
def validate(response)
|
||||
# case response.code
|
||||
# when 400; raise Error::BadRequest.new error_message(response)
|
||||
# when 401; raise Error::Unauthorized.new error_message(response)
|
||||
# when 403; raise Error::Forbidden.new error_message(response)
|
||||
# when 404; raise Error::NotFound.new error_message(response)
|
||||
# when 405; raise Error::MethodNotAllowed.new error_message(response)
|
||||
# when 406; raise Error::DataNotAccepted.new error_message(response)
|
||||
# when 409; raise Error::Conflict.new error_message(response)
|
||||
# when 500; raise Error::InternalServerError.new error_message(response)
|
||||
# when 502; raise Error::BadGateway.new error_message(response)
|
||||
# when 503; raise Error::ServiceUnavailable.new error_message(response)
|
||||
# end
|
||||
|
||||
response.parsed_response
|
||||
end
|
||||
|
||||
# Checks a base_uri and params for requests.
|
||||
def validate_request_params!(endpoint)
|
||||
raise "Please set an endpoint to API" unless endpoint
|
||||
end
|
||||
|
||||
def error_message(response)
|
||||
"Server responded with code #{response.code}, message: #{response.parsed_response.message}. " \
|
||||
"Request URI: #{response.request.base_uri}#{response.request.path}"
|
||||
end
|
||||
|
||||
def json_response(response)
|
||||
result = JSON.parse(response.body)
|
||||
status = response.status
|
||||
Rails.logger.info("[drone] response:#{status} #{result.inspect}")
|
||||
|
||||
response.status != 200 ? result.merge!(status: response.status) : result
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
module OauthEducoder
|
||||
class << self
|
||||
def config
|
||||
educoder_config = {}
|
||||
|
||||
begin
|
||||
config = Rails.application.config_for(:configuration).symbolize_keys!
|
||||
educoder_config = config[:oauth_educoder].symbolize_keys!
|
||||
raise 'oauth educoder config missing' if educoder_config.blank?
|
||||
rescue => ex
|
||||
raise ex if Rails.env.production?
|
||||
|
||||
puts %Q{\033[33m [warning] educoder config or configuration.yml missing,
|
||||
please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
|
||||
educoder_config = {}
|
||||
end
|
||||
educoder_config
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
class DevOps::CloudAccount < ApplicationRecord
|
||||
class Ci::CloudAccount < ApplicationRecord
|
||||
belongs_to :project
|
||||
belongs_to :user
|
||||
belongs_to :repository, foreign_key: :repo_id
|
|
@ -1,4 +1,4 @@
|
|||
class DevOps::Language < ApplicationRecord
|
||||
class Ci::Language < ApplicationRecord
|
||||
# before_save :encode_content
|
||||
|
||||
belongs_to :cover, class_name: "Attachment", foreign_key: :cover_id, optional: true
|
|
@ -0,0 +1,29 @@
|
|||
module Droneable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
end
|
||||
|
||||
def devops_uninit?
|
||||
self.devops_step === User::DEVOPS_UNINIT
|
||||
end
|
||||
|
||||
def devops_unverified?
|
||||
self.devops_step === User::DEVOPS_UNVERIFIED
|
||||
end
|
||||
|
||||
def devops_verified?
|
||||
self.devops_step === User::DEVOPS_VERIFIED
|
||||
end
|
||||
|
||||
def devops_has_token?
|
||||
self.devops_step === User::DEVOPS_HAS_TOKEN
|
||||
end
|
||||
|
||||
def set_drone_step!(step)
|
||||
self.update_column(:devops_step, step)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
end
|
||||
end
|
|
@ -0,0 +1,14 @@
|
|||
module ProjectAbility
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
|
||||
end
|
||||
|
||||
def can_read_project?(project)
|
||||
return true if self.admin?
|
||||
return false if !project.is_public? && !project.member?(self.id)
|
||||
true
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
class OpenUsers::Educoder < OpenUser
|
||||
def nickname
|
||||
extra&.[]('nickname')
|
||||
end
|
||||
|
||||
def en_type
|
||||
'educoder'
|
||||
end
|
||||
end
|
|
@ -20,7 +20,7 @@ class Project < ApplicationRecord
|
|||
has_many :fork_users, dependent: :destroy
|
||||
# has_many :commits, dependent: :destroy
|
||||
|
||||
has_one :dev_ops_cloud_account, class_name: 'DevOps::CloudAccount', dependent: :destroy
|
||||
has_one :ci_cloud_account, class_name: 'Ci::CloudAccount', dependent: :destroy
|
||||
has_one :project_score, dependent: :destroy
|
||||
has_one :repository, dependent: :destroy
|
||||
has_many :pull_requests, dependent: :destroy
|
||||
|
@ -169,4 +169,15 @@ class Project < ApplicationRecord
|
|||
joins(:members).where(members: { user_id: member_user_id})
|
||||
end
|
||||
|
||||
def self.find_with_namespace(namespace_path, identifier)
|
||||
logger.info "########namespace_path: #{namespace_path} ########identifier: #{identifier} "
|
||||
|
||||
user = User.find_by_login namespace_path
|
||||
return nil if user.blank?
|
||||
|
||||
project = user.projects.find_by(identifier: identifier)
|
||||
|
||||
return nil if project.blank?
|
||||
project
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ class Repository < ApplicationRecord
|
|||
belongs_to :project, :touch => true
|
||||
belongs_to :user
|
||||
has_one :mirror, foreign_key: :repo_id
|
||||
has_one :dev_ops_cloud_account, class_name: 'DevOps::CloudAccount', foreign_key: :repo_id
|
||||
has_one :ci_cloud_account, class_name: 'Ci::CloudAccount', foreign_key: :repo_id
|
||||
has_many :version_releases, dependent: :destroy
|
||||
|
||||
validates :identifier, presence: true
|
||||
|
|
|
@ -5,8 +5,17 @@ class User < ApplicationRecord
|
|||
include Likeable
|
||||
include BaseModel
|
||||
include ProjectOperable
|
||||
include ProjectAbility
|
||||
include Droneable
|
||||
# include Searchable::Dependents::User
|
||||
|
||||
# devops step
|
||||
# devops_step column: 0: 未填写服务器信息;1: 已填写服务器信息(未认证); 2: 已认证, 3: 已填写token值
|
||||
DEVOPS_UNINIT = 0
|
||||
DEVOPS_UNVERIFIED = 1
|
||||
DEVOPS_VERIFIED = 2
|
||||
DEVOPS_HAS_TOKEN = 3
|
||||
|
||||
# Account statuses
|
||||
STATUS_ANONYMOUS = 0
|
||||
STATUS_ACTIVE = 1
|
||||
|
@ -70,8 +79,9 @@ class User < ApplicationRecord
|
|||
# 关注
|
||||
has_many :be_watchers, foreign_key: :user_id, dependent: :destroy # 我的关注
|
||||
has_many :be_watcher_users, through: :be_watchers, dependent: :destroy # 我关注的用户
|
||||
|
||||
has_many :watchers, as: :watchable, dependent: :destroy
|
||||
has_many :watchers, as: :watchable, dependent: :destroy
|
||||
|
||||
has_one :ci_cloud_account, class_name: 'Ci::CloudAccount', dependent: :destroy
|
||||
|
||||
# 认证
|
||||
has_many :apply_user_authentication
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class Gitea::Repository::Entries::CreateService < Gitea::ClientService
|
||||
attr_reader :user, :repo_name, :filepath, :body
|
||||
attr_reader :token, :owner, :repo_name, :filepath, :body
|
||||
|
||||
# ref: The name of the commit/branch/tag. Default the repository’s default branch (usually master)
|
||||
# filepath: path of the dir, file, symlink or submodule in the repo
|
||||
|
@ -20,8 +20,9 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService
|
|||
# "new_branch": "string"
|
||||
# }
|
||||
#
|
||||
def initialize(user, repo_name, filepath, body)
|
||||
@user = user
|
||||
def initialize(token, owner, repo_name, filepath, body)
|
||||
@token = token
|
||||
@owner = owner
|
||||
@repo_name = repo_name
|
||||
@filepath = filepath
|
||||
@body = body
|
||||
|
@ -33,11 +34,11 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService
|
|||
|
||||
private
|
||||
def params
|
||||
Hash.new.merge(token: user.gitea_token, data: body)
|
||||
Hash.new.merge(token: token, data: body)
|
||||
end
|
||||
|
||||
def url
|
||||
"/repos/#{user.login}/#{repo_name}/contents/#{filepath}".freeze
|
||||
"/repos/#{owner}/#{repo_name}/contents/#{filepath}".freeze
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class Gitea::Repository::Entries::DeleteService < Gitea::ClientService
|
||||
attr_reader :user, :repo_name, :filepath, :body
|
||||
attr_reader :token, :owner, :repo_name, :filepath, :body
|
||||
|
||||
# ref: The name of the commit/branch/tag. Default the repository’s default branch (usually master)
|
||||
# filepath: path of the dir, file, symlink or submodule in the repo
|
||||
|
@ -19,8 +19,9 @@ class Gitea::Repository::Entries::DeleteService < Gitea::ClientService
|
|||
# "new_branch": "string",
|
||||
# "sha": "string", #require
|
||||
# }
|
||||
def initialize(user, repo_name, filepath, body)
|
||||
@user = user
|
||||
def initialize(token, owner, repo_name, filepath, body)
|
||||
@token = token
|
||||
@owner = owner
|
||||
@repo_name = repo_name
|
||||
@filepath = filepath
|
||||
@body = body
|
||||
|
@ -32,11 +33,11 @@ class Gitea::Repository::Entries::DeleteService < Gitea::ClientService
|
|||
|
||||
private
|
||||
def params
|
||||
Hash.new.merge(token: user.gitea_token, data: body)
|
||||
Hash.new.merge(token: token, data: body)
|
||||
end
|
||||
|
||||
def url
|
||||
"/repos/#{user.login}/#{repo_name}/contents/#{filepath}".freeze
|
||||
"/repos/#{owner}/#{repo_name}/contents/#{filepath}".freeze
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class Gitea::Repository::Entries::UpdateService < Gitea::ClientService
|
||||
attr_reader :user, :repo_name, :filepath, :body
|
||||
attr_reader :token, :owner, :repo_name, :filepath, :body
|
||||
|
||||
# ref: The name of the commit/branch/tag. Default the repository’s default branch (usually master)
|
||||
# filepath: path of the dir, file, symlink or submodule in the repo
|
||||
|
@ -20,8 +20,9 @@ class Gitea::Repository::Entries::UpdateService < Gitea::ClientService
|
|||
# "new_branch": "string"
|
||||
# }
|
||||
#
|
||||
def initialize(user, repo_name, filepath, body)
|
||||
@user = user
|
||||
def initialize(token, owner, repo_name, filepath, body)
|
||||
@token = token
|
||||
@owner = owner
|
||||
@repo_name = repo_name
|
||||
@filepath = filepath
|
||||
@body = body
|
||||
|
@ -33,11 +34,11 @@ class Gitea::Repository::Entries::UpdateService < Gitea::ClientService
|
|||
|
||||
private
|
||||
def params
|
||||
Hash.new.merge(token: user.gitea_token, data: body)
|
||||
Hash.new.merge(token: token, data: body)
|
||||
end
|
||||
|
||||
def url
|
||||
"/repos/#{user.login}/#{repo_name}/contents/#{filepath}".freeze
|
||||
"/repos/#{owner}/#{repo_name}/contents/#{filepath}".freeze
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<html>
|
||||
<head>
|
||||
<%= csrf_meta_tags %>
|
||||
<%= csp_meta_tag %>
|
||||
<%= javascript_include_tag '/javascripts/jquery-1.8.3-ui-1.9.2-ujs-2.0.3', '': '' %>
|
||||
<%= stylesheet_link_tag '/stylesheets/css/oauth', '', :media => 'all' %>
|
||||
</head>
|
||||
<body>
|
||||
<div class="IndexContent">
|
||||
<%= image_tag('/images/oauth/logo.png') %>
|
||||
<%= yield %>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,78 @@
|
|||
<div class="indexPanel">
|
||||
<p class="indexTitle">完善信息,进入比赛</p>
|
||||
<div class="indexInfos">
|
||||
|
||||
<%= 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] %>
|
||||
<div class="indexInfo">
|
||||
<span>用户名:</span>
|
||||
<%= text_field_tag :login, params[:login], placeholder: '请输入用户名', readonly: true, id: 'login' %>
|
||||
<p class="checkInfo loginCheck"><span></span></p>
|
||||
</div>
|
||||
<div class="indexInfo">
|
||||
<span>邮箱:</span>
|
||||
<%= text_field_tag :mail, '', placeholder: '请输入绑定邮箱', maxlength: 40, id: 'email' %>
|
||||
<p class="checkInfo emailCheck"><span></span></p>
|
||||
</div>
|
||||
<div class="indexInfo">
|
||||
<span>密码:</span>
|
||||
<%= password_field_tag :password, '', placeholder: '请输入账号密码', id: 'password' %>
|
||||
<p class="checkInfo passwordCheck"><span></span></p>
|
||||
</div>
|
||||
<div class="indexBtn">
|
||||
<button type="button" class="indexSubmit" id="indexSubmit" onclick="submitdata();">确定</button>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
function submitdata(){
|
||||
var login = $("#login").val();
|
||||
var email = $("#email").val();
|
||||
var password = $("#password").val();
|
||||
|
||||
if(!login){
|
||||
$(".loginCheck span").html("请输入账号");
|
||||
return;
|
||||
}else{
|
||||
$(".loginCheck span").html("");
|
||||
}
|
||||
if(!email){
|
||||
$(".emailCheck span").html("请输入绑定的邮箱");
|
||||
return;
|
||||
}else{
|
||||
$(".emailCheck span").html("");
|
||||
}
|
||||
if(!password){
|
||||
$(".passwordCheck span").html("请输入账号密码");
|
||||
return;
|
||||
}else if(password.length < 8){
|
||||
$(".passwordCheck span").html("密码最少为8位数");
|
||||
return;
|
||||
}else{
|
||||
$(".passwordCheck span").html("");
|
||||
}
|
||||
$.ajax({
|
||||
url: "<%= oauth_auto_register_path %>",
|
||||
data: $("#oauth_form").serialize(),
|
||||
type: 'post',
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
console.log(data)
|
||||
if (data) {
|
||||
if(data.message){
|
||||
$(".emailCheck span").html("该邮箱已存在.");
|
||||
return;
|
||||
}
|
||||
// data.redirect contains the string URL to redirect to
|
||||
// window.location.href = "<%#= params[:callback_url] %>";
|
||||
window.location.href = data.callback_url;
|
||||
}
|
||||
},
|
||||
error: function (data) {
|
||||
console.log('ajax error handling',data);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -1,12 +1,13 @@
|
|||
json.count @forks_count
|
||||
json.users do
|
||||
json.users do
|
||||
json.array! @fork_users.each do |f|
|
||||
user = f.user
|
||||
fork_project = Project.select(:id,:name).find_by(id: f.fork_project_id)
|
||||
user = f.user
|
||||
fork_project = Project.select(:id,:name, :identifier).find_by(id: f.fork_project_id)
|
||||
json.id f.fork_project_id
|
||||
json.identifier fork_project.identifier
|
||||
json.name "#{user.try(:show_real_name)}/#{fork_project.try(:name)}"
|
||||
json.login user.try(:login)
|
||||
json.image_url url_to_avatar(user)
|
||||
json.format_time f.created_at.strftime("%Y-%m-%d")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
json.commit do
|
||||
json.sha commit['sha']
|
||||
json.url EduSetting.get('host_name') + commit_repository_path(project.repository, commit['sha'])
|
||||
# json.url EduSetting.get('host_name') + commit_repository_path(project.repository, commit['sha'])
|
||||
json.message commit['commit']['message']
|
||||
json.author commit['commit']['author']
|
||||
json.committer commit['commit']['committer']
|
||||
|
|
|
@ -31,6 +31,7 @@ json.fork_info do
|
|||
if @fork_project.present?
|
||||
json.fork_form_name @fork_project.try(:name)
|
||||
json.fork_project_user_login @fork_project_user.try(:login)
|
||||
json.fork_project_identifier @fork_project.identifier
|
||||
json.fork_project_user_name @fork_project_user.try(:show_real_name)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
json.step @user.devops_step
|
||||
json.cloud_account do
|
||||
if @cloud_account && !@user.devops_uninit?
|
||||
json.account @cloud_account.account
|
||||
json.ip @cloud_account.drone_ip
|
||||
json.secret @cloud_account.visible_secret
|
||||
json.authenticate_url "#{@cloud_account.drone_url}/login" if @user.devops_unverified?
|
||||
json.get_drone_token_url "#{@cloud_account.drone_url}/account" if @user.devops_verified?
|
||||
else
|
||||
json.nil!
|
||||
end
|
||||
end
|
|
@ -12,5 +12,4 @@ json.user_phone_binded @user.phone.present?
|
|||
# json.email @user.mail
|
||||
json.profile_completed @user.profile_completed?
|
||||
json.professional_certification @user.professional_certification
|
||||
|
||||
|
||||
json.devops_step @user.devops_step
|
||||
|
|
|
@ -5,8 +5,8 @@ json.members_count project.members.count
|
|||
json.issues_count project.issues.count
|
||||
json.changesets_count project.project_score&.changeset_num.to_i
|
||||
|
||||
json.is_public project&.is_public
|
||||
json.can_visited project&.can_visited?
|
||||
json.is_public project.is_public?
|
||||
json.can_visited project.can_visited?
|
||||
|
||||
json.owner do
|
||||
json.partial! 'users/shared/real_user', user: project.owner
|
||||
|
|
|
@ -5,4 +5,4 @@ json.image_url url_to_avatar(subject)
|
|||
json.owner_id subject.user.id
|
||||
json.owner_name subject.user.full_name
|
||||
json.visits_count subject.visits
|
||||
json.can_visited subject&.can_visited?
|
||||
json.can_visited subject.can_visited?
|
||||
|
|
|
@ -12,5 +12,4 @@ Rails.application.config.assets.paths << Rails.root.join('vendor/assets')
|
|||
# Precompile additional assets.
|
||||
# application.js, application.css, and all non-JS/CSS in the app/assets
|
||||
# folder are already added.
|
||||
Rails.application.config.assets.precompile += %w( admin.js admin.css college.js college.css cooperative.js cooperative.css )
|
||||
|
||||
Rails.application.config.assets.precompile += %w( admin.js admin.css college.js college.css cooperative.js cooperative.css oauth.css )
|
||||
|
|
352
config/routes.rb
352
config/routes.rb
|
@ -13,10 +13,19 @@ Rails.application.routes.draw do
|
|||
get 'auth/qq/callback', to: 'oauth/qq#create'
|
||||
get 'auth/failure', to: 'oauth/base#auth_failure'
|
||||
get 'auth/cas/callback', to: 'oauth/cas#create'
|
||||
|
||||
get 'oauth/bind', to: 'oauth/educoder#bind'
|
||||
get 'oauth/register', to: 'oauth#register'
|
||||
post 'oauth/auto_register', to: 'oauth#auto_register'
|
||||
|
||||
resources :edu_settings
|
||||
scope '/api' do
|
||||
namespace :dev_ops do
|
||||
resources :cloud_accounts, only: [:create]
|
||||
namespace :ci do
|
||||
resources :cloud_accounts, only: [:create] do
|
||||
member do
|
||||
post :activate
|
||||
end
|
||||
end
|
||||
resources :languages, only: [:index, :show] do
|
||||
collection do
|
||||
get :common
|
||||
|
@ -85,41 +94,6 @@ Rails.application.routes.draw do
|
|||
end
|
||||
end
|
||||
resources :projects do
|
||||
resources :hooks
|
||||
resources :pull_requests, except: [:destroy] do
|
||||
member do
|
||||
post :pr_merge
|
||||
# post :check_merge
|
||||
post :refuse_merge
|
||||
end
|
||||
collection do
|
||||
post :check_can_merge
|
||||
get :create_merge_infos
|
||||
get :get_branches
|
||||
end
|
||||
end
|
||||
resources :version_releases, only: [:index,:new, :create, :edit, :update, :destroy]
|
||||
resources :project_trends, only: [:index, :create]
|
||||
resources :issues do
|
||||
collection do
|
||||
get :commit_issues
|
||||
get :index_chosen
|
||||
post :clean
|
||||
post :series_update
|
||||
end
|
||||
member do
|
||||
post :copy
|
||||
post :close_issue
|
||||
post :lock_issue
|
||||
end
|
||||
end
|
||||
resources :issue_tags, only: [:create, :edit, :update, :destroy, :index]
|
||||
resources :versions do
|
||||
member do
|
||||
post :update_status
|
||||
end
|
||||
end
|
||||
|
||||
resources :praise_tread, only: [:index] do
|
||||
collection do
|
||||
post :like
|
||||
|
@ -127,25 +101,10 @@ Rails.application.routes.draw do
|
|||
get :check_like
|
||||
end
|
||||
end
|
||||
resources :members, only: [:index, :create] do
|
||||
collection do
|
||||
delete :remove
|
||||
put :change_role
|
||||
end
|
||||
end
|
||||
resources :forks, only: [:create]
|
||||
|
||||
collection do
|
||||
post :migrate
|
||||
get :group_type_list
|
||||
post :watch
|
||||
end
|
||||
member do
|
||||
get :branches
|
||||
post :watch
|
||||
get :watch_users
|
||||
get :praise_users
|
||||
get :fork_users
|
||||
get :simple
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -190,11 +149,12 @@ Rails.application.routes.draw do
|
|||
post :sync_salt
|
||||
get :trustie_projects
|
||||
get :trustie_related_projects
|
||||
get :devops
|
||||
put :devops_authenticate
|
||||
end
|
||||
|
||||
scope module: :users do
|
||||
# resources :courses, only: [:index]
|
||||
resources :projects, only: [:index]
|
||||
# resources :projects, only: [:index]
|
||||
# resources :subjects, only: [:index]
|
||||
resources :project_packages, only: [:index]
|
||||
# 私信
|
||||
|
@ -204,11 +164,6 @@ Rails.application.routes.draw do
|
|||
# resource :unread_message_info, only: [:show]
|
||||
end
|
||||
|
||||
|
||||
resources :projects, module: :users, only: [] do
|
||||
get :search, on: :collection
|
||||
end
|
||||
|
||||
resources :tidings, only: [:index]
|
||||
|
||||
scope module: :users do
|
||||
|
@ -227,23 +182,6 @@ Rails.application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
resources :repositories, only: [:index, :show, :edit] do
|
||||
member do
|
||||
get :entries
|
||||
match :sub_entries, :via => [:get, :put]
|
||||
get :commits
|
||||
post :files
|
||||
get :tags
|
||||
post :create_file
|
||||
put :update_file
|
||||
delete :delete_file
|
||||
post :repo_hook
|
||||
post :sync_mirror
|
||||
get :top_counts
|
||||
get 'commits/:sha', to: 'repositories#commit', as: 'commit'
|
||||
end
|
||||
end
|
||||
|
||||
resources :users_for_private_messages, only: [:index]
|
||||
|
||||
resources :files, only: [:index, :show, :update] do
|
||||
|
@ -263,119 +201,6 @@ Rails.application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
resources :courses do
|
||||
member do
|
||||
get 'settings', :action => 'settings', :as => 'settings'
|
||||
post 'set_invite_code_halt'
|
||||
post 'set_public_or_private'
|
||||
post 'search_teacher_candidate'
|
||||
post 'add_teacher'
|
||||
post 'create_graduation_group'
|
||||
post 'join_graduation_group'
|
||||
post 'set_course_group'
|
||||
post 'change_course_admin'
|
||||
post 'change_member_role'
|
||||
post 'change_course_teacher'
|
||||
post 'delete_course_teacher'
|
||||
post 'teacher_application_review'
|
||||
post 'transfer_to_course_group'
|
||||
post 'delete_from_course'
|
||||
post 'add_students_by_search'
|
||||
post 'create_group_by_importing_file'
|
||||
post 'duplicate_course'
|
||||
post 'visits_plus_one'
|
||||
get 'get_historical_courses'
|
||||
get 'get_historical_course_students'
|
||||
get 'course_group_list'
|
||||
get 'add_teacher_popup'
|
||||
get 'teachers'
|
||||
get 'apply_teachers'
|
||||
get 'graduation_group_list'
|
||||
get 'top_banner'
|
||||
get 'left_banner'
|
||||
get 'students'
|
||||
get 'all_course_groups'
|
||||
get 'search_users'
|
||||
get 'base_info'
|
||||
get 'attahcment_category_list'
|
||||
get 'export_member_scores_excel' #导出课堂信息
|
||||
get 'export_couser_info'
|
||||
get 'export_member_act_score'
|
||||
post 'switch_to_teacher'
|
||||
post 'switch_to_assistant'
|
||||
post 'switch_to_student'
|
||||
post 'exit_course'
|
||||
get 'informs'
|
||||
post 'update_informs'
|
||||
post 'new_informs'
|
||||
delete 'delete_informs'
|
||||
get 'online_learning'
|
||||
post 'join_excellent_course'
|
||||
get 'tasks_list'
|
||||
post 'update_task_position'
|
||||
get 'course_groups'
|
||||
post 'join_course_group'
|
||||
get 'work_score'
|
||||
get 'act_score'
|
||||
get 'statistics'
|
||||
get 'course_videos'
|
||||
delete 'delete_course_video'
|
||||
post :inform_up
|
||||
post :inform_down
|
||||
end
|
||||
|
||||
collection do
|
||||
post 'apply_to_join_course'
|
||||
post 'search_course_list'
|
||||
get 'board_list'
|
||||
get 'mine'
|
||||
get 'search_slim'
|
||||
end
|
||||
|
||||
resources :course_stages, shallow: true do
|
||||
member do
|
||||
post :up_position
|
||||
post :down_position
|
||||
end
|
||||
end
|
||||
|
||||
resources :course_groups, shallow: true do
|
||||
member do
|
||||
post 'rename_group'
|
||||
post 'move_category'
|
||||
post 'set_invite_code_halt'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
resources :course_modules, shallow: true do
|
||||
member do
|
||||
get 'sticky_module'
|
||||
get 'hidden_module'
|
||||
post 'rename_module'
|
||||
post 'add_second_category'
|
||||
end
|
||||
collection do
|
||||
post 'unhidden_modules'
|
||||
end
|
||||
end
|
||||
|
||||
resources :course_second_categories, shallow: true do
|
||||
member do
|
||||
post 'rename_category'
|
||||
post 'move_category'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
resources :repertoires, only: [:index]
|
||||
|
||||
scope module: :projects do
|
||||
resources :project_applies, only: [:create]
|
||||
end
|
||||
|
||||
|
||||
namespace :wechats do
|
||||
resource :js_sdk_signature, only: [:create]
|
||||
end
|
||||
|
@ -428,6 +253,151 @@ Rails.application.routes.draw do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Project Area START
|
||||
scope "/:owner/:repo" do
|
||||
scope do
|
||||
get(
|
||||
'/activity',
|
||||
to: 'project_trends#index',
|
||||
as: :project_activity
|
||||
)
|
||||
end
|
||||
|
||||
resource :projects, path: '/', except: [:show, :edit] do
|
||||
member do
|
||||
get :branches
|
||||
get :simple
|
||||
get :watchers, to: 'projects#watch_users'
|
||||
get :stargazers, to: 'projects#praise_users'
|
||||
get :members, to: 'projects#fork_users'
|
||||
end
|
||||
end
|
||||
|
||||
resource :repositories, path: '/', only: [:show, :create, :edit] do
|
||||
member do
|
||||
get :archive
|
||||
get :top_counts
|
||||
get :entries
|
||||
match :sub_entries, :via => [:get, :put]
|
||||
get :commits
|
||||
get :tags
|
||||
post :create_file
|
||||
put :update_file
|
||||
delete :delete_file
|
||||
post :repo_hook
|
||||
post :sync_mirror
|
||||
get :top_counts
|
||||
get 'commits/:sha', to: 'repositories#commit', as: 'commit'
|
||||
end
|
||||
end
|
||||
|
||||
resources :issues do
|
||||
collection do
|
||||
get :commit_issues
|
||||
get :index_chosen
|
||||
post :clean
|
||||
post :series_update
|
||||
end
|
||||
member do
|
||||
post :copy
|
||||
post :close_issue
|
||||
post :lock_issue
|
||||
end
|
||||
end
|
||||
|
||||
resources :pull_requests, :path => :pulls, except: [:destroy] do
|
||||
member do
|
||||
post :pr_merge
|
||||
# post :check_merge
|
||||
post :refuse_merge
|
||||
end
|
||||
collection do
|
||||
post :check_can_merge
|
||||
get :create_merge_infos
|
||||
get :get_branches
|
||||
end
|
||||
end
|
||||
|
||||
resources :versions, :path => :milestones do
|
||||
member do
|
||||
post :update_status
|
||||
end
|
||||
end
|
||||
|
||||
resources :members, :path => :collaborators, only: [:index, :create] do
|
||||
collection do
|
||||
delete :remove
|
||||
put :change_role
|
||||
end
|
||||
end
|
||||
|
||||
resources :hooks
|
||||
resources :forks, only: [:create]
|
||||
resources :project_trends, :path => :activity, only: [:index, :create]
|
||||
resources :issue_tags, :path => :labels, only: [:create, :edit, :update, :destroy, :index]
|
||||
resources :version_releases, :path => :releases, only: [:index,:new, :create, :edit, :update, :destroy]
|
||||
|
||||
scope module: :projects do
|
||||
scope do
|
||||
get(
|
||||
'/blob/*id/diff',
|
||||
to: 'blob#diff',
|
||||
constraints: { id: /.+/, format: false },
|
||||
as: :blob_diff
|
||||
)
|
||||
get(
|
||||
'/blob/*id',
|
||||
to: 'blob#show',
|
||||
constraints: { id: /.+/, format: false },
|
||||
as: :blob
|
||||
)
|
||||
delete(
|
||||
'/blob/*id',
|
||||
to: 'blob#destroy',
|
||||
constraints: { id: /.+/, format: false }
|
||||
)
|
||||
put(
|
||||
'/blob/*id',
|
||||
to: 'blob#update',
|
||||
constraints: { id: /.+/, format: false }
|
||||
)
|
||||
post(
|
||||
'/blob/*id',
|
||||
to: 'blob#create',
|
||||
constraints: { id: /.+/, format: false }
|
||||
)
|
||||
end
|
||||
|
||||
scope do
|
||||
get(
|
||||
'/raw/*id',
|
||||
to: 'raw#show',
|
||||
constraints: { id: /.+/, format: /(html|js)/ },
|
||||
as: :raw
|
||||
)
|
||||
end
|
||||
|
||||
scope do
|
||||
get(
|
||||
'/blame/*id',
|
||||
to: 'blame#show',
|
||||
constraints: { id: /.+/, format: /(html|js)/ },
|
||||
as: :blame
|
||||
)
|
||||
end
|
||||
|
||||
scope do
|
||||
get(
|
||||
'/tree/*id',
|
||||
to: 'tree#show',
|
||||
constraints: { id: /.+/, format: /(html|js)/ },
|
||||
as: :tree
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
# Project Area END
|
||||
end
|
||||
|
||||
namespace :admins do
|
||||
|
@ -704,4 +674,6 @@ Rails.application.routes.draw do
|
|||
|
||||
## react用
|
||||
get '*path', to: 'main#index', constraints: ReactConstraint.new
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddDevopsStepToUsers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :users, :devops_step, :integer, default: 0, comment: '0: uninit devops; 1: unverified; 2: verified'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class RenameDevOpsCloudAccountToCiCloudAccount < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
rename_table :dev_ops_cloud_accounts, :ci_cloud_accounts
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class RenameDevOpsLanguageToCiLanguage < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
rename_table :dev_ops_languages, :ci_languages
|
||||
end
|
||||
end
|
Binary file not shown.
After Width: | Height: | Size: 106 KiB |
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
|
@ -0,0 +1,78 @@
|
|||
html{margin:0px;padding: 0px;font-size: 14px;font-family: "微软雅黑","宋体";}
|
||||
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.IndexContent{
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background-image: url('/images/oauth/backImg.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.indexLogo{
|
||||
width:80px;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
.indexPanel{
|
||||
width: 580px;
|
||||
min-height: 400px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 2px 10px 5px rgba(0,0,0,0.05);
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.indexTitle{
|
||||
height: 75px;
|
||||
line-height: 75px;
|
||||
font-size: 18px;
|
||||
color:#333;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.indexInfo{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.indexInfos{
|
||||
padding:40px 60px;
|
||||
}
|
||||
.indexInfo > span{
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.indexInfo input{
|
||||
width: 100%;
|
||||
height:40px;
|
||||
border-radius: 2px;
|
||||
border:1px solid #eee;
|
||||
margin-top: 5px;
|
||||
padding:0px 0px 0px 8px;
|
||||
outline: none;
|
||||
}
|
||||
.indexInfo .checkInfo{
|
||||
height: 15px;
|
||||
color: red;
|
||||
}
|
||||
.indexBtn{
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.indexSubmit{
|
||||
width: 50%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
background-color: #1890FF;
|
||||
border:none;
|
||||
color: #fff;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
Loading…
Reference in New Issue