mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
feat: Rbac more coderd endpoints, unit test to confirm (#1437)
* feat: Enforce authorize call on all endpoints - Make 'request()' exported for running custom requests * Rbac users endpoints * 401 -> 403
This commit is contained in:
@ -18,7 +18,7 @@ type BuildInfoResponse struct {
|
||||
|
||||
// BuildInfo returns build information for this instance of Coder.
|
||||
func (c *Client) BuildInfo(ctx context.Context) (BuildInfoResponse, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, "/api/v2/buildinfo", nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/v2/buildinfo", nil)
|
||||
if err != nil {
|
||||
return BuildInfoResponse{}, err
|
||||
}
|
||||
|
@ -35,9 +35,9 @@ type Client struct {
|
||||
|
||||
type requestOption func(*http.Request)
|
||||
|
||||
// request performs an HTTP request with the body provided.
|
||||
// Request performs an HTTP request with the body provided.
|
||||
// The caller is responsible for closing the response body.
|
||||
func (c *Client) request(ctx context.Context, method, path string, body interface{}, opts ...requestOption) (*http.Response, error) {
|
||||
func (c *Client) Request(ctx context.Context, method, path string, body interface{}, opts ...requestOption) (*http.Response, error) {
|
||||
serverURL, err := c.URL.Parse(path)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("parse url: %w", err)
|
||||
|
@ -20,7 +20,7 @@ type UploadResponse struct {
|
||||
// Upload uploads an arbitrary file with the content type provided.
|
||||
// This is used to upload a source-code archive.
|
||||
func (c *Client) Upload(ctx context.Context, contentType string, content []byte) (UploadResponse, error) {
|
||||
res, err := c.request(ctx, http.MethodPost, "/api/v2/files", content, func(r *http.Request) {
|
||||
res, err := c.Request(ctx, http.MethodPost, "/api/v2/files", content, func(r *http.Request) {
|
||||
r.Header.Set("Content-Type", contentType)
|
||||
})
|
||||
if err != nil {
|
||||
@ -36,7 +36,7 @@ func (c *Client) Upload(ctx context.Context, contentType string, content []byte)
|
||||
|
||||
// Download fetches a file by uploaded hash.
|
||||
func (c *Client) Download(ctx context.Context, hash string) ([]byte, string, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/files/%s", hash), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/files/%s", hash), nil)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ type AgentGitSSHKey struct {
|
||||
|
||||
// GitSSHKey returns the user's git SSH public key.
|
||||
func (c *Client) GitSSHKey(ctx context.Context, user string) (GitSSHKey, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/gitsshkey", user), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/gitsshkey", user), nil)
|
||||
if err != nil {
|
||||
return GitSSHKey{}, xerrors.Errorf("execute request: %w", err)
|
||||
}
|
||||
@ -41,7 +41,7 @@ func (c *Client) GitSSHKey(ctx context.Context, user string) (GitSSHKey, error)
|
||||
|
||||
// RegenerateGitSSHKey will create a new SSH key pair for the user and return it.
|
||||
func (c *Client) RegenerateGitSSHKey(ctx context.Context, user string) (GitSSHKey, error) {
|
||||
res, err := c.request(ctx, http.MethodPut, fmt.Sprintf("/api/v2/users/%s/gitsshkey", user), nil)
|
||||
res, err := c.Request(ctx, http.MethodPut, fmt.Sprintf("/api/v2/users/%s/gitsshkey", user), nil)
|
||||
if err != nil {
|
||||
return GitSSHKey{}, xerrors.Errorf("execute request: %w", err)
|
||||
}
|
||||
@ -57,7 +57,7 @@ func (c *Client) RegenerateGitSSHKey(ctx context.Context, user string) (GitSSHKe
|
||||
|
||||
// AgentGitSSHKey will return the user's SSH key pair for the workspace.
|
||||
func (c *Client) AgentGitSSHKey(ctx context.Context) (AgentGitSSHKey, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, "/api/v2/workspaceagents/me/gitsshkey", nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/v2/workspaceagents/me/gitsshkey", nil)
|
||||
if err != nil {
|
||||
return AgentGitSSHKey{}, xerrors.Errorf("execute request: %w", err)
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ type CreateWorkspaceRequest struct {
|
||||
}
|
||||
|
||||
func (c *Client) Organization(ctx context.Context, id uuid.UUID) (Organization, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s", id.String()), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s", id.String()), nil)
|
||||
if err != nil {
|
||||
return Organization{}, xerrors.Errorf("execute request: %w", err)
|
||||
}
|
||||
@ -78,7 +78,7 @@ func (c *Client) Organization(ctx context.Context, id uuid.UUID) (Organization,
|
||||
|
||||
// ProvisionerDaemonsByOrganization returns provisioner daemons available for an organization.
|
||||
func (c *Client) ProvisionerDaemonsByOrganization(ctx context.Context, organizationID uuid.UUID) ([]ProvisionerDaemon, error) {
|
||||
res, err := c.request(ctx, http.MethodGet,
|
||||
res, err := c.Request(ctx, http.MethodGet,
|
||||
fmt.Sprintf("/api/v2/organizations/%s/provisionerdaemons", organizationID.String()),
|
||||
nil,
|
||||
)
|
||||
@ -98,7 +98,7 @@ func (c *Client) ProvisionerDaemonsByOrganization(ctx context.Context, organizat
|
||||
// CreateTemplateVersion processes source-code and optionally associates the version with a template.
|
||||
// Executing without a template is useful for validating source-code.
|
||||
func (c *Client) CreateTemplateVersion(ctx context.Context, organizationID uuid.UUID, req CreateTemplateVersionRequest) (TemplateVersion, error) {
|
||||
res, err := c.request(ctx, http.MethodPost,
|
||||
res, err := c.Request(ctx, http.MethodPost,
|
||||
fmt.Sprintf("/api/v2/organizations/%s/templateversions", organizationID.String()),
|
||||
req,
|
||||
)
|
||||
@ -117,7 +117,7 @@ func (c *Client) CreateTemplateVersion(ctx context.Context, organizationID uuid.
|
||||
|
||||
// CreateTemplate creates a new template inside an organization.
|
||||
func (c *Client) CreateTemplate(ctx context.Context, organizationID uuid.UUID, request CreateTemplateRequest) (Template, error) {
|
||||
res, err := c.request(ctx, http.MethodPost,
|
||||
res, err := c.Request(ctx, http.MethodPost,
|
||||
fmt.Sprintf("/api/v2/organizations/%s/templates", organizationID.String()),
|
||||
request,
|
||||
)
|
||||
@ -136,7 +136,7 @@ func (c *Client) CreateTemplate(ctx context.Context, organizationID uuid.UUID, r
|
||||
|
||||
// TemplatesByOrganization lists all templates inside of an organization.
|
||||
func (c *Client) TemplatesByOrganization(ctx context.Context, organizationID uuid.UUID) ([]Template, error) {
|
||||
res, err := c.request(ctx, http.MethodGet,
|
||||
res, err := c.Request(ctx, http.MethodGet,
|
||||
fmt.Sprintf("/api/v2/organizations/%s/templates", organizationID.String()),
|
||||
nil,
|
||||
)
|
||||
@ -155,7 +155,7 @@ func (c *Client) TemplatesByOrganization(ctx context.Context, organizationID uui
|
||||
|
||||
// TemplateByName finds a template inside the organization provided with a case-insensitive name.
|
||||
func (c *Client) TemplateByName(ctx context.Context, organizationID uuid.UUID, name string) (Template, error) {
|
||||
res, err := c.request(ctx, http.MethodGet,
|
||||
res, err := c.Request(ctx, http.MethodGet,
|
||||
fmt.Sprintf("/api/v2/organizations/%s/templates/%s", organizationID.String(), name),
|
||||
nil,
|
||||
)
|
||||
@ -174,7 +174,7 @@ func (c *Client) TemplateByName(ctx context.Context, organizationID uuid.UUID, n
|
||||
|
||||
// CreateWorkspace creates a new workspace for the template specified.
|
||||
func (c *Client) CreateWorkspace(ctx context.Context, organizationID uuid.UUID, request CreateWorkspaceRequest) (Workspace, error) {
|
||||
res, err := c.request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/organizations/%s/workspaces", organizationID), request)
|
||||
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/organizations/%s/workspaces", organizationID), request)
|
||||
if err != nil {
|
||||
return Workspace{}, err
|
||||
}
|
||||
@ -190,7 +190,7 @@ func (c *Client) CreateWorkspace(ctx context.Context, organizationID uuid.UUID,
|
||||
|
||||
// WorkspacesByOrganization returns all workspaces in the specified organization.
|
||||
func (c *Client) WorkspacesByOrganization(ctx context.Context, organizationID uuid.UUID) ([]Workspace, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/workspaces", organizationID), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/workspaces", organizationID), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -206,7 +206,7 @@ func (c *Client) WorkspacesByOrganization(ctx context.Context, organizationID uu
|
||||
|
||||
// WorkspacesByOwner returns all workspaces contained in the organization owned by the user.
|
||||
func (c *Client) WorkspacesByOwner(ctx context.Context, organizationID uuid.UUID, user string) ([]Workspace, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/workspaces/%s", organizationID, user), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/workspaces/%s", organizationID, user), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -222,7 +222,7 @@ func (c *Client) WorkspacesByOwner(ctx context.Context, organizationID uuid.UUID
|
||||
|
||||
// WorkspaceByOwnerAndName returns a workspace by the owner's UUID and the workspace's name.
|
||||
func (c *Client) WorkspaceByOwnerAndName(ctx context.Context, organization uuid.UUID, owner string, name string) (Workspace, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/workspaces/%s/%s", organization, owner, name), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/workspaces/%s/%s", organization, owner, name), nil)
|
||||
if err != nil {
|
||||
return Workspace{}, err
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ type Pagination struct {
|
||||
Offset int `json:"offset,omitempty"`
|
||||
}
|
||||
|
||||
// asRequestOption returns a function that can be used in (*Client).request.
|
||||
// asRequestOption returns a function that can be used in (*Client).Request.
|
||||
// It modifies the request query parameters.
|
||||
func (p Pagination) asRequestOption() requestOption {
|
||||
return func(r *http.Request) {
|
||||
|
@ -43,7 +43,7 @@ type CreateParameterRequest struct {
|
||||
}
|
||||
|
||||
func (c *Client) CreateParameter(ctx context.Context, scope ParameterScope, id uuid.UUID, req CreateParameterRequest) (Parameter, error) {
|
||||
res, err := c.request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/parameters/%s/%s", scope, id.String()), req)
|
||||
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/parameters/%s/%s", scope, id.String()), req)
|
||||
if err != nil {
|
||||
return Parameter{}, err
|
||||
}
|
||||
@ -58,7 +58,7 @@ func (c *Client) CreateParameter(ctx context.Context, scope ParameterScope, id u
|
||||
}
|
||||
|
||||
func (c *Client) DeleteParameter(ctx context.Context, scope ParameterScope, id uuid.UUID, name string) error {
|
||||
res, err := c.request(ctx, http.MethodDelete, fmt.Sprintf("/api/v2/parameters/%s/%s/%s", scope, id.String(), name), nil)
|
||||
res, err := c.Request(ctx, http.MethodDelete, fmt.Sprintf("/api/v2/parameters/%s/%s/%s", scope, id.String(), name), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -73,7 +73,7 @@ func (c *Client) DeleteParameter(ctx context.Context, scope ParameterScope, id u
|
||||
}
|
||||
|
||||
func (c *Client) Parameters(ctx context.Context, scope ParameterScope, id uuid.UUID) ([]Parameter, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/parameters/%s/%s", scope, id.String()), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/parameters/%s/%s", scope, id.String()), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ func (c *Client) provisionerJobLogsBefore(ctx context.Context, path string, befo
|
||||
if !before.IsZero() {
|
||||
values["before"] = []string{strconv.FormatInt(before.UTC().UnixMilli(), 10)}
|
||||
}
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("%s?%s", path, values.Encode()), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("%s?%s", path, values.Encode()), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -118,7 +118,7 @@ func (c *Client) provisionerJobLogsAfter(ctx context.Context, path string, after
|
||||
if !after.IsZero() {
|
||||
afterQuery = fmt.Sprintf("&after=%d", after.UTC().UnixMilli())
|
||||
}
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("%s?follow%s", path, afterQuery), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("%s?follow%s", path, afterQuery), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ type Role struct {
|
||||
// ListSiteRoles lists all available site wide roles.
|
||||
// This is not user specific.
|
||||
func (c *Client) ListSiteRoles(ctx context.Context) ([]Role, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, "/api/v2/users/roles", nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/v2/users/roles", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -32,7 +32,7 @@ func (c *Client) ListSiteRoles(ctx context.Context) ([]Role, error) {
|
||||
// ListOrganizationRoles lists all available roles for a given organization.
|
||||
// This is not user specific.
|
||||
func (c *Client) ListOrganizationRoles(ctx context.Context, org uuid.UUID) ([]Role, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/members/roles/", org.String()), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/members/roles", org.String()), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -45,7 +45,7 @@ func (c *Client) ListOrganizationRoles(ctx context.Context, org uuid.UUID) ([]Ro
|
||||
}
|
||||
|
||||
func (c *Client) CheckPermissions(ctx context.Context, checks UserAuthorizationRequest) (UserAuthorizationResponse, error) {
|
||||
res, err := c.request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/users/%s/authorization", Me), checks)
|
||||
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/users/%s/authorization", Me), checks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ type UpdateActiveTemplateVersion struct {
|
||||
|
||||
// Template returns a single template.
|
||||
func (c *Client) Template(ctx context.Context, template uuid.UUID) (Template, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templates/%s", template), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templates/%s", template), nil)
|
||||
if err != nil {
|
||||
return Template{}, nil
|
||||
}
|
||||
@ -45,7 +45,7 @@ func (c *Client) Template(ctx context.Context, template uuid.UUID) (Template, er
|
||||
}
|
||||
|
||||
func (c *Client) DeleteTemplate(ctx context.Context, template uuid.UUID) error {
|
||||
res, err := c.request(ctx, http.MethodDelete, fmt.Sprintf("/api/v2/templates/%s", template), nil)
|
||||
res, err := c.Request(ctx, http.MethodDelete, fmt.Sprintf("/api/v2/templates/%s", template), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -59,7 +59,7 @@ func (c *Client) DeleteTemplate(ctx context.Context, template uuid.UUID) error {
|
||||
// UpdateActiveTemplateVersion updates the active template version to the ID provided.
|
||||
// The template version must be attached to the template.
|
||||
func (c *Client) UpdateActiveTemplateVersion(ctx context.Context, template uuid.UUID, req UpdateActiveTemplateVersion) error {
|
||||
res, err := c.request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/templates/%s/versions", template), req)
|
||||
res, err := c.Request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/templates/%s/versions", template), req)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -79,7 +79,7 @@ type TemplateVersionsByTemplateRequest struct {
|
||||
|
||||
// TemplateVersionsByTemplate lists versions associated with a template.
|
||||
func (c *Client) TemplateVersionsByTemplate(ctx context.Context, req TemplateVersionsByTemplateRequest) ([]TemplateVersion, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templates/%s/versions", req.TemplateID), nil, req.Pagination.asRequestOption())
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templates/%s/versions", req.TemplateID), nil, req.Pagination.asRequestOption())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -94,7 +94,7 @@ func (c *Client) TemplateVersionsByTemplate(ctx context.Context, req TemplateVer
|
||||
// TemplateVersionByName returns a template version by it's friendly name.
|
||||
// This is used for path-based routing. Like: /templates/example/versions/helloworld
|
||||
func (c *Client) TemplateVersionByName(ctx context.Context, template uuid.UUID, name string) (TemplateVersion, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templates/%s/versions/%s", template, name), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templates/%s/versions/%s", template, name), nil)
|
||||
if err != nil {
|
||||
return TemplateVersion{}, err
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ type TemplateVersionParameter parameter.ComputedValue
|
||||
|
||||
// TemplateVersion returns a template version by ID.
|
||||
func (c *Client) TemplateVersion(ctx context.Context, id uuid.UUID) (TemplateVersion, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s", id), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s", id), nil)
|
||||
if err != nil {
|
||||
return TemplateVersion{}, err
|
||||
}
|
||||
@ -45,7 +45,7 @@ func (c *Client) TemplateVersion(ctx context.Context, id uuid.UUID) (TemplateVer
|
||||
|
||||
// CancelTemplateVersion marks a template version job as canceled.
|
||||
func (c *Client) CancelTemplateVersion(ctx context.Context, version uuid.UUID) error {
|
||||
res, err := c.request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/templateversions/%s/cancel", version), nil)
|
||||
res, err := c.Request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/templateversions/%s/cancel", version), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -58,7 +58,7 @@ func (c *Client) CancelTemplateVersion(ctx context.Context, version uuid.UUID) e
|
||||
|
||||
// TemplateVersionSchema returns schemas for a template version by ID.
|
||||
func (c *Client) TemplateVersionSchema(ctx context.Context, version uuid.UUID) ([]TemplateVersionParameterSchema, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/schema", version), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/schema", version), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -72,7 +72,7 @@ func (c *Client) TemplateVersionSchema(ctx context.Context, version uuid.UUID) (
|
||||
|
||||
// TemplateVersionParameters returns computed parameters for a template version.
|
||||
func (c *Client) TemplateVersionParameters(ctx context.Context, version uuid.UUID) ([]TemplateVersionParameter, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/parameters", version), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/parameters", version), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -86,7 +86,7 @@ func (c *Client) TemplateVersionParameters(ctx context.Context, version uuid.UUI
|
||||
|
||||
// TemplateVersionResources returns resources a template version declares.
|
||||
func (c *Client) TemplateVersionResources(ctx context.Context, version uuid.UUID) ([]WorkspaceResource, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/resources", version), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/resources", version), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ type AuthMethods struct {
|
||||
|
||||
// HasFirstUser returns whether the first user has been created.
|
||||
func (c *Client) HasFirstUser(ctx context.Context) (bool, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, "/api/v2/users/first", nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/v2/users/first", nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@ -172,7 +172,7 @@ func (c *Client) HasFirstUser(ctx context.Context) (bool, error) {
|
||||
// CreateFirstUser attempts to create the first user on a Coder deployment.
|
||||
// This initial user has superadmin privileges. If >0 users exist, this request will fail.
|
||||
func (c *Client) CreateFirstUser(ctx context.Context, req CreateFirstUserRequest) (CreateFirstUserResponse, error) {
|
||||
res, err := c.request(ctx, http.MethodPost, "/api/v2/users/first", req)
|
||||
res, err := c.Request(ctx, http.MethodPost, "/api/v2/users/first", req)
|
||||
if err != nil {
|
||||
return CreateFirstUserResponse{}, err
|
||||
}
|
||||
@ -186,7 +186,7 @@ func (c *Client) CreateFirstUser(ctx context.Context, req CreateFirstUserRequest
|
||||
|
||||
// CreateUser creates a new user.
|
||||
func (c *Client) CreateUser(ctx context.Context, req CreateUserRequest) (User, error) {
|
||||
res, err := c.request(ctx, http.MethodPost, "/api/v2/users", req)
|
||||
res, err := c.Request(ctx, http.MethodPost, "/api/v2/users", req)
|
||||
if err != nil {
|
||||
return User{}, err
|
||||
}
|
||||
@ -200,7 +200,7 @@ func (c *Client) CreateUser(ctx context.Context, req CreateUserRequest) (User, e
|
||||
|
||||
// UpdateUserProfile enables callers to update profile information
|
||||
func (c *Client) UpdateUserProfile(ctx context.Context, user string, req UpdateUserProfileRequest) (User, error) {
|
||||
res, err := c.request(ctx, http.MethodPut, fmt.Sprintf("/api/v2/users/%s/profile", user), req)
|
||||
res, err := c.Request(ctx, http.MethodPut, fmt.Sprintf("/api/v2/users/%s/profile", user), req)
|
||||
if err != nil {
|
||||
return User{}, err
|
||||
}
|
||||
@ -224,7 +224,7 @@ func (c *Client) UpdateUserStatus(ctx context.Context, user string, status UserS
|
||||
return User{}, xerrors.Errorf("status %q is not supported", status)
|
||||
}
|
||||
|
||||
res, err := c.request(ctx, http.MethodPut, path, nil)
|
||||
res, err := c.Request(ctx, http.MethodPut, path, nil)
|
||||
if err != nil {
|
||||
return User{}, err
|
||||
}
|
||||
@ -240,7 +240,7 @@ func (c *Client) UpdateUserStatus(ctx context.Context, user string, status UserS
|
||||
// UpdateUserPassword updates a user password.
|
||||
// It calls PUT /users/{user}/password
|
||||
func (c *Client) UpdateUserPassword(ctx context.Context, user string, req UpdateUserPasswordRequest) error {
|
||||
res, err := c.request(ctx, http.MethodPut, fmt.Sprintf("/api/v2/users/%s/password", user), req)
|
||||
res, err := c.Request(ctx, http.MethodPut, fmt.Sprintf("/api/v2/users/%s/password", user), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -254,7 +254,7 @@ func (c *Client) UpdateUserPassword(ctx context.Context, user string, req Update
|
||||
// UpdateUserRoles grants the userID the specified roles.
|
||||
// Include ALL roles the user has.
|
||||
func (c *Client) UpdateUserRoles(ctx context.Context, user string, req UpdateRoles) (User, error) {
|
||||
res, err := c.request(ctx, http.MethodPut, fmt.Sprintf("/api/v2/users/%s/roles", user), req)
|
||||
res, err := c.Request(ctx, http.MethodPut, fmt.Sprintf("/api/v2/users/%s/roles", user), req)
|
||||
if err != nil {
|
||||
return User{}, err
|
||||
}
|
||||
@ -269,7 +269,7 @@ func (c *Client) UpdateUserRoles(ctx context.Context, user string, req UpdateRol
|
||||
// UpdateOrganizationMemberRoles grants the userID the specified roles in an org.
|
||||
// Include ALL roles the user has.
|
||||
func (c *Client) UpdateOrganizationMemberRoles(ctx context.Context, organizationID uuid.UUID, user string, req UpdateRoles) (OrganizationMember, error) {
|
||||
res, err := c.request(ctx, http.MethodPut, fmt.Sprintf("/api/v2/organizations/%s/members/%s/roles", organizationID, user), req)
|
||||
res, err := c.Request(ctx, http.MethodPut, fmt.Sprintf("/api/v2/organizations/%s/members/%s/roles", organizationID, user), req)
|
||||
if err != nil {
|
||||
return OrganizationMember{}, err
|
||||
}
|
||||
@ -283,7 +283,7 @@ func (c *Client) UpdateOrganizationMemberRoles(ctx context.Context, organization
|
||||
|
||||
// GetUserRoles returns all roles the user has
|
||||
func (c *Client) GetUserRoles(ctx context.Context, user string) (UserRoles, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/roles", user), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/roles", user), nil)
|
||||
if err != nil {
|
||||
return UserRoles{}, err
|
||||
}
|
||||
@ -297,7 +297,7 @@ func (c *Client) GetUserRoles(ctx context.Context, user string) (UserRoles, erro
|
||||
|
||||
// CreateAPIKey generates an API key for the user ID provided.
|
||||
func (c *Client) CreateAPIKey(ctx context.Context, user string) (*GenerateAPIKeyResponse, error) {
|
||||
res, err := c.request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/users/%s/keys", user), nil)
|
||||
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/users/%s/keys", user), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -312,7 +312,7 @@ func (c *Client) CreateAPIKey(ctx context.Context, user string) (*GenerateAPIKey
|
||||
// LoginWithPassword creates a session token authenticating with an email and password.
|
||||
// Call `SetSessionToken()` to apply the newly acquired token to the client.
|
||||
func (c *Client) LoginWithPassword(ctx context.Context, req LoginWithPasswordRequest) (LoginWithPasswordResponse, error) {
|
||||
res, err := c.request(ctx, http.MethodPost, "/api/v2/users/login", req)
|
||||
res, err := c.Request(ctx, http.MethodPost, "/api/v2/users/login", req)
|
||||
if err != nil {
|
||||
return LoginWithPasswordResponse{}, err
|
||||
}
|
||||
@ -333,7 +333,7 @@ func (c *Client) LoginWithPassword(ctx context.Context, req LoginWithPasswordReq
|
||||
func (c *Client) Logout(ctx context.Context) error {
|
||||
// Since `LoginWithPassword` doesn't actually set a SessionToken
|
||||
// (it requires a call to SetSessionToken), this is essentially a no-op
|
||||
res, err := c.request(ctx, http.MethodPost, "/api/v2/users/logout", nil)
|
||||
res, err := c.Request(ctx, http.MethodPost, "/api/v2/users/logout", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -343,7 +343,7 @@ func (c *Client) Logout(ctx context.Context) error {
|
||||
|
||||
// User returns a user for the ID/username provided.
|
||||
func (c *Client) User(ctx context.Context, userIdent string) (User, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s", userIdent), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s", userIdent), nil)
|
||||
if err != nil {
|
||||
return User{}, err
|
||||
}
|
||||
@ -358,7 +358,7 @@ func (c *Client) User(ctx context.Context, userIdent string) (User, error) {
|
||||
// Users returns all users according to the request parameters. If no parameters are set,
|
||||
// the default behavior is to return all users in a single page.
|
||||
func (c *Client) Users(ctx context.Context, req UsersRequest) ([]User, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, "/api/v2/users", nil,
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/v2/users", nil,
|
||||
req.Pagination.asRequestOption(),
|
||||
func(r *http.Request) {
|
||||
q := r.URL.Query()
|
||||
@ -382,7 +382,7 @@ func (c *Client) Users(ctx context.Context, req UsersRequest) ([]User, error) {
|
||||
|
||||
// OrganizationsByUser returns all organizations the user is a member of.
|
||||
func (c *Client) OrganizationsByUser(ctx context.Context, user string) ([]Organization, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/organizations", user), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/organizations", user), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -395,7 +395,7 @@ func (c *Client) OrganizationsByUser(ctx context.Context, user string) ([]Organi
|
||||
}
|
||||
|
||||
func (c *Client) OrganizationByName(ctx context.Context, user string, name string) (Organization, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/organizations/%s", user, name), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/organizations/%s", user, name), nil)
|
||||
if err != nil {
|
||||
return Organization{}, err
|
||||
}
|
||||
@ -409,7 +409,7 @@ func (c *Client) OrganizationByName(ctx context.Context, user string, name strin
|
||||
|
||||
// CreateOrganization creates an organization and adds the provided user as an admin.
|
||||
func (c *Client) CreateOrganization(ctx context.Context, user string, req CreateOrganizationRequest) (Organization, error) {
|
||||
res, err := c.request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/users/%s/organizations", user), req)
|
||||
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/users/%s/organizations", user), req)
|
||||
if err != nil {
|
||||
return Organization{}, err
|
||||
}
|
||||
@ -425,7 +425,7 @@ func (c *Client) CreateOrganization(ctx context.Context, user string, req Create
|
||||
|
||||
// AuthMethods returns types of authentication available to the user.
|
||||
func (c *Client) AuthMethods(ctx context.Context) (AuthMethods, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, "/api/v2/users/authmethods", nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/v2/users/authmethods", nil)
|
||||
if err != nil {
|
||||
return AuthMethods{}, err
|
||||
}
|
||||
@ -441,7 +441,7 @@ func (c *Client) AuthMethods(ctx context.Context) (AuthMethods, error) {
|
||||
|
||||
// WorkspacesByUser returns all workspaces a user has access to.
|
||||
func (c *Client) WorkspacesByUser(ctx context.Context, user string) ([]Workspace, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/workspaces", user), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/workspaces", user), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ func (c *Client) AuthWorkspaceGoogleInstanceIdentity(ctx context.Context, servic
|
||||
if err != nil {
|
||||
return WorkspaceAgentAuthenticateResponse{}, xerrors.Errorf("get metadata identity: %w", err)
|
||||
}
|
||||
res, err := c.request(ctx, http.MethodPost, "/api/v2/workspaceagents/google-instance-identity", GoogleInstanceIdentityToken{
|
||||
res, err := c.Request(ctx, http.MethodPost, "/api/v2/workspaceagents/google-instance-identity", GoogleInstanceIdentityToken{
|
||||
JSONWebToken: jwt,
|
||||
})
|
||||
if err != nil {
|
||||
@ -129,7 +129,7 @@ func (c *Client) AuthWorkspaceAWSInstanceIdentity(ctx context.Context) (Workspac
|
||||
return WorkspaceAgentAuthenticateResponse{}, xerrors.Errorf("read token: %w", err)
|
||||
}
|
||||
|
||||
res, err = c.request(ctx, http.MethodPost, "/api/v2/workspaceagents/aws-instance-identity", AWSInstanceIdentityToken{
|
||||
res, err = c.Request(ctx, http.MethodPost, "/api/v2/workspaceagents/aws-instance-identity", AWSInstanceIdentityToken{
|
||||
Signature: string(signature),
|
||||
Document: string(document),
|
||||
})
|
||||
@ -164,7 +164,7 @@ func (c *Client) AuthWorkspaceAzureInstanceIdentity(ctx context.Context) (Worksp
|
||||
return WorkspaceAgentAuthenticateResponse{}, err
|
||||
}
|
||||
|
||||
res, err = c.request(ctx, http.MethodPost, "/api/v2/workspaceagents/azure-instance-identity", token)
|
||||
res, err = c.Request(ctx, http.MethodPost, "/api/v2/workspaceagents/azure-instance-identity", token)
|
||||
if err != nil {
|
||||
return WorkspaceAgentAuthenticateResponse{}, err
|
||||
}
|
||||
@ -213,7 +213,7 @@ func (c *Client) ListenWorkspaceAgent(ctx context.Context, logger slog.Logger) (
|
||||
}
|
||||
listener, err := peerbroker.Listen(session, func(ctx context.Context) ([]webrtc.ICEServer, *peer.ConnOptions, error) {
|
||||
// This can be cached if it adds to latency too much.
|
||||
res, err := c.request(ctx, http.MethodGet, "/api/v2/workspaceagents/me/iceservers", nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/v2/workspaceagents/me/iceservers", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -240,7 +240,7 @@ func (c *Client) ListenWorkspaceAgent(ctx context.Context, logger slog.Logger) (
|
||||
if err != nil {
|
||||
return agent.Metadata{}, nil, xerrors.Errorf("listen peerbroker: %w", err)
|
||||
}
|
||||
res, err = c.request(ctx, http.MethodGet, "/api/v2/workspaceagents/me/metadata", nil)
|
||||
res, err = c.Request(ctx, http.MethodGet, "/api/v2/workspaceagents/me/metadata", nil)
|
||||
if err != nil {
|
||||
return agent.Metadata{}, nil, err
|
||||
}
|
||||
@ -292,7 +292,7 @@ func (c *Client) DialWorkspaceAgent(ctx context.Context, agentID uuid.UUID, opti
|
||||
return nil, xerrors.Errorf("negotiate connection: %w", err)
|
||||
}
|
||||
|
||||
res, err = c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaceagents/%s/iceservers", agentID.String()), nil)
|
||||
res, err = c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaceagents/%s/iceservers", agentID.String()), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -326,7 +326,7 @@ func (c *Client) DialWorkspaceAgent(ctx context.Context, agentID uuid.UUID, opti
|
||||
|
||||
// WorkspaceAgent returns an agent by ID.
|
||||
func (c *Client) WorkspaceAgent(ctx context.Context, id uuid.UUID) (WorkspaceAgent, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaceagents/%s", id), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaceagents/%s", id), nil)
|
||||
if err != nil {
|
||||
return WorkspaceAgent{}, err
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ type WorkspaceBuild struct {
|
||||
// WorkspaceBuild returns a single workspace build for a workspace.
|
||||
// If history is "", the latest version is returned.
|
||||
func (c *Client) WorkspaceBuild(ctx context.Context, id uuid.UUID) (WorkspaceBuild, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspacebuilds/%s", id), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspacebuilds/%s", id), nil)
|
||||
if err != nil {
|
||||
return WorkspaceBuild{}, err
|
||||
}
|
||||
@ -46,7 +46,7 @@ func (c *Client) WorkspaceBuild(ctx context.Context, id uuid.UUID) (WorkspaceBui
|
||||
|
||||
// CancelWorkspaceBuild marks a workspace build job as canceled.
|
||||
func (c *Client) CancelWorkspaceBuild(ctx context.Context, id uuid.UUID) error {
|
||||
res, err := c.request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/workspacebuilds/%s/cancel", id), nil)
|
||||
res, err := c.Request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/workspacebuilds/%s/cancel", id), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -59,7 +59,7 @@ func (c *Client) CancelWorkspaceBuild(ctx context.Context, id uuid.UUID) error {
|
||||
|
||||
// WorkspaceResourcesByBuild returns resources for a workspace build.
|
||||
func (c *Client) WorkspaceResourcesByBuild(ctx context.Context, build uuid.UUID) ([]WorkspaceResource, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspacebuilds/%s/resources", build), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspacebuilds/%s/resources", build), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -83,7 +83,7 @@ func (c *Client) WorkspaceBuildLogsAfter(ctx context.Context, build uuid.UUID, a
|
||||
|
||||
// WorkspaceBuildState returns the provisioner state of the build.
|
||||
func (c *Client) WorkspaceBuildState(ctx context.Context, build uuid.UUID) ([]byte, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspacebuilds/%s/state", build), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspacebuilds/%s/state", build), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ type WorkspaceAgentInstanceMetadata struct {
|
||||
}
|
||||
|
||||
func (c *Client) WorkspaceResource(ctx context.Context, id uuid.UUID) (WorkspaceResource, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaceresources/%s", id), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaceresources/%s", id), nil)
|
||||
if err != nil {
|
||||
return WorkspaceResource{}, err
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ type CreateWorkspaceBuildRequest struct {
|
||||
|
||||
// Workspace returns a single workspace.
|
||||
func (c *Client) Workspace(ctx context.Context, id uuid.UUID) (Workspace, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s", id), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s", id), nil)
|
||||
if err != nil {
|
||||
return Workspace{}, err
|
||||
}
|
||||
@ -53,7 +53,7 @@ func (c *Client) Workspace(ctx context.Context, id uuid.UUID) (Workspace, error)
|
||||
}
|
||||
|
||||
func (c *Client) WorkspaceBuilds(ctx context.Context, workspace uuid.UUID) ([]WorkspaceBuild, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s/builds", workspace), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s/builds", workspace), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -67,7 +67,7 @@ func (c *Client) WorkspaceBuilds(ctx context.Context, workspace uuid.UUID) ([]Wo
|
||||
|
||||
// CreateWorkspaceBuild queues a new build to occur for a workspace.
|
||||
func (c *Client) CreateWorkspaceBuild(ctx context.Context, workspace uuid.UUID, request CreateWorkspaceBuildRequest) (WorkspaceBuild, error) {
|
||||
res, err := c.request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/workspaces/%s/builds", workspace), request)
|
||||
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/workspaces/%s/builds", workspace), request)
|
||||
if err != nil {
|
||||
return WorkspaceBuild{}, err
|
||||
}
|
||||
@ -80,7 +80,7 @@ func (c *Client) CreateWorkspaceBuild(ctx context.Context, workspace uuid.UUID,
|
||||
}
|
||||
|
||||
func (c *Client) WorkspaceBuildByName(ctx context.Context, workspace uuid.UUID, name string) (WorkspaceBuild, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s/builds/%s", workspace, name), nil)
|
||||
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s/builds/%s", workspace, name), nil)
|
||||
if err != nil {
|
||||
return WorkspaceBuild{}, err
|
||||
}
|
||||
@ -101,7 +101,7 @@ type UpdateWorkspaceAutostartRequest struct {
|
||||
// If the provided schedule is empty, autostart is disabled for the workspace.
|
||||
func (c *Client) UpdateWorkspaceAutostart(ctx context.Context, id uuid.UUID, req UpdateWorkspaceAutostartRequest) error {
|
||||
path := fmt.Sprintf("/api/v2/workspaces/%s/autostart", id.String())
|
||||
res, err := c.request(ctx, http.MethodPut, path, req)
|
||||
res, err := c.Request(ctx, http.MethodPut, path, req)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("update workspace autostart: %w", err)
|
||||
}
|
||||
@ -121,7 +121,7 @@ type UpdateWorkspaceAutostopRequest struct {
|
||||
// If the provided schedule is empty, autostop is disabled for the workspace.
|
||||
func (c *Client) UpdateWorkspaceAutostop(ctx context.Context, id uuid.UUID, req UpdateWorkspaceAutostopRequest) error {
|
||||
path := fmt.Sprintf("/api/v2/workspaces/%s/autostop", id.String())
|
||||
res, err := c.request(ctx, http.MethodPut, path, req)
|
||||
res, err := c.Request(ctx, http.MethodPut, path, req)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("update workspace autostop: %w", err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user