mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
docs: API enterprise (#5625)
* docs: audit, deploymentconfig, files, parameters * Swagger comments in workspacebuilds.go * structs in workspacebuilds.go * workspaceagents: instance identity * workspaceagents.go in progress * workspaceagents.go in progress * Agents * workspacebuilds.go * /workspaces * templates.go, templateversions.go * templateversion.go in progress * cancel * templateversions * wip * Merge * x-apidocgen * NullTime hack not needed anymore * Fix: x-apidocgen * Members * Fixes * Fix * WIP * WIP * Users * Logout * User profile * Status suspend activate * User roles * User tokens * Keys * SSH key * All * Typo * Fix * Entitlements * Groups * SCIM * Fix * Fix * Clean templates * Sort API pages * Fix: HashedSecret * General is first
This commit is contained in:
@ -15,6 +15,13 @@ import (
|
||||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
// @Summary Get appearance
|
||||
// @ID get-appearance
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Success 200 {object} codersdk.AppearanceConfig
|
||||
// @Router /appearance [get]
|
||||
func (api *API) appearance(rw http.ResponseWriter, r *http.Request) {
|
||||
api.entitlementsMu.RLock()
|
||||
isEntitled := api.entitlements.Features[codersdk.FeatureAppearance].Entitlement == codersdk.EntitlementEntitled
|
||||
@ -74,6 +81,14 @@ func validateHexColor(color string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// @Summary Update appearance
|
||||
// @ID update-appearance
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Param request body codersdk.AppearanceConfig true "Update appearance request"
|
||||
// @Success 200 {object} codersdk.AppearanceConfig
|
||||
// @Router /appearance [put]
|
||||
func (api *API) putAppearance(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
|
@ -81,7 +81,7 @@ func New(ctx context.Context, options *Options) (*API, error) {
|
||||
httpmw.ExtractOrganizationParam(api.Database),
|
||||
)
|
||||
r.Post("/", api.postGroupByOrganization)
|
||||
r.Get("/", api.groups)
|
||||
r.Get("/", api.groupsByOrganization)
|
||||
r.Route("/{groupName}", func(r chi.Router) {
|
||||
r.Use(
|
||||
httpmw.ExtractGroupByNameParam(api.Database),
|
||||
@ -331,6 +331,13 @@ func (api *API) updateEntitlements(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// @Summary Get entitlements
|
||||
// @ID get-entitlements
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Success 200 {object} codersdk.Entitlements
|
||||
// @Router /entitlements [get]
|
||||
func (api *API) serveEntitlements(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
api.entitlementsMu.RLock()
|
||||
|
@ -17,6 +17,16 @@ import (
|
||||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
// @Summary Create group for organization
|
||||
// @ID create-group-for-organization
|
||||
// @Security CoderSessionToken
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags Templates
|
||||
// @Param request body codersdk.CreateGroupRequest true "Create group request"
|
||||
// @Param organization path string true "Organization ID"
|
||||
// @Success 201 {object} codersdk.Group
|
||||
// @Router /organizations/{organization}/groups [post]
|
||||
func (api *API) postGroupByOrganization(rw http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
ctx = r.Context()
|
||||
@ -264,6 +274,14 @@ func (api *API) deleteGroup(rw http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary Get group by name
|
||||
// @ID get-group-by-name
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Param groupName path string true "Group name"
|
||||
// @Success 200 {object} codersdk.Group
|
||||
// @Router /groups/{groupName} [get]
|
||||
func (api *API) group(rw http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
ctx = r.Context()
|
||||
@ -284,6 +302,26 @@ func (api *API) group(rw http.ResponseWriter, r *http.Request) {
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertGroup(group, users))
|
||||
}
|
||||
|
||||
// @Summary Get groups by organization
|
||||
// @ID get-groups-by-organization
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Param organization path string true "Organization ID" format(uuid)
|
||||
// @Success 200 {array} codersdk.Group
|
||||
// @Router /organizations/{organization}/groups [get]
|
||||
func (api *API) groupsByOrganization(rw http.ResponseWriter, r *http.Request) {
|
||||
api.groups(rw, r)
|
||||
}
|
||||
|
||||
// @Summary Get groups
|
||||
// @ID get-groups
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Param organization path string true "Organization ID" format(uuid)
|
||||
// @Success 200 {array} codersdk.Group
|
||||
// @Router /groups [get]
|
||||
func (api *API) groups(rw http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
ctx = r.Context()
|
||||
|
@ -48,6 +48,15 @@ var Keys = map[string]ed25519.PublicKey{"2022-08-12": ed25519.PublicKey(key20220
|
||||
// we generally don't want the old features to immediately break without warning. With a grace
|
||||
// period on the license, features will continue to work from the old license until its grace
|
||||
// period, then the users will get a warning allowing them to gracefully stop using the feature.
|
||||
//
|
||||
// @Summary Add new license
|
||||
// @ID add-new-license
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Organizations
|
||||
// @Param request body codersdk.AddLicenseRequest true "Add license request"
|
||||
// @Success 201 {object} codersdk.License
|
||||
// @Router /licenses [post]
|
||||
func (api *API) postLicense(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
if !api.AGPL.Authorize(r, rbac.ActionCreate, rbac.ResourceLicense) {
|
||||
@ -121,6 +130,13 @@ func (api *API) postLicense(rw http.ResponseWriter, r *http.Request) {
|
||||
httpapi.Write(ctx, rw, http.StatusCreated, convertLicense(dl, rawClaims))
|
||||
}
|
||||
|
||||
// @Summary Get licenses
|
||||
// @ID get-licenses
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Success 200 {array} codersdk.License
|
||||
// @Router /licenses [get]
|
||||
func (api *API) licenses(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
licenses, err := api.Database.GetLicenses(ctx)
|
||||
@ -155,6 +171,14 @@ func (api *API) licenses(rw http.ResponseWriter, r *http.Request) {
|
||||
httpapi.Write(ctx, rw, http.StatusOK, sdkLicenses)
|
||||
}
|
||||
|
||||
// @Summary Delete license
|
||||
// @ID delete-license
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Param id path string true "License ID" format(number)
|
||||
// @Success 200
|
||||
// @Router /license/{id} [delete]
|
||||
func (api *API) deleteLicense(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
if !api.AGPL.Authorize(r, rbac.ActionDelete, rbac.ResourceLicense) {
|
||||
|
@ -45,6 +45,14 @@ func (api *API) provisionerDaemonsEnabledMW(next http.Handler) http.Handler {
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary Get provisioner daemons
|
||||
// @ID get-provisioner-daemons
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Param organization path string true "Organization ID" format(uuid)
|
||||
// @Success 200 {array} codersdk.ProvisionerDaemon
|
||||
// @Router /organizations/{organization}/provisionerdaemons [get]
|
||||
func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
org := httpmw.OrganizationParam(r)
|
||||
@ -82,6 +90,15 @@ func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Serves the provisioner daemon protobuf API over a WebSocket.
|
||||
//
|
||||
// @Summary Serve provisioner daemon
|
||||
// @ID serve-provisioner-daemon
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Param organization path string true "Organization ID" format(uuid)
|
||||
// @Success 101
|
||||
// @Router /organizations/{organization}/provisionerdaemons/serve [get]
|
||||
func (api *API) provisionerDaemonServe(rw http.ResponseWriter, r *http.Request) {
|
||||
tags := map[string]string{}
|
||||
if r.URL.Query().Has("tag") {
|
||||
|
@ -10,6 +10,14 @@ import (
|
||||
)
|
||||
|
||||
// replicas returns the number of replicas that are active in Coder.
|
||||
//
|
||||
// @Summary Get active replicas
|
||||
// @ID get-active-replicas
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Success 200 {array} codersdk.Replica
|
||||
// @Router /replicas [get]
|
||||
func (api *API) replicas(rw http.ResponseWriter, r *http.Request) {
|
||||
if !api.AGPL.Authorize(r, rbac.ActionRead, rbac.ResourceReplicas) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
|
@ -43,6 +43,14 @@ func (api *API) scimVerifyAuthHeader(r *http.Request) bool {
|
||||
// Okta to try and create each user individually, this way we don't need to
|
||||
// implement fetching users twice.
|
||||
//
|
||||
// @Summary SCIM 2.0: Get users
|
||||
// @ID scim-get-users
|
||||
// @Security CoderSessionToken
|
||||
// @Produce application/scim+json
|
||||
// @Tags Enterprise
|
||||
// @Success 200
|
||||
// @Router /scim/v2/Users [post]
|
||||
//
|
||||
//nolint:revive
|
||||
func (api *API) scimGetUsers(rw http.ResponseWriter, r *http.Request) {
|
||||
if !api.scimVerifyAuthHeader(r) {
|
||||
@ -62,6 +70,19 @@ func (api *API) scimGetUsers(rw http.ResponseWriter, r *http.Request) {
|
||||
// This is done to always force Okta to try and create the user, this way we
|
||||
// don't need to implement fetching users twice.
|
||||
//
|
||||
// scimGetUsers intentionally always returns no users. This is done to always force
|
||||
// Okta to try and create each user individually, this way we don't need to
|
||||
// implement fetching users twice.
|
||||
//
|
||||
// @Summary SCIM 2.0: Get user by ID
|
||||
// @ID scim-get-user-by-id
|
||||
// @Security CoderSessionToken
|
||||
// @Produce application/scim+json
|
||||
// @Tags Enterprise
|
||||
// @Param id path string true "User ID" format(uuid)
|
||||
// @Failure 404
|
||||
// @Router /scim/v2/Users/{id} [get]
|
||||
//
|
||||
//nolint:revive
|
||||
func (api *API) scimGetUser(rw http.ResponseWriter, r *http.Request) {
|
||||
if !api.scimVerifyAuthHeader(r) {
|
||||
@ -86,7 +107,7 @@ type SCIMUser struct {
|
||||
} `json:"name"`
|
||||
Emails []struct {
|
||||
Primary bool `json:"primary"`
|
||||
Value string `json:"value"`
|
||||
Value string `json:"value" format:"email"`
|
||||
Type string `json:"type"`
|
||||
Display string `json:"display"`
|
||||
} `json:"emails"`
|
||||
@ -98,6 +119,15 @@ type SCIMUser struct {
|
||||
}
|
||||
|
||||
// scimPostUser creates a new user, or returns the existing user if it exists.
|
||||
//
|
||||
// @Summary SCIM 2.0: Create new user
|
||||
// @ID scim-create-new-user
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Param request body coderd.SCIMUser true "New user"
|
||||
// @Success 200 {object} coderd.SCIMUser
|
||||
// @Router /scim/v2/Users [post]
|
||||
func (api *API) scimPostUser(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
if !api.scimVerifyAuthHeader(r) {
|
||||
@ -144,6 +174,16 @@ func (api *API) scimPostUser(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// scimPatchUser supports suspending and activating users only.
|
||||
//
|
||||
// @Summary SCIM 2.0: Update user account
|
||||
// @ID scim-update-user-status
|
||||
// @Security CoderSessionToken
|
||||
// @Produce application/scim+json
|
||||
// @Tags Enterprise
|
||||
// @Param id path string true "User ID" format(uuid)
|
||||
// @Param request body coderd.SCIMUser true "Update user request"
|
||||
// @Success 200 {object} codersdk.User
|
||||
// @Router /scim/v2/Users/{id} [patch]
|
||||
func (api *API) scimPatchUser(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
if !api.scimVerifyAuthHeader(r) {
|
||||
|
@ -34,7 +34,7 @@ func makeScimUser(t testing.TB) coderd.SCIMUser {
|
||||
},
|
||||
Emails: []struct {
|
||||
Primary bool "json:\"primary\""
|
||||
Value string "json:\"value\""
|
||||
Value string "json:\"value\" format:\"email\""
|
||||
Type string "json:\"type\""
|
||||
Display string "json:\"display\""
|
||||
}{
|
||||
|
@ -18,6 +18,14 @@ import (
|
||||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
// @Summary Get template ACLs
|
||||
// @ID get-template-acls
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Param template path string true "Template ID" format(uuid)
|
||||
// @Success 200 {array} codersdk.TemplateUser
|
||||
// @Router /templates/{template}/acl [get]
|
||||
func (api *API) templateACL(rw http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
ctx = r.Context()
|
||||
@ -92,6 +100,15 @@ func (api *API) templateACL(rw http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary Update template ACL
|
||||
// @ID update-template-acl
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Param template path string true "Template ID" format(uuid)
|
||||
// @Param request body codersdk.UpdateTemplateACL true "Update template request"
|
||||
// @Success 200 {object} codersdk.Response
|
||||
// @Router /templates/{template}/acl [patch]
|
||||
func (api *API) patchTemplateACL(rw http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
ctx = r.Context()
|
||||
|
@ -99,6 +99,14 @@ func (c *committer) CommitQuota(
|
||||
}, nil
|
||||
}
|
||||
|
||||
// @Summary Get workspace quota by user
|
||||
// @ID get-workspace-quota-by-user
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Param user path string true "User ID, name, or me"
|
||||
// @Success 200 {object} codersdk.WorkspaceQuota
|
||||
// @Router /workspace-quota/{user} [get]
|
||||
func (api *API) workspaceQuota(rw http.ResponseWriter, r *http.Request) {
|
||||
user := httpmw.UserParam(r)
|
||||
|
||||
|
Reference in New Issue
Block a user