Fix routing, hash api keys, start ws
This commit is contained in:
parent
c670c76d76
commit
22c4afadb6
9 changed files with 45 additions and 24 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
13
pkg/gordio/ws/session.go
Normal 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) {
|
||||
|
||||
}
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue