diff --git a/internal/daemon/controller/handlers/authmethods/password.go b/internal/daemon/controller/handlers/authmethods/password.go index f095187e9a..40d921507c 100644 --- a/internal/daemon/controller/handlers/authmethods/password.go +++ b/internal/daemon/controller/handlers/authmethods/password.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/boundary/internal/daemon/controller/auth" "github.com/hashicorp/boundary/internal/daemon/controller/handlers" "github.com/hashicorp/boundary/internal/errors" + "github.com/hashicorp/boundary/internal/event" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" "github.com/hashicorp/boundary/internal/types/action" pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/authmethods" @@ -100,6 +101,7 @@ func (s Service) authenticatePassword(ctx context.Context, req *pbs.Authenticate } func (s Service) authenticateWithPwRepo(ctx context.Context, scopeId, authMethodId, loginName, pw string) (*pba.AuthToken, error) { + const op = "authmethods.(Service).authenticateWithPwRepo" iamRepo, err := s.iamRepoFn() if err != nil { return nil, err @@ -130,6 +132,11 @@ func (s Service) authenticateWithPwRepo(ctx context.Context, scopeId, authMethod return nil, err } + if err := event.WriteObservation(ctx, op, event.WithDetails("user_id", u.GetPublicId(), "auth_token_start", + tok.GetCreateTime(), "auth_token_end", tok.GetExpirationTime())); err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithMsg("Unable to write observation event for authenticate method")) + } + return s.ConvertInternalAuthTokenToApiAuthToken( ctx, tok, diff --git a/internal/daemon/controller/handlers/authmethods/password_test.go b/internal/daemon/controller/handlers/authmethods/password_test.go index 4e2bdfa69c..f9ad7d29a7 100644 --- a/internal/daemon/controller/handlers/authmethods/password_test.go +++ b/internal/daemon/controller/handlers/authmethods/password_test.go @@ -5,7 +5,10 @@ package authmethods_test import ( "context" + "encoding/json" + "os" "strings" + "sync" "testing" "github.com/google/go-cmp/cmp" @@ -19,12 +22,15 @@ import ( "github.com/hashicorp/boundary/internal/daemon/controller/handlers/authmethods" "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/errors" + "github.com/hashicorp/boundary/internal/event" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" "github.com/hashicorp/boundary/internal/types/scope" pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/authmethods" scopepb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/scopes" + "github.com/hashicorp/eventlogger/formatter_filters/cloudevents" + "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/genproto/protobuf/field_mask" @@ -508,6 +514,18 @@ func TestAuthenticate_Password(t *testing.T) { require.NoError(t, err) require.NotNil(t, acct) + c := event.TestEventerConfig(t, "Test_StartAuth_to_Callback", event.TestWithObservationSink(t)) + testLock := &sync.Mutex{} + testLogger := hclog.New(&hclog.LoggerOptions{ + Mutex: testLock, + Name: "test", + }) + require.NoError(t, event.InitSysEventer(testLogger, testLock, "use-Test_Authenticate", event.WithEventerConfig(&c.EventerConfig))) + sinkFileName := c.ObservationEvents.Name() + t.Cleanup(func() { + require.NoError(t, os.Remove(sinkFileName)) + }) + cases := []struct { name string request *pbs.AuthenticateRequest @@ -648,6 +666,20 @@ func TestAuthenticate_Password(t *testing.T) { assert.Equal(acct.GetPublicId(), aToken.GetAccountId()) assert.Equal(am.GetPublicId(), aToken.GetAuthMethodId()) assert.Equal(tc.wantType, resp.GetType()) + + defer func() { _ = os.WriteFile(sinkFileName, nil, 0o666) }() + b, err := os.ReadFile(sinkFileName) + require.NoError(err) + gotRes := &cloudevents.Event{} + err = json.Unmarshal(b, gotRes) + require.NoErrorf(err, "json: %s", string(b)) + details, ok := gotRes.Data.(map[string]any)["details"] + require.True(ok) + for _, key := range details.([]any) { + assert.Contains(key.(map[string]any)["payload"], "user_id") + assert.Contains(key.(map[string]any)["payload"], "auth_token_start") + assert.Contains(key.(map[string]any)["payload"], "auth_token_end") + } }) } }