mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: app sharing (now open source!) (#4378)
This commit is contained in:
+38
-18
@@ -13,13 +13,14 @@ import (
|
||||
type APIKey struct {
|
||||
ID string `json:"id" validate:"required"`
|
||||
// NOTE: do not ever return the HashedSecret
|
||||
UserID uuid.UUID `json:"user_id" validate:"required"`
|
||||
LastUsed time.Time `json:"last_used" validate:"required"`
|
||||
ExpiresAt time.Time `json:"expires_at" validate:"required"`
|
||||
CreatedAt time.Time `json:"created_at" validate:"required"`
|
||||
UpdatedAt time.Time `json:"updated_at" validate:"required"`
|
||||
LoginType LoginType `json:"login_type" validate:"required"`
|
||||
LifetimeSeconds int64 `json:"lifetime_seconds" validate:"required"`
|
||||
UserID uuid.UUID `json:"user_id" validate:"required"`
|
||||
LastUsed time.Time `json:"last_used" validate:"required"`
|
||||
ExpiresAt time.Time `json:"expires_at" validate:"required"`
|
||||
CreatedAt time.Time `json:"created_at" validate:"required"`
|
||||
UpdatedAt time.Time `json:"updated_at" validate:"required"`
|
||||
LoginType LoginType `json:"login_type" validate:"required"`
|
||||
Scope APIKeyScope `json:"scope" validate:"required"`
|
||||
LifetimeSeconds int64 `json:"lifetime_seconds" validate:"required"`
|
||||
}
|
||||
|
||||
type LoginType string
|
||||
@@ -31,32 +32,51 @@ const (
|
||||
LoginTypeToken LoginType = "token"
|
||||
)
|
||||
|
||||
type APIKeyScope string
|
||||
|
||||
const (
|
||||
APIKeyScopeAll APIKeyScope = "all"
|
||||
APIKeyScopeApplicationConnect APIKeyScope = "application_connect"
|
||||
)
|
||||
|
||||
type CreateTokenRequest struct {
|
||||
Scope APIKeyScope `json:"scope"`
|
||||
}
|
||||
|
||||
// GenerateAPIKeyResponse contains an API key for a user.
|
||||
type GenerateAPIKeyResponse struct {
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
// CreateToken generates an API key that doesn't expire.
|
||||
func (c *Client) CreateToken(ctx context.Context, userID string) (*GenerateAPIKeyResponse, error) {
|
||||
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/users/%s/keys/tokens", userID), nil)
|
||||
func (c *Client) CreateToken(ctx context.Context, userID string, req CreateTokenRequest) (GenerateAPIKeyResponse, error) {
|
||||
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/users/%s/keys/tokens", userID), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return GenerateAPIKeyResponse{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode > http.StatusCreated {
|
||||
return nil, readBodyAsError(res)
|
||||
return GenerateAPIKeyResponse{}, readBodyAsError(res)
|
||||
}
|
||||
apiKey := &GenerateAPIKeyResponse{}
|
||||
return apiKey, json.NewDecoder(res.Body).Decode(apiKey)
|
||||
|
||||
var apiKey GenerateAPIKeyResponse
|
||||
return apiKey, json.NewDecoder(res.Body).Decode(&apiKey)
|
||||
}
|
||||
|
||||
// CreateAPIKey generates an API key for the user ID provided.
|
||||
func (c *Client) CreateAPIKey(ctx context.Context, user string) (*GenerateAPIKeyResponse, error) {
|
||||
// DEPRECATED: use CreateToken instead.
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return GenerateAPIKeyResponse{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode > http.StatusCreated {
|
||||
return nil, readBodyAsError(res)
|
||||
return GenerateAPIKeyResponse{}, readBodyAsError(res)
|
||||
}
|
||||
apiKey := &GenerateAPIKeyResponse{}
|
||||
return apiKey, json.NewDecoder(res.Body).Decode(apiKey)
|
||||
|
||||
var apiKey GenerateAPIKeyResponse
|
||||
return apiKey, json.NewDecoder(res.Body).Decode(&apiKey)
|
||||
}
|
||||
|
||||
// GetTokens list machine API keys.
|
||||
|
||||
@@ -96,11 +96,6 @@ type LoginWithPasswordResponse struct {
|
||||
SessionToken string `json:"session_token" validate:"required"`
|
||||
}
|
||||
|
||||
// GenerateAPIKeyResponse contains an API key for a user.
|
||||
type GenerateAPIKeyResponse struct {
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
type CreateOrganizationRequest struct {
|
||||
Name string `json:"name" validate:"required,username"`
|
||||
}
|
||||
|
||||
@@ -13,6 +13,14 @@ const (
|
||||
WorkspaceAppHealthUnhealthy WorkspaceAppHealth = "unhealthy"
|
||||
)
|
||||
|
||||
type WorkspaceAppSharingLevel string
|
||||
|
||||
const (
|
||||
WorkspaceAppSharingLevelOwner WorkspaceAppSharingLevel = "owner"
|
||||
WorkspaceAppSharingLevelAuthenticated WorkspaceAppSharingLevel = "authenticated"
|
||||
WorkspaceAppSharingLevelPublic WorkspaceAppSharingLevel = "public"
|
||||
)
|
||||
|
||||
type WorkspaceApp struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
// Name is a unique identifier attached to an agent.
|
||||
@@ -25,7 +33,8 @@ type WorkspaceApp struct {
|
||||
// `coder server` or via a hostname-based dev URL. If this is set to true
|
||||
// and there is no app wildcard configured on the server, the app will not
|
||||
// be accessible in the UI.
|
||||
Subdomain bool `json:"subdomain"`
|
||||
Subdomain bool `json:"subdomain"`
|
||||
SharingLevel WorkspaceAppSharingLevel `json:"sharing_level"`
|
||||
// Healthcheck specifies the configuration for checking app health.
|
||||
Healthcheck Healthcheck `json:"healthcheck"`
|
||||
Health WorkspaceAppHealth `json:"health"`
|
||||
|
||||
Reference in New Issue
Block a user