Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ generate:
$(codegen) -old-config-style -generate gin --package api $(openapi) > internal/api/api.gen.go
$(codegen) -old-config-style -generate types --package api $(openapi) > internal/api/types.gen.go
$(codegen) -old-config-style -generate spec --package api $(openapi) > internal/api/spec.gen.go
$(codegen) -old-config-style -generate client --package api $(openapi) > internal/api/client.gen.go

.PHONY: build
build:
Expand Down
34 changes: 34 additions & 0 deletions packages/api/internal/api/api.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6,737 changes: 6,737 additions & 0 deletions packages/api/internal/api/client.gen.go

Large diffs are not rendered by default.

258 changes: 130 additions & 128 deletions packages/api/internal/api/spec.gen.go

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions packages/api/internal/api/types.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions packages/api/internal/handlers/template_alias.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package handlers

import (
"database/sql"
"errors"
"net/http"

"github.com/gin-gonic/gin"

"github.com/e2b-dev/infra/packages/api/internal/api"
"github.com/e2b-dev/infra/packages/shared/pkg/telemetry"
)

func (a *APIStore) GetTemplatesAliasesAlias(c *gin.Context, alias string) {
ctx := c.Request.Context()

team, apiErr := a.GetTeam(ctx, c, nil)
if apiErr != nil {
a.sendAPIStoreError(c, apiErr.Code, apiErr.ClientMsg)
telemetry.ReportCriticalError(ctx, "error when getting team and tier", apiErr.Err)

return
}

result, err := a.sqlcDB.GetTemplateAliasByAlias(ctx, alias)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
a.sendAPIStoreError(c, http.StatusNotFound, "Template alias not found")

return
}

a.sendAPIStoreError(c, http.StatusInternalServerError, "Error when getting template alias")
telemetry.ReportCriticalError(ctx, "error when getting template alias", err)

return
}

// Team is not alias owner so we are returning forbidden
// We don't want to return not found here as this endpoint is used for alias existence even for non owners
if result.TeamID != team.ID {
a.sendAPIStoreError(c, http.StatusForbidden, "You don't have access to this template alias")

return
}

// Team is alias owner
c.JSON(
http.StatusOK, api.TemplateAliasResponse{
Public: result.Public,
TemplateID: result.EnvID,
},
)
}
118 changes: 118 additions & 0 deletions packages/api/internal/handlers/template_alias_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package handlers

import (
"fmt"
"net/http"
"net/http/httptest"
"testing"

"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

apispec "github.com/e2b-dev/infra/packages/api/internal/api"
"github.com/e2b-dev/infra/packages/api/internal/auth"
"github.com/e2b-dev/infra/packages/api/internal/db/types"
"github.com/e2b-dev/infra/packages/db/queries"
"github.com/e2b-dev/infra/packages/db/testutils"
)

func TestQueryNotExistingTemplateAlias(t *testing.T) {
t.Parallel()

testDB := testutils.SetupDatabase(t)

store := &APIStore{
sqlcDB: testDB,
}

alias := "non-existing-template-alias"
teamID := testutils.CreateTestTeam(t, testDB)

w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest(http.MethodGet, fmt.Sprintf("/templates/aliases/%s", alias), nil)
c.Set(
auth.TeamContextKey,
&types.Team{
Team: &queries.Team{
ID: teamID,
},
},
)

store.GetTemplatesAliasesAlias(c, alias)

res, err := apispec.ParseGetTemplatesAliasesAliasResponse(w.Result())
require.NoError(t, err)
require.Equal(t, http.StatusNotFound, res.StatusCode())
}

func TestQueryExistingTemplateAlias(t *testing.T) {
t.Parallel()

testDB := testutils.SetupDatabase(t)

teamID := testutils.CreateTestTeam(t, testDB)
templateID, alias := testutils.CreateTestTemplateWithAlias(t, testDB, teamID)

store := &APIStore{
sqlcDB: testDB,
}

w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest(http.MethodGet, fmt.Sprintf("/templates/aliases/%s", alias), nil)
c.Set(
auth.TeamContextKey,
&types.Team{
Team: &queries.Team{
ID: teamID,
},
},
)

store.GetTemplatesAliasesAlias(c, alias)

res, err := apispec.ParseGetTemplatesAliasesAliasResponse(w.Result())
require.NoError(t, err)
require.Equal(t, http.StatusOK, res.StatusCode())

require.NotNil(t, res.JSON200)

resBody := *res.JSON200
assert.Equal(t, templateID, resBody.TemplateID)
assert.True(t, resBody.Public)
}

