feat: implement organization context in the cli (#12259)

* feat: implement organization context in the cli

`coder org show current`
This commit is contained in:
Steven Masley
2024-02-26 10:03:49 -06:00
committed by GitHub
parent f44c89d200
commit d2998c6b7b
24 changed files with 290 additions and 52 deletions

View File

@ -2,8 +2,12 @@ package httpmw
import (
"context"
"fmt"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/httpapi"
@ -40,19 +44,34 @@ 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) {
ctx := r.Context()
orgID, ok := ParseUUIDParam(rw, r, "organization")
if !ok {
arg := chi.URLParam(r, "organization")
if arg == "" {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: "\"organization\" must be provided.",
})
return
}
organization, err := db.GetOrganizationByID(ctx, orgID)
var organization database.Organization
var err error
// Try by name or uuid.
id, err := uuid.Parse(arg)
if err == nil {
organization, err = db.GetOrganizationByID(ctx, id)
} else {
organization, err = db.GetOrganizationByName(ctx, arg)
}
if httpapi.Is404Error(err) {
httpapi.ResourceNotFound(rw)
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
Message: fmt.Sprintf("Organization %q not found.", arg),
Detail: "Provide either the organization id or name.",
})
return
}
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching organization.",
Message: fmt.Sprintf("Internal error fetching organization %q.", arg),
Detail: err.Error(),
})
return

View File

@ -103,7 +103,7 @@ func TestOrganizationParam(t *testing.T) {
rtr.ServeHTTP(rw, r)
res := rw.Result()
defer res.Body.Close()
require.Equal(t, http.StatusBadRequest, res.StatusCode)
require.Equal(t, http.StatusNotFound, res.StatusCode)
})
t.Run("NotInOrganization", func(t *testing.T) {
@ -160,8 +160,6 @@ func TestOrganizationParam(t *testing.T) {
})
require.NoError(t, err)
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID.String())
chi.RouteContext(r.Context()).URLParams.Add("user", user.ID.String())
rtr.Use(
httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
DB: db,
@ -194,9 +192,21 @@ func TestOrganizationParam(t *testing.T) {
assert.NotEmpty(t, orgMem.OrganizationMember.UserID)
assert.NotEmpty(t, orgMem.OrganizationMember.Roles)
})
// Try by ID
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID.String())
chi.RouteContext(r.Context()).URLParams.Add("user", user.ID.String())
rtr.ServeHTTP(rw, r)
res := rw.Result()
defer res.Body.Close()
require.Equal(t, http.StatusOK, res.StatusCode)
require.Equal(t, http.StatusOK, res.StatusCode, "by id")
// Try by name
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.Name)
chi.RouteContext(r.Context()).URLParams.Add("user", user.ID.String())
rtr.ServeHTTP(rw, r)
res = rw.Result()
defer res.Body.Close()
require.Equal(t, http.StatusOK, res.StatusCode, "by name")
})
}

View File

@ -66,7 +66,7 @@ func TestOrganizationByUserAndName(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
_, err := client.OrganizationByName(ctx, codersdk.Me, "nothing")
_, err := client.OrganizationByUserAndName(ctx, codersdk.Me, "nothing")
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
@ -85,7 +85,7 @@ func TestOrganizationByUserAndName(t *testing.T) {
Name: "another",
})
require.NoError(t, err)
_, err = other.OrganizationByName(ctx, codersdk.Me, org.Name)
_, err = other.OrganizationByUserAndName(ctx, codersdk.Me, org.Name)
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
@ -101,7 +101,7 @@ func TestOrganizationByUserAndName(t *testing.T) {
org, err := client.Organization(ctx, user.OrganizationID)
require.NoError(t, err)
_, err = client.OrganizationByName(ctx, codersdk.Me, org.Name)
_, err = client.OrganizationByUserAndName(ctx, codersdk.Me, org.Name)
require.NoError(t, err)
})
}