mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-12 11:04:25 +00:00
058192c22b
* test: fix log headers * ensure just public types are tested * fix(postgres): proper statements for setup step 7 --------- Co-authored-by: adlerhurst <silvan.reusser@gmail.com>
98 lines
2.8 KiB
Go
98 lines
2.8 KiB
Go
package access
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
zitadel_http "github.com/zitadel/zitadel/internal/api/http"
|
|
"github.com/zitadel/zitadel/internal/logstore"
|
|
)
|
|
|
|
var _ logstore.LogRecord = (*Record)(nil)
|
|
|
|
type Record struct {
|
|
LogDate time.Time `json:"logDate"`
|
|
Protocol Protocol `json:"protocol"`
|
|
RequestURL string `json:"requestUrl"`
|
|
ResponseStatus uint32 `json:"responseStatus"`
|
|
// RequestHeaders are plain maps so varying implementation
|
|
// between HTTP and gRPC don't interfere with each other
|
|
RequestHeaders map[string][]string `json:"requestHeaders"`
|
|
// ResponseHeaders are plain maps so varying implementation
|
|
// between HTTP and gRPC don't interfere with each other
|
|
ResponseHeaders map[string][]string `json:"responseHeaders"`
|
|
InstanceID string `json:"instanceId"`
|
|
ProjectID string `json:"projectId"`
|
|
RequestedDomain string `json:"requestedDomain"`
|
|
RequestedHost string `json:"requestedHost"`
|
|
}
|
|
|
|
type Protocol uint8
|
|
|
|
const (
|
|
GRPC Protocol = iota
|
|
HTTP
|
|
|
|
redacted = "[REDACTED]"
|
|
)
|
|
|
|
func (a Record) Normalize() logstore.LogRecord {
|
|
a.RequestedDomain = cutString(a.RequestedDomain, 200)
|
|
a.RequestURL = cutString(a.RequestURL, 200)
|
|
a.RequestHeaders = normalizeHeaders(a.RequestHeaders, strings.ToLower(zitadel_http.Authorization), "grpcgateway-authorization", "cookie", "grpcgateway-cookie")
|
|
a.ResponseHeaders = normalizeHeaders(a.ResponseHeaders, "set-cookie")
|
|
return &a
|
|
}
|
|
|
|
// normalizeHeaders lowers all header keys and redacts secrets
|
|
func normalizeHeaders(header map[string][]string, redactKeysLower ...string) map[string][]string {
|
|
return pruneKeys(redactKeys(lowerKeys(header), redactKeysLower...))
|
|
}
|
|
|
|
func lowerKeys(header map[string][]string) map[string][]string {
|
|
lower := make(map[string][]string, len(header))
|
|
for k, v := range header {
|
|
lower[strings.ToLower(k)] = v
|
|
}
|
|
return lower
|
|
}
|
|
|
|
func redactKeys(header map[string][]string, redactKeysLower ...string) map[string][]string {
|
|
redactedKeys := make(map[string][]string, len(header))
|
|
for k, v := range header {
|
|
redactedKeys[k] = v
|
|
}
|
|
for _, redactKey := range redactKeysLower {
|
|
if _, ok := redactedKeys[redactKey]; ok {
|
|
redactedKeys[redactKey] = []string{redacted}
|
|
}
|
|
}
|
|
return redactedKeys
|
|
}
|
|
|
|
const maxValuesPerKey = 10
|
|
|
|
func pruneKeys(header map[string][]string) map[string][]string {
|
|
prunedKeys := make(map[string][]string, len(header))
|
|
for key, value := range header {
|
|
valueItems := make([]string, 0, maxValuesPerKey)
|
|
for i, valueItem := range value {
|
|
// Max 10 header values per key
|
|
if i > maxValuesPerKey {
|
|
break
|
|
}
|
|
// Max 200 value length
|
|
valueItems = append(valueItems, cutString(valueItem, 200))
|
|
}
|
|
prunedKeys[key] = valueItems
|
|
}
|
|
return prunedKeys
|
|
}
|
|
|
|
func cutString(str string, pos int) string {
|
|
if len(str) <= pos {
|
|
return str
|
|
}
|
|
return str[:pos-1]
|
|
}
|