Satisfy API policy boundary lint
Authored by
mfwolffe <wolffemf@dukes.jmu.edu>
- SHA
c8156e7bd512cd17afb1249ff2b301c057024657- Parents
-
ff4e857 - Tree
e70876f
c8156e7
c8156e7bd512cd17afb1249ff2b301c057024657ff4e857
e70876f| Status | File | + | - |
|---|---|---|---|
| M |
internal/auth/policy/resources.go
|
7 | 0 |
| M |
internal/web/handlers/api/collaborators.go
|
1 | 1 |
| M |
internal/web/handlers/api/repos.go
|
2 | 1 |
| M |
internal/web/handlers/api/search.go
|
3 | 1 |
internal/auth/policy/resources.gomodified@@ -43,3 +43,10 @@ func (r RepoRef) IsPublic() bool { return r.Visibility == "public" } | ||
| 43 | 43 | // IsPrivate is the inverse. Use whichever phrasing reads better at the |
| 44 | 44 | // call site. |
| 45 | 45 | func (r RepoRef) IsPrivate() bool { return r.Visibility == "private" } |
| 46 | + | |
| 47 | +// IsOwnedByUser reports whether userID is the direct user owner. Keep | |
| 48 | +// ownership interpretation here so handlers do not grow inline owner | |
| 49 | +// checks next to request behavior. | |
| 50 | +func (r RepoRef) IsOwnedByUser(userID int64) bool { | |
| 51 | + return userID != 0 && r.OwnerUserID == userID | |
| 52 | +} | |
internal/web/handlers/api/collaborators.gomodified@@ -152,7 +152,7 @@ func (h *Handlers) collaboratorPut(w http.ResponseWriter, r *http.Request) { | ||
| 152 | 152 | // implicitly hold every permission, so a row would be confusing |
| 153 | 153 | // at best (and could lock the legitimate owner into a downgraded |
| 154 | 154 | // role at worst). |
| 155 | - if repo.OwnerUserID.Valid && repo.OwnerUserID.Int64 == user.ID { | |
| 155 | + if policy.NewRepoRefFromRepo(*repo).IsOwnedByUser(user.ID) { | |
| 156 | 156 | writeAPIError(w, http.StatusUnprocessableEntity, "owner already has full access") |
| 157 | 157 | return |
| 158 | 158 | } |
internal/web/handlers/api/repos.gomodified@@ -84,6 +84,7 @@ func presentRepo(r reposdb.Repo, ownerLogin string) repoResponse { | ||
| 84 | 84 | if r.OwnerOrgID.Valid { |
| 85 | 85 | ownerType = "org" |
| 86 | 86 | } |
| 87 | + repoRef := policy.NewRepoRefFromRepo(r) | |
| 87 | 88 | return repoResponse{ |
| 88 | 89 | ID: r.ID, |
| 89 | 90 | Name: r.Name, |
@@ -92,7 +93,7 @@ func presentRepo(r reposdb.Repo, ownerLogin string) repoResponse { | ||
| 92 | 93 | OwnerType: ownerType, |
| 93 | 94 | Description: r.Description, |
| 94 | 95 | Visibility: string(r.Visibility), |
| 95 | - Private: string(r.Visibility) == "private", | |
| 96 | + Private: repoRef.IsPrivate(), | |
| 96 | 97 | DefaultBranch: r.DefaultBranch, |
| 97 | 98 | Fork: r.ForkOfRepoID.Valid, |
| 98 | 99 | Archived: r.IsArchived, |
internal/web/handlers/api/search.gomodified@@ -10,6 +10,7 @@ import ( | ||
| 10 | 10 | "github.com/go-chi/chi/v5" |
| 11 | 11 | |
| 12 | 12 | "github.com/tenseleyFlow/shithub/internal/auth/pat" |
| 13 | + "github.com/tenseleyFlow/shithub/internal/auth/policy" | |
| 13 | 14 | "github.com/tenseleyFlow/shithub/internal/search" |
| 14 | 15 | "github.com/tenseleyFlow/shithub/internal/web/handlers/api/apipage" |
| 15 | 16 | "github.com/tenseleyFlow/shithub/internal/web/middleware" |
@@ -86,6 +87,7 @@ func (h *Handlers) searchRepositories(w http.ResponseWriter, r *http.Request) { | ||
| 86 | 87 | } |
| 87 | 88 | items := make([]searchRepoItem, 0, len(rows)) |
| 88 | 89 | for _, row := range rows { |
| 90 | + repoRef := policy.RepoRef{Visibility: row.Visibility} | |
| 89 | 91 | items = append(items, searchRepoItem{ |
| 90 | 92 | ID: row.ID, |
| 91 | 93 | Name: row.Name, |
@@ -93,7 +95,7 @@ func (h *Handlers) searchRepositories(w http.ResponseWriter, r *http.Request) { | ||
| 93 | 95 | OwnerLogin: row.OwnerUsername, |
| 94 | 96 | Description: row.Description, |
| 95 | 97 | Visibility: row.Visibility, |
| 96 | - Private: row.Visibility == "private", | |
| 98 | + Private: repoRef.IsPrivate(), | |
| 97 | 99 | StarCount: row.StarCount, |
| 98 | 100 | UpdatedAt: row.UpdatedAt.UTC().Format(time.RFC3339), |
| 99 | 101 | Score: row.Rank, |