diff --git a/changes/28502-api-only-user-backend b/changes/28502-api-only-user-backend new file mode 100644 index 0000000000..69fba61e2a --- /dev/null +++ b/changes/28502-api-only-user-backend @@ -0,0 +1 @@ +- Added whether user is api_only to backend activity details diff --git a/server/datastore/mysql/activities.go b/server/datastore/mysql/activities.go index 80da10d82e..ab7d981659 100644 --- a/server/datastore/mysql/activities.go +++ b/server/datastore/mysql/activities.go @@ -214,7 +214,7 @@ func (ds *Datastore) ListActivities(ctx context.Context, opt fleet.ListActivitie if len(lookup) != 0 { usersQ := ` - SELECT u.id, u.name, u.gravatar_url, u.email + SELECT u.id, u.name, u.gravatar_url, u.email, u.api_only FROM users u WHERE id IN (?) ` @@ -233,6 +233,7 @@ func (ds *Datastore) ListActivities(ctx context.Context, opt fleet.ListActivitie Name string `db:"name"` GravatarUrl string `db:"gravatar_url"` Email string `db:"email"` + APIOnly bool `db:"api_only"` } err = sqlx.SelectContext(ctx, ds.reader(ctx), &usersR, usersQ, usersArgs...) @@ -249,11 +250,13 @@ func (ds *Datastore) ListActivities(ctx context.Context, opt fleet.ListActivitie email := r.Email gravatar := r.GravatarUrl name := r.Name + apiOnly := r.APIOnly for _, idx := range entries { activities[idx].ActorEmail = &email activities[idx].ActorGravatar = &gravatar activities[idx].ActorFullName = &name + activities[idx].ActorAPIOnly = &apiOnly } } } @@ -314,6 +317,7 @@ func (ds *Datastore) ListHostUpcomingActivities(ctx context.Context, hostID uint ua.execution_id as uuid, IF(ua.fleet_initiated, 'Fleet', COALESCE(u.name, ua.payload->>'$.user.name')) as name, u.id as user_id, + u.api_only as api_only, COALESCE(u.gravatar_url, ua.payload->>'$.user.gravatar_url') as gravatar_url, COALESCE(u.email, ua.payload->>'$.user.email') as user_email, :ran_script_type as activity_type, @@ -353,6 +357,7 @@ func (ds *Datastore) ListHostUpcomingActivities(ctx context.Context, hostID uint ua.execution_id as uuid, IF(ua.fleet_initiated, 'Fleet', COALESCE(u.name, ua.payload->>'$.user.name')) AS name, ua.user_id as user_id, + u.api_only as api_only, COALESCE(u.gravatar_url, ua.payload->>'$.user.gravatar_url') as gravatar_url, COALESCE(u.email, ua.payload->>'$.user.email') as user_email, :installed_software_type as activity_type, @@ -394,6 +399,7 @@ func (ds *Datastore) ListHostUpcomingActivities(ctx context.Context, hostID uint ua.execution_id as uuid, IF(ua.fleet_initiated, 'Fleet', COALESCE(u.name, ua.payload->>'$.user.name')) AS name, ua.user_id as user_id, + u.api_only as api_only, COALESCE(u.gravatar_url, ua.payload->>'$.user.gravatar_url') as gravatar_url, COALESCE(u.email, ua.payload->>'$.user.email') as user_email, :uninstalled_software_type as activity_type, @@ -433,6 +439,7 @@ func (ds *Datastore) ListHostUpcomingActivities(ctx context.Context, hostID uint ua.execution_id AS uuid, IF(ua.fleet_initiated, 'Fleet', COALESCE(u.name, ua.payload->>'$.user.name')) AS name, u.id AS user_id, + u.api_only as api_only, COALESCE(u.gravatar_url, ua.payload->>'$.user.gravatar_url') as gravatar_url, COALESCE(u.email, ua.payload->>'$.user.email') as user_email, :installed_app_store_app_type AS activity_type, @@ -474,6 +481,7 @@ func (ds *Datastore) ListHostUpcomingActivities(ctx context.Context, hostID uint user_id, gravatar_url, user_email, + api_only, activity_type, created_at, details, @@ -522,6 +530,7 @@ func (ds *Datastore) ListHostPastActivities(ctx context.Context, hostID uint, op u.gravatar_url as gravatar_url, a.created_at as created_at, u.id as user_id, + u.api_only as api_only, a.fleet_initiated as fleet_initiated FROM host_activities ha diff --git a/server/datastore/mysql/activities_test.go b/server/datastore/mysql/activities_test.go index d0622fd14a..1c764bddb2 100644 --- a/server/datastore/mysql/activities_test.go +++ b/server/datastore/mysql/activities_test.go @@ -87,6 +87,7 @@ func testActivityUsernameChange(t *testing.T, ds *Datastore) { Name: "fullname", Email: "email@asd.com", GravatarURL: "http://asd.com", + APIOnly: true, GlobalRole: ptr.String(fleet.RoleObserver), } _, err := ds.NewUser(context.Background(), u) @@ -126,6 +127,7 @@ func testActivityUsernameChange(t *testing.T, ds *Datastore) { assert.Equal(t, "newname", *activities[0].ActorFullName) assert.Equal(t, "http://asd.com", *activities[0].ActorGravatar) assert.Equal(t, "email@asd.com", *activities[0].ActorEmail) + assert.Equal(t, true, *activities[0].ActorAPIOnly) err = ds.DeleteUser(context.Background(), u.ID) require.NoError(t, err) diff --git a/server/fleet/activities.go b/server/fleet/activities.go index c6a723ae70..4bab001475 100644 --- a/server/fleet/activities.go +++ b/server/fleet/activities.go @@ -30,6 +30,7 @@ type Activity struct { ActorID *uint `json:"actor_id,omitempty" db:"user_id"` ActorGravatar *string `json:"actor_gravatar,omitempty" db:"gravatar_url"` ActorEmail *string `json:"actor_email,omitempty" db:"user_email"` + ActorAPIOnly *bool `json:"actor_api_only,omitempty" db:"api_only"` Type string `json:"type" db:"activity_type"` Details *json.RawMessage `json:"details" db:"details"` Streamed *bool `json:"-" db:"streamed"`