Documentation
¶
Index ¶
- func AllowCrossTenant(ctx context.Context) context.Context
- func ApplyTenantFilter(builder *query.QueryBuilder, tenantID string)
- func GetTenantID(ctx context.Context) string
- func InjectTenantID(data map[string]any, ctx context.Context)
- func IsCrossTenant(ctx context.Context) bool
- func SetTenantID(ctx context.Context, id string) context.Context
- func TenantMiddleware(header string) func(http.Handler) http.Handler
- func WithMultiTenant(ent *entity.Entity, config TenantConfig) *entity.Entity
- type TenantConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AllowCrossTenant ¶
AllowCrossTenant marks ctx as permitted to operate without a tenant id. Multi-tenant CRUD reads then span every tenant (the scope helpers no-op on an empty tenant id) and the secure-by-default RequireTenant gate stops refusing the request.
SECURITY: use ONLY on deliberately-admin routes, and gate those routes with your own permission check — there is no built-in role check. Never set this from a request header or any other client-controlled value.
func ApplyTenantFilter ¶
func ApplyTenantFilter(builder *query.QueryBuilder, tenantID string)
ApplyTenantFilter adds a WHERE tenant_id = ? clause to the query builder. The tenantID is parameterized to prevent SQL injection. An empty tenantID is FAIL-CLOSED — the query is scoped to a guaranteed- empty result set ("WHERE 1 = 0") rather than being left unscoped. Apps that genuinely want cross-tenant queries (admin tooling) must construct them with the tenant filter disabled deliberately, not by handing in an empty string here.
This standalone helper always uses the default "tenant_id" column. For an entity with a custom EntityConfig.TenantField, the CRUD auto-scope (CrudHandler.ApplyTenantScope*) already filters by the right column — use that rather than this helper, which has no entity context.
func GetTenantID ¶
GetTenantID retrieves the tenant ID string from the context. Returns an empty string if no tenant ID is set.
func InjectTenantID ¶
InjectTenantID automatically injects the tenant_id field into a data map before insert/update operations. This ensures records are associated with the current tenant from the context. Like ApplyTenantFilter, it uses the default "tenant_id" column; entities with a custom EntityConfig.TenantField are handled by the CRUD layer (CrudHandler.InjectTenant), not this helper.
func IsCrossTenant ¶
IsCrossTenant reports whether ctx was explicitly marked for cross-tenant access via AllowCrossTenant.
func SetTenantID ¶
SetTenantID stores the tenant ID string in the context.
func TenantMiddleware ¶
TenantMiddleware returns an HTTP middleware that resolves the tenant ID for the request from server-side state.
SECURITY: the middleware does NOT trust the raw `header` value sent by the client. Doing so would let any caller impersonate any tenant by setting an HTTP header. Instead, the header is treated as a *hint* and the middleware looks up a server-resolved tenant for the authenticated user (via handler.GetTenant). Hosts that need a different resolution strategy (subdomain, JWT claim, etc.) should compose their own middleware and call SetTenantID directly.
The legacy `header` parameter is retained for API compatibility but only consulted when the resolved tenant matches it — preventing header-only privilege escalation.
func WithMultiTenant ¶
func WithMultiTenant(ent *entity.Entity, config TenantConfig) *entity.Entity
WithMultiTenant configures an entity for multi-tenancy. It honors a custom tenant column: TenantConfig.Field flows into EntityConfig.TenantField, the single source of the column name used by entity injection, auto-migrate, and the CRUD insert/scope/filter paths. A blank or default "tenant_id" leaves TenantField unset (the default applies).
Types ¶
type TenantConfig ¶
type TenantConfig struct {
// Field is the database column name used for tenant scoping.
// Defaults to "tenant_id".
Field string
// Header is the HTTP header name from which the tenant ID is extracted.
// Defaults to "X-Tenant-ID".
Header string
// AutoScope, when true, automatically adds tenant filtering to all queries.
AutoScope bool
}
TenantConfig configures multi-tenancy behavior for an entity.
func DefaultTenantConfig ¶
func DefaultTenantConfig() TenantConfig
DefaultTenantConfig returns a TenantConfig with sensible defaults.