func TestQueryExistingTemplateAliasAsNotOwnerTeam(t *testing.T) {
t.Parallel()

testDB := testutils.SetupDatabase(t)

ownerTeamID := testutils.CreateTestTeam(t, testDB)
foreignTeamID := testutils.CreateTestTeam(t, testDB)
_, alias := testutils.CreateTestTemplateWithAlias(t, testDB, ownerTeamID)

store := &APIStore{
sqlcDB: testDB,
}

w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest(http.MethodGet, fmt.Sprintf("/templates/aliases/%s", alias), nil)
c.Set(
auth.TeamContextKey,
&types.Team{
Team: &queries.Team{
ID: foreignTeamID,
},
},
)

store.GetTemplatesAliasesAlias(c, alias)

res, err := apispec.ParseGetTemplatesAliasesAliasResponse(w.Result())
require.NoError(t, err)
require.Equal(t, http.StatusForbidden, res.StatusCode())
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,72 +4,22 @@ import (
"context"
"testing"

"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/e2b-dev/infra/packages/db/client"
"github.com/e2b-dev/infra/packages/db/testutils"
)

// createTestTeam creates a test team in the database using raw SQL
func createTestTeam(t *testing.T, db *client.Client) uuid.UUID {
t.Helper()
teamID := uuid.New()

// Insert a team directly into the database using raw SQL
// Using the default tier 'base_v1' that is created in migrations
err := db.TestsRawSQL(t.Context(),
"INSERT INTO public.teams (id, name, tier, email) VALUES ($1, $2, $3, $4)",
teamID, "Test Team "+teamID.String(), "base_v1", "test-"+teamID.String()+"@example.com",
)
require.NoError(t, err, "Failed to create test team")

return teamID
}

// createTestTemplate creates a base env in the database (required by foreign key constraint)
func createTestTemplate(t *testing.T, db *client.Client, teamID uuid.UUID) string {
t.Helper()
envID := "base-env-" + uuid.New().String()

// Insert a base env directly into the database
// After the env_builds migration, envs table only has: id, team_id, public, updated_at, build_count, spawn_count, last_spawned_at
err := db.TestsRawSQL(t.Context(),
"INSERT INTO public.envs (id, team_id, public, updated_at) VALUES ($1, $2, $3, NOW())",
envID, teamID, true,
)
require.NoError(t, err, "Failed to create test base env")

return envID
}

func createTestTemplateAlias(t *testing.T, db *client.Client, templateID string) string {
t.Helper()
alias := "alias-" + uuid.New().String()

// Insert a base env directly into the database
// After the env_builds migration, envs table only has: id, team_id, public, updated_at, build_count, spawn_count, last_spawned_at
err := db.TestsRawSQL(t.Context(),
"INSERT INTO public.env_aliases (alias, env_id, is_renamable) VALUES ($1, $2, $3)",
alias, templateID, true,
)
require.NoError(t, err, "Failed to create test base env")

return alias
}

func TestDeleteTemplateAliases_Success(t *testing.T) {
t.Parallel()
// Setup test database with migrations
client := testutils.SetupDatabase(t)
ctx := context.Background()

// Create a test team first (required by foreign key constraint)
teamID := createTestTeam(t, client)
teamID := testutils.CreateTestTeam(t, client)
// Create a base env (required by foreign key constraint on snapshots table)
templateID := createTestTemplate(t, client, teamID)
_ = createTestTemplateAlias(t, client, templateID)
templateID, _ := testutils.CreateTestTemplateWithAlias(t, client, teamID)

// Execute UpsertSnapshot for a new snapshot
result, err := client.DeleteOtherTemplateAliases(ctx, templateID)
Expand All @@ -84,11 +34,10 @@ func TestDeleteTemplateAliases_NoAlias(t *testing.T) {
ctx := context.Background()

// Create a test team first (required by foreign key constraint)
teamID := createTestTeam(t, client)
teamID := testutils.CreateTestTeam(t, client)
// Create a base env (required by foreign key constraint on snapshots table)
templateID := createTestTemplate(t, client, teamID)
_ = createTestTemplateAlias(t, client, templateID)
anotherTemplateID := createTestTemplate(t, client, teamID)
_, _ = testutils.CreateTestTemplateWithAlias(t, client, teamID)
anotherTemplateID := testutils.CreateTestTemplate(t, client, teamID)

// Execute UpsertSnapshot for a new snapshot
result, err := client.DeleteOtherTemplateAliases(ctx, anotherTemplateID)
Expand Down
Loading
Loading