* [Feature] Added DevContainer Public Key Login, and deprecated SSH Password login * [Improvement] Anti-spam * GET /api/devstar_ssh/key_pair/new_temp: SSH Keypair Gen * fix HTTP 500 error while deleting Repo * updated DevContainer WorkDIR * updated warn msg
84 lines
3.2 KiB
Go
84 lines
3.2 KiB
Go
package api_services
|
||
|
||
import (
|
||
"code.gitea.io/gitea/models/db"
|
||
"code.gitea.io/gitea/models/repo"
|
||
DevcontainersVO "code.gitea.io/gitea/routers/api/devcontainer/vo"
|
||
gitea_web_context "code.gitea.io/gitea/services/context"
|
||
DevcontainersService "code.gitea.io/gitea/services/devstar_devcontainer"
|
||
devcontainer_service_errors "code.gitea.io/gitea/services/devstar_devcontainer/errors"
|
||
devcontainer_service_options "code.gitea.io/gitea/services/devstar_devcontainer/options"
|
||
"context"
|
||
"fmt"
|
||
)
|
||
|
||
// CreateDevcontainerAPIService API专用创建 DevContainer Service
|
||
func CreateDevcontainerAPIService(ctx *gitea_web_context.Context, opts *devcontainer_service_options.CreateDevcontainerOptions) error {
|
||
// 0. 检查用户传入参数
|
||
if ctx == nil || opts == nil || opts.Actor == nil || opts.RepoId <= 0 {
|
||
return devcontainer_service_errors.ErrIllegalParams{
|
||
FieldNameList: []string{"ctx", "opts", "opts.Actor", "opts.RepoId"},
|
||
}
|
||
}
|
||
|
||
// 1. 开启事务
|
||
errTxn := db.WithTx(ctx, func(ctx context.Context) error {
|
||
|
||
// 1.1 调用 model层,查询数据库,将 repoId 变换为 Repository 对象
|
||
repositoryInDB, err := repo.GetRepositoryByID(ctx, opts.RepoId)
|
||
if err != nil || repositoryInDB == nil {
|
||
return devcontainer_service_errors.ErrIllegalParams{
|
||
FieldNameList: []string{"opts.RepoId"},
|
||
}
|
||
}
|
||
|
||
// 1.2 检查该用户在该仓库 是否已经创建过 DevContainer
|
||
optsRepoDevcontainer := &DevcontainersVO.RepoDevcontainerOptions{
|
||
Actor: opts.Actor,
|
||
Repository: repositoryInDB,
|
||
}
|
||
devcontainerDetails, err := DevcontainersService.GetRepoDevcontainerDetails(ctx, optsRepoDevcontainer)
|
||
if err != nil || devcontainerDetails.DevContainerId > 0 {
|
||
return devcontainer_service_errors.ErrDevcontainerAlreadyCreated{
|
||
Actor: opts.Actor,
|
||
Repository: repositoryInDB,
|
||
}
|
||
}
|
||
|
||
// 1.3 查询数据库,收集用户 SSH 公钥,合并用户临时填入SSH公钥(若用户合计 SSH公钥个数为0,拒绝创建DevContainer)
|
||
/**
|
||
SELECT content FROM public_key where owner_id = #{opts.Actor.ID}
|
||
*/
|
||
var userSSHPublicKeyList []string
|
||
err = db.GetEngine(ctx).
|
||
Table("public_key").
|
||
Select("content").
|
||
Where("owner_id = ?", opts.Actor.ID).
|
||
Find(&userSSHPublicKeyList)
|
||
if err != nil {
|
||
return devcontainer_service_errors.ErrOperateDevcontainer{
|
||
Action: fmt.Sprintf("query SSH Public Key List for User %s", opts.Actor.Name),
|
||
Message: err.Error(),
|
||
}
|
||
}
|
||
userSSHPublicKeyList = append(userSSHPublicKeyList, opts.SSHPublicKeyList...)
|
||
if len(userSSHPublicKeyList) <= 0 {
|
||
// API没提供临时SSH公钥,用户后台也没有永久SSH公钥,直接结束并回滚事务
|
||
return devcontainer_service_errors.ErrOperateDevcontainer{
|
||
Action: "Check SSH Public Key List",
|
||
Message: "禁止创建无法连通的DevContainer:用户未提供 SSH 公钥,请先使用API临时创建SSH密钥对、或在Web端手动添加SSH公钥",
|
||
}
|
||
}
|
||
|
||
// 1.4 调用 DevContainer Service 创建 DevContainer
|
||
optsCreateDevcontainer := &DevcontainersVO.CreateRepoDevcontainerOptions{
|
||
Actor: opts.Actor,
|
||
Repository: repositoryInDB,
|
||
SSHPublicKeyList: userSSHPublicKeyList,
|
||
}
|
||
return DevcontainersService.CreateRepoDevcontainer(ctx, optsCreateDevcontainer)
|
||
})
|
||
|
||
return errTxn
|
||
}
|