diff --git a/internal/http/controllers/v1/management/apikeys.go b/internal/http/controllers/v1/management/apikeys.go new file mode 100644 index 00000000..1744bbc1 --- /dev/null +++ b/internal/http/controllers/v1/management/apikeys.go @@ -0,0 +1,165 @@ +package v1 + +import ( + "errors" + "net/http" + + "github.com/google/uuid" + "github.com/jmoiron/sqlx" + "github.com/lunogram/platform/internal/http/controllers/v1/management/oapi" + "github.com/lunogram/platform/internal/http/json" + "github.com/lunogram/platform/internal/http/problem" + "github.com/lunogram/platform/internal/store" + "github.com/lunogram/platform/internal/store/management" + "go.uber.org/zap" +) + +func NewApiKeysController(logger *zap.Logger, db *sqlx.DB) *ApiKeysController { + return &ApiKeysController{ + logger: logger, + db: db, + store: management.NewState(db), + } +} + +type ApiKeysController struct { + logger *zap.Logger + db *sqlx.DB + store *management.State +} + +func (srv *ApiKeysController) CreateApiKey(w http.ResponseWriter, r *http.Request, projectID uuid.UUID) { + ctx := r.Context() + body := oapi.CreateApiKeyJSONRequestBody{} + err := json.Decode(r.Body, &body) + if err != nil { + oapi.WriteProblem(w, err) + return + } + + logger := srv.logger.With(zap.Stringer("project_id", projectID), zap.String("name", body.Name)) + logger.Info("creating API key") + + // Set default role if not provided + role := "support" + if body.Role != nil { + role = string(*body.Role) + } + + apiKey, err := srv.store.ApiKeysStore.CreateApiKey(ctx, projectID, body.Name, string(body.Scope), role, body.Description) + if err != nil { + logger.Error("failed to create API key", zap.Error(err)) + oapi.WriteProblem(w, err) + return + } + + logger.Info("API key created", zap.Stringer("key_id", apiKey.ID)) + json.Write(w, http.StatusCreated, apiKey.OAPI()) +} + +func (srv *ApiKeysController) ListApiKeys(w http.ResponseWriter, r *http.Request, projectID uuid.UUID, params oapi.ListApiKeysParams) { + ctx := r.Context() + logger := srv.logger.With(zap.Stringer("project_id", projectID)) + logger.Info("listing API keys") + + pagination := store.Pagination{ + Limit: params.Limit.ToInt(), + Offset: params.Offset.ToInt(), + } + + result, total, err := srv.store.ApiKeysStore.ListApiKeys(ctx, projectID, pagination) + if err != nil { + logger.Error("failed to list API keys", zap.Error(err)) + oapi.WriteProblem(w, err) + return + } + + logger.Info("listed API keys", zap.Int("count", len(result))) + json.Write(w, http.StatusOK, oapi.ApiKeyListResponse{ + Total: total, + Limit: pagination.Limit, + Offset: pagination.Offset, + Results: result.OAPI(), + }) +} + +func (srv *ApiKeysController) GetApiKey(w http.ResponseWriter, r *http.Request, projectID uuid.UUID, keyID uuid.UUID) { + ctx := r.Context() + logger := srv.logger.With(zap.Stringer("project_id", projectID), zap.Stringer("key_id", keyID)) + logger.Info("getting API key") + + apiKey, err := srv.store.ApiKeysStore.GetApiKey(ctx, projectID, keyID) + if errors.Is(err, store.ErrNoRows) { + logger.Info("API key not found", zap.Stringer("key_id", keyID)) + oapi.WriteProblem(w, problem.ErrNotFound(problem.Describe("API key not found"))) + return + } + + if err != nil { + logger.Error("failed to fetch API key", zap.Error(err)) + oapi.WriteProblem(w, err) + return + } + + logger.Info("API key retrieved") + json.Write(w, http.StatusOK, apiKey.OAPI()) +} + +func (srv *ApiKeysController) UpdateApiKey(w http.ResponseWriter, r *http.Request, projectID uuid.UUID, keyID uuid.UUID) { + logger := srv.logger.With(zap.Stringer("project_id", projectID), zap.Stringer("key_id", keyID)) + logger.Info("updating API key") + + ctx := r.Context() + body := oapi.UpdateApiKeyJSONRequestBody{} + err := json.Decode(r.Body, &body) + if err != nil { + oapi.WriteProblem(w, err) + return + } + + // Convert role to string pointer if provided + var role *string + if body.Role != nil { + roleStr := string(*body.Role) + role = &roleStr + } + + err = srv.store.ApiKeysStore.UpdateApiKey(ctx, projectID, keyID, body.Name, role, body.Description) + if err != nil { + logger.Error("failed to update API key", zap.Error(err)) + oapi.WriteProblem(w, err) + return + } + + apiKey, err := srv.store.ApiKeysStore.GetApiKey(ctx, projectID, keyID) + if errors.Is(err, store.ErrNoRows) { + logger.Info("API key not found", zap.Stringer("key_id", keyID)) + oapi.WriteProblem(w, problem.ErrNotFound(problem.Describe("API key not found"))) + return + } + + if err != nil { + logger.Error("failed to fetch updated API key", zap.Error(err)) + oapi.WriteProblem(w, err) + return + } + + logger.Info("API key updated") + json.Write(w, http.StatusOK, apiKey.OAPI()) +} + +func (srv *ApiKeysController) DeleteApiKey(w http.ResponseWriter, r *http.Request, projectID uuid.UUID, keyID uuid.UUID) { + ctx := r.Context() + logger := srv.logger.With(zap.Stringer("project_id", projectID), zap.Stringer("key_id", keyID)) + logger.Info("deleting API key") + + err := srv.store.ApiKeysStore.DeleteApiKey(ctx, projectID, keyID) + if err != nil { + logger.Error("failed to delete API key", zap.Error(err)) + oapi.WriteProblem(w, err) + return + } + + logger.Info("API key deleted") + w.WriteHeader(http.StatusNoContent) +} diff --git a/internal/http/controllers/v1/management/controller.go b/internal/http/controllers/v1/management/controller.go index 02969d09..4f619a93 100644 --- a/internal/http/controllers/v1/management/controller.go +++ b/internal/http/controllers/v1/management/controller.go @@ -25,6 +25,7 @@ func NewController(logger *zap.Logger, db *sqlx.DB, cfg config.Node, storage sto DocumentsController: NewDocumentsController(logger, db, storage, cfg.Storage.MaxUploadSize), ProvidersController: NewProvidersController(logger, db, registry), SubscriptionsController: NewSubscriptionsController(logger, db), + ApiKeysController: NewApiKeysController(logger, db), } controller.AuthController, err = NewAuthController(logger, db, cfg) @@ -51,4 +52,5 @@ type Controller struct { *ProvidersController *SubscriptionsController *AuthController + *ApiKeysController } diff --git a/internal/http/controllers/v1/management/oapi/resources.yml b/internal/http/controllers/v1/management/oapi/resources.yml index 4a785161..354a81db 100644 --- a/internal/http/controllers/v1/management/oapi/resources.yml +++ b/internal/http/controllers/v1/management/oapi/resources.yml @@ -2555,6 +2555,165 @@ paths: default: $ref: "#/components/responses/Error" + /api/admin/projects/{projectID}/keys: + get: + summary: List API keys + description: Retrieves a paginated list of API keys for a project + operationId: listApiKeys + tags: + - API Keys + security: + - HttpBearerAuth: [] + parameters: + - name: projectID + in: path + required: true + schema: + type: string + format: uuid + description: The project ID + - $ref: "#/components/parameters/Limit" + - $ref: "#/components/parameters/Offset" + responses: + "200": + $ref: "#/components/responses/ApiKeyListResponse" + default: + $ref: "#/components/responses/Error" + + post: + summary: Create API key + description: Creates a new API key for a project + operationId: createApiKey + tags: + - API Keys + security: + - HttpBearerAuth: [] + parameters: + - name: projectID + in: path + required: true + schema: + type: string + format: uuid + description: The project ID + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/CreateApiKey" + responses: + "201": + description: API key created successfully + content: + application/json: + schema: + $ref: "#/components/schemas/ApiKey" + default: + $ref: "#/components/responses/Error" + + /api/admin/projects/{projectID}/keys/{keyID}: + get: + summary: Get API key by ID + description: Retrieves a specific API key + operationId: getApiKey + tags: + - API Keys + security: + - HttpBearerAuth: [] + parameters: + - name: projectID + in: path + required: true + schema: + type: string + format: uuid + description: The project ID + - name: keyID + in: path + required: true + schema: + type: string + format: uuid + description: The API key ID + responses: + "200": + description: API key retrieved successfully + content: + application/json: + schema: + $ref: "#/components/schemas/ApiKey" + default: + $ref: "#/components/responses/Error" + + patch: + summary: Update API key + description: Updates an API key's name or description (scope cannot be changed) + operationId: updateApiKey + tags: + - API Keys + security: + - HttpBearerAuth: [] + parameters: + - name: projectID + in: path + required: true + schema: + type: string + format: uuid + description: The project ID + - name: keyID + in: path + required: true + schema: + type: string + format: uuid + description: The API key ID + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/UpdateApiKey" + responses: + "200": + description: API key updated successfully + content: + application/json: + schema: + $ref: "#/components/schemas/ApiKey" + default: + $ref: "#/components/responses/Error" + + delete: + summary: Delete API key + description: Deletes an API key, revoking access + operationId: deleteApiKey + tags: + - API Keys + security: + - HttpBearerAuth: [] + parameters: + - name: projectID + in: path + required: true + schema: + type: string + format: uuid + description: The project ID + - name: keyID + in: path + required: true + schema: + type: string + format: uuid + description: The API key ID + responses: + "204": + description: API key deleted successfully + default: + $ref: "#/components/responses/Error" + /api/admin/projects/{projectID}/providers: get: summary: List providers @@ -2977,6 +3136,22 @@ components: items: $ref: "#/components/schemas/Provider" + ApiKeyListResponse: + description: API keys retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/PaginatedResponse" + - type: object + required: + - results + properties: + results: + type: array + items: + $ref: "#/components/schemas/ApiKey" + schemas: Channel: type: string @@ -4763,6 +4938,84 @@ components: items: $ref: "#/components/schemas/ProjectAdmin" + ApiKeyScope: + type: string + enum: [public, secret] + description: API key scope - public keys are safe to expose in client-side code + example: secret + + ApiKey: + type: object + required: + - id + - project_id + - name + - value + - scope + - role + - created_at + - updated_at + properties: + id: + type: string + format: uuid + example: "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d" + project_id: + type: string + format: uuid + example: "4c9d3163-7b64-4f9e-9068-d2e4b96be56b" + name: + type: string + example: "Production API Key" + value: + type: string + example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" + description: The API key value + scope: + $ref: "#/components/schemas/ApiKeyScope" + role: + $ref: "#/components/schemas/ProjectRole" + description: + type: string + example: "API key for production environment" + created_at: + type: string + format: date-time + example: "2025-11-19T14:18:42.960Z" + updated_at: + type: string + format: date-time + example: "2025-11-23T17:20:00.021Z" + + CreateApiKey: + type: object + required: + - name + - scope + properties: + name: + type: string + example: "Production API Key" + scope: + $ref: "#/components/schemas/ApiKeyScope" + role: + $ref: "#/components/schemas/ProjectRole" + description: + type: string + example: "API key for production environment" + + UpdateApiKey: + type: object + properties: + name: + type: string + example: "Updated API Key Name" + role: + $ref: "#/components/schemas/ProjectRole" + description: + type: string + example: "Updated description" + ClientEvent: type: object required: diff --git a/internal/http/controllers/v1/management/oapi/resources_gen.go b/internal/http/controllers/v1/management/oapi/resources_gen.go index 8796df08..3b85ea5e 100644 --- a/internal/http/controllers/v1/management/oapi/resources_gen.go +++ b/internal/http/controllers/v1/management/oapi/resources_gen.go @@ -24,6 +24,12 @@ const ( HttpBearerAuthScopes = "HttpBearerAuth.Scopes" ) +// Defines values for ApiKeyScope. +const ( + Public ApiKeyScope = "public" + Secret ApiKeyScope = "secret" +) + // Defines values for CampaignUserStatus. const ( Aborted CampaignUserStatus = "aborted" @@ -167,6 +173,28 @@ type AdminList struct { Total int `json:"total"` } +// ApiKey defines model for ApiKey. +type ApiKey struct { + CreatedAt time.Time `json:"created_at"` + Description *string `json:"description,omitempty"` + Id openapi_types.UUID `json:"id"` + Name string `json:"name"` + ProjectId openapi_types.UUID `json:"project_id"` + + // Role Role within a project + Role ProjectRole `json:"role"` + + // Scope API key scope - public keys are safe to expose in client-side code + Scope ApiKeyScope `json:"scope"` + UpdatedAt time.Time `json:"updated_at"` + + // Value The API key value + Value string `json:"value"` +} + +// ApiKeyScope API key scope - public keys are safe to expose in client-side code +type ApiKeyScope string + // AuthCallbackRequest defines model for AuthCallbackRequest. type AuthCallbackRequest struct { // Email Email address (required for basic auth) @@ -221,6 +249,18 @@ type CreateAdmin struct { Role OrganizationRole `json:"role"` } +// CreateApiKey defines model for CreateApiKey. +type CreateApiKey struct { + Description *string `json:"description,omitempty"` + Name string `json:"name"` + + // Role Role within a project + Role *ProjectRole `json:"role,omitempty"` + + // Scope API key scope - public keys are safe to expose in client-side code + Scope ApiKeyScope `json:"scope"` +} + // CreateCampaign defines model for CreateCampaign. type CreateCampaign struct { // Channel Communication channel type @@ -714,6 +754,15 @@ type UpdateAdmin struct { Role *OrganizationRole `json:"role,omitempty"` } +// UpdateApiKey defines model for UpdateApiKey. +type UpdateApiKey struct { + Description *string `json:"description,omitempty"` + Name *string `json:"name,omitempty"` + + // Role Role within a project + Role *ProjectRole `json:"role,omitempty"` +} + // UpdateCampaign defines model for UpdateCampaign. type UpdateCampaign struct { Name *string `json:"name,omitempty"` @@ -917,6 +966,19 @@ type Offset = PaginationOffset // Search defines model for Search. type Search = PaginationSearch +// ApiKeyListResponse defines model for ApiKeyListResponse. +type ApiKeyListResponse struct { + // Limit Maximum number of items returned + Limit int `json:"limit"` + + // Offset Number of items skipped + Offset int `json:"offset"` + Results []ApiKey `json:"results"` + + // Total Total number of items matching the filters + Total int `json:"total"` +} + // CampaignListResponse defines model for CampaignListResponse. type CampaignListResponse struct { // Limit Maximum number of items returned @@ -1094,6 +1156,15 @@ type ListJourneysParams struct { Offset *Offset `form:"offset,omitempty" json:"offset,omitempty"` } +// ListApiKeysParams defines parameters for ListApiKeys. +type ListApiKeysParams struct { + // Limit Maximum number of items to return + Limit *Limit `form:"limit,omitempty" json:"limit,omitempty"` + + // Offset Number of items to skip + Offset *Offset `form:"offset,omitempty" json:"offset,omitempty"` +} + // ListListsParams defines parameters for ListLists. type ListListsParams struct { // Limit Maximum number of items to return @@ -1250,6 +1321,12 @@ type UpdateJourneyJSONRequestBody = UpdateJourney // SetJourneyStepsJSONRequestBody defines body for SetJourneySteps for application/json ContentType. type SetJourneyStepsJSONRequestBody = JourneyStepMap +// CreateApiKeyJSONRequestBody defines body for CreateApiKey for application/json ContentType. +type CreateApiKeyJSONRequestBody = CreateApiKey + +// UpdateApiKeyJSONRequestBody defines body for UpdateApiKey for application/json ContentType. +type UpdateApiKeyJSONRequestBody = UpdateApiKey + // CreateListJSONRequestBody defines body for CreateList for application/json ContentType. type CreateListJSONRequestBody = CreateList @@ -1709,6 +1786,25 @@ type ClientInterface interface { // VersionJourney request VersionJourney(ctx context.Context, projectID openapi_types.UUID, journeyID openapi_types.UUID, reqEditors ...RequestEditorFn) (*http.Response, error) + // ListApiKeys request + ListApiKeys(ctx context.Context, projectID openapi_types.UUID, params *ListApiKeysParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateApiKeyWithBody request with any body + CreateApiKeyWithBody(ctx context.Context, projectID openapi_types.UUID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateApiKey(ctx context.Context, projectID openapi_types.UUID, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteApiKey request + DeleteApiKey(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetApiKey request + GetApiKey(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, reqEditors ...RequestEditorFn) (*http.Response, error) + + // UpdateApiKeyWithBody request with any body + UpdateApiKeyWithBody(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + UpdateApiKey(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // ListLists request ListLists(ctx context.Context, projectID openapi_types.UUID, params *ListListsParams, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -2558,6 +2654,90 @@ func (c *Client) VersionJourney(ctx context.Context, projectID openapi_types.UUI return c.Client.Do(req) } +func (c *Client) ListApiKeys(ctx context.Context, projectID openapi_types.UUID, params *ListApiKeysParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewListApiKeysRequest(c.Server, projectID, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateApiKeyWithBody(ctx context.Context, projectID openapi_types.UUID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateApiKeyRequestWithBody(c.Server, projectID, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateApiKey(ctx context.Context, projectID openapi_types.UUID, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateApiKeyRequest(c.Server, projectID, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteApiKey(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteApiKeyRequest(c.Server, projectID, keyID) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetApiKey(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetApiKeyRequest(c.Server, projectID, keyID) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateApiKeyWithBody(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateApiKeyRequestWithBody(c.Server, projectID, keyID, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateApiKey(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateApiKeyRequest(c.Server, projectID, keyID, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) ListLists(ctx context.Context, projectID openapi_types.UUID, params *ListListsParams, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewListListsRequest(c.Server, projectID, params) if err != nil { @@ -5338,8 +5518,8 @@ func NewVersionJourneyRequest(server string, projectID openapi_types.UUID, journ return req, nil } -// NewListListsRequest generates requests for ListLists -func NewListListsRequest(server string, projectID openapi_types.UUID, params *ListListsParams) (*http.Request, error) { +// NewListApiKeysRequest generates requests for ListApiKeys +func NewListApiKeysRequest(server string, projectID openapi_types.UUID, params *ListApiKeysParams) (*http.Request, error) { var err error var pathParam0 string @@ -5354,7 +5534,7 @@ func NewListListsRequest(server string, projectID openapi_types.UUID, params *Li return nil, err } - operationPath := fmt.Sprintf("/api/admin/projects/%s/lists", pathParam0) + operationPath := fmt.Sprintf("/api/admin/projects/%s/keys", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -5410,19 +5590,19 @@ func NewListListsRequest(server string, projectID openapi_types.UUID, params *Li return req, nil } -// NewCreateListRequest calls the generic CreateList builder with application/json body -func NewCreateListRequest(server string, projectID openapi_types.UUID, body CreateListJSONRequestBody) (*http.Request, error) { +// NewCreateApiKeyRequest calls the generic CreateApiKey builder with application/json body +func NewCreateApiKeyRequest(server string, projectID openapi_types.UUID, body CreateApiKeyJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader buf, err := json.Marshal(body) if err != nil { return nil, err } bodyReader = bytes.NewReader(buf) - return NewCreateListRequestWithBody(server, projectID, "application/json", bodyReader) + return NewCreateApiKeyRequestWithBody(server, projectID, "application/json", bodyReader) } -// NewCreateListRequestWithBody generates requests for CreateList with any type of body -func NewCreateListRequestWithBody(server string, projectID openapi_types.UUID, contentType string, body io.Reader) (*http.Request, error) { +// NewCreateApiKeyRequestWithBody generates requests for CreateApiKey with any type of body +func NewCreateApiKeyRequestWithBody(server string, projectID openapi_types.UUID, contentType string, body io.Reader) (*http.Request, error) { var err error var pathParam0 string @@ -5437,7 +5617,7 @@ func NewCreateListRequestWithBody(server string, projectID openapi_types.UUID, c return nil, err } - operationPath := fmt.Sprintf("/api/admin/projects/%s/lists", pathParam0) + operationPath := fmt.Sprintf("/api/admin/projects/%s/keys", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -5457,8 +5637,8 @@ func NewCreateListRequestWithBody(server string, projectID openapi_types.UUID, c return req, nil } -// NewDeleteListRequest generates requests for DeleteList -func NewDeleteListRequest(server string, projectID openapi_types.UUID, listID openapi_types.UUID) (*http.Request, error) { +// NewDeleteApiKeyRequest generates requests for DeleteApiKey +func NewDeleteApiKeyRequest(server string, projectID openapi_types.UUID, keyID openapi_types.UUID) (*http.Request, error) { var err error var pathParam0 string @@ -5470,7 +5650,7 @@ func NewDeleteListRequest(server string, projectID openapi_types.UUID, listID op var pathParam1 string - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "keyID", runtime.ParamLocationPath, keyID) if err != nil { return nil, err } @@ -5480,7 +5660,7 @@ func NewDeleteListRequest(server string, projectID openapi_types.UUID, listID op return nil, err } - operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/api/admin/projects/%s/keys/%s", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -5498,8 +5678,8 @@ func NewDeleteListRequest(server string, projectID openapi_types.UUID, listID op return req, nil } -// NewGetListRequest generates requests for GetList -func NewGetListRequest(server string, projectID openapi_types.UUID, listID openapi_types.UUID) (*http.Request, error) { +// NewGetApiKeyRequest generates requests for GetApiKey +func NewGetApiKeyRequest(server string, projectID openapi_types.UUID, keyID openapi_types.UUID) (*http.Request, error) { var err error var pathParam0 string @@ -5511,7 +5691,7 @@ func NewGetListRequest(server string, projectID openapi_types.UUID, listID opena var pathParam1 string - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "keyID", runtime.ParamLocationPath, keyID) if err != nil { return nil, err } @@ -5521,7 +5701,7 @@ func NewGetListRequest(server string, projectID openapi_types.UUID, listID opena return nil, err } - operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/api/admin/projects/%s/keys/%s", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -5539,19 +5719,19 @@ func NewGetListRequest(server string, projectID openapi_types.UUID, listID opena return req, nil } -// NewUpdateListRequest calls the generic UpdateList builder with application/json body -func NewUpdateListRequest(server string, projectID openapi_types.UUID, listID openapi_types.UUID, body UpdateListJSONRequestBody) (*http.Request, error) { +// NewUpdateApiKeyRequest calls the generic UpdateApiKey builder with application/json body +func NewUpdateApiKeyRequest(server string, projectID openapi_types.UUID, keyID openapi_types.UUID, body UpdateApiKeyJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader buf, err := json.Marshal(body) if err != nil { return nil, err } bodyReader = bytes.NewReader(buf) - return NewUpdateListRequestWithBody(server, projectID, listID, "application/json", bodyReader) + return NewUpdateApiKeyRequestWithBody(server, projectID, keyID, "application/json", bodyReader) } -// NewUpdateListRequestWithBody generates requests for UpdateList with any type of body -func NewUpdateListRequestWithBody(server string, projectID openapi_types.UUID, listID openapi_types.UUID, contentType string, body io.Reader) (*http.Request, error) { +// NewUpdateApiKeyRequestWithBody generates requests for UpdateApiKey with any type of body +func NewUpdateApiKeyRequestWithBody(server string, projectID openapi_types.UUID, keyID openapi_types.UUID, contentType string, body io.Reader) (*http.Request, error) { var err error var pathParam0 string @@ -5563,7 +5743,7 @@ func NewUpdateListRequestWithBody(server string, projectID openapi_types.UUID, l var pathParam1 string - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "keyID", runtime.ParamLocationPath, keyID) if err != nil { return nil, err } @@ -5573,7 +5753,7 @@ func NewUpdateListRequestWithBody(server string, projectID openapi_types.UUID, l return nil, err } - operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/api/admin/projects/%s/keys/%s", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -5593,49 +5773,8 @@ func NewUpdateListRequestWithBody(server string, projectID openapi_types.UUID, l return req, nil } -// NewDuplicateListRequest generates requests for DuplicateList -func NewDuplicateListRequest(server string, projectID openapi_types.UUID, listID openapi_types.UUID) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) - if err != nil { - return nil, err - } - - var pathParam1 string - - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) - if err != nil { - return nil, err - } - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s/duplicate", pathParam0, pathParam1) - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewGetListUsersRequest generates requests for GetListUsers -func NewGetListUsersRequest(server string, projectID openapi_types.UUID, listID openapi_types.UUID, params *GetListUsersParams) (*http.Request, error) { +// NewListListsRequest generates requests for ListLists +func NewListListsRequest(server string, projectID openapi_types.UUID, params *ListListsParams) (*http.Request, error) { var err error var pathParam0 string @@ -5645,19 +5784,12 @@ func NewGetListUsersRequest(server string, projectID openapi_types.UUID, listID return nil, err } - var pathParam1 string - - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) - if err != nil { - return nil, err - } - serverURL, err := url.Parse(server) if err != nil { return nil, err } - operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s/users", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/api/admin/projects/%s/lists", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -5713,20 +5845,24 @@ func NewGetListUsersRequest(server string, projectID openapi_types.UUID, listID return req, nil } -// NewImportListUsersRequestWithBody generates requests for ImportListUsers with any type of body -func NewImportListUsersRequestWithBody(server string, projectID openapi_types.UUID, listID openapi_types.UUID, contentType string, body io.Reader) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) +// NewCreateListRequest calls the generic CreateList builder with application/json body +func NewCreateListRequest(server string, projectID openapi_types.UUID, body CreateListJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) if err != nil { return nil, err } + bodyReader = bytes.NewReader(buf) + return NewCreateListRequestWithBody(server, projectID, "application/json", bodyReader) +} - var pathParam1 string +// NewCreateListRequestWithBody generates requests for CreateList with any type of body +func NewCreateListRequestWithBody(server string, projectID openapi_types.UUID, contentType string, body io.Reader) (*http.Request, error) { + var err error - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) if err != nil { return nil, err } @@ -5736,7 +5872,7 @@ func NewImportListUsersRequestWithBody(server string, projectID openapi_types.UU return nil, err } - operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s/users", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/api/admin/projects/%s/lists", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -5756,8 +5892,8 @@ func NewImportListUsersRequestWithBody(server string, projectID openapi_types.UU return req, nil } -// NewListLocalesRequest generates requests for ListLocales -func NewListLocalesRequest(server string, projectID openapi_types.UUID, params *ListLocalesParams) (*http.Request, error) { +// NewDeleteListRequest generates requests for DeleteList +func NewDeleteListRequest(server string, projectID openapi_types.UUID, listID openapi_types.UUID) (*http.Request, error) { var err error var pathParam0 string @@ -5767,12 +5903,19 @@ func NewListLocalesRequest(server string, projectID openapi_types.UUID, params * return nil, err } + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) + if err != nil { + return nil, err + } + serverURL, err := url.Parse(server) if err != nil { return nil, err } - operationPath := fmt.Sprintf("/api/admin/projects/%s/locales", pathParam0) + operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -5782,22 +5925,314 @@ func NewListLocalesRequest(server string, projectID openapi_types.UUID, params * return nil, err } - if params != nil { - queryValues := queryURL.Query() - - if params.Limit != nil { + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } + return req, nil +} + +// NewGetListRequest generates requests for GetList +func NewGetListRequest(server string, projectID openapi_types.UUID, listID openapi_types.UUID) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewUpdateListRequest calls the generic UpdateList builder with application/json body +func NewUpdateListRequest(server string, projectID openapi_types.UUID, listID openapi_types.UUID, body UpdateListJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewUpdateListRequestWithBody(server, projectID, listID, "application/json", bodyReader) +} + +// NewUpdateListRequestWithBody generates requests for UpdateList with any type of body +func NewUpdateListRequestWithBody(server string, projectID openapi_types.UUID, listID openapi_types.UUID, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PATCH", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDuplicateListRequest generates requests for DuplicateList +func NewDuplicateListRequest(server string, projectID openapi_types.UUID, listID openapi_types.UUID) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s/duplicate", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGetListUsersRequest generates requests for GetListUsers +func NewGetListUsersRequest(server string, projectID openapi_types.UUID, listID openapi_types.UUID, params *GetListUsersParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s/users", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Limit != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.Offset != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "offset", runtime.ParamLocationQuery, *params.Offset); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewImportListUsersRequestWithBody generates requests for ImportListUsers with any type of body +func NewImportListUsersRequestWithBody(server string, projectID openapi_types.UUID, listID openapi_types.UUID, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "listID", runtime.ParamLocationPath, listID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/api/admin/projects/%s/lists/%s/users", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewListLocalesRequest generates requests for ListLocales +func NewListLocalesRequest(server string, projectID openapi_types.UUID, params *ListLocalesParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/api/admin/projects/%s/locales", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Limit != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } } @@ -7751,6 +8186,25 @@ type ClientWithResponsesInterface interface { // VersionJourneyWithResponse request VersionJourneyWithResponse(ctx context.Context, projectID openapi_types.UUID, journeyID openapi_types.UUID, reqEditors ...RequestEditorFn) (*VersionJourneyResponse, error) + // ListApiKeysWithResponse request + ListApiKeysWithResponse(ctx context.Context, projectID openapi_types.UUID, params *ListApiKeysParams, reqEditors ...RequestEditorFn) (*ListApiKeysResponse, error) + + // CreateApiKeyWithBodyWithResponse request with any body + CreateApiKeyWithBodyWithResponse(ctx context.Context, projectID openapi_types.UUID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error) + + CreateApiKeyWithResponse(ctx context.Context, projectID openapi_types.UUID, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error) + + // DeleteApiKeyWithResponse request + DeleteApiKeyWithResponse(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, reqEditors ...RequestEditorFn) (*DeleteApiKeyResponse, error) + + // GetApiKeyWithResponse request + GetApiKeyWithResponse(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, reqEditors ...RequestEditorFn) (*GetApiKeyResponse, error) + + // UpdateApiKeyWithBodyWithResponse request with any body + UpdateApiKeyWithBodyWithResponse(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error) + + UpdateApiKeyWithResponse(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error) + // ListListsWithResponse request ListListsWithResponse(ctx context.Context, projectID openapi_types.UUID, params *ListListsParams, reqEditors ...RequestEditorFn) (*ListListsResponse, error) @@ -8723,7 +9177,121 @@ type ListJourneysResponse struct { } // Status returns HTTPResponse.Status -func (r ListJourneysResponse) Status() string { +func (r ListJourneysResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ListJourneysResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateJourneyResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Journey + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r CreateJourneyResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateJourneyResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteJourneyResponse struct { + Body []byte + HTTPResponse *http.Response + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r DeleteJourneyResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteJourneyResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetJourneyResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Journey + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r GetJourneyResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetJourneyResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type UpdateJourneyResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Journey + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r UpdateJourneyResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r UpdateJourneyResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DuplicateJourneyResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Journey + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r DuplicateJourneyResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -8731,22 +9299,22 @@ func (r ListJourneysResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r ListJourneysResponse) StatusCode() int { +func (r DuplicateJourneyResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type CreateJourneyResponse struct { +type PublishJourneyResponse struct { Body []byte HTTPResponse *http.Response - JSON201 *Journey + JSON200 *Journey JSONDefault *Error } // Status returns HTTPResponse.Status -func (r CreateJourneyResponse) Status() string { +func (r PublishJourneyResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -8754,21 +9322,22 @@ func (r CreateJourneyResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r CreateJourneyResponse) StatusCode() int { +func (r PublishJourneyResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type DeleteJourneyResponse struct { +type GetJourneyStepsResponse struct { Body []byte HTTPResponse *http.Response + JSON200 *JourneyStepMap JSONDefault *Error } // Status returns HTTPResponse.Status -func (r DeleteJourneyResponse) Status() string { +func (r GetJourneyStepsResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -8776,22 +9345,22 @@ func (r DeleteJourneyResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r DeleteJourneyResponse) StatusCode() int { +func (r GetJourneyStepsResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type GetJourneyResponse struct { +type SetJourneyStepsResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *Journey + JSON200 *JourneyStepMap JSONDefault *Error } // Status returns HTTPResponse.Status -func (r GetJourneyResponse) Status() string { +func (r SetJourneyStepsResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -8799,22 +9368,22 @@ func (r GetJourneyResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r GetJourneyResponse) StatusCode() int { +func (r SetJourneyStepsResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type UpdateJourneyResponse struct { +type VersionJourneyResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *Journey + JSON201 *Journey JSONDefault *Error } // Status returns HTTPResponse.Status -func (r UpdateJourneyResponse) Status() string { +func (r VersionJourneyResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -8822,22 +9391,22 @@ func (r UpdateJourneyResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r UpdateJourneyResponse) StatusCode() int { +func (r VersionJourneyResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type DuplicateJourneyResponse struct { +type ListApiKeysResponse struct { Body []byte HTTPResponse *http.Response - JSON201 *Journey + JSON200 *ApiKeyListResponse JSONDefault *Error } // Status returns HTTPResponse.Status -func (r DuplicateJourneyResponse) Status() string { +func (r ListApiKeysResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -8845,22 +9414,22 @@ func (r DuplicateJourneyResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r DuplicateJourneyResponse) StatusCode() int { +func (r ListApiKeysResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type PublishJourneyResponse struct { +type CreateApiKeyResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *Journey + JSON201 *ApiKey JSONDefault *Error } // Status returns HTTPResponse.Status -func (r PublishJourneyResponse) Status() string { +func (r CreateApiKeyResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -8868,22 +9437,21 @@ func (r PublishJourneyResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r PublishJourneyResponse) StatusCode() int { +func (r CreateApiKeyResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type GetJourneyStepsResponse struct { +type DeleteApiKeyResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *JourneyStepMap JSONDefault *Error } // Status returns HTTPResponse.Status -func (r GetJourneyStepsResponse) Status() string { +func (r DeleteApiKeyResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -8891,22 +9459,22 @@ func (r GetJourneyStepsResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r GetJourneyStepsResponse) StatusCode() int { +func (r DeleteApiKeyResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type SetJourneyStepsResponse struct { +type GetApiKeyResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *JourneyStepMap + JSON200 *ApiKey JSONDefault *Error } // Status returns HTTPResponse.Status -func (r SetJourneyStepsResponse) Status() string { +func (r GetApiKeyResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -8914,22 +9482,22 @@ func (r SetJourneyStepsResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r SetJourneyStepsResponse) StatusCode() int { +func (r GetApiKeyResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type VersionJourneyResponse struct { +type UpdateApiKeyResponse struct { Body []byte HTTPResponse *http.Response - JSON201 *Journey + JSON200 *ApiKey JSONDefault *Error } // Status returns HTTPResponse.Status -func (r VersionJourneyResponse) Status() string { +func (r UpdateApiKeyResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -8937,7 +9505,7 @@ func (r VersionJourneyResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r VersionJourneyResponse) StatusCode() int { +func (r UpdateApiKeyResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } @@ -10422,6 +10990,67 @@ func (c *ClientWithResponses) VersionJourneyWithResponse(ctx context.Context, pr return ParseVersionJourneyResponse(rsp) } +// ListApiKeysWithResponse request returning *ListApiKeysResponse +func (c *ClientWithResponses) ListApiKeysWithResponse(ctx context.Context, projectID openapi_types.UUID, params *ListApiKeysParams, reqEditors ...RequestEditorFn) (*ListApiKeysResponse, error) { + rsp, err := c.ListApiKeys(ctx, projectID, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseListApiKeysResponse(rsp) +} + +// CreateApiKeyWithBodyWithResponse request with arbitrary body returning *CreateApiKeyResponse +func (c *ClientWithResponses) CreateApiKeyWithBodyWithResponse(ctx context.Context, projectID openapi_types.UUID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error) { + rsp, err := c.CreateApiKeyWithBody(ctx, projectID, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateApiKeyResponse(rsp) +} + +func (c *ClientWithResponses) CreateApiKeyWithResponse(ctx context.Context, projectID openapi_types.UUID, body CreateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateApiKeyResponse, error) { + rsp, err := c.CreateApiKey(ctx, projectID, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateApiKeyResponse(rsp) +} + +// DeleteApiKeyWithResponse request returning *DeleteApiKeyResponse +func (c *ClientWithResponses) DeleteApiKeyWithResponse(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, reqEditors ...RequestEditorFn) (*DeleteApiKeyResponse, error) { + rsp, err := c.DeleteApiKey(ctx, projectID, keyID, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteApiKeyResponse(rsp) +} + +// GetApiKeyWithResponse request returning *GetApiKeyResponse +func (c *ClientWithResponses) GetApiKeyWithResponse(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, reqEditors ...RequestEditorFn) (*GetApiKeyResponse, error) { + rsp, err := c.GetApiKey(ctx, projectID, keyID, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetApiKeyResponse(rsp) +} + +// UpdateApiKeyWithBodyWithResponse request with arbitrary body returning *UpdateApiKeyResponse +func (c *ClientWithResponses) UpdateApiKeyWithBodyWithResponse(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error) { + rsp, err := c.UpdateApiKeyWithBody(ctx, projectID, keyID, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateApiKeyResponse(rsp) +} + +func (c *ClientWithResponses) UpdateApiKeyWithResponse(ctx context.Context, projectID openapi_types.UUID, keyID openapi_types.UUID, body UpdateApiKeyJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateApiKeyResponse, error) { + rsp, err := c.UpdateApiKey(ctx, projectID, keyID, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateApiKeyResponse(rsp) +} + // ListListsWithResponse request returning *ListListsResponse func (c *ClientWithResponses) ListListsWithResponse(ctx context.Context, projectID openapi_types.UUID, params *ListListsParams, reqEditors ...RequestEditorFn) (*ListListsResponse, error) { rsp, err := c.ListLists(ctx, projectID, params, reqEditors...) @@ -12108,7 +12737,172 @@ func ParseDeleteJourneyResponse(rsp *http.Response) (*DeleteJourneyResponse, err HTTPResponse: rsp, } - switch { + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &dest + + } + + return response, nil +} + +// ParseGetJourneyResponse parses an HTTP response from a GetJourneyWithResponse call +func ParseGetJourneyResponse(rsp *http.Response) (*GetJourneyResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetJourneyResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Journey + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &dest + + } + + return response, nil +} + +// ParseUpdateJourneyResponse parses an HTTP response from a UpdateJourneyWithResponse call +func ParseUpdateJourneyResponse(rsp *http.Response) (*UpdateJourneyResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &UpdateJourneyResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Journey + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &dest + + } + + return response, nil +} + +// ParseDuplicateJourneyResponse parses an HTTP response from a DuplicateJourneyWithResponse call +func ParseDuplicateJourneyResponse(rsp *http.Response) (*DuplicateJourneyResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DuplicateJourneyResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Journey + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &dest + + } + + return response, nil +} + +// ParsePublishJourneyResponse parses an HTTP response from a PublishJourneyWithResponse call +func ParsePublishJourneyResponse(rsp *http.Response) (*PublishJourneyResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PublishJourneyResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Journey + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &dest + + } + + return response, nil +} + +// ParseGetJourneyStepsResponse parses an HTTP response from a GetJourneyStepsWithResponse call +func ParseGetJourneyStepsResponse(rsp *http.Response) (*GetJourneyStepsResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetJourneyStepsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest JourneyStepMap + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: var dest Error if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -12121,22 +12915,22 @@ func ParseDeleteJourneyResponse(rsp *http.Response) (*DeleteJourneyResponse, err return response, nil } -// ParseGetJourneyResponse parses an HTTP response from a GetJourneyWithResponse call -func ParseGetJourneyResponse(rsp *http.Response) (*GetJourneyResponse, error) { +// ParseSetJourneyStepsResponse parses an HTTP response from a SetJourneyStepsWithResponse call +func ParseSetJourneyStepsResponse(rsp *http.Response) (*SetJourneyStepsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &GetJourneyResponse{ + response := &SetJourneyStepsResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest Journey + var dest JourneyStepMap if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -12154,26 +12948,26 @@ func ParseGetJourneyResponse(rsp *http.Response) (*GetJourneyResponse, error) { return response, nil } -// ParseUpdateJourneyResponse parses an HTTP response from a UpdateJourneyWithResponse call -func ParseUpdateJourneyResponse(rsp *http.Response) (*UpdateJourneyResponse, error) { +// ParseVersionJourneyResponse parses an HTTP response from a VersionJourneyWithResponse call +func ParseVersionJourneyResponse(rsp *http.Response) (*VersionJourneyResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &UpdateJourneyResponse{ + response := &VersionJourneyResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: var dest Journey if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON200 = &dest + response.JSON201 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: var dest Error @@ -12187,26 +12981,26 @@ func ParseUpdateJourneyResponse(rsp *http.Response) (*UpdateJourneyResponse, err return response, nil } -// ParseDuplicateJourneyResponse parses an HTTP response from a DuplicateJourneyWithResponse call -func ParseDuplicateJourneyResponse(rsp *http.Response) (*DuplicateJourneyResponse, error) { +// ParseListApiKeysResponse parses an HTTP response from a ListApiKeysWithResponse call +func ParseListApiKeysResponse(rsp *http.Response) (*ListApiKeysResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &DuplicateJourneyResponse{ + response := &ListApiKeysResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: - var dest Journey + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ApiKeyListResponse if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON201 = &dest + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: var dest Error @@ -12220,26 +13014,26 @@ func ParseDuplicateJourneyResponse(rsp *http.Response) (*DuplicateJourneyRespons return response, nil } -// ParsePublishJourneyResponse parses an HTTP response from a PublishJourneyWithResponse call -func ParsePublishJourneyResponse(rsp *http.Response) (*PublishJourneyResponse, error) { +// ParseCreateApiKeyResponse parses an HTTP response from a CreateApiKeyWithResponse call +func ParseCreateApiKeyResponse(rsp *http.Response) (*CreateApiKeyResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &PublishJourneyResponse{ + response := &CreateApiKeyResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest Journey + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest ApiKey if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON200 = &dest + response.JSON201 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: var dest Error @@ -12253,27 +13047,20 @@ func ParsePublishJourneyResponse(rsp *http.Response) (*PublishJourneyResponse, e return response, nil } -// ParseGetJourneyStepsResponse parses an HTTP response from a GetJourneyStepsWithResponse call -func ParseGetJourneyStepsResponse(rsp *http.Response) (*GetJourneyStepsResponse, error) { +// ParseDeleteApiKeyResponse parses an HTTP response from a DeleteApiKeyWithResponse call +func ParseDeleteApiKeyResponse(rsp *http.Response) (*DeleteApiKeyResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &GetJourneyStepsResponse{ + response := &DeleteApiKeyResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest JourneyStepMap - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: var dest Error if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -12286,22 +13073,22 @@ func ParseGetJourneyStepsResponse(rsp *http.Response) (*GetJourneyStepsResponse, return response, nil } -// ParseSetJourneyStepsResponse parses an HTTP response from a SetJourneyStepsWithResponse call -func ParseSetJourneyStepsResponse(rsp *http.Response) (*SetJourneyStepsResponse, error) { +// ParseGetApiKeyResponse parses an HTTP response from a GetApiKeyWithResponse call +func ParseGetApiKeyResponse(rsp *http.Response) (*GetApiKeyResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &SetJourneyStepsResponse{ + response := &GetApiKeyResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest JourneyStepMap + var dest ApiKey if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -12319,26 +13106,26 @@ func ParseSetJourneyStepsResponse(rsp *http.Response) (*SetJourneyStepsResponse, return response, nil } -// ParseVersionJourneyResponse parses an HTTP response from a VersionJourneyWithResponse call -func ParseVersionJourneyResponse(rsp *http.Response) (*VersionJourneyResponse, error) { +// ParseUpdateApiKeyResponse parses an HTTP response from a UpdateApiKeyWithResponse call +func ParseUpdateApiKeyResponse(rsp *http.Response) (*UpdateApiKeyResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &VersionJourneyResponse{ + response := &UpdateApiKeyResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: - var dest Journey + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ApiKey if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON201 = &dest + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: var dest Error @@ -13824,6 +14611,21 @@ type ServerInterface interface { // Create journey version // (POST /api/admin/projects/{projectID}/journeys/{journeyID}/version) VersionJourney(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID, journeyID openapi_types.UUID) + // List API keys + // (GET /api/admin/projects/{projectID}/keys) + ListApiKeys(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID, params ListApiKeysParams) + // Create API key + // (POST /api/admin/projects/{projectID}/keys) + CreateApiKey(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID) + // Delete API key + // (DELETE /api/admin/projects/{projectID}/keys/{keyID}) + DeleteApiKey(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID, keyID openapi_types.UUID) + // Get API key by ID + // (GET /api/admin/projects/{projectID}/keys/{keyID}) + GetApiKey(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID, keyID openapi_types.UUID) + // Update API key + // (PATCH /api/admin/projects/{projectID}/keys/{keyID}) + UpdateApiKey(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID, keyID openapi_types.UUID) // List lists // (GET /api/admin/projects/{projectID}/lists) ListLists(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID, params ListListsParams) @@ -14226,6 +15028,36 @@ func (_ Unimplemented) VersionJourney(w http.ResponseWriter, r *http.Request, pr w.WriteHeader(http.StatusNotImplemented) } +// List API keys +// (GET /api/admin/projects/{projectID}/keys) +func (_ Unimplemented) ListApiKeys(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID, params ListApiKeysParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Create API key +// (POST /api/admin/projects/{projectID}/keys) +func (_ Unimplemented) CreateApiKey(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Delete API key +// (DELETE /api/admin/projects/{projectID}/keys/{keyID}) +func (_ Unimplemented) DeleteApiKey(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID, keyID openapi_types.UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Get API key by ID +// (GET /api/admin/projects/{projectID}/keys/{keyID}) +func (_ Unimplemented) GetApiKey(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID, keyID openapi_types.UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Update API key +// (PATCH /api/admin/projects/{projectID}/keys/{keyID}) +func (_ Unimplemented) UpdateApiKey(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID, keyID openapi_types.UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // List lists // (GET /api/admin/projects/{projectID}/lists) func (_ Unimplemented) ListLists(w http.ResponseWriter, r *http.Request, projectID openapi_types.UUID, params ListListsParams) { @@ -16158,6 +16990,207 @@ func (siw *ServerInterfaceWrapper) VersionJourney(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } +// ListApiKeys operation middleware +func (siw *ServerInterfaceWrapper) ListApiKeys(w http.ResponseWriter, r *http.Request) { + + var err error + + // ------------- Path parameter "projectID" ------------- + var projectID openapi_types.UUID + + err = runtime.BindStyledParameterWithOptions("simple", "projectID", chi.URLParam(r, "projectID"), &projectID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "projectID", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, HttpBearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params ListApiKeysParams + + // ------------- Optional query parameter "limit" ------------- + + err = runtime.BindQueryParameter("form", true, false, "limit", r.URL.Query(), ¶ms.Limit) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "limit", Err: err}) + return + } + + // ------------- Optional query parameter "offset" ------------- + + err = runtime.BindQueryParameter("form", true, false, "offset", r.URL.Query(), ¶ms.Offset) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "offset", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ListApiKeys(w, r, projectID, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// CreateApiKey operation middleware +func (siw *ServerInterfaceWrapper) CreateApiKey(w http.ResponseWriter, r *http.Request) { + + var err error + + // ------------- Path parameter "projectID" ------------- + var projectID openapi_types.UUID + + err = runtime.BindStyledParameterWithOptions("simple", "projectID", chi.URLParam(r, "projectID"), &projectID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "projectID", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, HttpBearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.CreateApiKey(w, r, projectID) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// DeleteApiKey operation middleware +func (siw *ServerInterfaceWrapper) DeleteApiKey(w http.ResponseWriter, r *http.Request) { + + var err error + + // ------------- Path parameter "projectID" ------------- + var projectID openapi_types.UUID + + err = runtime.BindStyledParameterWithOptions("simple", "projectID", chi.URLParam(r, "projectID"), &projectID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "projectID", Err: err}) + return + } + + // ------------- Path parameter "keyID" ------------- + var keyID openapi_types.UUID + + err = runtime.BindStyledParameterWithOptions("simple", "keyID", chi.URLParam(r, "keyID"), &keyID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "keyID", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, HttpBearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.DeleteApiKey(w, r, projectID, keyID) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetApiKey operation middleware +func (siw *ServerInterfaceWrapper) GetApiKey(w http.ResponseWriter, r *http.Request) { + + var err error + + // ------------- Path parameter "projectID" ------------- + var projectID openapi_types.UUID + + err = runtime.BindStyledParameterWithOptions("simple", "projectID", chi.URLParam(r, "projectID"), &projectID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "projectID", Err: err}) + return + } + + // ------------- Path parameter "keyID" ------------- + var keyID openapi_types.UUID + + err = runtime.BindStyledParameterWithOptions("simple", "keyID", chi.URLParam(r, "keyID"), &keyID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "keyID", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, HttpBearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetApiKey(w, r, projectID, keyID) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// UpdateApiKey operation middleware +func (siw *ServerInterfaceWrapper) UpdateApiKey(w http.ResponseWriter, r *http.Request) { + + var err error + + // ------------- Path parameter "projectID" ------------- + var projectID openapi_types.UUID + + err = runtime.BindStyledParameterWithOptions("simple", "projectID", chi.URLParam(r, "projectID"), &projectID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "projectID", Err: err}) + return + } + + // ------------- Path parameter "keyID" ------------- + var keyID openapi_types.UUID + + err = runtime.BindStyledParameterWithOptions("simple", "keyID", chi.URLParam(r, "keyID"), &keyID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "keyID", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, HttpBearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.UpdateApiKey(w, r, projectID, keyID) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + // ListLists operation middleware func (siw *ServerInterfaceWrapper) ListLists(w http.ResponseWriter, r *http.Request) { @@ -18146,6 +19179,21 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/api/admin/projects/{projectID}/journeys/{journeyID}/version", wrapper.VersionJourney) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/api/admin/projects/{projectID}/keys", wrapper.ListApiKeys) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/api/admin/projects/{projectID}/keys", wrapper.CreateApiKey) + }) + r.Group(func(r chi.Router) { + r.Delete(options.BaseURL+"/api/admin/projects/{projectID}/keys/{keyID}", wrapper.DeleteApiKey) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/api/admin/projects/{projectID}/keys/{keyID}", wrapper.GetApiKey) + }) + r.Group(func(r chi.Router) { + r.Patch(options.BaseURL+"/api/admin/projects/{projectID}/keys/{keyID}", wrapper.UpdateApiKey) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/api/admin/projects/{projectID}/lists", wrapper.ListLists) }) diff --git a/internal/store/management/apikeys.go b/internal/store/management/apikeys.go new file mode 100644 index 00000000..d4a7234a --- /dev/null +++ b/internal/store/management/apikeys.go @@ -0,0 +1,175 @@ +package management + +import ( + "context" + "crypto/rand" + "encoding/hex" + "time" + + "github.com/google/uuid" + "github.com/lunogram/platform/internal/http/controllers/v1/management/oapi" + "github.com/lunogram/platform/internal/store" +) + +type ApiKeys []ApiKey + +func (keys ApiKeys) OAPI() []oapi.ApiKey { + results := make([]oapi.ApiKey, len(keys)) + for i, key := range keys { + results[i] = key.OAPI() + } + return results +} + +type ApiKey struct { + ID uuid.UUID `db:"id"` + ProjectID uuid.UUID `db:"project_id"` + Value string `db:"value"` + Scope *string `db:"scope"` + Name string `db:"name"` + Description *string `db:"description"` + Role string `db:"role"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` +} + +func (k *ApiKey) OAPI() oapi.ApiKey { + result := oapi.ApiKey{ + Id: k.ID, + ProjectId: k.ProjectID, + Value: k.Value, + Name: k.Name, + Role: oapi.ProjectRole(k.Role), + CreatedAt: k.CreatedAt, + UpdatedAt: k.UpdatedAt, + } + + if k.Scope != nil { + result.Scope = oapi.ApiKeyScope(*k.Scope) + } + + if k.Description != nil { + result.Description = k.Description + } + + return result +} + +func NewApiKeysStore(db store.DB) *ApiKeysStore { + return &ApiKeysStore{db: db} +} + +type ApiKeysStore struct { + db store.DB +} + +// generateKeyValue generates a cryptographically secure 32-byte random value encoded as hex +func generateKeyValue() (string, error) { + bytes := make([]byte, 32) + if _, err := rand.Read(bytes); err != nil { + return "", err + } + return hex.EncodeToString(bytes), nil +} + +func (s *ApiKeysStore) CreateApiKey(ctx context.Context, projectID uuid.UUID, name string, scope string, role string, description *string) (*ApiKey, error) { + keyValue, err := generateKeyValue() + if err != nil { + return nil, err + } + + stmt := ` + INSERT INTO project_api_keys (project_id, value, scope, name, description, role) + VALUES ($1, $2, $3, $4, $5, $6) + RETURNING id, project_id, value, scope, name, description, role, created_at, updated_at` + + var apiKey ApiKey + err = s.db.GetContext(ctx, &apiKey, stmt, projectID, keyValue, scope, name, description, role) + if err != nil { + return nil, err + } + + return &apiKey, nil +} + +func (s *ApiKeysStore) GetApiKey(ctx context.Context, projectID, keyID uuid.UUID) (*ApiKey, error) { + stmt := ` + SELECT id, project_id, value, scope, name, description, role, created_at, updated_at + FROM project_api_keys + WHERE id = $1 AND project_id = $2 AND deleted_at IS NULL` + + var apiKey ApiKey + err := s.db.GetContext(ctx, &apiKey, stmt, keyID, projectID) + if err != nil { + return nil, err + } + + return &apiKey, nil +} + +func (s *ApiKeysStore) ListApiKeys(ctx context.Context, projectID uuid.UUID, pagination store.Pagination) (ApiKeys, int, error) { + query := ` + SELECT + id, + project_id, + value, + scope, + name, + description, + role, + created_at, + updated_at, + COUNT(*) OVER () AS total_count + FROM project_api_keys + WHERE project_id = $1 AND deleted_at IS NULL + ORDER BY created_at DESC + LIMIT $2 OFFSET $3` + + type result struct { + ApiKey + TotalCount int `db:"total_count"` + } + + var results []result + err := s.db.SelectContext(ctx, &results, query, projectID, pagination.Limit, pagination.Offset) + if err != nil { + return nil, 0, err + } + + if len(results) == 0 { + return []ApiKey{}, 0, nil + } + + total := results[0].TotalCount + apiKeys := make([]ApiKey, len(results)) + + for index, r := range results { + apiKeys[index] = r.ApiKey + } + + return apiKeys, total, nil +} + +func (s *ApiKeysStore) UpdateApiKey(ctx context.Context, projectID, keyID uuid.UUID, name *string, role *string, description *string) error { + stmt := ` + UPDATE project_api_keys + SET + name = COALESCE($1, name), + role = COALESCE($2, role), + description = COALESCE($3, description), + updated_at = CURRENT_TIMESTAMP + WHERE id = $4 AND project_id = $5 AND deleted_at IS NULL` + + _, err := s.db.ExecContext(ctx, stmt, name, role, description, keyID, projectID) + return err +} + +func (s *ApiKeysStore) DeleteApiKey(ctx context.Context, projectID, keyID uuid.UUID) error { + stmt := ` + UPDATE project_api_keys + SET deleted_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP + WHERE id = $1 AND project_id = $2 AND deleted_at IS NULL` + + _, err := s.db.ExecContext(ctx, stmt, keyID, projectID) + return err +} diff --git a/internal/store/management/store.go b/internal/store/management/store.go index fb6591af..da2b5f9e 100644 --- a/internal/store/management/store.go +++ b/internal/store/management/store.go @@ -47,6 +47,7 @@ func NewState(db store.DB) *State { LocalesStore: NewLocalesStore(db), DocumentsStore: NewDocumentsStore(db), AuthStore: NewAuthStore(db), + ApiKeysStore: NewApiKeysStore(db), } } @@ -62,4 +63,5 @@ type State struct { *LocalesStore *DocumentsStore *AuthStore + *ApiKeysStore }