CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package modulecall
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
HeaderTenant = "X-Nexarch-Tenant"
|
|
HeaderUser = "X-Nexarch-User"
|
|
maxLen = 128
|
|
)
|
|
|
|
var (
|
|
ErrTenantRequired = errors.New("modulecall: tenant-kontext fehlt")
|
|
ErrTenantMismatch = errors.New("modulecall: tenant-kontext passt nicht zur instanz")
|
|
)
|
|
|
|
type Context struct {
|
|
Tenant string
|
|
User string
|
|
}
|
|
|
|
func valid(s string) bool {
|
|
if s == "" || len(s) > maxLen {
|
|
return false
|
|
}
|
|
for _, r := range s {
|
|
if r < 0x21 || r == 0x7f {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func Apply(req *http.Request, tc Context, instanceTenant string) error {
|
|
if !valid(instanceTenant) || !valid(tc.Tenant) {
|
|
return ErrTenantRequired
|
|
}
|
|
if tc.Tenant != instanceTenant {
|
|
return ErrTenantMismatch
|
|
}
|
|
if tc.User != "" && !valid(tc.User) {
|
|
return ErrTenantRequired
|
|
}
|
|
req.Header.Set(HeaderTenant, tc.Tenant)
|
|
if tc.User != "" {
|
|
req.Header.Set(HeaderUser, tc.User)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func FromRequest(r *http.Request, instanceTenant string) (Context, error) {
|
|
if !valid(instanceTenant) {
|
|
return Context{}, ErrTenantRequired
|
|
}
|
|
tenant := strings.TrimSpace(r.Header.Get(HeaderTenant))
|
|
if !valid(tenant) {
|
|
return Context{}, ErrTenantRequired
|
|
}
|
|
if tenant != instanceTenant {
|
|
return Context{Tenant: tenant}, ErrTenantMismatch
|
|
}
|
|
return Context{Tenant: tenant, User: strings.TrimSpace(r.Header.Get(HeaderUser))}, nil
|
|
}
|