| 40 | } |
| 41 | |
| 42 | func (s) TestStdoutLogger_Log(t *testing.T) { |
| 43 | tests := map[string]struct { |
| 44 | event *audit.Event |
| 45 | wantMessage string |
| 46 | wantErr string |
| 47 | }{ |
| 48 | "few fields": { |
| 49 | event: &audit.Event{PolicyName: "test policy", Principal: "test principal"}, |
| 50 | wantMessage: `{"fullMethodName":"","principal":"test principal","policyName":"test policy","matchedRule":"","authorized":false`, |
| 51 | }, |
| 52 | "all fields": { |
| 53 | event: &audit.Event{ |
| 54 | FullMethodName: "/helloworld.Greeter/SayHello", |
| 55 | Principal: "spiffe://example.org/ns/default/sa/default/backend", |
| 56 | PolicyName: "example-policy", |
| 57 | MatchedRule: "dev-access", |
| 58 | Authorized: true, |
| 59 | }, |
| 60 | wantMessage: `{"fullMethodName":"/helloworld.Greeter/SayHello",` + |
| 61 | `"principal":"spiffe://example.org/ns/default/sa/default/backend","policyName":"example-policy",` + |
| 62 | `"matchedRule":"dev-access","authorized":true`, |
| 63 | }, |
| 64 | } |
| 65 | |
| 66 | for name, test := range tests { |
| 67 | t.Run(name, func(t *testing.T) { |
| 68 | before := time.Now().Unix() |
| 69 | var buf bytes.Buffer |
| 70 | builder := &loggerBuilder{goLogger: log.New(&buf, "", 0)} |
| 71 | auditLogger := builder.Build(nil) |
| 72 | |
| 73 | auditLogger.Log(test.event) |
| 74 | |
| 75 | var container map[string]any |
| 76 | if err := json.Unmarshal(buf.Bytes(), &container); err != nil { |
| 77 | t.Fatalf("Failed to unmarshal audit log event: %v", err) |
| 78 | } |
| 79 | innerEvent := extractEvent(container["grpc_audit_log"].(map[string]any)) |
| 80 | if innerEvent.Timestamp == "" { |
| 81 | t.Fatalf("Resulted event has no timestamp: %v", innerEvent) |
| 82 | } |
| 83 | after := time.Now().Unix() |
| 84 | innerEventUnixTime, err := time.Parse(time.RFC3339Nano, innerEvent.Timestamp) |
| 85 | if err != nil { |
| 86 | t.Fatalf("Failed to convert event timestamp into Unix time format: %v", err) |
| 87 | } |
| 88 | if before > innerEventUnixTime.Unix() || after < innerEventUnixTime.Unix() { |
| 89 | t.Errorf("The audit event timestamp is outside of the test interval: test start %v, event timestamp %v, test end %v", before, innerEventUnixTime.Unix(), after) |
| 90 | } |
| 91 | if diff := cmp.Diff(trimEvent(innerEvent), test.event); diff != "" { |
| 92 | t.Fatalf("Unexpected message\ndiff (-got +want):\n%s", diff) |
| 93 | } |
| 94 | }) |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | func (s) TestStdoutLoggerBuilder_NilConfig(t *testing.T) { |
| 99 | builder := &loggerBuilder{ |