feat: add gateway API, voice service, WebSocket hub, and startup entry
- services/gateway/api: net/http router with JWT auth, stub login, 6 tests - services/gateway/ws: WebSocket hub with echo support - services/voice: STT/TTS provider chain with fallback, 6 tests - cmd/cyrene/main.go: single binary startup, 108 tests total - Smoke test: health check + login verified on :8080
This commit is contained in:
1 parent
81ebdb910c
commit
99806fefad
12 files changed
+874
-1
No files matched your search
@@ -0,0 +1,56 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// StubAuthManager is an in-memory auth manager for development and testing.
|
||||
type StubAuthManager struct {
|
||||
tokens map[string]TokenInfo
|
||||
users map[string]UserInfo
|
||||
}
|
||||
|
||||
// TokenInfo holds decoded token information.
|
||||
type TokenInfo struct {
|
||||
UserID string
|
||||
Username string
|
||||
Role string
|
||||
}
|
||||
|
||||
// UserInfo holds user credentials (development only — production uses bcrypt).
|
||||
type UserInfo struct {
|
||||
Username string
|
||||
Password string
|
||||
Role string
|
||||
}
|
||||
|
||||
// NewStubAuthManager creates an in-memory auth manager with a default admin user.
|
||||
func NewStubAuthManager() *StubAuthManager {
|
||||
m := &StubAuthManager{
|
||||
tokens: make(map[string]TokenInfo),
|
||||
users: make(map[string]UserInfo),
|
||||
}
|
||||
m.users["admin"] = UserInfo{Username: "admin", Password: "admin", Role: "admin"}
|
||||
m.users["user"] = UserInfo{Username: "user", Password: "user", Role: "user"}
|
||||
return m
|
||||
}
|
||||
|
||||
// ValidateToken validates a stub token.
|
||||
func (m *StubAuthManager) ValidateToken(token string) (string, string, string, error) {
|
||||
info, ok := m.tokens[token]
|
||||
if !ok {
|
||||
return "", "", "", http.ErrNoCookie
|
||||
}
|
||||
return info.UserID, info.Username, info.Role, nil
|
||||
}
|
||||
|
||||
// Login authenticates a user and returns a stub token.
|
||||
func (m *StubAuthManager) Login(username, password string) (string, error) {
|
||||
user, ok := m.users[username]
|
||||
if !ok || user.Password != password {
|
||||
return "", http.ErrNoCookie
|
||||
}
|
||||
token := "stub-token-" + username
|
||||
m.tokens[token] = TokenInfo{UserID: username, Username: username, Role: user.Role}
|
||||
return token, nil
|
||||
}
|
||||
Reference in new issue
Block a user