mirror of
https://dev.azure.com/schwarzit/schwarzit.stackit-public/_git/audit-go
synced 2026-02-07 16:47:24 +00:00
Merged PR 752362: feat: Apply stricter linter rules
Security-concept-update-needed: false. JIRA Work Item: STACKITALO-184
This commit is contained in:
parent
68cec628e0
commit
618be58a26
15 changed files with 388 additions and 125 deletions
272
.golangci.yml
Normal file
272
.golangci.yml
Normal file
|
|
@ -0,0 +1,272 @@
|
||||||
|
linters-settings:
|
||||||
|
errcheck:
|
||||||
|
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
|
||||||
|
# default is false: such cases aren't reported by default.
|
||||||
|
check-type-assertions: true
|
||||||
|
|
||||||
|
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
|
||||||
|
# default is false: such cases aren't reported by default.
|
||||||
|
check-blank: true
|
||||||
|
exhaustive:
|
||||||
|
# Presence of "default" case in switch statements satisfies exhaustiveness,
|
||||||
|
# even if all enum members are not listed.
|
||||||
|
default-signifies-exhaustive: true
|
||||||
|
funlen:
|
||||||
|
lines: 100
|
||||||
|
statements: 50
|
||||||
|
gocyclo:
|
||||||
|
min-complexity: 45
|
||||||
|
gocognit:
|
||||||
|
min-complexity: 45
|
||||||
|
dupl:
|
||||||
|
threshold: 150
|
||||||
|
goconst:
|
||||||
|
min-len: 3
|
||||||
|
min-occurrences: 5
|
||||||
|
govet:
|
||||||
|
enable-all: true
|
||||||
|
disable:
|
||||||
|
- fieldalignment
|
||||||
|
lll:
|
||||||
|
line-length: 180
|
||||||
|
tab-width: 1
|
||||||
|
cyclop:
|
||||||
|
# the maximal code complexity to report
|
||||||
|
max-complexity: 45
|
||||||
|
# the maximal average package complexity. If it's higher than 0.0 (float) the check is enabled (default 0.0)
|
||||||
|
package-average: 0.0
|
||||||
|
unused:
|
||||||
|
# treat code as a program (not a library) and report unused exported identifiers; default is false.
|
||||||
|
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
|
||||||
|
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
|
||||||
|
# with golangci-lint call it on a directory with the changed file.
|
||||||
|
check-exported: false
|
||||||
|
unparam:
|
||||||
|
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
|
||||||
|
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
|
||||||
|
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
|
||||||
|
# with golangci-lint call it on a directory with the changed file.
|
||||||
|
check-exported: false
|
||||||
|
nakedret:
|
||||||
|
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
|
||||||
|
max-func-lines: 5
|
||||||
|
prealloc:
|
||||||
|
# XXX: we don't recommend using this linter before doing performance profiling.
|
||||||
|
# For most programs usage of prealloc will be a premature optimization.
|
||||||
|
|
||||||
|
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
|
||||||
|
# True by default.
|
||||||
|
simple: true
|
||||||
|
range-loops: true # Report preallocation suggestions on range loops, true by default
|
||||||
|
for-loops: true # Report preallocation suggestions on for loops, false by default
|
||||||
|
gocritic:
|
||||||
|
enabled-tags:
|
||||||
|
- diagnostic
|
||||||
|
- experimental
|
||||||
|
- opinionated
|
||||||
|
- performance
|
||||||
|
- style
|
||||||
|
disabled-checks:
|
||||||
|
- dupImport # https://github.com/go-critic/go-critic/issues/845
|
||||||
|
- octalLiteral
|
||||||
|
- unnamedResult
|
||||||
|
# Settings passed to gocritic.
|
||||||
|
# The settings key is the name of a supported gocritic checker.
|
||||||
|
# The list of supported checkers can be find in https://go-critic.github.io/overview.
|
||||||
|
settings:
|
||||||
|
hugeParam:
|
||||||
|
# Size in bytes that makes the warning trigger.
|
||||||
|
# Default: 80
|
||||||
|
sizeThreshold: 121
|
||||||
|
dogsled:
|
||||||
|
# checks assignments with too many blank identifiers; default is 2
|
||||||
|
max-blank-identifiers: 2
|
||||||
|
whitespace:
|
||||||
|
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
|
||||||
|
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
|
||||||
|
gomoddirectives:
|
||||||
|
# List of allowed `replace` directives. Default is empty.
|
||||||
|
# Add your allowed `replace` targets here, this rule is so you don't accidentally commit replacements you added for testing
|
||||||
|
replace-allow-list: []
|
||||||
|
nolintlint:
|
||||||
|
allow-leading-space: false # require machine-readable nolint directives (i.e. with no leading space)
|
||||||
|
allow-unused: false # report any unused nolint directives
|
||||||
|
require-explanation: true # require an explanation for nolint directives
|
||||||
|
require-specific: true # require nolint directives to be specific about which linter is being skipped
|
||||||
|
nlreturn:
|
||||||
|
# Size of the block (including return statement that is still "OK")
|
||||||
|
# so no return split required.
|
||||||
|
block-size: 5
|
||||||
|
stylecheck:
|
||||||
|
initialisms: ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS"]
|
||||||
|
revive:
|
||||||
|
rules:
|
||||||
|
- name: context-keys-type
|
||||||
|
disabled: false
|
||||||
|
- name: time-naming
|
||||||
|
disabled: false
|
||||||
|
- name: var-declaration
|
||||||
|
disabled: false
|
||||||
|
- name: unexported-return
|
||||||
|
disabled: false
|
||||||
|
- name: errorf
|
||||||
|
disabled: false
|
||||||
|
- name: blank-imports
|
||||||
|
disabled: false
|
||||||
|
- name: context-as-argument
|
||||||
|
disabled: false
|
||||||
|
- name: dot-imports
|
||||||
|
disabled: false
|
||||||
|
- name: error-return
|
||||||
|
disabled: false
|
||||||
|
- name: error-strings
|
||||||
|
disabled: false
|
||||||
|
- name: error-naming
|
||||||
|
disabled: false
|
||||||
|
- name: exported
|
||||||
|
disabled: false
|
||||||
|
- name: increment-decrement
|
||||||
|
disabled: false
|
||||||
|
- name: var-naming
|
||||||
|
disabled: true
|
||||||
|
- name: package-comments
|
||||||
|
disabled: false
|
||||||
|
- name: range
|
||||||
|
disabled: false
|
||||||
|
- name: receiver-naming
|
||||||
|
disabled: false
|
||||||
|
- name: indent-error-flow
|
||||||
|
disabled: false
|
||||||
|
nestif:
|
||||||
|
min-complexity: 10
|
||||||
|
|
||||||
|
linters:
|
||||||
|
# please, do not use `enable-all`: it's deprecated and will be removed soon.
|
||||||
|
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- dogsled
|
||||||
|
- dupl
|
||||||
|
- copyloopvar
|
||||||
|
- exhaustive
|
||||||
|
- gochecknoinits
|
||||||
|
- goconst
|
||||||
|
- gocritic
|
||||||
|
- gocyclo
|
||||||
|
- goprintffuncname
|
||||||
|
- gosec
|
||||||
|
- govet
|
||||||
|
- ineffassign
|
||||||
|
- lll
|
||||||
|
- gosimple
|
||||||
|
- misspell
|
||||||
|
- nakedret
|
||||||
|
- nolintlint
|
||||||
|
- revive
|
||||||
|
- staticcheck
|
||||||
|
- typecheck
|
||||||
|
- unconvert
|
||||||
|
- unused
|
||||||
|
- gochecknoglobals
|
||||||
|
- prealloc
|
||||||
|
- asciicheck
|
||||||
|
- nestif
|
||||||
|
- bodyclose
|
||||||
|
- cyclop
|
||||||
|
- durationcheck
|
||||||
|
- errcheck
|
||||||
|
- errorlint
|
||||||
|
- forbidigo
|
||||||
|
- forcetypeassert
|
||||||
|
- gocognit
|
||||||
|
- gomoddirectives
|
||||||
|
- gomodguard
|
||||||
|
- importas
|
||||||
|
- makezero
|
||||||
|
- nilerr
|
||||||
|
- noctx
|
||||||
|
- predeclared
|
||||||
|
- promlinter
|
||||||
|
- rowserrcheck
|
||||||
|
- sqlclosecheck
|
||||||
|
- tparallel
|
||||||
|
- unparam
|
||||||
|
- wastedassign
|
||||||
|
|
||||||
|
issues:
|
||||||
|
# Excluding configuration per-path, per-linter, per-text and per-source
|
||||||
|
exclude-rules:
|
||||||
|
- path: audit/api/api_common.go
|
||||||
|
text: 'context-as-argument'
|
||||||
|
- path: audit/api/api.go|log/log.go|audit/api/model.go|telemetry/telemetry.go
|
||||||
|
linters:
|
||||||
|
- gochecknoglobals
|
||||||
|
- path: audit/api/api_.*.go
|
||||||
|
linters:
|
||||||
|
- dupl
|
||||||
|
- path: audit/api/model.go
|
||||||
|
text: 'exported: type name will be used as api.ApiRequest by other packages'
|
||||||
|
- path: audit/api/model_test.go|audit/api/model.go
|
||||||
|
text: 'G115'
|
||||||
|
- path: audit/api/test_data.go
|
||||||
|
linters:
|
||||||
|
- gosec
|
||||||
|
- path: _test\.go
|
||||||
|
linters:
|
||||||
|
- gochecknoglobals
|
||||||
|
- noctx
|
||||||
|
- forcetypeassert
|
||||||
|
- dogsled
|
||||||
|
- goconst
|
||||||
|
- unparam
|
||||||
|
- dupl
|
||||||
|
- errcheck
|
||||||
|
- forbidigo
|
||||||
|
- lll
|
||||||
|
- gocritic
|
||||||
|
- nestif
|
||||||
|
- revive
|
||||||
|
- gocognit
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- wsl
|
||||||
|
- gosimple
|
||||||
|
- ineffassign
|
||||||
|
- nakedret
|
||||||
|
- nlreturn
|
||||||
|
- staticcheck
|
||||||
|
- wastedassign
|
||||||
|
- text: 'declaration of "err" shadows declaration'
|
||||||
|
linters:
|
||||||
|
- govet
|
||||||
|
- path: test_.*\.go|audit/messaging/solace.go
|
||||||
|
linters:
|
||||||
|
- gochecknoglobals
|
||||||
|
- noctx
|
||||||
|
- forcetypeassert
|
||||||
|
- dogsled
|
||||||
|
- goconst
|
||||||
|
- unparam
|
||||||
|
- dupl
|
||||||
|
- errcheck
|
||||||
|
- forbidigo
|
||||||
|
- lll
|
||||||
|
- gocritic
|
||||||
|
- nestif
|
||||||
|
- revive
|
||||||
|
- gocognit
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- wsl
|
||||||
|
- gosimple
|
||||||
|
- ineffassign
|
||||||
|
- nakedret
|
||||||
|
- nlreturn
|
||||||
|
- staticcheck
|
||||||
|
- wastedassign
|
||||||
|
max-same-issues: 0
|
||||||
|
max-issues-per-linter: 0
|
||||||
|
run:
|
||||||
|
timeout: 10m
|
||||||
|
issues-exit-code: 1
|
||||||
|
tests: true
|
||||||
|
|
@ -47,13 +47,7 @@ func ObjectTypeFromPluralString(value string) ObjectType {
|
||||||
|
|
||||||
func (t ObjectType) IsSupportedType() error {
|
func (t ObjectType) IsSupportedType() error {
|
||||||
switch t {
|
switch t {
|
||||||
case ObjectTypeOrganization:
|
case ObjectTypeOrganization, ObjectTypeFolder, ObjectTypeProject, ObjectTypeSystem:
|
||||||
fallthrough
|
|
||||||
case ObjectTypeFolder:
|
|
||||||
fallthrough
|
|
||||||
case ObjectTypeProject:
|
|
||||||
fallthrough
|
|
||||||
case ObjectTypeSystem:
|
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return ErrUnknownObjectType
|
return ErrUnknownObjectType
|
||||||
|
|
|
||||||
|
|
@ -22,15 +22,16 @@ func convertAndSerializeIntoLegacyFormat(
|
||||||
|
|
||||||
// Event type
|
// Event type
|
||||||
var eventType string
|
var eventType string
|
||||||
if strings.HasSuffix(event.LogName, string(EventTypeAdminActivity)) {
|
switch {
|
||||||
|
case strings.HasSuffix(event.LogName, string(EventTypeAdminActivity)):
|
||||||
eventType = "ADMIN_ACTIVITY"
|
eventType = "ADMIN_ACTIVITY"
|
||||||
} else if strings.HasSuffix(event.LogName, string(EventTypeSystemEvent)) {
|
case strings.HasSuffix(event.LogName, string(EventTypeSystemEvent)):
|
||||||
eventType = "SYSTEM_EVENT"
|
eventType = "SYSTEM_EVENT"
|
||||||
} else if strings.HasSuffix(event.LogName, string(EventTypePolicyDenied)) {
|
case strings.HasSuffix(event.LogName, string(EventTypePolicyDenied)):
|
||||||
eventType = "POLICY_DENIED"
|
eventType = "POLICY_DENIED"
|
||||||
} else if strings.HasSuffix(event.LogName, string(EventTypeDataAccess)) {
|
case strings.HasSuffix(event.LogName, string(EventTypeDataAccess)):
|
||||||
return nil, ErrUnsupportedEventTypeDataAccess
|
return nil, ErrUnsupportedEventTypeDataAccess
|
||||||
} else {
|
default:
|
||||||
return nil, errors.New("unsupported event type")
|
return nil, errors.New("unsupported event type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,7 +47,7 @@ func convertAndSerializeIntoLegacyFormat(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Principals
|
// Principals
|
||||||
var serviceAccountDelegationInfo *LegacyAuditEventServiceAccountDelegationInfo = nil
|
var serviceAccountDelegationInfo *LegacyAuditEventServiceAccountDelegationInfo
|
||||||
if len(event.ProtoPayload.AuthenticationInfo.ServiceAccountDelegationInfo) > 0 {
|
if len(event.ProtoPayload.AuthenticationInfo.ServiceAccountDelegationInfo) > 0 {
|
||||||
var principals []LegacyAuditEventPrincipal
|
var principals []LegacyAuditEventPrincipal
|
||||||
for _, principal := range event.ProtoPayload.AuthenticationInfo.ServiceAccountDelegationInfo {
|
for _, principal := range event.ProtoPayload.AuthenticationInfo.ServiceAccountDelegationInfo {
|
||||||
|
|
@ -73,7 +74,7 @@ func convertAndSerializeIntoLegacyFormat(
|
||||||
Endpoint: "none",
|
Endpoint: "none",
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var parameters map[string]interface{} = nil
|
var parameters map[string]interface{}
|
||||||
if event.ProtoPayload.RequestMetadata.RequestAttributes.Path != "" &&
|
if event.ProtoPayload.RequestMetadata.RequestAttributes.Path != "" &&
|
||||||
event.ProtoPayload.RequestMetadata.RequestAttributes.Query != nil &&
|
event.ProtoPayload.RequestMetadata.RequestAttributes.Query != nil &&
|
||||||
*event.ProtoPayload.RequestMetadata.RequestAttributes.Query != "" {
|
*event.ProtoPayload.RequestMetadata.RequestAttributes.Query != "" {
|
||||||
|
|
@ -95,11 +96,11 @@ func convertAndSerializeIntoLegacyFormat(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var body map[string]interface{} = nil
|
var body map[string]interface{}
|
||||||
if event.ProtoPayload.Request != nil {
|
if event.ProtoPayload.Request != nil {
|
||||||
body = event.ProtoPayload.Request.AsMap()
|
body = event.ProtoPayload.Request.AsMap()
|
||||||
}
|
}
|
||||||
var headers map[string]interface{} = nil
|
var headers map[string]interface{}
|
||||||
if event.ProtoPayload.RequestMetadata.RequestAttributes.Headers != nil {
|
if event.ProtoPayload.RequestMetadata.RequestAttributes.Headers != nil {
|
||||||
headers = map[string]interface{}{}
|
headers = map[string]interface{}{}
|
||||||
for key, value := range event.ProtoPayload.RequestMetadata.RequestAttributes.Headers {
|
for key, value := range event.ProtoPayload.RequestMetadata.RequestAttributes.Headers {
|
||||||
|
|
@ -152,6 +153,8 @@ func convertAndSerializeIntoLegacyFormat(
|
||||||
visibility = "PUBLIC"
|
visibility = "PUBLIC"
|
||||||
case auditV1.Visibility_VISIBILITY_PRIVATE:
|
case auditV1.Visibility_VISIBILITY_PRIVATE:
|
||||||
visibility = "PRIVATE"
|
visibility = "PRIVATE"
|
||||||
|
case auditV1.Visibility_VISIBILITY_UNSPECIFIED:
|
||||||
|
visibility = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Details
|
// Details
|
||||||
|
|
@ -171,23 +174,16 @@ func convertAndSerializeIntoLegacyFormat(
|
||||||
// Severity
|
// Severity
|
||||||
var severity string
|
var severity string
|
||||||
switch event.Severity {
|
switch event.Severity {
|
||||||
case auditV1.LogSeverity_LOG_SEVERITY_DEFAULT:
|
case auditV1.LogSeverity_LOG_SEVERITY_DEFAULT,
|
||||||
fallthrough
|
auditV1.LogSeverity_LOG_SEVERITY_DEBUG,
|
||||||
case auditV1.LogSeverity_LOG_SEVERITY_DEBUG:
|
auditV1.LogSeverity_LOG_SEVERITY_INFO,
|
||||||
fallthrough
|
auditV1.LogSeverity_LOG_SEVERITY_NOTICE,
|
||||||
case auditV1.LogSeverity_LOG_SEVERITY_INFO:
|
auditV1.LogSeverity_LOG_SEVERITY_WARNING:
|
||||||
fallthrough
|
|
||||||
case auditV1.LogSeverity_LOG_SEVERITY_NOTICE:
|
|
||||||
fallthrough
|
|
||||||
case auditV1.LogSeverity_LOG_SEVERITY_WARNING:
|
|
||||||
severity = "INFO"
|
severity = "INFO"
|
||||||
case auditV1.LogSeverity_LOG_SEVERITY_ERROR:
|
case auditV1.LogSeverity_LOG_SEVERITY_ERROR,
|
||||||
fallthrough
|
auditV1.LogSeverity_LOG_SEVERITY_CRITICAL,
|
||||||
case auditV1.LogSeverity_LOG_SEVERITY_CRITICAL:
|
auditV1.LogSeverity_LOG_SEVERITY_ALERT,
|
||||||
fallthrough
|
auditV1.LogSeverity_LOG_SEVERITY_EMERGENCY:
|
||||||
case auditV1.LogSeverity_LOG_SEVERITY_ALERT:
|
|
||||||
fallthrough
|
|
||||||
case auditV1.LogSeverity_LOG_SEVERITY_EMERGENCY:
|
|
||||||
severity = "ERROR"
|
severity = "ERROR"
|
||||||
default:
|
default:
|
||||||
return nil, ErrUnsupportedSeverity
|
return nil, ErrUnsupportedSeverity
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ func (a *DynamicLegacyAuditApi) Send(
|
||||||
return ErrNoTopicNameProvided
|
return ErrNoTopicNameProvided
|
||||||
}
|
}
|
||||||
topicName := fmt.Sprintf("%s", rawTopicName)
|
topicName := fmt.Sprintf("%s", rawTopicName)
|
||||||
if len(topicName) == 0 {
|
if topicName == "" {
|
||||||
return ErrTopicNameEmpty
|
return ErrTopicNameEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,9 @@ func TestDynamicLegacyAuditApi(t *testing.T) {
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
||||||
ctx := context.WithValue(ctx, ContextKeyTopic, topicName)
|
ctxWithTopic := context.WithValue(ctx, ContextKeyTopic, topicName)
|
||||||
assert.ErrorIs(t, auditApi.Log(
|
assert.ErrorIs(t, auditApi.Log(
|
||||||
ctx,
|
ctxWithTopic,
|
||||||
event,
|
event,
|
||||||
visibility,
|
visibility,
|
||||||
NewRoutableIdentifier(objectIdentifier),
|
NewRoutableIdentifier(objectIdentifier),
|
||||||
|
|
@ -102,9 +102,9 @@ func TestDynamicLegacyAuditApi(t *testing.T) {
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
||||||
ctx := context.WithValue(ctx, ContextKeyTopic, topicName)
|
ctxWithTopic := context.WithValue(ctx, ContextKeyTopic, topicName)
|
||||||
assert.NoError(t, auditApi.Log(
|
assert.NoError(t, auditApi.Log(
|
||||||
ctx,
|
ctxWithTopic,
|
||||||
event,
|
event,
|
||||||
visibility,
|
visibility,
|
||||||
NewRoutableIdentifier(objectIdentifier),
|
NewRoutableIdentifier(objectIdentifier),
|
||||||
|
|
@ -139,9 +139,9 @@ func TestDynamicLegacyAuditApi(t *testing.T) {
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PRIVATE
|
visibility := auditV1.Visibility_VISIBILITY_PRIVATE
|
||||||
ctx := context.WithValue(ctx, ContextKeyTopic, topicName)
|
ctxWithTopic := context.WithValue(ctx, ContextKeyTopic, topicName)
|
||||||
assert.NoError(t, auditApi.Log(
|
assert.NoError(t, auditApi.Log(
|
||||||
ctx,
|
ctxWithTopic,
|
||||||
event,
|
event,
|
||||||
visibility,
|
visibility,
|
||||||
NewRoutableIdentifier(objectIdentifier),
|
NewRoutableIdentifier(objectIdentifier),
|
||||||
|
|
@ -177,9 +177,9 @@ func TestDynamicLegacyAuditApi(t *testing.T) {
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
||||||
ctx := context.WithValue(ctx, ContextKeyTopic, topicName)
|
ctxWithTopic := context.WithValue(ctx, ContextKeyTopic, topicName)
|
||||||
assert.NoError(t, auditApi.Log(
|
assert.NoError(t, auditApi.Log(
|
||||||
ctx,
|
ctxWithTopic,
|
||||||
event,
|
event,
|
||||||
visibility,
|
visibility,
|
||||||
NewRoutableIdentifier(objectIdentifier),
|
NewRoutableIdentifier(objectIdentifier),
|
||||||
|
|
@ -214,9 +214,9 @@ func TestDynamicLegacyAuditApi(t *testing.T) {
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PRIVATE
|
visibility := auditV1.Visibility_VISIBILITY_PRIVATE
|
||||||
ctx := context.WithValue(ctx, ContextKeyTopic, topicName)
|
ctxWithTopic := context.WithValue(ctx, ContextKeyTopic, topicName)
|
||||||
assert.NoError(t, auditApi.Log(
|
assert.NoError(t, auditApi.Log(
|
||||||
ctx,
|
ctxWithTopic,
|
||||||
event,
|
event,
|
||||||
visibility,
|
visibility,
|
||||||
NewRoutableIdentifier(objectIdentifier),
|
NewRoutableIdentifier(objectIdentifier),
|
||||||
|
|
@ -252,9 +252,9 @@ func TestDynamicLegacyAuditApi(t *testing.T) {
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
||||||
ctx := context.WithValue(ctx, ContextKeyTopic, topicName)
|
ctxWithTopic := context.WithValue(ctx, ContextKeyTopic, topicName)
|
||||||
assert.NoError(t, auditApi.Log(
|
assert.NoError(t, auditApi.Log(
|
||||||
ctx,
|
ctxWithTopic,
|
||||||
event,
|
event,
|
||||||
visibility,
|
visibility,
|
||||||
NewRoutableIdentifier(objectIdentifier),
|
NewRoutableIdentifier(objectIdentifier),
|
||||||
|
|
@ -289,9 +289,9 @@ func TestDynamicLegacyAuditApi(t *testing.T) {
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PRIVATE
|
visibility := auditV1.Visibility_VISIBILITY_PRIVATE
|
||||||
ctx := context.WithValue(ctx, ContextKeyTopic, topicName)
|
ctxWithTopic := context.WithValue(ctx, ContextKeyTopic, topicName)
|
||||||
assert.NoError(t, auditApi.Log(
|
assert.NoError(t, auditApi.Log(
|
||||||
ctx,
|
ctxWithTopic,
|
||||||
event,
|
event,
|
||||||
visibility,
|
visibility,
|
||||||
NewRoutableIdentifier(objectIdentifier),
|
NewRoutableIdentifier(objectIdentifier),
|
||||||
|
|
@ -326,10 +326,10 @@ func TestDynamicLegacyAuditApi(t *testing.T) {
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PRIVATE
|
visibility := auditV1.Visibility_VISIBILITY_PRIVATE
|
||||||
ctx := context.WithValue(ctx, ContextKeyTopic, topicName)
|
ctxWithTopic := context.WithValue(ctx, ContextKeyTopic, topicName)
|
||||||
assert.NoError(t,
|
assert.NoError(t,
|
||||||
auditApi.Log(
|
auditApi.Log(
|
||||||
ctx,
|
ctxWithTopic,
|
||||||
event,
|
event,
|
||||||
visibility,
|
visibility,
|
||||||
RoutableSystemIdentifier,
|
RoutableSystemIdentifier,
|
||||||
|
|
@ -382,10 +382,10 @@ func TestDynamicLegacyAuditApi(t *testing.T) {
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PRIVATE
|
visibility := auditV1.Visibility_VISIBILITY_PRIVATE
|
||||||
ctx := context.WithValue(ctx, ContextKeyTopic, topicName)
|
ctxWithTopic := context.WithValue(ctx, ContextKeyTopic, topicName)
|
||||||
assert.NoError(t,
|
assert.NoError(t,
|
||||||
auditApi.Log(
|
auditApi.Log(
|
||||||
ctx,
|
ctxWithTopic,
|
||||||
event,
|
event,
|
||||||
visibility,
|
visibility,
|
||||||
RoutableSystemIdentifier,
|
RoutableSystemIdentifier,
|
||||||
|
|
@ -439,9 +439,9 @@ func TestDynamicLegacyAuditApi(t *testing.T) {
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
||||||
ctx := context.WithValue(ctx, ContextKeyTopic, topicName)
|
ctxWithTopic := context.WithValue(ctx, ContextKeyTopic, topicName)
|
||||||
assert.NoError(t, auditApi.Log(
|
assert.NoError(t, auditApi.Log(
|
||||||
ctx,
|
ctxWithTopic,
|
||||||
event,
|
event,
|
||||||
visibility,
|
visibility,
|
||||||
NewRoutableIdentifier(objectIdentifier),
|
NewRoutableIdentifier(objectIdentifier),
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,12 @@ func TestMockAuditApi_Log(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("reject data access event", func(t *testing.T) {
|
t.Run("reject data access event", func(t *testing.T) {
|
||||||
event, objectIdentifier := newOrganizationAuditEvent(nil)
|
orgEvent, objIdentifier := newOrganizationAuditEvent(nil)
|
||||||
event.LogName = strings.Replace(event.LogName, string(EventTypeAdminActivity), string(EventTypeDataAccess), 1)
|
orgEvent.LogName = strings.Replace(orgEvent.LogName, string(EventTypeAdminActivity), string(EventTypeDataAccess), 1)
|
||||||
routableObjectIdentifier := NewRoutableIdentifier(objectIdentifier)
|
rtIdentifier := NewRoutableIdentifier(objIdentifier)
|
||||||
|
|
||||||
assert.ErrorIs(t, auditApi.Log(
|
assert.ErrorIs(t, auditApi.Log(
|
||||||
context.Background(), event, auditV1.Visibility_VISIBILITY_PUBLIC, routableObjectIdentifier),
|
context.Background(), orgEvent, auditV1.Visibility_VISIBILITY_PUBLIC, rtIdentifier),
|
||||||
ErrUnsupportedEventTypeDataAccess)
|
ErrUnsupportedEventTypeDataAccess)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ func ToBase64(
|
||||||
}
|
}
|
||||||
|
|
||||||
base64Str := base64.StdEncoding.EncodeToString(serializedEvent)
|
base64Str := base64.StdEncoding.EncodeToString(serializedEvent)
|
||||||
base64Str = base64Str + base64AuditEventV1
|
base64Str += base64AuditEventV1
|
||||||
return &base64Str, nil
|
return &base64Str, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ func (builder *AuditLogEntryBuilder) WithResponseBody(responseBody any) *AuditLo
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithResponseBodyBytes adds the response body as bytes (serialized json or protobuf message expected)
|
// WithResponseBodyBytes adds the response body as bytes (serialized json or protobuf message expected)
|
||||||
func (builder *AuditLogEntryBuilder) WithResponseBodyBytes(responseBody *[]byte) *AuditLogEntryBuilder {
|
func (builder *AuditLogEntryBuilder) WithResponseBodyBytes(responseBody []byte) *AuditLogEntryBuilder {
|
||||||
builder.auditResponse.ResponseBodyBytes = responseBody
|
builder.auditResponse.ResponseBodyBytes = responseBody
|
||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
@ -359,9 +359,9 @@ func (builder *AuditLogEntryBuilder) Build(ctx context.Context, sequenceNumber S
|
||||||
builder.auditMetadata.AuditLogName = fmt.Sprintf("%s/%s/logs/%s", logType.Plural(), logIdentifier, builder.auditParams.EventType)
|
builder.auditMetadata.AuditLogName = fmt.Sprintf("%s/%s/logs/%s", logType.Plural(), logIdentifier, builder.auditParams.EventType)
|
||||||
builder.auditMetadata.AuditResourceName = resourceName
|
builder.auditMetadata.AuditResourceName = resourceName
|
||||||
|
|
||||||
var details *map[string]interface{} = nil
|
var details map[string]interface{}
|
||||||
if len(builder.auditParams.Details) > 0 {
|
if len(builder.auditParams.Details) > 0 {
|
||||||
details = &builder.auditParams.Details
|
details = builder.auditParams.Details
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instantiate the audit event
|
// Instantiate the audit event
|
||||||
|
|
@ -575,7 +575,7 @@ func (builder *AuditEventBuilder) WithResponseBody(responseBody any) *AuditEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithResponseBodyBytes adds the response body as bytes (serialized json or protobuf message expected)
|
// WithResponseBodyBytes adds the response body as bytes (serialized json or protobuf message expected)
|
||||||
func (builder *AuditEventBuilder) WithResponseBodyBytes(responseBody *[]byte) *AuditEventBuilder {
|
func (builder *AuditEventBuilder) WithResponseBodyBytes(responseBody []byte) *AuditEventBuilder {
|
||||||
builder.auditLogEntryBuilder.WithResponseBodyBytes(responseBody)
|
builder.auditLogEntryBuilder.WithResponseBodyBytes(responseBody)
|
||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,14 @@ var ErrInvalidAuthorizationHeaderValue = errors.New("invalid authorization heade
|
||||||
var ErrInvalidBearerToken = errors.New("invalid bearer token")
|
var ErrInvalidBearerToken = errors.New("invalid bearer token")
|
||||||
var ErrTokenIsNotBearerToken = errors.New("token is not a bearer token")
|
var ErrTokenIsNotBearerToken = errors.New("token is not a bearer token")
|
||||||
|
|
||||||
var objectTypeIdPattern, _ = regexp.Compile(".*/(projects|folders|organizations)/([0-9a-fA-F-]{36})(?:/.*)?")
|
var objectTypeIdPattern = regexp.MustCompile(".*/(projects|folders|organizations)/([0-9a-fA-F-]{36})(?:/.*)?")
|
||||||
|
|
||||||
type ApiRequest struct {
|
type ApiRequest struct {
|
||||||
|
|
||||||
// Body
|
// Body
|
||||||
//
|
//
|
||||||
// Required: false
|
// Required: false
|
||||||
Body *[]byte
|
Body []byte
|
||||||
|
|
||||||
// The (HTTP) request headers / gRPC metadata.
|
// The (HTTP) request headers / gRPC metadata.
|
||||||
//
|
//
|
||||||
|
|
@ -145,7 +145,7 @@ type AuditResponse struct {
|
||||||
// elsewhere in the log record.
|
// elsewhere in the log record.
|
||||||
//
|
//
|
||||||
// Required: false
|
// Required: false
|
||||||
ResponseBodyBytes *[]byte
|
ResponseBodyBytes []byte
|
||||||
|
|
||||||
// The http or gRPC status code.
|
// The http or gRPC status code.
|
||||||
//
|
//
|
||||||
|
|
@ -294,7 +294,7 @@ func NewAuditLogEntry(
|
||||||
auditResponse AuditResponse,
|
auditResponse AuditResponse,
|
||||||
|
|
||||||
// Optional map that is added as "details" to the message
|
// Optional map that is added as "details" to the message
|
||||||
eventMetadata *map[string]interface{},
|
eventMetadata map[string]interface{},
|
||||||
|
|
||||||
// Required metadata
|
// Required metadata
|
||||||
auditMetadata AuditMetadata,
|
auditMetadata AuditMetadata,
|
||||||
|
|
@ -309,9 +309,9 @@ func NewAuditLogEntry(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Join(err, ErrInvalidResponse)
|
return nil, errors.Join(err, ErrInvalidResponse)
|
||||||
}
|
}
|
||||||
var responseLength *int64 = nil
|
var responseLength *int64
|
||||||
if responseBody != nil {
|
if responseBody != nil {
|
||||||
length := int64(len(*auditResponse.ResponseBodyBytes))
|
length := int64(len(auditResponse.ResponseBodyBytes))
|
||||||
responseLength = &length
|
responseLength = &length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -332,7 +332,7 @@ func NewAuditLogEntry(
|
||||||
scheme := auditRequest.Request.Scheme
|
scheme := auditRequest.Request.Scheme
|
||||||
|
|
||||||
// Initialize authorization info if available
|
// Initialize authorization info if available
|
||||||
var authorizationInfo []*auditV1.AuthorizationInfo = nil
|
var authorizationInfo []*auditV1.AuthorizationInfo
|
||||||
if auditMetadata.AuditPermission != nil && auditMetadata.AuditPermissionGranted != nil {
|
if auditMetadata.AuditPermission != nil && auditMetadata.AuditPermissionGranted != nil {
|
||||||
authorizationInfo = []*auditV1.AuthorizationInfo{
|
authorizationInfo = []*auditV1.AuthorizationInfo{
|
||||||
NewAuthorizationInfo(
|
NewAuthorizationInfo(
|
||||||
|
|
@ -342,15 +342,15 @@ func NewAuditLogEntry(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize labels if available
|
// Initialize labels if available
|
||||||
var labels map[string]string = nil
|
var labels map[string]string
|
||||||
if auditMetadata.AuditLabels != nil {
|
if auditMetadata.AuditLabels != nil {
|
||||||
labels = *auditMetadata.AuditLabels
|
labels = *auditMetadata.AuditLabels
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize metadata/details
|
// Initialize metadata/details
|
||||||
var metadata *structpb.Struct = nil
|
var metadata *structpb.Struct
|
||||||
if eventMetadata != nil {
|
if eventMetadata != nil {
|
||||||
metadataStruct, err := structpb.NewStruct(*eventMetadata)
|
metadataStruct, err := structpb.NewStruct(eventMetadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -480,7 +480,7 @@ func NewRequestAttributes(
|
||||||
) *auditV1.AttributeContext_Request {
|
) *auditV1.AttributeContext_Request {
|
||||||
|
|
||||||
rawQuery := request.URL.RawQuery
|
rawQuery := request.URL.RawQuery
|
||||||
var query *string = nil
|
var query *string
|
||||||
if rawQuery != nil && *rawQuery != "" {
|
if rawQuery != nil && *rawQuery != "" {
|
||||||
escapedQuery := url.QueryEscape(*rawQuery)
|
escapedQuery := url.QueryEscape(*rawQuery)
|
||||||
query = &escapedQuery
|
query = &escapedQuery
|
||||||
|
|
@ -505,7 +505,7 @@ func NewRequestAttributes(
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAuthorizationInfo returns protobuf AuthorizationInfo for the given parameters.
|
// NewAuthorizationInfo returns protobuf AuthorizationInfo for the given parameters.
|
||||||
func NewAuthorizationInfo(resourceName string, permission string, granted bool) *auditV1.AuthorizationInfo {
|
func NewAuthorizationInfo(resourceName, permission string, granted bool) *auditV1.AuthorizationInfo {
|
||||||
return &auditV1.AuthorizationInfo{
|
return &auditV1.AuthorizationInfo{
|
||||||
Resource: resourceName,
|
Resource: resourceName,
|
||||||
Permission: &permission,
|
Permission: &permission,
|
||||||
|
|
@ -514,14 +514,14 @@ func NewAuthorizationInfo(resourceName string, permission string, granted bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInsertId returns a correctly formatted insert id.
|
// NewInsertId returns a correctly formatted insert id.
|
||||||
func NewInsertId(insertTime time.Time, location string, workerId string, eventSequenceNumber uint64) string {
|
func NewInsertId(insertTime time.Time, location, workerId string, eventSequenceNumber uint64) string {
|
||||||
return fmt.Sprintf("%d/%s/%s/%d", insertTime.UnixNano(), location, workerId, eventSequenceNumber)
|
return fmt.Sprintf("%d/%s/%s/%d", insertTime.UnixNano(), location, workerId, eventSequenceNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewResponseMetadata returns protobuf response status with status code and short message.
|
// NewResponseMetadata returns protobuf response status with status code and short message.
|
||||||
func NewResponseMetadata(statusCode int, numResponseItems *int64, responseSize *int64, headers map[string]string, responseTime time.Time) *auditV1.ResponseMetadata {
|
func NewResponseMetadata(statusCode int, numResponseItems, responseSize *int64, headers map[string]string, responseTime time.Time) *auditV1.ResponseMetadata {
|
||||||
|
|
||||||
var message *string = nil
|
var message *string
|
||||||
if statusCode >= 400 && statusCode < 500 {
|
if statusCode >= 400 && statusCode < 500 {
|
||||||
text := "Client error"
|
text := "Client error"
|
||||||
message = &text
|
message = &text
|
||||||
|
|
@ -530,7 +530,7 @@ func NewResponseMetadata(statusCode int, numResponseItems *int64, responseSize *
|
||||||
message = &text
|
message = &text
|
||||||
}
|
}
|
||||||
|
|
||||||
var size *wrapperspb.Int64Value = nil
|
var size *wrapperspb.Int64Value
|
||||||
if responseSize != nil {
|
if responseSize != nil {
|
||||||
size = wrapperspb.Int64(*responseSize)
|
size = wrapperspb.Int64(*responseSize)
|
||||||
}
|
}
|
||||||
|
|
@ -548,26 +548,26 @@ func NewResponseMetadata(statusCode int, numResponseItems *int64, responseSize *
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewResponseBody converts the JSON byte response into a protobuf struct.
|
// NewResponseBody converts the JSON byte response into a protobuf struct.
|
||||||
func NewResponseBody(response *[]byte) (*structpb.Struct, error) {
|
func NewResponseBody(response []byte) (*structpb.Struct, error) {
|
||||||
|
|
||||||
// Return if nil
|
// Return if nil
|
||||||
if response == nil || len(*response) == 0 {
|
if len(response) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to protobuf struct
|
// Convert to protobuf struct
|
||||||
return byteArrayToPbStruct(*response)
|
return byteArrayToPbStruct(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRequestBody converts the request body into a protobuf struct.
|
// NewRequestBody converts the request body into a protobuf struct.
|
||||||
func NewRequestBody(request *ApiRequest) (*structpb.Struct, error) {
|
func NewRequestBody(request *ApiRequest) (*structpb.Struct, error) {
|
||||||
|
|
||||||
if request.Body == nil || len(*request.Body) == 0 {
|
if len(request.Body) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to protobuf struct
|
// Convert to protobuf struct
|
||||||
return byteArrayToPbStruct(*request.Body)
|
return byteArrayToPbStruct(request.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// byteArrayToPbStruct converts a given json byte array into a protobuf struct.
|
// byteArrayToPbStruct converts a given json byte array into a protobuf struct.
|
||||||
|
|
@ -636,14 +636,17 @@ func AuditAttributesFromAuthorizationHeader(request *ApiRequest) (
|
||||||
error,
|
error,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
var authenticationPrincipal = "none/none"
|
||||||
var principalId = "none"
|
var principalId = "none"
|
||||||
var principalEmail = EmailAddressDoNotReplyAtStackItDotCloud
|
var principalEmail = EmailAddressDoNotReplyAtStackItDotCloud
|
||||||
emptyClaims, _ := structpb.NewStruct(make(map[string]interface{}))
|
emptyClaims, err := structpb.NewStruct(make(map[string]interface{}))
|
||||||
|
if err != nil {
|
||||||
|
return nil, authenticationPrincipal, nil, nil, err
|
||||||
|
}
|
||||||
var auditClaims = emptyClaims
|
var auditClaims = emptyClaims
|
||||||
var authenticationPrincipal = "none/none"
|
var serviceAccountName *string
|
||||||
var serviceAccountName *string = nil
|
|
||||||
audiences := make([]string, 0)
|
audiences := make([]string, 0)
|
||||||
var delegationInfo []*auditV1.ServiceAccountDelegationInfo = nil
|
var delegationInfo []*auditV1.ServiceAccountDelegationInfo
|
||||||
|
|
||||||
authorizationHeaders := request.Header["Authorization"]
|
authorizationHeaders := request.Header["Authorization"]
|
||||||
if len(authorizationHeaders) == 0 {
|
if len(authorizationHeaders) == 0 {
|
||||||
|
|
@ -652,7 +655,7 @@ func AuditAttributesFromAuthorizationHeader(request *ApiRequest) (
|
||||||
}
|
}
|
||||||
authorizationHeader := strings.Join(authorizationHeaders, ",")
|
authorizationHeader := strings.Join(authorizationHeaders, ",")
|
||||||
trimmedAuthorizationHeader := strings.TrimSpace(authorizationHeader)
|
trimmedAuthorizationHeader := strings.TrimSpace(authorizationHeader)
|
||||||
if len(trimmedAuthorizationHeader) > 0 {
|
if trimmedAuthorizationHeader != "" {
|
||||||
|
|
||||||
// Parse claims
|
// Parse claims
|
||||||
token, err := parseToken(trimmedAuthorizationHeader)
|
token, err := parseToken(trimmedAuthorizationHeader)
|
||||||
|
|
@ -712,9 +715,8 @@ func getTokenClaim(token jwt.Token, claimName string) *string {
|
||||||
if claimExists {
|
if claimExists {
|
||||||
claimString := fmt.Sprintf("%s", claim)
|
claimString := fmt.Sprintf("%s", claim)
|
||||||
return &claimString
|
return &claimString
|
||||||
} else {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractAuthenticationPrincipal(token jwt.Token) string {
|
func extractAuthenticationPrincipal(token jwt.Token) string {
|
||||||
|
|
@ -792,9 +794,8 @@ func extractServiceAccountDelegationInfoDetails(actClaims map[string]interface{}
|
||||||
nestedDelegations := extractServiceAccountDelegationInfo(actClaims)
|
nestedDelegations := extractServiceAccountDelegationInfo(actClaims)
|
||||||
if len(nestedDelegations) > 0 {
|
if len(nestedDelegations) > 0 {
|
||||||
return append(delegations, nestedDelegations...)
|
return append(delegations, nestedDelegations...)
|
||||||
} else {
|
|
||||||
return delegations
|
|
||||||
}
|
}
|
||||||
|
return delegations
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractServiceAccountDelegationInfo(claims map[string]interface{}) []*auditV1.ServiceAccountDelegationInfo {
|
func extractServiceAccountDelegationInfo(claims map[string]interface{}) []*auditV1.ServiceAccountDelegationInfo {
|
||||||
|
|
@ -840,7 +841,7 @@ func extractSubjectAndEmail(token jwt.Token) (string, string) {
|
||||||
// - PATCH - update
|
// - PATCH - update
|
||||||
// - DELETE - delete
|
// - DELETE - delete
|
||||||
// - others - read
|
// - others - read
|
||||||
func OperationNameFromUrlPath(path string, requestMethod string) string {
|
func OperationNameFromUrlPath(path, requestMethod string) string {
|
||||||
queryIdx := strings.Index(path, "?")
|
queryIdx := strings.Index(path, "?")
|
||||||
if queryIdx != -1 {
|
if queryIdx != -1 {
|
||||||
path = path[:queryIdx]
|
path = path[:queryIdx]
|
||||||
|
|
@ -862,13 +863,12 @@ func OperationNameFromUrlPath(path string, requestMethod string) string {
|
||||||
operation = strings.ReplaceAll(operation, "/", ".")
|
operation = strings.ReplaceAll(operation, "/", ".")
|
||||||
operation = strings.TrimPrefix(operation, ".")
|
operation = strings.TrimPrefix(operation, ".")
|
||||||
operation = strings.ToLower(operation)
|
operation = strings.ToLower(operation)
|
||||||
if len(operation) > 0 {
|
if operation != "" {
|
||||||
method := StringToHttpMethod(requestMethod)
|
method := StringToHttpMethod(requestMethod)
|
||||||
var action string
|
var action string
|
||||||
switch method {
|
switch method {
|
||||||
case auditV1.AttributeContext_HTTP_METHOD_PUT:
|
case auditV1.AttributeContext_HTTP_METHOD_PUT,
|
||||||
fallthrough
|
auditV1.AttributeContext_HTTP_METHOD_PATCH:
|
||||||
case auditV1.AttributeContext_HTTP_METHOD_PATCH:
|
|
||||||
action = "update"
|
action = "update"
|
||||||
case auditV1.AttributeContext_HTTP_METHOD_POST:
|
case auditV1.AttributeContext_HTTP_METHOD_POST:
|
||||||
action = "create"
|
action = "create"
|
||||||
|
|
@ -936,14 +936,14 @@ func StringAttributeFromMetadata(metadata map[string][]string, name string) stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResponseBodyToBytes converts a JSON or Protobuf response into a byte array
|
// ResponseBodyToBytes converts a JSON or Protobuf response into a byte array
|
||||||
func ResponseBodyToBytes(response any) (*[]byte, error) {
|
func ResponseBodyToBytes(response any) ([]byte, error) {
|
||||||
if response == nil {
|
if response == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
responseBytes, isBytes := response.([]byte)
|
responseBytes, isBytes := response.([]byte)
|
||||||
if isBytes {
|
if isBytes {
|
||||||
return &responseBytes, nil
|
return responseBytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
responseProtoMessage, isProtoMessage := response.(proto.Message)
|
responseProtoMessage, isProtoMessage := response.(proto.Message)
|
||||||
|
|
@ -952,12 +952,13 @@ func ResponseBodyToBytes(response any) (*[]byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &responseJson, nil
|
return responseJson, nil
|
||||||
} else {
|
|
||||||
responseJson, err := json.Marshal(response)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &responseJson, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
responseJson, err := json.Marshal(response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return responseJson, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -787,7 +787,7 @@ func Test_NewAuditLogEntry(t *testing.T) {
|
||||||
Proto: "HTTP/1.1",
|
Proto: "HTTP/1.1",
|
||||||
Scheme: "http",
|
Scheme: "http",
|
||||||
Header: requestHeaders,
|
Header: requestHeaders,
|
||||||
Body: &requestBodyBytes,
|
Body: requestBodyBytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
clientIp := "127.0.0.1"
|
clientIp := "127.0.0.1"
|
||||||
|
|
@ -814,7 +814,7 @@ func Test_NewAuditLogEntry(t *testing.T) {
|
||||||
responseTime := time.Now().UTC()
|
responseTime := time.Now().UTC()
|
||||||
|
|
||||||
auditResponse := AuditResponse{
|
auditResponse := AuditResponse{
|
||||||
ResponseBodyBytes: &responseBody,
|
ResponseBodyBytes: responseBody,
|
||||||
ResponseStatusCode: responseStatusCode,
|
ResponseStatusCode: responseStatusCode,
|
||||||
ResponseHeaders: responseHeader,
|
ResponseHeaders: responseHeader,
|
||||||
ResponseNumItems: &responseNumItems,
|
ResponseNumItems: &responseNumItems,
|
||||||
|
|
@ -853,7 +853,7 @@ func Test_NewAuditLogEntry(t *testing.T) {
|
||||||
logEntry, _ := NewAuditLogEntry(
|
logEntry, _ := NewAuditLogEntry(
|
||||||
auditRequest,
|
auditRequest,
|
||||||
auditResponse,
|
auditResponse,
|
||||||
&eventMetadata,
|
eventMetadata,
|
||||||
auditMetadata)
|
auditMetadata)
|
||||||
|
|
||||||
assert.Equal(t, logName, logEntry.LogName)
|
assert.Equal(t, logName, logEntry.LogName)
|
||||||
|
|
@ -1104,7 +1104,7 @@ func Test_ResponseBodyToBytes(t *testing.T) {
|
||||||
responseBody := []byte("data")
|
responseBody := []byte("data")
|
||||||
bytes, err := ResponseBodyToBytes(responseBody)
|
bytes, err := ResponseBodyToBytes(responseBody)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, &responseBody, bytes)
|
assert.Equal(t, responseBody, bytes)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1116,7 +1116,7 @@ func Test_ResponseBodyToBytes(t *testing.T) {
|
||||||
|
|
||||||
expected, err := protojson.Marshal(&protobufMessage)
|
expected, err := protojson.Marshal(&protobufMessage)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, &expected, bytes)
|
assert.Equal(t, expected, bytes)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1132,7 +1132,7 @@ func Test_ResponseBodyToBytes(t *testing.T) {
|
||||||
|
|
||||||
expected, err := json.Marshal(responseBody)
|
expected, err := json.Marshal(responseBody)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, &expected, bytes)
|
assert.Equal(t, expected, bytes)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1145,7 +1145,7 @@ func Test_ResponseBodyToBytes(t *testing.T) {
|
||||||
|
|
||||||
expected, err := json.Marshal(responseBody)
|
expected, err := json.Marshal(responseBody)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, &expected, bytes)
|
assert.Equal(t, expected, bytes)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ func TraceParentAndStateFromContext(ctx context.Context) (string, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddTraceParentAndStateToContext adds trace and state related information to the given context.
|
// AddTraceParentAndStateToContext adds trace and state related information to the given context.
|
||||||
func AddTraceParentAndStateToContext(ctx context.Context, traceParent string, traceState string) context.Context {
|
func AddTraceParentAndStateToContext(ctx context.Context, traceParent, traceState string) context.Context {
|
||||||
mapCarrier := propagation.MapCarrier{}
|
mapCarrier := propagation.MapCarrier{}
|
||||||
mapCarrier[traceParentHeader] = traceParent
|
mapCarrier[traceParentHeader] = traceParent
|
||||||
mapCarrier[traceStateHeader] = traceState
|
mapCarrier[traceStateHeader] = traceState
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ConnectionClosedError = errors.New("amqp connection is closed")
|
var ErrConnectionClosed = errors.New("amqp connection is closed")
|
||||||
|
|
||||||
type AmqpConnection struct {
|
type AmqpConnection struct {
|
||||||
connectionName string
|
connectionName string
|
||||||
|
|
@ -115,7 +115,7 @@ func (c *AmqpConnection) NewSender(ctx context.Context, topic string) (*AmqpSend
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.internalIsClosed() {
|
if c.internalIsClosed() {
|
||||||
return nil, ConnectionClosedError
|
return nil, ErrConnectionClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
c.lock.RLock()
|
c.lock.RLock()
|
||||||
|
|
|
||||||
|
|
@ -137,9 +137,9 @@ func (p *AmqpConnectionPool) NewHandle() *ConnectionPoolHandle {
|
||||||
defer p.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
|
|
||||||
offset := p.handleOffset
|
offset := p.handleOffset
|
||||||
p.handleOffset += 1
|
p.handleOffset++
|
||||||
|
|
||||||
offset = offset % p.config.PoolSize
|
offset %= p.config.PoolSize
|
||||||
|
|
||||||
return &ConnectionPoolHandle{
|
return &ConnectionPoolHandle{
|
||||||
connectionOffset: offset,
|
connectionOffset: offset,
|
||||||
|
|
@ -224,7 +224,6 @@ func (p *AmqpConnectionPool) nextConnectionForHandle(handle *ConnectionPoolHandl
|
||||||
func (p *AmqpConnectionPool) connectionIndex(handle *ConnectionPoolHandle, iteration int) int {
|
func (p *AmqpConnectionPool) connectionIndex(handle *ConnectionPoolHandle, iteration int) int {
|
||||||
if iteration+handle.connectionOffset >= p.config.PoolSize {
|
if iteration+handle.connectionOffset >= p.config.PoolSize {
|
||||||
return (iteration + handle.connectionOffset) % p.config.PoolSize
|
return (iteration + handle.connectionOffset) % p.config.PoolSize
|
||||||
} else {
|
|
||||||
return iteration + handle.connectionOffset
|
|
||||||
}
|
}
|
||||||
|
return iteration + handle.connectionOffset
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ func (g *DefaultSequenceNumberGenerator) Next() uint64 {
|
||||||
var next uint64
|
var next uint64
|
||||||
if len(g.backlog) == 0 {
|
if len(g.backlog) == 0 {
|
||||||
next = g.sequenceNumber
|
next = g.sequenceNumber
|
||||||
g.sequenceNumber += 1
|
g.sequenceNumber++
|
||||||
} else {
|
} else {
|
||||||
next = g.backlog[0]
|
next = g.backlog[0]
|
||||||
g.backlog = g.backlog[1:]
|
g.backlog = g.backlog[1:]
|
||||||
|
|
@ -53,7 +53,7 @@ func (g *DefaultSequenceNumberGenerator) Revert(value uint64) {
|
||||||
g.sequenceNumberLock.Lock()
|
g.sequenceNumberLock.Lock()
|
||||||
defer g.sequenceNumberLock.Unlock()
|
defer g.sequenceNumberLock.Unlock()
|
||||||
if value == g.sequenceNumber-1 {
|
if value == g.sequenceNumber-1 {
|
||||||
g.sequenceNumber -= 1
|
g.sequenceNumber--
|
||||||
} else if !slices.Contains(g.backlog, value) {
|
} else if !slices.Contains(g.backlog, value) {
|
||||||
g.backlog = append(g.backlog, value)
|
g.backlog = append(g.backlog, value)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,12 @@ type Logger interface {
|
||||||
|
|
||||||
func wrapErr(err []error) error {
|
func wrapErr(err []error) error {
|
||||||
var e error
|
var e error
|
||||||
if len(err) == 0 {
|
switch {
|
||||||
|
case len(err) == 0:
|
||||||
e = nil
|
e = nil
|
||||||
} else if len(err) == 1 {
|
case len(err) == 1:
|
||||||
e = err[0]
|
e = err[0]
|
||||||
} else {
|
default:
|
||||||
e = errors.Join(err...)
|
e = errors.Join(err...)
|
||||||
}
|
}
|
||||||
return e
|
return e
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue