Files
nilesh.pandClaude Opus 4.8 4d3eb18a6c 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>
2026-09-13 11:38:01 +05:30

48 lines
1.4 KiB
Go

// 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"
}