Fix routing, hash api keys, start ws

This commit is contained in:
Daniel 2024-08-03 00:05:02 -04:00
parent c670c76d76
commit 22c4afadb6
9 changed files with 45 additions and 24 deletions

View file

@ -2,6 +2,8 @@ package auth
import (
"context"
"crypto/sha256"
"encoding/base64"
"time"
"dynatron.me/x/stillbox/pkg/gordio/database"
@ -24,7 +26,9 @@ func (a *authenticator) CheckAPIKey(ctx context.Context, key string) (*UserID, e
}
db := database.FromCtx(ctx)
apik, err := db.GetAPIKey(ctx, keyUuid)
hash := sha256.Sum256([]byte(keyUuid.String()))
b64hash := base64.StdEncoding.EncodeToString(hash[:])
apik, err := db.GetAPIKey(ctx, b64hash)
if err != nil {
if database.IsNoRows(err) {
log.Error().Str("apikey", keyUuid.String()).Msg("no such key")
@ -36,7 +40,7 @@ func (a *authenticator) CheckAPIKey(ctx context.Context, key string) (*UserID, e
}
if (apik.Disabled != nil && *apik.Disabled) || (apik.Expires.Valid && time.Now().After(apik.Expires.Time)) {
log.Error().Str("key", apik.ApiKey.String()).Msg("key disabled")
log.Error().Str("key", apik.ApiKey).Msg("key disabled")
return nil, ErrUnauthorized
}

View file

@ -23,13 +23,13 @@ type jwtAuth interface {
Login(ctx context.Context, username, password string) (token string, err error)
// InstallVerifyMiddleware installs the JWT verifier middleware to the provided chi Router.
InstallVerifyMiddleware(r chi.Router)
VerifyMiddleware() func(http.Handler) http.Handler
// InstallAuthMiddleware installs the JWT authenticator middleware to the provided chi Router.
InstallAuthMiddleware(r chi.Router)
AuthMiddleware() func(http.Handler) http.Handler
// InstallRoutes installs the auth route to the provided chi Router.
InstallRoutes(r chi.Router)
Routes() chi.Router
}
type claims map[string]interface{}
@ -40,12 +40,12 @@ func (a *authenticator) Authenticated(r *http.Request) (claims, bool) {
return cl, err != nil && tok != nil
}
func (a *authenticator) InstallVerifyMiddleware(r chi.Router) {
r.Use(jwtauth.Verifier(a.jwt))
func (a *authenticator) VerifyMiddleware() func(http.Handler) http.Handler {
return jwtauth.Verifier(a.jwt)
}
func (a *authenticator) InstallAuthMiddleware(r chi.Router) {
r.Use(jwtauth.Authenticator(a.jwt))
func (a *authenticator) AuthMiddleware() func(http.Handler) http.Handler {
return jwtauth.Authenticator(a.jwt)
}
func (a *authenticator) Login(ctx context.Context, username, password string) (token string, err error) {
@ -89,8 +89,11 @@ func (a *authenticator) newToken(uid int32) string {
return tokenString
}
func (a *authenticator) InstallRoutes(r chi.Router) {
func (a *authenticator) Routes() chi.Router {
r := chi.NewRouter()
r.Post("/auth", a.routeAuth)
return r
}
func (a *authenticator) routeAuth(w http.ResponseWriter, r *http.Request) {

View file

@ -17,7 +17,7 @@ type ApiKey struct {
CreatedAt time.Time `json:"created_at"`
Expires pgtype.Timestamp `json:"expires"`
Disabled *bool `json:"disabled"`
ApiKey uuid.UUID `json:"api_key"`
ApiKey string `json:"api_key"`
}
type Call struct {

View file

@ -15,9 +15,9 @@ type Querier interface {
AddCall(ctx context.Context, arg AddCallParams) (uuid.UUID, error)
CreateAPIKey(ctx context.Context, owner int, expires pgtype.Timestamp, disabled *bool) (ApiKey, error)
CreateUser(ctx context.Context, arg CreateUserParams) (User, error)
DeleteAPIKey(ctx context.Context, apiKey uuid.UUID) error
DeleteAPIKey(ctx context.Context, apiKey string) error
DeleteUser(ctx context.Context, username string) error
GetAPIKey(ctx context.Context, apiKey uuid.UUID) (ApiKey, error)
GetAPIKey(ctx context.Context, apiKey string) (ApiKey, error)
GetTalkgroupTags(ctx context.Context, systemID int, tgid int) ([]string, error)
GetTalkgroupsWithAllTags(ctx context.Context, tags []string) ([]Talkgroup, error)
GetTalkgroupsWithAnyTags(ctx context.Context, tags []string) ([]Talkgroup, error)

View file

@ -8,7 +8,6 @@ package database
import (
"context"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
)
@ -77,7 +76,7 @@ const deleteAPIKey = `-- name: DeleteAPIKey :exec
DELETE FROM api_keys WHERE api_key = $1
`
func (q *Queries) DeleteAPIKey(ctx context.Context, apiKey uuid.UUID) error {
func (q *Queries) DeleteAPIKey(ctx context.Context, apiKey string) error {
_, err := q.db.Exec(ctx, deleteAPIKey, apiKey)
return err
}
@ -95,7 +94,7 @@ const getAPIKey = `-- name: GetAPIKey :one
SELECT id, owner, created_at, expires, disabled, api_key FROM api_keys WHERE api_key = $1
`
func (q *Queries) GetAPIKey(ctx context.Context, apiKey uuid.UUID) (ApiKey, error) {
func (q *Queries) GetAPIKey(ctx context.Context, apiKey string) (ApiKey, error) {
row := q.db.QueryRow(ctx, getAPIKey, apiKey)
var i ApiKey
err := row.Scan(

View file

@ -17,21 +17,19 @@ func (s *Server) setupRoutes() {
r.Group(func(r chi.Router) {
// authenticated routes
s.auth.InstallVerifyMiddleware(r)
s.auth.InstallAuthMiddleware(r)
r.Use(s.auth.AuthMiddleware(), s.auth.VerifyMiddleware())
})
r.Group(func(r chi.Router) {
r.Use(rateLimiter())
r.Use(render.SetContentType(render.ContentTypeJSON))
// public routes
s.auth.InstallRoutes(r)
s.sources.InstallPublicRoutes(r)
r.Mount("/", s.auth.Routes())
r.Mount("/", s.sources.PublicRoutes())
})
r.Group(func(r chi.Router) {
r.Use(rateLimiter())
s.auth.InstallVerifyMiddleware(r)
r.Use(rateLimiter(), s.auth.VerifyMiddleware())
// optional auth routes

View file

@ -2,6 +2,7 @@ package sources
import (
"context"
"dynatron.me/x/stillbox/pkg/gordio/calls"
"github.com/go-chi/chi/v5"
@ -25,12 +26,15 @@ func (s *Sources) Register(name string, src Source) {
})
}
func (s *Sources) InstallPublicRoutes(r chi.Router) {
func (s *Sources) PublicRoutes() chi.Router {
r := chi.NewRouter()
for _, si := range *s {
if rs, ok := si.Source.(PublicRouteSource); ok {
rs.InstallPublicRoutes(r)
}
}
return r
}
type Ingestor interface {

13
pkg/gordio/ws/session.go Normal file
View file

@ -0,0 +1,13 @@
package ws
import (
"github.com/go-chi/chi/v5"
// "github.com/gorilla/websocket"
)
type SessionManager struct {
}
func (s *SessionManager) InstallPrivateRoutes(r chi.Router) {
}

View file

@ -15,7 +15,7 @@ CREATE TABLE IF NOT EXISTS api_keys(
created_at TIMESTAMP NOT NULL,
expires TIMESTAMP,
disabled BOOLEAN,
api_key UUID UNIQUE NOT NULL
api_key TEXT UNIQUE NOT NULL
);
CREATE TABLE IF NOT EXISTS systems(