From d65b30315b726bc2f8b39dd9dfa7ad290c173a5e Mon Sep 17 00:00:00 2001 From: Infinity Date: Mon, 2 Jan 2023 17:59:08 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E9=95=9C=E5=83=8F=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...DeleteProjectProjectIdImageReposRequest.kt | 22 ++++++++++++ .../DeleteProjectProjectIdImagesRequest.kt | 24 +++++++++++++ .../edu/buaa/scs/controller/models/Project.kt | 34 +++++++++---------- .../cn/edu/buaa/scs/harbor/HarborClient.kt | 17 ++++++++-- .../kotlin/cn/edu/buaa/scs/route/Project.kt | 13 +++++++ .../kotlin/cn/edu/buaa/scs/service/Project.kt | 10 ++++++ 6 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 src/main/kotlin/cn/edu/buaa/scs/controller/models/DeleteProjectProjectIdImageReposRequest.kt create mode 100644 src/main/kotlin/cn/edu/buaa/scs/controller/models/DeleteProjectProjectIdImagesRequest.kt diff --git a/src/main/kotlin/cn/edu/buaa/scs/controller/models/DeleteProjectProjectIdImageReposRequest.kt b/src/main/kotlin/cn/edu/buaa/scs/controller/models/DeleteProjectProjectIdImageReposRequest.kt new file mode 100644 index 00000000..c6876168 --- /dev/null +++ b/src/main/kotlin/cn/edu/buaa/scs/controller/models/DeleteProjectProjectIdImageReposRequest.kt @@ -0,0 +1,22 @@ +/** +* cloudapi_v2 +* buaa scs cloud api v2 +* +* The version of the OpenAPI document: 2.0 +* Contact: loheagn@icloud.com +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package cn.edu.buaa.scs.controller.models + + +/** + * + * @param repo + */ +data class DeleteProjectProjectIdImageReposRequest( + val repo: kotlin.String +) + diff --git a/src/main/kotlin/cn/edu/buaa/scs/controller/models/DeleteProjectProjectIdImagesRequest.kt b/src/main/kotlin/cn/edu/buaa/scs/controller/models/DeleteProjectProjectIdImagesRequest.kt new file mode 100644 index 00000000..38c2fcee --- /dev/null +++ b/src/main/kotlin/cn/edu/buaa/scs/controller/models/DeleteProjectProjectIdImagesRequest.kt @@ -0,0 +1,24 @@ +/** +* cloudapi_v2 +* buaa scs cloud api v2 +* +* The version of the OpenAPI document: 2.0 +* Contact: loheagn@icloud.com +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package cn.edu.buaa.scs.controller.models + + +/** + * + * @param repo + * @param tag + */ +data class DeleteProjectProjectIdImagesRequest( + val repo: kotlin.String, + val tag: kotlin.String +) + diff --git a/src/main/kotlin/cn/edu/buaa/scs/controller/models/Project.kt b/src/main/kotlin/cn/edu/buaa/scs/controller/models/Project.kt index dc3eff13..3cd298ec 100644 --- a/src/main/kotlin/cn/edu/buaa/scs/controller/models/Project.kt +++ b/src/main/kotlin/cn/edu/buaa/scs/controller/models/Project.kt @@ -1,27 +1,27 @@ /** - * cloudapi_v2 - * buaa scs cloud api v2 - * - * The version of the OpenAPI document: 2.0 - * Contact: loheagn@icloud.com - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ +* cloudapi_v2 +* buaa scs cloud api v2 +* +* The version of the OpenAPI document: 2.0 +* Contact: loheagn@icloud.com +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ package cn.edu.buaa.scs.controller.models /** - * - * @param id - * @param name - * @param owner + * + * @param id + * @param name + * @param owner * @param token 当前该用户访问该Project中的资源,例如clone代码仓库、push和pull镜像等,所需要使用的token,即密码 - * @param createdTime + * @param createdTime * @param displayName 区别于name之外的一个格式随便的,便于记忆和展示的名字 - * @param description - * @param expId + * @param description + * @param expId */ data class Project( val id: kotlin.Long, diff --git a/src/main/kotlin/cn/edu/buaa/scs/harbor/HarborClient.kt b/src/main/kotlin/cn/edu/buaa/scs/harbor/HarborClient.kt index 274e1501..89dc78ba 100644 --- a/src/main/kotlin/cn/edu/buaa/scs/harbor/HarborClient.kt +++ b/src/main/kotlin/cn/edu/buaa/scs/harbor/HarborClient.kt @@ -6,6 +6,7 @@ import cn.edu.buaa.scs.sdk.harbor.infrastructure.ClientException import cn.edu.buaa.scs.sdk.harbor.models.* import io.ktor.http.* + object HarborClient : IProjectManager { private val projectClient by lazy { ProjectApi() } @@ -27,7 +28,19 @@ object HarborClient : IProjectManager { ).filter { artifact -> artifact.type?.lowercase() == "image" } } } - + fun deleteImageRepo(projectName:String,repositoryName: String): Result = runCatching { + repoClient.deleteRepository( + projectName = projectName, + repositoryName = repositoryName + ) + } + fun deleteImage(projectName: String, repositoryName: String,reference: String ): Result = runCatching { + artifactClient.deleteArtifact( + projectName = projectName, + repositoryName = repositoryName, + reference = reference + ) + } override suspend fun createUser(userID: String, realName: String, email: String, password: String): Result = runCatching { if (userClient.searchUsers(userID).isNotEmpty()) return Result.success(userID) @@ -73,9 +86,7 @@ object HarborClient : IProjectManager { deleteProjectMember(projectName, memberID) } - fun deleteTag() { - } private fun existProject(projectName: String): Boolean { return try { diff --git a/src/main/kotlin/cn/edu/buaa/scs/route/Project.kt b/src/main/kotlin/cn/edu/buaa/scs/route/Project.kt index eb44d174..d033ae79 100644 --- a/src/main/kotlin/cn/edu/buaa/scs/route/Project.kt +++ b/src/main/kotlin/cn/edu/buaa/scs/route/Project.kt @@ -13,6 +13,7 @@ import cn.edu.buaa.scs.service.id import cn.edu.buaa.scs.service.project import cn.edu.buaa.scs.storage.mysql import cn.edu.buaa.scs.utils.user +import com.fkorotkov.openshift.newAWSResourceTag import io.ktor.server.application.* import io.ktor.server.request.* import io.ktor.server.response.* @@ -112,6 +113,12 @@ fun Route.projectRoute() { convertImageBuildTaskResponse(imageMeta, taskData) ) } + delete{ + val projectID = call.getProjectID() + val req =call.receive() + call.project.deleteImage(projectID, req.repo, req.tag) + call.respond("OK") + } } route("/imageBuildTasks") { @@ -128,6 +135,12 @@ fun Route.projectRoute() { call.project.getImageReposByProject(call.getProjectID()) ) } + delete{ + val projectID = call.getProjectID() + val req = call.receive(); + call.project.deleteImageRepo(projectID,req.repo) + call.respond("OK") + } } route("/containers") { diff --git a/src/main/kotlin/cn/edu/buaa/scs/service/Project.kt b/src/main/kotlin/cn/edu/buaa/scs/service/Project.kt index 9950bf88..f7dcadc9 100644 --- a/src/main/kotlin/cn/edu/buaa/scs/service/Project.kt +++ b/src/main/kotlin/cn/edu/buaa/scs/service/Project.kt @@ -348,6 +348,12 @@ class ProjectService(val call: ApplicationCall) : IService, FileService.FileDeco pullCommand = "docker pull ${ImageMeta.hostPrefix}/${repoName}@${this.digest}", ) + + fun deleteImage(projectID: Long, repositoryName: String,reference: String ){ + val project = Project.id(projectID) + HarborClient.deleteImage(project.name,repositoryName,reference) + } + fun getImagesByProject(projectID: Long): List { val project = Project.id(projectID) call.user().assertRead(project) @@ -373,6 +379,10 @@ class ProjectService(val call: ApplicationCall) : IService, FileService.FileDeco ) } } + fun deleteImageRepo(projectID: Long, repositoryName: String){ + val project = Project.id(projectID) + HarborClient.deleteImageRepo(project.name,repositoryName) + } fun getImageBuildTasksByProject(projectID: Long): List> { val project = Project.id(projectID) From ea68208894f0d13f0bc247c6b0cfcf14e576c9f0 Mon Sep 17 00:00:00 2001 From: Infinity Date: Mon, 2 Jan 2023 17:59:50 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E9=95=9C=E5=83=8F=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openapi/cloudapi_v2.yaml | 62 +++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/openapi/cloudapi_v2.yaml b/openapi/cloudapi_v2.yaml index f74bc6e2..9ef340a0 100644 --- a/openapi/cloudapi_v2.yaml +++ b/openapi/cloudapi_v2.yaml @@ -439,7 +439,7 @@ paths: description: 获取课程信息 security: - Authorization: [] - '/courses': + /courses: get: summary: 管理员获取所有课程 tags: @@ -455,7 +455,7 @@ paths: $ref: '#/components/schemas/CourseResponse' operationId: get-course-list security: - - Authorization: [ ] + - Authorization: [] description: 管理员获取所有课程 '/stat/exp/{expId}/assignments': parameters: @@ -1490,6 +1490,29 @@ paths: description: 获取当前项目中的所有可用镜像 tags: - 镜像 + delete: + summary: 删除镜像 + operationId: delete-project-projectId-images + responses: + '200': + description: OK + description: ' 删除镜像。' + security: + - Authorization: [] + requestBody: + content: + application/json: + schema: + type: object + properties: + repo: + type: string + tag: + type: string + required: + - repo + - tag + description: '' '/project/{projectId}/containers': parameters: - schema: @@ -1626,6 +1649,25 @@ paths: description: 获取当前项目下的所有Harbor镜像仓库 security: - Authorization: [] + delete: + summary: 删除镜像仓库 + operationId: delete-project-projectId-imageRepos + responses: + '200': + description: OK + description: 删除镜像仓库 + requestBody: + content: + application/json: + schema: + type: object + properties: + repo: + type: string + required: + - repo + security: + - Authorization: [] /captcha: get: summary: 获取验证码 @@ -1869,7 +1911,7 @@ paths: tags: - 容器服务 security: - - Authorization: [ ] + - Authorization: [] get: summary: 获取容器服务 operationId: get-project-projectId-containers-containerServiceId @@ -1881,7 +1923,7 @@ paths: schema: $ref: '#/components/schemas/ContainerServiceResponse' security: - - Authorization: [ ] + - Authorization: [] description: 根据ID获取容器服务 tags: - 容器服务 @@ -1906,7 +1948,7 @@ paths: operationId: get-resourceUsedRecords-resourceUsedRecordId description: 获取资源使用记录 security: - - Authorization: [ ] + - Authorization: [] parameters: - schema: type: boolean @@ -1939,7 +1981,7 @@ paths: operationId: get-resourcePool-resourcePoolId description: 通过ID获取资源池信息 security: - - Authorization: [ ] + - Authorization: [] '/stat/resourcePools/{resourcePoolId}/used': parameters: - schema: @@ -1973,7 +2015,7 @@ paths: operationId: get-stat-resourcePools-resourcePoolId-used description: 统计资源池的资源使用情况 security: - - Authorization: [ ] + - Authorization: [] /containerServiceTemplates: get: summary: 获取容器服务模板列表 @@ -2011,7 +2053,7 @@ paths: operationId: get-containerServiceTemplates description: 获取容器服务模板列表 security: - - Authorization: [ ] + - Authorization: [] /containerServices: get: summary: 获取所有容器服务列表 @@ -2029,7 +2071,7 @@ paths: operationId: get-containerServices description: 获取当前用户所归属的所有项目的所有容器服务列表的总和 security: - - Authorization: [ ] + - Authorization: [] '/project/{projectId}/containers/fromTemplate': parameters: - schema: @@ -2047,7 +2089,7 @@ paths: - 容器服务 description: 从模板创建容器服务 security: - - Authorization: [ ] + - Authorization: [] requestBody: content: application/json: From 4c30097241a0cf8d44da96d07e7d418bf2d760c0 Mon Sep 17 00:00:00 2001 From: Infinity Date: Mon, 2 Jan 2023 18:46:01 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E8=BA=AB?= =?UTF-8?q?=E4=BB=BD=E8=AE=A4=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/cn/edu/buaa/scs/model/User.kt | 6 ++++++ src/main/kotlin/cn/edu/buaa/scs/service/Project.kt | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/main/kotlin/cn/edu/buaa/scs/model/User.kt b/src/main/kotlin/cn/edu/buaa/scs/model/User.kt index d57eb2f1..1d0e4a84 100644 --- a/src/main/kotlin/cn/edu/buaa/scs/model/User.kt +++ b/src/main/kotlin/cn/edu/buaa/scs/model/User.kt @@ -109,6 +109,12 @@ interface User : Entity, IEntity { .and(it.role.eq(ProjectRole.ADMIN) or it.role.eq(ProjectRole.OWNER)) } || isAdmin() + fun isProjectMember(projectID: Long): Boolean = isProjectMember(Project.id(projectID)) + + fun isProjectMember(project: Project): Boolean = + isProjectAdmin(project)||mysql.projectMembers.exists { + it.projectId.eq(project.id) and it.userId.eq(this.id) + } fun personalProjectName() = "personal-${this.id.lowercase()}" diff --git a/src/main/kotlin/cn/edu/buaa/scs/service/Project.kt b/src/main/kotlin/cn/edu/buaa/scs/service/Project.kt index f7dcadc9..8d4e9115 100644 --- a/src/main/kotlin/cn/edu/buaa/scs/service/Project.kt +++ b/src/main/kotlin/cn/edu/buaa/scs/service/Project.kt @@ -351,6 +351,9 @@ class ProjectService(val call: ApplicationCall) : IService, FileService.FileDeco fun deleteImage(projectID: Long, repositoryName: String,reference: String ){ val project = Project.id(projectID) + if(!call.user().isProjectMember(project)){ + throw AuthorizationException("You are not the project member") + } HarborClient.deleteImage(project.name,repositoryName,reference) } @@ -381,6 +384,9 @@ class ProjectService(val call: ApplicationCall) : IService, FileService.FileDeco } fun deleteImageRepo(projectID: Long, repositoryName: String){ val project = Project.id(projectID) + if(!call.user().isProjectMember(project)){ + throw AuthorizationException("You are not the project member") + } HarborClient.deleteImageRepo(project.name,repositoryName) }