PUT/POST audit config for database
()
| 927 | |
| 928 | // PUT/POST audit config for database |
| 929 | func (h *handler) handlePutDbAuditConfig() error { |
| 930 | |
| 931 | var bodyRaw []byte |
| 932 | var previousAuditEnabled, updatedAuditEnabled bool |
| 933 | var updatedAuditEvents []uint |
| 934 | err := h.mutateDbConfig(func(config *DbConfig) error { |
| 935 | previousAuditEnabled, _ = config.IsAuditLoggingEnabled() |
| 936 | bodyRaw, err := h.readBody() |
| 937 | if err != nil { |
| 938 | return err |
| 939 | } |
| 940 | var body HandleDbAuditConfigBody |
| 941 | if err := base.JSONUnmarshal(bodyRaw, &body); err != nil { |
| 942 | return err |
| 943 | } |
| 944 | |
| 945 | // isReplace if the request is a PUT, and we want to overwrite existing config |
| 946 | isReplace := h.rq.Method == http.MethodPut |
| 947 | |
| 948 | // This API endpoint takes audit config in a format that does not match the actual DbConfig stored, so translate the request here. |
| 949 | toChange := make(map[base.AuditID]bool, len(body.Events)) |
| 950 | var multiError *base.MultiError |
| 951 | for id, val := range body.Events { |
| 952 | // find the event |
| 953 | auditID, err := base.ParseAuditID(id) |
| 954 | if err != nil { |
| 955 | multiError = multiError.Append(fmt.Errorf("invalid audit event ID: %q", id)) |
| 956 | continue |
| 957 | } |
| 958 | _, ok := base.AuditEvents[auditID] |
| 959 | if !ok { |
| 960 | multiError = multiError.Append(fmt.Errorf("unknown audit event ID: %q", auditID)) |
| 961 | continue |
| 962 | } |
| 963 | |
| 964 | var eventEnabled bool |
| 965 | switch valT := val.(type) { |
| 966 | case bool: |
| 967 | eventEnabled = valT |
| 968 | case map[string]any: |
| 969 | // verbose format |
| 970 | eventEnabled = valT["enabled"].(bool) |
| 971 | } |
| 972 | |
| 973 | // check if explicitly disabled events are allowed to be filtered |
| 974 | // we'll ensure that non-filterable events are always considered enabled at runtime instead of at config persistence time |
| 975 | // this will ensure we are able to add events in the future that are non-filterable and have them work correctly |
| 976 | if e, ok := base.AuditEvents[auditID]; !ok { |
| 977 | multiError = multiError.Append(fmt.Errorf("unknown audit event ID: %q", auditID)) |
| 978 | } else if e.IsGlobalEvent { |
| 979 | multiError = multiError.Append(fmt.Errorf("event %q is not configurable at the database level", auditID)) |
| 980 | } else if !e.FilteringPermitted && !eventEnabled { |
| 981 | multiError = multiError.Append(fmt.Errorf("event %q is not filterable and cannot be disabled", auditID)) |
| 982 | } else { |
| 983 | toChange[auditID] = eventEnabled |
| 984 | } |
| 985 | } |
| 986 | if err := multiError.ErrorOrNil(); err != nil { |
nothing calls this directly
no test coverage detected