AI Gateway Go 0.10.0 源码快照 + 旗舰版需求规划报告

M0-M7 已完成:核心网关(身份/RBAC/TOTP/OIDC/SAML/Provider/配额/路由/内容策略/审计/定价)+ 资源市场(MCP/Skills/数字员工)。
含 22 个 PostgreSQL 迁移、管理端/门户端前端源码、OpenAPI 契约、部署 compose。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ben
2026-08-12 11:45:54 +08:00
commit 5759c1862e
807 changed files with 114727 additions and 0 deletions
+93
View File
@@ -0,0 +1,93 @@
package portal
import (
"context"
"errors"
"fmt"
"aigateway.local/core/internal/apikey"
"aigateway.local/core/internal/platform/cryptox"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
"github.com/jackc/pgx/v5/pgxpool"
)
type RuntimeCredentials struct {
pool *pgxpool.Pool
repository *apikey.Repository
cipher cryptox.Cipher
}
func NewRuntimeCredentials(pool *pgxpool.Pool, repository *apikey.Repository, cipher cryptox.Cipher) *RuntimeCredentials {
return &RuntimeCredentials{pool: pool, repository: repository, cipher: cipher}
}
// Ensure returns an internal application credential. The plaintext is only
// held for the duration of the request and is never returned to a browser.
func (s *RuntimeCredentials) Ensure(ctx context.Context, applicationID string, departmentID *string) (string, string, error) {
var encrypted []byte
var version int
var keyID string
err := s.pool.QueryRow(ctx, `SELECT encrypted_key,key_kek_version,api_key_id::text FROM gateway.application_runtime_credentials WHERE application_id=$1 AND department_id IS NOT DISTINCT FROM $2::uuid`, applicationID, departmentID).Scan(&encrypted, &version, &keyID)
if err == nil {
plain, decryptErr := s.cipher.Decrypt(encrypted, version)
return string(plain), keyID, decryptErr
}
if !errors.Is(err, pgx.ErrNoRows) {
return "", "", err
}
record, secret, err := s.repository.Create(ctx, "application-runtime", []string{"application:run"}, 120, 0, 0, nil, "")
if err != nil {
return "", "", err
}
encrypted, version, err = s.cipher.Encrypt([]byte(secret))
if err != nil {
_, _ = s.repository.Revoke(ctx, record.ID, "")
return "", "", err
}
tx, err := s.pool.Begin(ctx)
if err != nil {
_, _ = s.repository.Revoke(ctx, record.ID, "")
return "", "", err
}
defer func() { _ = tx.Rollback(ctx) }()
_, err = tx.Exec(ctx, `UPDATE gateway.api_keys SET tenant_id=$2,application_id=$3 WHERE id=$1`, record.ID, departmentID, applicationID)
if err == nil {
_, err = tx.Exec(ctx, `INSERT INTO gateway.application_runtime_credentials(application_id,department_id,api_key_id,encrypted_key,key_kek_version) VALUES($1,$2,$3,$4,$5)`, applicationID, departmentID, record.ID, encrypted, version)
}
if err != nil {
_ = tx.Rollback(ctx)
_, _ = s.repository.Revoke(ctx, record.ID, "")
// A concurrent request may have won the unique-key race.
var pgError *pgconn.PgError
if errors.As(err, &pgError) && pgError.Code == "23505" {
return s.Ensure(ctx, applicationID, departmentID)
}
return "", "", fmt.Errorf("store application runtime credential: %w", err)
}
if err = tx.Commit(ctx); err != nil {
_, _ = s.repository.Revoke(ctx, record.ID, "")
return "", "", err
}
return secret, record.ID, nil
}
func (s *RuntimeCredentials) Metadata(ctx context.Context, applicationID string) ([]map[string]any, error) {
rows, err := s.pool.Query(ctx, `SELECT c.api_key_id::text,k.key_prefix,c.department_id::text,k.enabled,c.created_at FROM gateway.application_runtime_credentials c JOIN gateway.api_keys k ON k.id=c.api_key_id WHERE c.application_id=$1 ORDER BY c.created_at`, applicationID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []map[string]any{}
for rows.Next() {
var id, prefix string
var department *string
var enabled bool
var created any
if err := rows.Scan(&id, &prefix, &department, &enabled, &created); err != nil {
return nil, err
}
items = append(items, map[string]any{"api_key_id": id, "key_prefix": prefix, "department_id": department, "enabled": enabled, "created_at": created})
}
return items, rows.Err()
}