chore: update v1 schema (#643)

This commit is contained in:
Colin Adler
2022-04-01 14:42:36 -05:00
committed by GitHub
parent cbb82ce017
commit 2b1a0ee126
69 changed files with 757 additions and 624 deletions
+8
View File
@@ -19,6 +19,13 @@ func parseUUID(rw http.ResponseWriter, r *http.Request, param string) (uuid.UUID
})
return uuid.UUID{}, false
}
// Automatically set uuid.Nil to the acting users id.
if param == UserKey && rawID == "me" {
key := APIKey(r)
return key.UserID, true
}
parsed, err := uuid.Parse(rawID)
if err != nil {
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
@@ -26,5 +33,6 @@ func parseUUID(rw http.ResponseWriter, r *http.Request, param string) (uuid.UUID
})
return uuid.UUID{}, false
}
return parsed, true
}
+6 -9
View File
@@ -7,8 +7,6 @@ import (
"fmt"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/coder/coder/coderd/database"
"github.com/coder/coder/coderd/httpapi"
)
@@ -40,17 +38,15 @@ func OrganizationMemberParam(r *http.Request) database.OrganizationMember {
func ExtractOrganizationParam(db database.Store) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
organizationID := chi.URLParam(r, "organization")
if organizationID == "" {
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
Message: "organization must be provided",
})
orgID, ok := parseUUID(rw, r, "organization")
if !ok {
return
}
organization, err := db.GetOrganizationByID(r.Context(), organizationID)
organization, err := db.GetOrganizationByID(r.Context(), orgID)
if errors.Is(err, sql.ErrNoRows) {
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
Message: fmt.Sprintf("organization %q does not exist", organizationID),
Message: fmt.Sprintf("organization %q does not exist", orgID),
})
return
}
@@ -60,6 +56,7 @@ func ExtractOrganizationParam(db database.Store) func(http.Handler) http.Handler
})
return
}
apiKey := APIKey(r)
organizationMember, err := db.GetOrganizationMemberByUserID(r.Context(), database.GetOrganizationMemberByUserIDParams{
OrganizationID: organization.ID,
+28 -7
View File
@@ -32,10 +32,11 @@ func TestOrganizationParam(t *testing.T) {
Name: httpmw.AuthCookie,
Value: fmt.Sprintf("%s-%s", id, secret),
})
userID, err := cryptorand.String(16)
require.NoError(t, err)
userID := uuid.New()
username, err := cryptorand.String(8)
require.NoError(t, err)
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
ID: userID,
Email: "testaccount@coder.com",
@@ -86,7 +87,7 @@ func TestOrganizationParam(t *testing.T) {
r, _ = setupAuthentication(db)
rtr = chi.NewRouter()
)
chi.RouteContext(r.Context()).URLParams.Add("organization", "nothin")
chi.RouteContext(r.Context()).URLParams.Add("organization", uuid.NewString())
rtr.Use(
httpmw.ExtractAPIKey(db, nil),
httpmw.ExtractOrganizationParam(db),
@@ -98,6 +99,26 @@ func TestOrganizationParam(t *testing.T) {
require.Equal(t, http.StatusNotFound, res.StatusCode)
})
t.Run("InvalidUUID", func(t *testing.T) {
t.Parallel()
var (
db = databasefake.New()
rw = httptest.NewRecorder()
r, _ = setupAuthentication(db)
rtr = chi.NewRouter()
)
chi.RouteContext(r.Context()).URLParams.Add("organization", "not-a-uuid")
rtr.Use(
httpmw.ExtractAPIKey(db, nil),
httpmw.ExtractOrganizationParam(db),
)
rtr.Get("/", nil)
rtr.ServeHTTP(rw, r)
res := rw.Result()
defer res.Body.Close()
require.Equal(t, http.StatusBadRequest, res.StatusCode)
})
t.Run("NotInOrganization", func(t *testing.T) {
t.Parallel()
var (
@@ -107,13 +128,13 @@ func TestOrganizationParam(t *testing.T) {
rtr = chi.NewRouter()
)
organization, err := db.InsertOrganization(r.Context(), database.InsertOrganizationParams{
ID: uuid.NewString(),
ID: uuid.New(),
Name: "test",
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
})
require.NoError(t, err)
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID)
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID.String())
rtr.Use(
httpmw.ExtractAPIKey(db, nil),
httpmw.ExtractOrganizationParam(db),
@@ -134,7 +155,7 @@ func TestOrganizationParam(t *testing.T) {
rtr = chi.NewRouter()
)
organization, err := db.InsertOrganization(r.Context(), database.InsertOrganizationParams{
ID: uuid.NewString(),
ID: uuid.New(),
Name: "test",
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
@@ -147,7 +168,7 @@ func TestOrganizationParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID)
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID.String())
rtr.Use(
httpmw.ExtractAPIKey(db, nil),
httpmw.ExtractOrganizationParam(db),
+1 -1
View File
@@ -46,7 +46,7 @@ func ExtractProjectParam(db database.Store) func(http.Handler) http.Handler {
}
ctx := context.WithValue(r.Context(), projectParamContextKey{}, project)
chi.RouteContext(ctx).URLParams.Add("organization", project.OrganizationID)
chi.RouteContext(ctx).URLParams.Add("organization", project.OrganizationID.String())
next.ServeHTTP(rw, r.WithContext(ctx))
})
}
+6 -4
View File
@@ -32,8 +32,8 @@ func TestProjectParam(t *testing.T) {
Name: httpmw.AuthCookie,
Value: fmt.Sprintf("%s-%s", id, secret),
})
userID, err := cryptorand.String(16)
require.NoError(t, err)
userID := uuid.New()
username, err := cryptorand.String(8)
require.NoError(t, err)
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
@@ -47,6 +47,7 @@ func TestProjectParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertAPIKey(r.Context(), database.InsertAPIKeyParams{
ID: id,
UserID: user.ID,
@@ -55,8 +56,8 @@ func TestProjectParam(t *testing.T) {
ExpiresAt: database.Now().Add(time.Minute),
})
require.NoError(t, err)
orgID, err := cryptorand.String(16)
require.NoError(t, err)
orgID := uuid.New()
organization, err := db.InsertOrganization(r.Context(), database.InsertOrganizationParams{
ID: orgID,
Name: "banana",
@@ -65,6 +66,7 @@ func TestProjectParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertOrganizationMember(r.Context(), database.InsertOrganizationMemberParams{
OrganizationID: orgID,
UserID: user.ID,
+1 -1
View File
@@ -47,7 +47,7 @@ func ExtractProjectVersionParam(db database.Store) func(http.Handler) http.Handl
}
ctx := context.WithValue(r.Context(), projectVersionParamContextKey{}, projectVersion)
chi.RouteContext(ctx).URLParams.Add("organization", projectVersion.OrganizationID)
chi.RouteContext(ctx).URLParams.Add("organization", projectVersion.OrganizationID.String())
next.ServeHTTP(rw, r.WithContext(ctx))
})
}
+7 -4
View File
@@ -32,8 +32,8 @@ func TestProjectVersionParam(t *testing.T) {
Name: httpmw.AuthCookie,
Value: fmt.Sprintf("%s-%s", id, secret),
})
userID, err := cryptorand.String(16)
require.NoError(t, err)
userID := uuid.New()
username, err := cryptorand.String(8)
require.NoError(t, err)
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
@@ -47,6 +47,7 @@ func TestProjectVersionParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertAPIKey(r.Context(), database.InsertAPIKeyParams{
ID: id,
UserID: user.ID,
@@ -55,8 +56,8 @@ func TestProjectVersionParam(t *testing.T) {
ExpiresAt: database.Now().Add(time.Minute),
})
require.NoError(t, err)
orgID, err := cryptorand.String(16)
require.NoError(t, err)
orgID := uuid.New()
organization, err := db.InsertOrganization(r.Context(), database.InsertOrganizationParams{
ID: orgID,
Name: "banana",
@@ -65,6 +66,7 @@ func TestProjectVersionParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertOrganizationMember(r.Context(), database.InsertOrganizationMemberParams{
OrganizationID: orgID,
UserID: user.ID,
@@ -72,6 +74,7 @@ func TestProjectVersionParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
project, err := db.InsertProject(context.Background(), database.InsertProjectParams{
ID: uuid.New(),
OrganizationID: organization.ID,
+8 -9
View File
@@ -5,12 +5,12 @@ import (
"fmt"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/coder/coder/coderd/database"
"github.com/coder/coder/coderd/httpapi"
)
const UserKey = "user"
type userParamContextKey struct{}
// UserParam returns the user from the ExtractUserParam handler.
@@ -26,21 +26,20 @@ func UserParam(r *http.Request) database.User {
func ExtractUserParam(db database.Store) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
userID := chi.URLParam(r, "user")
if userID == "" {
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
Message: "user id or name must be provided",
})
userID, ok := parseUUID(rw, r, UserKey)
if !ok {
return
}
apiKey := APIKey(r)
if apiKey.UserID != userID && userID != "me" {
if apiKey.UserID != userID {
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
Message: "getting non-personal users isn't supported yet",
})
return
}
user, err := db.GetUserByID(r.Context(), apiKey.UserID)
user, err := db.GetUserByID(r.Context(), userID)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("get user: %s", err.Error()),
+7 -4
View File
@@ -10,6 +10,7 @@ import (
"time"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/coder/coder/coderd/database"
@@ -32,18 +33,20 @@ func TestUserParam(t *testing.T) {
Value: fmt.Sprintf("%s-%s", id, secret),
})
_, err := db.InsertUser(r.Context(), database.InsertUserParams{
ID: "bananas",
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
ID: uuid.New(),
})
require.NoError(t, err)
_, err = db.InsertAPIKey(r.Context(), database.InsertAPIKeyParams{
ID: id,
UserID: "bananas",
UserID: user.ID,
HashedSecret: hashed[:],
LastUsed: database.Now(),
ExpiresAt: database.Now().Add(time.Minute),
})
require.NoError(t, err)
return db, rw, r
}
@@ -82,7 +85,7 @@ func TestUserParam(t *testing.T) {
require.Equal(t, http.StatusBadRequest, res.StatusCode)
})
t.Run("Me", func(t *testing.T) {
t.Run("me", func(t *testing.T) {
t.Parallel()
db, rw, r := setup(t)
+5 -3
View File
@@ -32,8 +32,8 @@ func TestWorkspaceBuildParam(t *testing.T) {
Name: httpmw.AuthCookie,
Value: fmt.Sprintf("%s-%s", id, secret),
})
userID, err := cryptorand.String(16)
require.NoError(t, err)
userID := uuid.New()
username, err := cryptorand.String(8)
require.NoError(t, err)
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
@@ -47,6 +47,7 @@ func TestWorkspaceBuildParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertAPIKey(r.Context(), database.InsertAPIKeyParams{
ID: id,
UserID: user.ID,
@@ -55,6 +56,7 @@ func TestWorkspaceBuildParam(t *testing.T) {
ExpiresAt: database.Now().Add(time.Minute),
})
require.NoError(t, err)
workspace, err := db.InsertWorkspace(context.Background(), database.InsertWorkspaceParams{
ID: uuid.New(),
ProjectID: uuid.New(),
@@ -64,7 +66,7 @@ func TestWorkspaceBuildParam(t *testing.T) {
require.NoError(t, err)
ctx := chi.NewRouteContext()
ctx.URLParams.Add("user", userID)
ctx.URLParams.Add("user", userID.String())
ctx.URLParams.Add("workspace", workspace.Name)
r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx))
return r, workspace
+4 -3
View File
@@ -32,8 +32,8 @@ func TestWorkspaceParam(t *testing.T) {
Name: httpmw.AuthCookie,
Value: fmt.Sprintf("%s-%s", id, secret),
})
userID, err := cryptorand.String(16)
require.NoError(t, err)
userID := uuid.New()
username, err := cryptorand.String(8)
require.NoError(t, err)
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
@@ -47,6 +47,7 @@ func TestWorkspaceParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertAPIKey(r.Context(), database.InsertAPIKeyParams{
ID: id,
UserID: user.ID,
@@ -105,7 +106,7 @@ func TestWorkspaceParam(t *testing.T) {
r, _ := setup(db)
workspace, err := db.InsertWorkspace(context.Background(), database.InsertWorkspaceParams{
ID: uuid.New(),
OwnerID: "not-me",
OwnerID: uuid.New(),
Name: "hello",
})
require.NoError(t, err)