mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
agentic review fixes
This commit is contained in:
@@ -28,7 +28,7 @@ const (
|
||||
//
|
||||
// Key shape: "cgw_" + 7 random chars + 32 random chars = 43 chars total.
|
||||
func New(name string) (database.InsertAIGatewayCoderdKeyParams, string, error) {
|
||||
secret, hashed, err := apikey.GenerateSecret(KeyLength)
|
||||
secret, hashed, err := apikey.GenerateSecret(visiblePrefixLength + privateSuffixLength)
|
||||
if err != nil {
|
||||
return database.InsertAIGatewayCoderdKeyParams{}, "", xerrors.Errorf("generate secret: %w", err)
|
||||
}
|
||||
|
||||
Generated
+94
-94
@@ -64,100 +64,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/aibridge/coderd-keys": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Enterprise"
|
||||
],
|
||||
"summary": "List AI Gateway coderd keys",
|
||||
"operationId": "list-ai-gateway-coderd-keys",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.AIGatewayCoderdKey"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Enterprise"
|
||||
],
|
||||
"summary": "Create AI Gateway coderd key",
|
||||
"operationId": "create-ai-gateway-coderd-key",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Create AI Gateway coderd key request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateAIGatewayCoderdKeyRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateAIGatewayCoderdKeyResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/aibridge/coderd-keys/{key}": {
|
||||
"delete": {
|
||||
"tags": [
|
||||
"Enterprise"
|
||||
],
|
||||
"summary": "Delete AI Gateway coderd key",
|
||||
"operationId": "delete-ai-gateway-coderd-key",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Key ID",
|
||||
"name": "key",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/experimental/chats": {
|
||||
"get": {
|
||||
"description": "Experimental: this endpoint is subject to change.",
|
||||
@@ -1516,6 +1422,100 @@ const docTemplate = `{
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/v2/aibridge/coderd-keys": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Enterprise"
|
||||
],
|
||||
"summary": "List AI Gateway coderd keys",
|
||||
"operationId": "list-ai-gateway-coderd-keys",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.AIGatewayCoderdKey"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Enterprise"
|
||||
],
|
||||
"summary": "Create AI Gateway coderd key",
|
||||
"operationId": "create-ai-gateway-coderd-key",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Create AI Gateway coderd key request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateAIGatewayCoderdKeyRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateAIGatewayCoderdKeyResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/v2/aibridge/coderd-keys/{key}": {
|
||||
"delete": {
|
||||
"tags": [
|
||||
"Enterprise"
|
||||
],
|
||||
"summary": "Delete AI Gateway coderd key",
|
||||
"operationId": "delete-ai-gateway-coderd-key",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Key ID",
|
||||
"name": "key",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/v2/aibridge/interceptions": {
|
||||
"get": {
|
||||
"produces": [
|
||||
|
||||
Generated
+82
-82
@@ -49,88 +49,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/aibridge/coderd-keys": {
|
||||
"get": {
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Enterprise"],
|
||||
"summary": "List AI Gateway coderd keys",
|
||||
"operationId": "list-ai-gateway-coderd-keys",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.AIGatewayCoderdKey"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"consumes": ["application/json"],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Enterprise"],
|
||||
"summary": "Create AI Gateway coderd key",
|
||||
"operationId": "create-ai-gateway-coderd-key",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Create AI Gateway coderd key request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateAIGatewayCoderdKeyRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateAIGatewayCoderdKeyResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/aibridge/coderd-keys/{key}": {
|
||||
"delete": {
|
||||
"tags": ["Enterprise"],
|
||||
"summary": "Delete AI Gateway coderd key",
|
||||
"operationId": "delete-ai-gateway-coderd-key",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Key ID",
|
||||
"name": "key",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/experimental/chats": {
|
||||
"get": {
|
||||
"description": "Experimental: this endpoint is subject to change.",
|
||||
@@ -1337,6 +1255,88 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/v2/aibridge/coderd-keys": {
|
||||
"get": {
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Enterprise"],
|
||||
"summary": "List AI Gateway coderd keys",
|
||||
"operationId": "list-ai-gateway-coderd-keys",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.AIGatewayCoderdKey"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"consumes": ["application/json"],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Enterprise"],
|
||||
"summary": "Create AI Gateway coderd key",
|
||||
"operationId": "create-ai-gateway-coderd-key",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Create AI Gateway coderd key request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateAIGatewayCoderdKeyRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateAIGatewayCoderdKeyResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/v2/aibridge/coderd-keys/{key}": {
|
||||
"delete": {
|
||||
"tags": ["Enterprise"],
|
||||
"summary": "Delete AI Gateway coderd key",
|
||||
"operationId": "delete-ai-gateway-coderd-key",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Key ID",
|
||||
"name": "key",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/v2/aibridge/interceptions": {
|
||||
"get": {
|
||||
"produces": ["application/json"],
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// AIGatewayCoderdKey is a shared secret used by an standalone AI Gateway
|
||||
// AIGatewayCoderdKey is a shared secret used by a standalone AI Gateway
|
||||
// to authenticate into coderd.
|
||||
type AIGatewayCoderdKey struct {
|
||||
ID uuid.UUID `json:"id" format:"uuid"`
|
||||
|
||||
Generated
+6
-6
@@ -90,12 +90,12 @@ curl -X GET http://coder-server:8080/.well-known/oauth-protected-resource \
|
||||
|
||||
```shell
|
||||
# Example request using curl
|
||||
curl -X GET http://coder-server:8080/aibridge/coderd-keys \
|
||||
curl -X GET http://coder-server:8080/api/v2/aibridge/coderd-keys \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Coder-Session-Token: API_KEY'
|
||||
```
|
||||
|
||||
`GET /aibridge/coderd-keys`
|
||||
`GET /api/v2/aibridge/coderd-keys`
|
||||
|
||||
### Example responses
|
||||
|
||||
@@ -140,13 +140,13 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio
|
||||
|
||||
```shell
|
||||
# Example request using curl
|
||||
curl -X POST http://coder-server:8080/aibridge/coderd-keys \
|
||||
curl -X POST http://coder-server:8080/api/v2/aibridge/coderd-keys \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Coder-Session-Token: API_KEY'
|
||||
```
|
||||
|
||||
`POST /aibridge/coderd-keys`
|
||||
`POST /api/v2/aibridge/coderd-keys`
|
||||
|
||||
> Body parameter
|
||||
|
||||
@@ -190,11 +190,11 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio
|
||||
|
||||
```shell
|
||||
# Example request using curl
|
||||
curl -X DELETE http://coder-server:8080/aibridge/coderd-keys/{key} \
|
||||
curl -X DELETE http://coder-server:8080/api/v2/aibridge/coderd-keys/{key} \
|
||||
-H 'Coder-Session-Token: API_KEY'
|
||||
```
|
||||
|
||||
`DELETE /aibridge/coderd-keys/{key}`
|
||||
`DELETE /api/v2/aibridge/coderd-keys/{key}`
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/aigatewaycoderdkey"
|
||||
"github.com/coder/coder/v2/coderd/audit"
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/httpapi"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
@@ -21,7 +22,7 @@ import (
|
||||
const maxKeyInsertAttempts = 7
|
||||
|
||||
// nameFormatDetail is the human-readable description of valid key names.
|
||||
const nameFormatDetail = "Must be 64 characters or fewer, lowercase letters, numbers, and non-consecutive hyphens, cannot start or end with a hyphen."
|
||||
const nameFormatDetail = "Must be 64 characters or fewer, lowercase letters, numbers, and non-consecutive hyphens, cannot start or end with a hyphen."
|
||||
|
||||
// @Summary Create AI Gateway coderd key
|
||||
// @ID create-ai-gateway-coderd-key
|
||||
@@ -31,9 +32,19 @@ const nameFormatDetail = "Must be 64 characters or fewer, lowercase letters, nu
|
||||
// @Tags Enterprise
|
||||
// @Param request body codersdk.CreateAIGatewayCoderdKeyRequest true "Create AI Gateway coderd key request"
|
||||
// @Success 201 {object} codersdk.CreateAIGatewayCoderdKeyResponse
|
||||
// @Router /aibridge/coderd-keys [post]
|
||||
// @Router /api/v2/aibridge/coderd-keys [post]
|
||||
func (api *API) postAIGatewayCoderdKey(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var (
|
||||
ctx = r.Context()
|
||||
auditor = api.AGPL.Auditor.Load()
|
||||
aReq, commitAudit = audit.InitRequest[database.AiGatewayCoderdKey](rw, &audit.RequestParams{
|
||||
Audit: *auditor,
|
||||
Log: api.Logger,
|
||||
Request: r,
|
||||
Action: database.AuditActionCreate,
|
||||
})
|
||||
)
|
||||
defer commitAudit()
|
||||
|
||||
var req codersdk.CreateAIGatewayCoderdKeyRequest
|
||||
if !httpapi.Read(ctx, rw, r, &req) {
|
||||
@@ -49,6 +60,13 @@ func (api *API) postAIGatewayCoderdKey(rw http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
aReq.New = database.AiGatewayCoderdKey{
|
||||
ID: row.ID,
|
||||
Name: row.Name,
|
||||
SecretPrefix: row.SecretPrefix,
|
||||
CreatedAt: row.CreatedAt,
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusCreated, codersdk.CreateAIGatewayCoderdKeyResponse{
|
||||
ID: row.ID,
|
||||
Name: row.Name,
|
||||
@@ -109,7 +127,7 @@ func writeKeyInsertError(ctx context.Context, rw http.ResponseWriter, err error)
|
||||
// @Produce json
|
||||
// @Tags Enterprise
|
||||
// @Success 200 {array} codersdk.AIGatewayCoderdKey
|
||||
// @Router /aibridge/coderd-keys [get]
|
||||
// @Router /api/v2/aibridge/coderd-keys [get]
|
||||
func (api *API) aiGatewayCoderdKeys(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
@@ -137,9 +155,19 @@ func (api *API) aiGatewayCoderdKeys(rw http.ResponseWriter, r *http.Request) {
|
||||
// @Tags Enterprise
|
||||
// @Param key path string true "Key ID" format(uuid)
|
||||
// @Success 204
|
||||
// @Router /aibridge/coderd-keys/{key} [delete]
|
||||
// @Router /api/v2/aibridge/coderd-keys/{key} [delete]
|
||||
func (api *API) deleteAIGatewayCoderdKey(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var (
|
||||
ctx = r.Context()
|
||||
auditor = api.AGPL.Auditor.Load()
|
||||
aReq, commitAudit = audit.InitRequest[database.AiGatewayCoderdKey](rw, &audit.RequestParams{
|
||||
Audit: *auditor,
|
||||
Log: api.Logger,
|
||||
Request: r,
|
||||
Action: database.AuditActionDelete,
|
||||
})
|
||||
)
|
||||
defer commitAudit()
|
||||
|
||||
id, err := uuid.Parse(chi.URLParam(r, "key"))
|
||||
if err != nil {
|
||||
@@ -150,7 +178,8 @@ func (api *API) deleteAIGatewayCoderdKey(rw http.ResponseWriter, r *http.Request
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := api.Database.DeleteAIGatewayCoderdKey(ctx, id); err != nil {
|
||||
deleted, err := api.Database.DeleteAIGatewayCoderdKey(ctx, id)
|
||||
if err != nil {
|
||||
if httpapi.IsUnauthorizedError(err) {
|
||||
httpapi.Forbidden(rw)
|
||||
return
|
||||
@@ -163,6 +192,15 @@ func (api *API) deleteAIGatewayCoderdKey(rw http.ResponseWriter, r *http.Request
|
||||
return
|
||||
}
|
||||
|
||||
aReq.Old = database.AiGatewayCoderdKey{
|
||||
ID: deleted.ID,
|
||||
Name: deleted.Name,
|
||||
SecretPrefix: deleted.SecretPrefix,
|
||||
HashedSecret: deleted.HashedSecret,
|
||||
CreatedAt: deleted.CreatedAt,
|
||||
LastUsedAt: deleted.LastUsedAt,
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusNoContent, nil)
|
||||
}
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -306,7 +306,7 @@ export interface AIConfig {
|
||||
|
||||
// From codersdk/aigatewaycoderdkeys.go
|
||||
/**
|
||||
* AIGatewayCoderdKey is a shared secret used by an standalone AI Gateway
|
||||
* AIGatewayCoderdKey is a shared secret used by a standalone AI Gateway
|
||||
* to authenticate into coderd.
|
||||
*/
|
||||
export interface AIGatewayCoderdKey {
|
||||
|
||||
Reference in New Issue
Block a user