diff --git a/routers/api/devcontainer/devcontainer.go b/routers/api/devcontainer/devcontainer.go index 4207cf4ec2..e73310b0eb 100644 --- a/routers/api/devcontainer/devcontainer.go +++ b/routers/api/devcontainer/devcontainer.go @@ -3,6 +3,7 @@ package devcontainer import ( "strconv" + "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/log" web_module "code.gitea.io/gitea/modules/web" Result "code.gitea.io/gitea/routers/entity" @@ -58,18 +59,19 @@ func CreateRepoDevcontainer(ctx *context.Context) { } // 4. 调用 API Service 层创建 DevContainer - if !ctx.Doer.IsAdmin { + repo, err := repo.GetRepositoryByID(ctx, repoId) + if err != nil { errCreateDevcontainer := Result.ResultType{ Code: Result.RespFailedCreateDevcontainer.Code, Msg: Result.RespFailedCreateDevcontainer.Msg, Data: map[string]string{ - "ErrorMsg": "Permission Denied", + "ErrorMsg": "repo not found", }, } errCreateDevcontainer.RespondJson2HttpResponseWriter(ctx.Resp) return } - devcontainer_service.CreateDevcontainerJSON(ctx) + devcontainer_service.CreateDevcontainerJSON(ctx, repo, ctx.Doer) opts := &devcontainer_service.CreateDevcontainerOptions{ Actor: ctx.Doer, diff --git a/routers/web/devcontainer/devcontainer.go b/routers/web/devcontainer/devcontainer.go index 20ff66da13..67d50bebda 100644 --- a/routers/web/devcontainer/devcontainer.go +++ b/routers/web/devcontainer/devcontainer.go @@ -55,6 +55,8 @@ func GetRepoDevContainerDetails(ctx *context.Context) { } else { canRead, _ := devcontainer_service.CanCreateDevcontainer(ctx, ctx.Repo.Repository.ID, ctx.Doer.ID) ctx.Data["canRead"] = canRead + isAdmin, _ := devcontainer_service.IsOwner(ctx, ctx.Repo.Repository.ID, ctx.Doer.ID) + ctx.Data["isAdmin"] = isAdmin } //ctx.Repo.RepoLink == ctx.Repo.Repository.Link() @@ -153,7 +155,7 @@ func CreateRepoDevContainerConfiguration(ctx *context.Context) { ctx.Flash.Error("permisson denied", true) return } - devcontainer_service.CreateDevcontainerJSON(ctx) + devcontainer_service.CreateDevcontainerJSON(ctx, ctx.Repo.Repository, ctx.Doer) ctx.Redirect(path.Join(ctx.Repo.RepoLink, "/dev-container")) } func ParseImageName(imageName string) (registry, namespace, repo, tag string) { diff --git a/routers/web/web.go b/routers/web/web.go index f9b2985566..3dce1f487c 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1353,7 +1353,7 @@ func registerRoutes(m *web.Router) { m.Group("/{username}/{reponame}/dev-container", func() { // repo Dev Container m.Group("", func() { m.Combo("").Get(devcontainer_web.GetRepoDevContainerDetails) - }, reqSignIn, context.RepoAssignment, reqRepoCodeReader, context.RepoRef(), canEnableEditor, context.RepoMustNotBeArchived(), repo.MustBeEditable) + }) m.Get("/createConfiguration", devcontainer_web.CreateRepoDevContainerConfiguration) m.Get("/create", devcontainer_web.CreateRepoDevContainer, context.RepoMustNotBeArchived()) // 仓库状态非 Archived 才可以创建 DevContainer @@ -1367,7 +1367,7 @@ func registerRoutes(m *web.Router) { // 1. 已登录 // 2. repo 信息已加载到 Gitea Web Context (否则无法判定当前repo是否有写入Code权限,从而返回无权访问错误码 HTTP 404) // 3. 具有code写入权限 - reqSignIn, context.RepoAssignment, reqRepoCodeWriter, + reqSignIn, context.RepoAssignment, reqRepoCodeReader, ) m.Group("/{username}/{reponame}", func() { // repo tags diff --git a/services/devcontainer/devcontainer.go b/services/devcontainer/devcontainer.go index 648dfb4a43..31b2acef3e 100644 --- a/services/devcontainer/devcontainer.go +++ b/services/devcontainer/devcontainer.go @@ -753,6 +753,21 @@ func CanCreateDevcontainer(gitea_ctx context.Context, repoID, userID int64) (boo return repo_model.IsCollaborator(gitea_ctx, repoID, userID) } -func IsOwner(ctx context.Context, repo *repo_model.Repository, userID int64) (bool, error) { - return repo_model.IsOwnerMemberCollaborator(ctx, repo, userID) +func IsOwner(gitea_ctx context.Context, repoID, userID int64) (bool, error) { + e := db.GetEngine(gitea_ctx) + + teamMember, err := e.Table("team_user"). + Join("INNER", "team_repo", "`team_repo`.team_id = `team_user`.team_id"). + Join("INNER", "team_unit", "`team_unit`.team_id = `team_user`.team_id"). + Where("`team_repo`.repo_id = ? AND `team_unit`.access_mode = ? ", + repoID, perm.AccessModeAdmin). + And("team_user.uid = ?", userID).Exist() + if err != nil { + return false, nil + } + if teamMember { + return true, nil + } + + return e.Get(&repo_model.Collaboration{RepoID: repoID, UserID: userID, Mode: 3}) } diff --git a/services/devcontainer/devcontainer_json.go b/services/devcontainer/devcontainer_json.go index 259a6de6cb..657f3c56e3 100644 --- a/services/devcontainer/devcontainer_json.go +++ b/services/devcontainer/devcontainer_json.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/db" devcontainer_model "code.gitea.io/gitea/models/devcontainer" "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" @@ -33,7 +34,7 @@ type DevStarJSON struct { RunArgs []string } -func CreateDevcontainerJSON(ctx *gitea_context.Context) { +func CreateDevcontainerJSON(ctx *gitea_context.Context, repo *repo.Repository, doer *user.User) { jsonString := `{ "image":"mcr.microsoft.com/devcontainers/base:dev-ubuntu-20.04", "forwardPorts": [ @@ -55,7 +56,7 @@ func CreateDevcontainerJSON(ctx *gitea_context.Context) { "8888:8888" ] }` - _, err := files_service.ChangeRepoFiles(db.DefaultContext, ctx.Repo.Repository, ctx.Doer, &files_service.ChangeRepoFilesOptions{ + _, err := files_service.ChangeRepoFiles(db.DefaultContext, repo, doer, &files_service.ChangeRepoFilesOptions{ Files: []*files_service.ChangeRepoFile{ { Operation: "create", diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index 26753a069e..7d0fd72b9f 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -139,7 +139,7 @@ {{end}} - {{if .Permission.CanWrite ctx.Consts.RepoUnitTypeCode}} + {{if .Permission.CanRead ctx.Consts.RepoUnitTypeCode}} {{svg "octicon-container"}} {{ctx.Locale.Tr "repo.dev_container"}}