chore: add api endpoints to get idp field values (#16063)

Supports coder/internal#210
This commit is contained in:
Jaayden Halko
2025-01-08 16:07:02 -05:00
committed by GitHub
parent 303c4a9edb
commit 6ca1e5973e
7 changed files with 359 additions and 0 deletions
+2
View File
@@ -297,6 +297,7 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
r.Patch("/", api.patchOrganizationIDPSyncSettings)
})
r.Get("/available-fields", api.deploymentIDPSyncClaimFields)
r.Get("/field-values", api.deploymentIDPSyncClaimFieldValues)
})
})
@@ -311,6 +312,7 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
r.Patch("/idpsync/groups", api.patchGroupIDPSyncSettings)
r.Get("/idpsync/roles", api.roleIDPSyncSettings)
r.Patch("/idpsync/roles", api.patchRoleIDPSyncSettings)
r.Get("/idpsync/field-values", api.organizationIDPSyncClaimFieldValues)
})
})
+60
View File
@@ -363,3 +363,63 @@ func (api *API) idpSyncClaimFields(orgID uuid.UUID, rw http.ResponseWriter, r *h
httpapi.Write(ctx, rw, http.StatusOK, fields)
}
// @Summary Get the organization idp sync claim field values
// @ID get-the-organization-idp-sync-claim-field-values
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param organization path string true "Organization ID" format(uuid)
// @Param claimField query string true "Claim Field" format(string)
// @Success 200 {array} string
// @Router /organizations/{organization}/settings/idpsync/field-values [get]
func (api *API) organizationIDPSyncClaimFieldValues(rw http.ResponseWriter, r *http.Request) {
org := httpmw.OrganizationParam(r)
api.idpSyncClaimFieldValues(org.ID, rw, r)
}
// @Summary Get the idp sync claim field values
// @ID get-the-idp-sync-claim-field-values
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param organization path string true "Organization ID" format(uuid)
// @Param claimField query string true "Claim Field" format(string)
// @Success 200 {array} string
// @Router /settings/idpsync/field-values [get]
func (api *API) deploymentIDPSyncClaimFieldValues(rw http.ResponseWriter, r *http.Request) {
// nil uuid implies all organizations
api.idpSyncClaimFieldValues(uuid.Nil, rw, r)
}
func (api *API) idpSyncClaimFieldValues(orgID uuid.UUID, rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
claimField := r.URL.Query().Get("claimField")
if claimField == "" {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: "claimField query parameter is required",
})
return
}
fieldValues, err := api.Database.OIDCClaimFieldValues(ctx, database.OIDCClaimFieldValuesParams{
OrganizationID: orgID,
ClaimField: claimField,
})
if httpapi.IsUnauthorizedError(err) {
// Give a helpful error. The user could read the org, so this does not
// leak anything.
httpapi.Write(ctx, rw, http.StatusForbidden, codersdk.Response{
Message: "You do not have permission to view the IDP claim field values",
Detail: fmt.Sprintf("%s.read permission is required", rbac.ResourceIdpsyncSettings.Type),
})
return
}
if err != nil {
httpapi.InternalServerError(rw, err)
return
}
httpapi.Write(ctx, rw, http.StatusOK, fieldValues)
}
+8
View File
@@ -178,6 +178,14 @@ func TestUserOIDC(t *testing.T) {
require.NoError(t, err)
require.ElementsMatch(t, fields, orgFields)
fieldValues, err := runner.AdminClient.GetIDPSyncFieldValues(ctx, "organization")
require.NoError(t, err)
require.ElementsMatch(t, []string{"first", "second"}, fieldValues)
orgFieldValues, err := runner.AdminClient.GetOrganizationIDPSyncFieldValues(ctx, orgOne.ID.String(), "organization")
require.NoError(t, err)
require.ElementsMatch(t, []string{"first", "second"}, orgFieldValues)
// When: they are manually added to the fourth organization, a new sync
// should remove them.
_, err = runner.AdminClient.PostOrganizationMember(ctx, orgThree.ID, "alice")