Initial commit: TravelHub multi-tenant flight booking platform
Angular + Go + PostgreSQL sample with strict per-tenant isolation. - Backend: Go API (basic auth, tenant-scoped repository layer, pgx pool) - Frontend: Angular 22 SPA (search, checkout, bookings, dashboard) - Database: schema, seed data and demo bookings migrations - Tests: 311 across Go (integration), Angular (unit) and Playwright (e2e), plus a generated evidence report with PDF export - Security: whitebox VAPT report under security/ Secrets (.env, tokens, DB credentials) are git-ignored. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
// Package auth carries the authenticated caller through the request context.
|
||||
//
|
||||
// Every tenant-scoped query in this service takes its tenant id from the
|
||||
// Identity stored here, never from anything the client can name directly in a
|
||||
// query string or body. That is the single rule that keeps tenants isolated.
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/travelswitch/travelhub/backend/internal/models"
|
||||
)
|
||||
|
||||
// Identity is the authenticated user together with the tenant they signed into.
|
||||
type Identity struct {
|
||||
User models.User
|
||||
Tenant models.Tenant
|
||||
}
|
||||
|
||||
// contextKey is unexported so no other package can collide with our key.
|
||||
type contextKey struct{}
|
||||
|
||||
var identityKey contextKey
|
||||
|
||||
// ErrNoIdentity means the handler ran without authentication middleware in
|
||||
// front of it, which is a programming error rather than a client error.
|
||||
var ErrNoIdentity = errors.New("no identity in request context")
|
||||
|
||||
// WithIdentity returns a context carrying the identity.
|
||||
func WithIdentity(ctx context.Context, id Identity) context.Context {
|
||||
return context.WithValue(ctx, identityKey, id)
|
||||
}
|
||||
|
||||
// FromContext retrieves the identity placed by the auth middleware.
|
||||
func FromContext(ctx context.Context) (Identity, error) {
|
||||
id, ok := ctx.Value(identityKey).(Identity)
|
||||
if !ok {
|
||||
return Identity{}, ErrNoIdentity
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
// IsAdmin reports whether the caller holds the tenant admin role.
|
||||
func (i Identity) IsAdmin() bool {
|
||||
return i.User.Role == "admin"
|
||||
}
|
||||
Reference in New Issue
Block a user