diff --git a/packages/api/internal/handlers/template_tags.go b/packages/api/internal/handlers/template_tags.go index 68883acedc..a1181dbcb7 100644 --- a/packages/api/internal/handlers/template_tags.go +++ b/packages/api/internal/handlers/template_tags.go @@ -75,6 +75,13 @@ func (a *APIStore) PostTemplatesTags(c *gin.Context) { return } + if aliasInfo.TeamID != team.ID { + a.sendAPIStoreError(c, http.StatusForbidden, fmt.Sprintf("You don't have access to sandbox template '%s'", identifier)) + telemetry.ReportError(ctx, "no access to the template", nil, telemetry.WithTemplateID(aliasInfo.TemplateID)) + + return + } + client, tx, err := a.sqlcDB.WithTx(ctx) if err != nil { telemetry.ReportCriticalError(ctx, "error when beginning transaction", err) @@ -112,13 +119,6 @@ func (a *APIStore) PostTemplatesTags(c *gin.Context) { telemetry.WithTemplateID(template.ID), ) - if aliasInfo.TeamID != team.ID { - a.sendAPIStoreError(c, http.StatusForbidden, fmt.Sprintf("You don't have access to sandbox template '%s'", identifier)) - telemetry.ReportError(ctx, "no access to the template", nil, telemetry.WithTemplateID(template.ID)) - - return - } - tags, err := id.ValidateAndDeduplicateTags(body.Tags) if err != nil { a.sendAPIStoreError(c, http.StatusBadRequest, fmt.Sprintf("Invalid tag: %s", err)) diff --git a/packages/api/internal/handlers/template_tags_test.go b/packages/api/internal/handlers/template_tags_test.go new file mode 100644 index 0000000000..083a8f8380 --- /dev/null +++ b/packages/api/internal/handlers/template_tags_test.go @@ -0,0 +1,63 @@ +package handlers + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/require" + + apispec "github.com/e2b-dev/infra/packages/api/internal/api" + templatecache "github.com/e2b-dev/infra/packages/api/internal/cache/templates" + "github.com/e2b-dev/infra/packages/auth/pkg/auth" + "github.com/e2b-dev/infra/packages/auth/pkg/types" + authqueries "github.com/e2b-dev/infra/packages/db/pkg/auth/queries" + "github.com/e2b-dev/infra/packages/db/pkg/testutils" + redis_utils "github.com/e2b-dev/infra/packages/shared/pkg/redis" +) + +func TestPostTemplatesTags_RejectsOtherTeamTemplate(t *testing.T) { + t.Parallel() + + testDB := testutils.SetupDatabase(t) + redis := redis_utils.SetupInstance(t) + ctx := t.Context() + + ownerTeamID := testutils.CreateTestTeam(t, testDB) + templateID := testutils.CreateTestTemplate(t, testDB, ownerTeamID) + + otherTeamID := testutils.CreateTestTeam(t, testDB) + otherTeamSlug := testutils.GetTeamSlug(t, ctx, testDB, otherTeamID) + + store := &APIStore{ + sqlcDB: testDB.SqlcClient, + authDB: testDB.AuthDb, + templateCache: templatecache.NewTemplateCache(testDB.SqlcClient, redis), + } + + body, err := json.Marshal(apispec.AssignTemplateTagsRequest{ + Target: templateID, + Tags: []string{"v1.0.0"}, + }) + require.NoError(t, err) + + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + c.Request = httptest.NewRequestWithContext(ctx, http.MethodPost, "/templates/tags", bytes.NewReader(body)) + c.Request.Header.Set("Content-Type", "application/json") + auth.SetTeamInfoForTest(t, c, &types.Team{ + Team: &authqueries.Team{ + ID: otherTeamID, + Slug: otherTeamSlug, + }, + }) + + store.PostTemplatesTags(c) + + res, err := apispec.ParsePostTemplatesTagsResponse(w.Result()) + require.NoError(t, err) + require.Equal(t, http.StatusForbidden, res.StatusCode()) +}