mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-17 05:18:04 +00:00
681541f41b
adds possibilities to cap authenticated requests and execution seconds of actions on a defined intervall
92 lines
2.5 KiB
Go
92 lines
2.5 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)
|
|
normalizeHeaders(a.RequestHeaders, strings.ToLower(zitadel_http.Authorization), "grpcgateway-authorization", "cookie", "grpcgateway-cookie")
|
|
normalizeHeaders(a.ResponseHeaders, "set-cookie")
|
|
return &a
|
|
}
|
|
|
|
const maxValuesPerKey = 10
|
|
|
|
// normalizeHeaders lowers all header keys and redacts secrets
|
|
func normalizeHeaders(header map[string][]string, redactKeysLower ...string) {
|
|
lowerKeys(header)
|
|
redactKeys(header, redactKeysLower...)
|
|
pruneKeys(header)
|
|
}
|
|
|
|
func lowerKeys(header map[string][]string) {
|
|
for k, v := range header {
|
|
delete(header, k)
|
|
header[strings.ToLower(k)] = v
|
|
}
|
|
}
|
|
|
|
func redactKeys(header map[string][]string, redactKeysLower ...string) {
|
|
for _, redactKey := range redactKeysLower {
|
|
if _, ok := header[redactKey]; ok {
|
|
header[redactKey] = []string{redacted}
|
|
}
|
|
}
|
|
}
|
|
|
|
func pruneKeys(header map[string][]string) {
|
|
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))
|
|
}
|
|
header[key] = valueItems
|
|
}
|
|
}
|
|
|
|
func cutString(str string, pos int) string {
|
|
if len(str) <= pos {
|
|
return str
|
|
}
|
|
return str[:pos-1]
|
|
}
|