mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
feat: implement organization context in the cli (#12259)
* feat: implement organization context in the cli `coder org show current`
This commit is contained in:
@ -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
|
||||
|
@ -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")
|
||||
})
|
||||
}
|
||||
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user