Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions internal/auth/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ type MachineProfile struct {
}

type HardwareProfile struct {
CPU string `json:"cpu,omitempty"`
Cores int `json:"cores,omitempty"`
Arch string `json:"arch,omitempty"`
RAMMB int `json:"ram_mb,omitempty"`
StorageMB int `json:"storage_mb,omitempty"`
GPU string `json:"gpu,omitempty"`
TPM bool `json:"tpm,omitempty"`
CPU string `json:"cpu,omitempty"`
Cores int `json:"cores,omitempty"`
Arch string `json:"arch,omitempty"`
RAMMB int `json:"ram_mb,omitempty"`
StorageMB int `json:"storage_mb,omitempty"`
GPU string `json:"gpu,omitempty"`
TPM bool `json:"tpm,omitempty"`
MachineID string `json:"machine_id,omitempty"`
}

Expand Down
2 changes: 1 addition & 1 deletion internal/auth/owner.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type OwnerStore interface {
type MemoryOwnerStore struct {
mu sync.RWMutex
owners map[int64]*Owner
ByKey map[string]*ownerKeyRef
ByKey map[string]*ownerKeyRef
}

func NewMemoryOwnerStore() *MemoryOwnerStore {
Expand Down
2 changes: 1 addition & 1 deletion internal/auth/sshmiddleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package auth
import (
"bytes"
"crypto/ed25519"
"crypto/sha256"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"io"
Expand Down
6 changes: 3 additions & 3 deletions internal/github/github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ func TestPublishPackage(t *testing.T) {
releaseCreated = true
w.WriteHeader(201)
json.NewEncoder(w).Encode(map[string]interface{}{
"id": 123,
"tag_name": "v1.0.0",
"name": "hello-world v1.0.0",
"id": 123,
"tag_name": "v1.0.0",
"name": "hello-world v1.0.0",
})
})

Expand Down
20 changes: 10 additions & 10 deletions internal/middleware/ratelimit.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ type routeLimiter struct {
}

type RateLimitConfig struct {
Global rate.Limit
GlobalBurst int
Routes []RouteLimit
Global rate.Limit
GlobalBurst int
Routes []RouteLimit
}

type RouteLimit struct {
Expand All @@ -47,12 +47,12 @@ func DefaultRateLimitConfig() RateLimitConfig {
Global: rate.Limit(30.0 / 60), // 30 per minute global per IP
GlobalBurst: 30,
Routes: []RouteLimit{
{Pattern: "search", Rate: 100.0 / 60, Burst: 20}, // Read: 100/min
{Pattern: "patches", Rate: 100.0 / 60, Burst: 20}, // Read: 100/min
{Pattern: "notary", Rate: 30.0 / 60, Burst: 10}, // Notary: 30/min
{Pattern: "unlock", Rate: 5.0 / 60, Burst: 5}, // Unlock: 5/min
{Pattern: "auth", Rate: 10.0 / 60, Burst: 5}, // Auth: 10/min
{Pattern: "download", Rate: 50.0 / 60, Burst: 15}, // Download: 50/min
{Pattern: "search", Rate: 100.0 / 60, Burst: 20}, // Read: 100/min
{Pattern: "patches", Rate: 100.0 / 60, Burst: 20}, // Read: 100/min
{Pattern: "notary", Rate: 30.0 / 60, Burst: 10}, // Notary: 30/min
{Pattern: "unlock", Rate: 5.0 / 60, Burst: 5}, // Unlock: 5/min
{Pattern: "auth", Rate: 10.0 / 60, Burst: 5}, // Auth: 10/min
{Pattern: "download", Rate: 50.0 / 60, Burst: 15}, // Download: 50/min
},
}
}
Expand Down Expand Up @@ -143,7 +143,7 @@ func (rl *RateLimiter) Middleware(next http.Handler) http.Handler {
rt := rl.matchRoute(r.URL.Path)
limiter := rl.getVisitor(key, rt)

remaining := int(limiter.Tokens()-1)
remaining := int(limiter.Tokens() - 1)
if remaining < 0 {
remaining = 0
}
Expand Down
28 changes: 14 additions & 14 deletions internal/server/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ func TestE2EFullFlow(t *testing.T) {
publishBody := map[string]interface{}{
"name": "contacts-bridge", "version": "1.2.0",
"description": "Contacts bridge MCP", "author": "tester", "license": "MIT",
"sha256": "bbbb2222bbbb2222bbbb2222bbbb2222bbbb2222bbbb2222bbbb2222bbbb2222",
"download_urls": map[string]string{"linux/amd64": "https://example.com/contacts-bridge-1.2.0.cgp"},
"manifest": map[string]interface{}{"name": "contacts-bridge", "version": "1.2.0", "description": "Contacts bridge MCP"},
"sha256": "bbbb2222bbbb2222bbbb2222bbbb2222bbbb2222bbbb2222bbbb2222bbbb2222",
"download_urls": map[string]string{"linux/amd64": "https://example.com/contacts-bridge-1.2.0.cgp"},
"manifest": map[string]interface{}{"name": "contacts-bridge", "version": "1.2.0", "description": "Contacts bridge MCP"},
"hardware_requirements": map[string]interface{}{"min_ram_mb": 256, "min_storage_mb": 100},
}
code, resp := e2eReq(srv, "POST", "/v1/patches", publishBody, nil)
Expand All @@ -132,15 +132,15 @@ func TestE2EFullFlow(t *testing.T) {
"name": "hello-world", "version": "1.0.0",
"description": "A test hello world", "author": "tester", "license": "MIT",
"hardware_requirements": map[string]interface{}{"min_ram_mb": 512},
"dependencies": map[string]interface{}{"contacts-bridge": "^1.0.0"},
"dependencies": map[string]interface{}{"contacts-bridge": "^1.0.0"},
}

publishBody := map[string]interface{}{
"name": "hello-world", "version": "1.0.0",
"description": "A test hello world package", "author": "tester", "license": "MIT",
"sha256": "aaaa1111aaaa1111aaaa1111aaaa1111aaaa1111aaaa1111aaaa1111aaaa1111",
"download_urls": map[string]string{"linux/amd64": "https://example.com/hello-world-1.0.0-linux-amd64.cgp"},
"manifest": manifest,
"sha256": "aaaa1111aaaa1111aaaa1111aaaa1111aaaa1111aaaa1111aaaa1111aaaa1111",
"download_urls": map[string]string{"linux/amd64": "https://example.com/hello-world-1.0.0-linux-amd64.cgp"},
"manifest": manifest,
"hardware_requirements": map[string]interface{}{"min_ram_mb": 512},
}

Expand Down Expand Up @@ -168,7 +168,7 @@ func TestE2EFullFlow(t *testing.T) {
"linux/amd64": "https://example.com/email-manager-2.0.0.cgp",
"linux/arm64": "https://example.com/email-manager-2.0.0-arm64.cgp",
},
"manifest": emailManifest,
"manifest": emailManifest,
"hardware_requirements": map[string]interface{}{"min_ram_mb": 1024, "min_storage_mb": 500},
}
code, _ := e2eReq(srv, "POST", "/v1/patches", publishBody, nil)
Expand Down Expand Up @@ -277,7 +277,7 @@ func TestE2EFullFlow(t *testing.T) {
"name": "hello-world", "version": "1.0.0",
"description": "duplicate", "sha256": "dddd",
"download_urls": map[string]string{"": "https://example.com/dup.cgp"},
"manifest": map[string]interface{}{"name": "hello-world", "version": "1.0.0", "description": "A test hello world package"},
"manifest": map[string]interface{}{"name": "hello-world", "version": "1.0.0", "description": "A test hello world package"},
}
code, body := e2eReq(srv, "POST", "/v1/patches", publishBody, nil)
test("duplicate 409", code == 409)
Expand Down Expand Up @@ -332,17 +332,17 @@ func TestE2EMinRAMFilter(t *testing.T) {
packages := []map[string]interface{}{
{
"name": "light-pkg", "version": "1.0.0", "sha256": "aaaa",
"download_urls": map[string]string{"": "https://example.com/light.cgp"},
"download_urls": map[string]string{"": "https://example.com/light.cgp"},
"hardware_requirements": map[string]interface{}{"min_ram_mb": 256},
},
{
"name": "medium-pkg", "version": "1.0.0", "sha256": "bbbb",
"download_urls": map[string]string{"": "https://example.com/medium.cgp"},
"download_urls": map[string]string{"": "https://example.com/medium.cgp"},
"hardware_requirements": map[string]interface{}{"min_ram_mb": 1024},
},
{
"name": "heavy-pkg", "version": "1.0.0", "sha256": "cccc",
"download_urls": map[string]string{"": "https://example.com/heavy.cgp"},
"download_urls": map[string]string{"": "https://example.com/heavy.cgp"},
"hardware_requirements": map[string]interface{}{"min_ram_mb": 4096, "min_storage_mb": 2000},
},
}
Expand Down Expand Up @@ -395,7 +395,7 @@ func TestE2EDependenciesTransitive(t *testing.T) {
{
"name": "leaf-dep", "version": "1.0.0", "sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"download_urls": map[string]string{"": "https://example.com/leaf.cgp"},
"manifest": map[string]interface{}{"name": "leaf-dep", "version": "1.0.0", "description": "leaf dep"},
"manifest": map[string]interface{}{"name": "leaf-dep", "version": "1.0.0", "description": "leaf dep"},
},
{
"name": "mid-dep", "version": "1.0.0", "sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
Expand Down Expand Up @@ -485,7 +485,7 @@ func TestE2EMultiVariantDownload(t *testing.T) {
if w.Code != http.StatusFound {
t.Errorf("expected 302 redirect, got %d", w.Code)
}
Location := w.Header().Get("Location")
Location := w.Header().Get("Location")
if Location != "https://example.com/multi-linux-arm64.cgp" {
t.Errorf("wrong redirect URL: %s", Location)
}
Expand Down
56 changes: 28 additions & 28 deletions internal/server/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ func (s *Server) handleHealth() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
patchesCount, _ := s.config.Store.List()
writeJSON(w, http.StatusOK, map[string]interface{}{
"status": "healthy",
"status": "healthy",
"uptime_seconds": int(time.Since(s.startedAt).Seconds()),
"patches_count": len(patchesCount),
"version": "2.1.0",
"patches_count": len(patchesCount),
"version": "2.1.0",
})
}
}
Expand Down Expand Up @@ -70,16 +70,16 @@ func (s *Server) handleSearch() http.HandlerFunc {
}

type searchResult struct {
Name string `json:"name"`
Version string `json:"version"`
Description string `json:"description"`
Author string `json:"author,omitempty"`
License string `json:"license"`
SHA256 string `json:"sha256"`
Downloads int64 `json:"downloads"`
Name string `json:"name"`
Version string `json:"version"`
Description string `json:"description"`
Author string `json:"author,omitempty"`
License string `json:"license"`
SHA256 string `json:"sha256"`
Downloads int64 `json:"downloads"`
HardwareRequirements *store.HardwareReqs `json:"hardware_requirements,omitempty"`
Capabilities []string `json:"capabilities,omitempty"`
PublishedAt string `json:"published_at,omitempty"`
Capabilities []string `json:"capabilities,omitempty"`
PublishedAt string `json:"published_at,omitempty"`
}
items := make([]searchResult, len(results))
for i, r := range results {
Expand Down Expand Up @@ -222,19 +222,19 @@ func (s *Server) handleDownload() http.HandlerFunc {
}

type publishRequest struct {
Name string `json:"name"`
Version string `json:"version"`
Description string `json:"description,omitempty"`
Author string `json:"author,omitempty"`
License string `json:"license,omitempty"`
SourceRepository string `json:"source_repository,omitempty"`
SourceIssues string `json:"source_issues,omitempty"`
DownloadURL string `json:"download_url,omitempty"` // v1 compat
DownloadURLs map[string]string `json:"download_urls,omitempty"` // v2: variant-keyed
SHA256 string `json:"sha256"`
Tags []string `json:"tags,omitempty"`
Capabilities []string `json:"capabilities,omitempty"`
Manifest json.RawMessage `json:"manifest"`
Name string `json:"name"`
Version string `json:"version"`
Description string `json:"description,omitempty"`
Author string `json:"author,omitempty"`
License string `json:"license,omitempty"`
SourceRepository string `json:"source_repository,omitempty"`
SourceIssues string `json:"source_issues,omitempty"`
DownloadURL string `json:"download_url,omitempty"` // v1 compat
DownloadURLs map[string]string `json:"download_urls,omitempty"` // v2: variant-keyed
SHA256 string `json:"sha256"`
Tags []string `json:"tags,omitempty"`
Capabilities []string `json:"capabilities,omitempty"`
Manifest json.RawMessage `json:"manifest"`
Hardware *store.HardwareReqs `json:"hardware_requirements,omitempty"`
}

Expand Down Expand Up @@ -879,10 +879,10 @@ func (s *Server) handleAuthRegister() http.HandlerFunc {
}

writeJSON(w, http.StatusCreated, map[string]interface{}{
"fingerprint": info.Fingerprint,
"fingerprint": info.Fingerprint,
"public_key_type": info.KeyType,
"comment": info.Comment,
"registered_at": info.Registered.Format(time.RFC3339),
"comment": info.Comment,
"registered_at": info.Registered.Format(time.RFC3339),
})
}
}
Expand Down
30 changes: 15 additions & 15 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ import (
)

type Config struct {
Addr string
DataDir string
Store store.Store
TokenAuth auth.TokenStore
SSHKeys auth.SSHKeyStore
Machines auth.MachineKeyStore
Owners auth.OwnerStore
GitHub *githubclient.Client
Session *SessionMiddleware
UI *UIHandlers
Addr string
DataDir string
Store store.Store
TokenAuth auth.TokenStore
SSHKeys auth.SSHKeyStore
Machines auth.MachineKeyStore
Owners auth.OwnerStore
GitHub *githubclient.Client
Session *SessionMiddleware
UI *UIHandlers
}

type Server struct {
config Config
mux *http.ServeMux
rateLimit *middleware.RateLimiter
antiBot *middleware.AntiBot
startedAt time.Time
config Config
mux *http.ServeMux
rateLimit *middleware.RateLimiter
antiBot *middleware.AntiBot
startedAt time.Time
}

func New(config Config) *Server {
Expand Down
4 changes: 2 additions & 2 deletions internal/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1154,8 +1154,8 @@ func TestAuthSignup(t *testing.T) {
"ram_mb": 8192,
},
"software": map[string]interface{}{
"os": "linux",
"distro": "CognitiveOS",
"os": "linux",
"distro": "CognitiveOS",
"cpm_version": "1.0.0",
},
}
Expand Down
8 changes: 4 additions & 4 deletions internal/server/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import (
)

type SessionMiddleware struct {
Secret []byte
MaxAge time.Duration
Path string
Secret []byte
MaxAge time.Duration
Path string
}

type Session struct {
Expand Down Expand Up @@ -90,7 +90,7 @@ func (s *SessionMiddleware) GetSession(r *http.Request) (*Session, error) {
return nil, fmt.Errorf("invalid session signature")
}

_fields := strings.Split(value, "|")
_fields := strings.Split(value, "|")
if len(_fields) != 3 {
return nil, fmt.Errorf("invalid session data")
}
Expand Down
14 changes: 7 additions & 7 deletions internal/store/s3store.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ import (
)

type S3Store struct {
client *s3.Client
bucket string
prefix string
mu sync.RWMutex
cache map[string]Package
loaded bool
loadedAt time.Time
client *s3.Client
bucket string
prefix string
mu sync.RWMutex
cache map[string]Package
loaded bool
loadedAt time.Time
}

type S3Config struct {
Expand Down
4 changes: 2 additions & 2 deletions internal/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ type Package struct {
License string `json:"license,omitempty"`
SourceRepository string `json:"source_repository,omitempty"`
SourceIssues string `json:"source_issues,omitempty"`
DownloadURL string `json:"download_url,omitempty"` // v1 compat (deprecated)
DownloadURLs map[string]string `json:"download_urls,omitempty"` // v2: variant-keyed URLs
DownloadURL string `json:"download_url,omitempty"` // v1 compat (deprecated)
DownloadURLs map[string]string `json:"download_urls,omitempty"` // v2: variant-keyed URLs
Size int64 `json:"size,omitempty"`
ChecksumSHA256 string `json:"checksum_sha256,omitempty"`
Status string `json:"status,omitempty"`
Expand Down
Loading
Loading