cloudapi: handle multi-tenancy in all compose/<id> endpoints
Use the `EnsureJobChannel()` middleware in all `compose/<id>` endpoints. Specifically in the: - status - metadata - manifests - logs As a result, these endpoints now return `404` in case the server has JWT enabled and the channel associated with the request does not match the channel associated with the requested compose (job). Extend the multi-tenancy unit test to ensure that these endpoints behave as expected in case of match and mismatch between the request and compose channels.
This commit is contained in:
parent
fc7d090498
commit
4a94b46f33
2 changed files with 57 additions and 0 deletions
|
|
@ -492,6 +492,10 @@ func imageTypeFromApiImageType(it ImageTypes, arch distro.Arch) string {
|
|||
}
|
||||
|
||||
func (h *apiHandlers) GetComposeStatus(ctx echo.Context, id string) error {
|
||||
return h.server.EnsureJobChannel(h.getComposeStatusImpl)(ctx, id)
|
||||
}
|
||||
|
||||
func (h *apiHandlers) getComposeStatusImpl(ctx echo.Context, id string) error {
|
||||
jobId, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
return HTTPError(ErrorInvalidComposeId)
|
||||
|
|
@ -738,6 +742,10 @@ func composeStatusFromKojiJobStatus(js *worker.JobStatus, initResult *worker.Koj
|
|||
|
||||
// ComposeMetadata handles a /composes/{id}/metadata GET request
|
||||
func (h *apiHandlers) GetComposeMetadata(ctx echo.Context, id string) error {
|
||||
return h.server.EnsureJobChannel(h.getComposeMetadataImpl)(ctx, id)
|
||||
}
|
||||
|
||||
func (h *apiHandlers) getComposeMetadataImpl(ctx echo.Context, id string) error {
|
||||
jobId, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
return HTTPError(ErrorInvalidComposeId)
|
||||
|
|
@ -849,6 +857,11 @@ func stagesToPackageMetadata(stages []osbuild.RPMStageMetadata) []PackageMetadat
|
|||
|
||||
// Get logs for a compose
|
||||
func (h *apiHandlers) GetComposeLogs(ctx echo.Context, id string) error {
|
||||
return h.server.EnsureJobChannel(h.getComposeLogsImpl)(ctx, id)
|
||||
}
|
||||
|
||||
func (h *apiHandlers) getComposeLogsImpl(ctx echo.Context, id string) error {
|
||||
|
||||
jobId, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
return HTTPError(ErrorInvalidComposeId)
|
||||
|
|
@ -959,6 +972,10 @@ func manifestJobResultsFromJobDeps(w *worker.Server, deps []uuid.UUID) (*worker.
|
|||
|
||||
// GetComposeIdManifests returns the Manifests for a given Compose (one for each image).
|
||||
func (h *apiHandlers) GetComposeManifests(ctx echo.Context, id string) error {
|
||||
return h.server.EnsureJobChannel(h.getComposeManifestsImpl)(ctx, id)
|
||||
}
|
||||
|
||||
func (h *apiHandlers) getComposeManifestsImpl(ctx echo.Context, id string) error {
|
||||
jobId, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
return HTTPError(ErrorInvalidComposeId)
|
||||
|
|
|
|||
|
|
@ -276,5 +276,45 @@ func TestMultitenancy(t *testing.T) {
|
|||
}
|
||||
require.NoError(t, json.Unmarshal(resp.Body, &result))
|
||||
require.NotEqual(t, "pending", result.Status)
|
||||
|
||||
composeEndpoints := []string{"", "logs", "manifests", "metadata"}
|
||||
// Verify that all compose endpoints work with the appropriate orgID
|
||||
for _, endpoint := range composeEndpoints {
|
||||
// TODO: "metadata" endpoint is not supported for Koji composes
|
||||
jobType, err := workerServer.JobType(c.id)
|
||||
require.NoError(t, err)
|
||||
if jobType == worker.JobTypeKojiFinalize && endpoint == "metadata" {
|
||||
continue
|
||||
}
|
||||
|
||||
path := "/api/image-builder-composer/v2/composes/" + c.id.String()
|
||||
if endpoint != "" {
|
||||
path = path + "/" + endpoint
|
||||
}
|
||||
|
||||
_ = test.APICall{
|
||||
Handler: handler,
|
||||
Method: http.MethodGet,
|
||||
Context: reqContext(c.orgID),
|
||||
Path: path,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
}.Do(t)
|
||||
}
|
||||
|
||||
// Verify that no compose endpoints are accessible with wrong orgID
|
||||
for _, endpoint := range composeEndpoints {
|
||||
path := "/api/image-builder-composer/v2/composes/" + c.id.String()
|
||||
if endpoint != "" {
|
||||
path = path + "/" + endpoint
|
||||
}
|
||||
|
||||
_ = test.APICall{
|
||||
Handler: handler,
|
||||
Method: http.MethodGet,
|
||||
Context: reqContext("bad-org"),
|
||||
Path: path,
|
||||
ExpectedStatus: http.StatusNotFound,
|
||||
}.Do(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue