Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

Removing featureflag for expanded audit logs #64415

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion client/web/src/featureFlags/featureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import type { OrgFeatureFlagOverridesResult, OrgFeatureFlagOverridesVariables }
export const FEATURE_FLAGS = [
'admin-analytics-cache-disabled',
'admin-onboarding',
'auditlog-expansion',
'blob-page-switch-areas-shortcuts',
'cody-chat-mock-test',
'contrast-compliant-syntax-highlighting',
Expand Down
88 changes: 41 additions & 47 deletions cmd/frontend/graphqlbackend/external_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/extsvc"
"github.com/sourcegraph/sourcegraph/internal/featureflag"
"github.com/sourcegraph/sourcegraph/internal/gqlutil"
"github.com/sourcegraph/sourcegraph/internal/repos"
"github.com/sourcegraph/sourcegraph/internal/repoupdater"
Expand Down Expand Up @@ -80,22 +79,20 @@ func (r *schemaResolver) AddExternalService(ctx context.Context, args *addExtern
return nil, err
}

if featureflag.FromContext(ctx).GetBoolOr("auditlog-expansion", false) {

arg := struct {
Kind string
DisplayName string
Namespace *graphql.ID
}{
Kind: args.Input.Kind,
DisplayName: args.Input.DisplayName,
Namespace: args.Input.Namespace,
}
// Log action of Code Host Connection being added
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameCodeHostConnectionAdded, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", arg); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))
}
arg := struct {
Kind string
DisplayName string
Namespace *graphql.ID
}{
Kind: args.Input.Kind,
DisplayName: args.Input.DisplayName,
Namespace: args.Input.Namespace,
}
// Log action of Code Host Connection being added
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameCodeHostConnectionAdded, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", arg); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))
}

// Now, schedule the external service for syncing immediately.
s := repos.NewStore(r.logger, r.db)
err = s.EnqueueSingleSyncJob(ctx, externalService.ID)
Expand Down Expand Up @@ -196,26 +193,24 @@ func (r *schemaResolver) UpdateExternalService(ctx context.Context, args *update
logger.Warn("Failed to get new redacted config", log.Error(err))
}

if featureflag.FromContext(ctx).GetBoolOr("auditlog-expansion", false) {
arg := struct {
ID graphql.ID
DisplayName *string
UpdaterID *int32
PrevConfig string
LatestConfig *string
}{
ID: args.Input.ID,
DisplayName: args.Input.DisplayName,
UpdaterID: &userID,
PrevConfig: prevConfig,
LatestConfig: &latestConfig,
}
// Log action of Code Host Connection being updated
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameCodeHostConnectionUpdated, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", arg); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))
}

arg := struct {
ID graphql.ID
DisplayName *string
UpdaterID *int32
PrevConfig string
LatestConfig *string
}{
ID: args.Input.ID,
DisplayName: args.Input.DisplayName,
UpdaterID: &userID,
PrevConfig: prevConfig,
LatestConfig: &latestConfig,
}
// Log action of Code Host Connection being updated
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameCodeHostConnectionUpdated, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", arg); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))
}

// Now, schedule the external service for syncing immediately.
s := repos.NewStore(r.logger, r.db)
err = s.EnqueueSingleSyncJob(ctx, es.ID)
Expand Down Expand Up @@ -344,19 +339,18 @@ func (r *schemaResolver) DeleteExternalService(ctx context.Context, args *delete
}
}

if featureflag.FromContext(ctx).GetBoolOr("auditlog-expansion", false) {
arguments := struct {
GraphQLID graphql.ID `json:"GraphQL ID"`
ExternalServiceID int64 `json:"External Service ID"`
}{
GraphQLID: args.ExternalService,
ExternalServiceID: id,
}
// Log action of Code Host Connection being deleted
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameCodeHostConnectionDeleted, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", arguments); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))
}
arguments := struct {
GraphQLID graphql.ID `json:"GraphQL ID"`
ExternalServiceID int64 `json:"External Service ID"`
}{
GraphQLID: args.ExternalService,
ExternalServiceID: id,
}
// Log action of Code Host Connection being deleted
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameCodeHostConnectionDeleted, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", arguments); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))
}

return &EmptyResponse{}, nil
}

Expand Down
14 changes: 14 additions & 0 deletions cmd/frontend/graphqlbackend/external_services_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"
"time"

mockrequire "github.com/derision-test/go-mockgen/v2/testutil/require"
"github.com/google/go-cmp/cmp"
"github.com/graph-gophers/graphql-go"
gqlerrors "github.com/graph-gophers/graphql-go/errors"
Expand Down Expand Up @@ -68,6 +69,9 @@ func TestAddExternalService(t *testing.T) {
db.UsersFunc.SetDefaultReturn(users)
db.ExternalServicesFunc.SetDefaultReturn(externalServices)
db.HandleFunc.SetDefaultReturn(&handle{db})
securityLogEvents := dbmocks.NewMockSecurityEventLogsStore()
securityLogEvents.LogSecurityEventFunc.SetDefaultReturn(nil)
db.SecurityEventLogsFunc.SetDefaultReturn(securityLogEvents)

RunTests(t, []*Test{
{
Expand Down Expand Up @@ -96,6 +100,7 @@ func TestAddExternalService(t *testing.T) {
`,
},
})
mockrequire.Called(t, securityLogEvents.LogSecurityEventFunc)
}

func TestUpdateExternalService(t *testing.T) {
Expand Down Expand Up @@ -203,6 +208,10 @@ func TestUpdateExternalService(t *testing.T) {
es := backend.NewStrictMockExternalServicesService()
es.ValidateConnectionFunc.SetDefaultReturn(nil)

securityLogEvents := dbmocks.NewMockSecurityEventLogsStore()
securityLogEvents.LogSecurityEventFunc.SetDefaultReturn(nil)
db.SecurityEventLogsFunc.SetDefaultReturn(securityLogEvents)

mockExternalServicesService = es
t.Cleanup(func() { mockExternalServicesService = nil })

Expand Down Expand Up @@ -231,6 +240,7 @@ func TestUpdateExternalService(t *testing.T) {
`,
Context: actor.WithActor(context.Background(), &actor.Actor{UID: 1}),
})
mockrequire.Called(t, securityLogEvents.LogSecurityEventFunc)
}

func TestExcludeRepoFromExternalServices_ExternalServiceDoesntSupportRepoExclusion(t *testing.T) {
Expand Down Expand Up @@ -566,6 +576,9 @@ func TestDeleteExternalService(t *testing.T) {
db := dbmocks.NewMockDB()
db.UsersFunc.SetDefaultReturn(users)
db.ExternalServicesFunc.SetDefaultReturn(externalServices)
securityLogEvents := dbmocks.NewMockSecurityEventLogsStore()
securityLogEvents.LogSecurityEventFunc.SetDefaultReturn(nil)
db.SecurityEventLogsFunc.SetDefaultReturn(securityLogEvents)

RunTests(t, []*Test{
{
Expand All @@ -587,6 +600,7 @@ func TestDeleteExternalService(t *testing.T) {
Context: actor.WithActor(context.Background(), &actor.Actor{UID: 1}),
},
})
mockrequire.Called(t, securityLogEvents.LogSecurityEventFunc)
}

func TestExternalServicesResolver(t *testing.T) {
Expand Down
26 changes: 10 additions & 16 deletions cmd/frontend/graphqlbackend/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/dotcom"
"github.com/sourcegraph/sourcegraph/internal/errcode"
"github.com/sourcegraph/sourcegraph/internal/featureflag"
"github.com/sourcegraph/sourcegraph/internal/gqlutil"
"github.com/sourcegraph/sourcegraph/internal/types"
"github.com/sourcegraph/sourcegraph/lib/errors"
Expand All @@ -27,11 +26,9 @@ func (r *schemaResolver) Organization(ctx context.Context, args struct{ Name str
return nil, err
}

if featureflag.FromContext(ctx).GetBoolOr("auditlog-expansion", false) {
// Log action for siteadmin viewing an organization's details
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameOrgViewed, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", args); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))
}
// Log action for siteadmin viewing an organization's details
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameOrgViewed, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", args); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))
}

return &OrgResolver{db: r.db, org: org}, nil
Expand Down Expand Up @@ -272,12 +269,10 @@ func (r *schemaResolver) CreateOrganization(ctx context.Context, args *struct {
return nil, err
}

if featureflag.FromContext(ctx).GetBoolOr("auditlog-expansion", false) {
// Log an event when a new organization being created
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameOrgCreated, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", args); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))
// Log an event when a new organization being created
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameOrgCreated, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", args); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))

}
}

// Add the current user as the first member of the new org.
Expand Down Expand Up @@ -310,13 +305,12 @@ func (r *schemaResolver) UpdateOrganization(ctx context.Context, args *struct {
return nil, err
}

if featureflag.FromContext(ctx).GetBoolOr("auditlog-expansion", false) {
// Log an event when organization settings are updated
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameOrgUpdated, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", args); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))
// Log an event when organization settings are updated
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameOrgUpdated, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", args); err != nil {
r.logger.Warn("Error logging security event", log.Error(err))

}
}

return &OrgResolver{db: r.db, org: updatedOrg}, nil
}

Expand Down
23 changes: 23 additions & 0 deletions cmd/frontend/graphqlbackend/org_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strconv"
"testing"

mockrequire "github.com/derision-test/go-mockgen/v2/testutil/require"
gqlerrors "github.com/graph-gophers/graphql-go/errors"
"github.com/graph-gophers/graphql-go/relay"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -38,10 +39,14 @@ func TestOrganization(t *testing.T) {
orgs.GetByNameFunc.SetDefaultReturn(&mockedOrg, nil)
orgs.GetByIDFunc.SetDefaultReturn(&mockedOrg, nil)

securityLogEvents := dbmocks.NewMockSecurityEventLogsStore()
securityLogEvents.LogSecurityEventFunc.SetDefaultReturn(nil)

db := dbmocks.NewMockDB()
db.OrgsFunc.SetDefaultReturn(orgs)
db.UsersFunc.SetDefaultReturn(users)
db.OrgMembersFunc.SetDefaultReturn(orgMembers)
db.SecurityEventLogsFunc.SetDefaultReturn(securityLogEvents)

t.Run("can access organizations", func(t *testing.T) {
RunTests(t, []*Test{
Expand All @@ -64,6 +69,8 @@ func TestOrganization(t *testing.T) {
},
})
})
mockrequire.Called(t, securityLogEvents.LogSecurityEventFunc)

}

func TestOrganizationMembers(t *testing.T) {
Expand All @@ -85,10 +92,14 @@ func TestOrganizationMembers(t *testing.T) {
mockedOrg := types.Org{ID: 1, Name: "acme"}
orgs.GetByNameFunc.SetDefaultReturn(&mockedOrg, nil)

securityLogEvents := dbmocks.NewMockSecurityEventLogsStore()
securityLogEvents.LogSecurityEventFunc.SetDefaultReturn(nil)

db := dbmocks.NewMockDB()
db.OrgsFunc.SetDefaultReturn(orgs)
db.UsersFunc.SetDefaultReturn(users)
db.OrgMembersFunc.SetDefaultReturn(orgMembers)
db.SecurityEventLogsFunc.SetDefaultReturn(securityLogEvents)

t.Run("org members can list members", func(t *testing.T) {
users.GetByCurrentAuthUserFunc.SetDefaultReturn(&types.User{Username: "alice", ID: 1}, nil)
Expand Down Expand Up @@ -120,6 +131,7 @@ func TestOrganizationMembers(t *testing.T) {
})
})
}
mockrequire.Called(t, securityLogEvents.LogSecurityEventFunc)
})

t.Run("non-members", func(t *testing.T) {
Expand Down Expand Up @@ -208,6 +220,8 @@ func TestOrganizationMembers(t *testing.T) {
},
})
})
mockrequire.Called(t, securityLogEvents.LogSecurityEventFunc)

})
}

Expand All @@ -224,10 +238,14 @@ func TestCreateOrganization(t *testing.T) {
orgMembers := dbmocks.NewMockOrgMemberStore()
orgMembers.CreateFunc.SetDefaultReturn(&types.OrgMembership{OrgID: mockedOrg.ID, UserID: userID}, nil)

securityLogEvents := dbmocks.NewMockSecurityEventLogsStore()
securityLogEvents.LogSecurityEventFunc.SetDefaultReturn(nil)

db := dbmocks.NewMockDB()
db.OrgsFunc.SetDefaultReturn(orgs)
db.UsersFunc.SetDefaultReturn(users)
db.OrgMembersFunc.SetDefaultReturn(orgMembers)
db.SecurityEventLogsFunc.SetDefaultReturn(securityLogEvents)

ctx := actor.WithActor(context.Background(), &actor.Actor{UID: userID})

Expand All @@ -253,6 +271,7 @@ func TestCreateOrganization(t *testing.T) {
"name": "acme",
},
})
mockrequire.Called(t, securityLogEvents.LogSecurityEventFunc)
})

t.Run("Fails for unauthenticated user", func(t *testing.T) {
Expand Down Expand Up @@ -335,11 +354,15 @@ func TestAddOrganizationMember(t *testing.T) {
permssync.MockSchedulePermsSync = func(_ context.Context, logger log.Logger, _ database.DB, _ permssync.ScheduleSyncOpts) {}
defer func() { permssync.MockSchedulePermsSync = nil }()

securityLogEvents := dbmocks.NewMockSecurityEventLogsStore()
securityLogEvents.LogSecurityEventFunc.SetDefaultReturn(nil)

db := dbmocks.NewMockDB()
db.OrgsFunc.SetDefaultReturn(orgs)
db.UsersFunc.SetDefaultReturn(users)
db.OrgMembersFunc.SetDefaultReturn(orgMembers)
db.FeatureFlagsFunc.SetDefaultReturn(featureFlags)
db.SecurityEventLogsFunc.SetDefaultReturn(securityLogEvents)

ctx := actor.WithActor(context.Background(), &actor.Actor{UID: 1})

Expand Down
10 changes: 4 additions & 6 deletions cmd/frontend/graphqlbackend/orgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"github.com/sourcegraph/sourcegraph/internal/actor"
"github.com/sourcegraph/sourcegraph/internal/auth"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/featureflag"
"github.com/sourcegraph/sourcegraph/internal/gqlutil"
)

Expand Down Expand Up @@ -47,14 +46,13 @@ func (r *orgConnectionResolver) Nodes(ctx context.Context) ([]*OrgResolver, erro
org: org,
})
}
if featureflag.FromContext(ctx).GetBoolOr("auditlog-expansion", false) {

// Log an event when listing organizations.
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameOrgListViewed, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", nil); err != nil {
logger.Error(err)
// Log an event when listing organizations.
if err := r.db.SecurityEventLogs().LogSecurityEvent(ctx, database.SecurityEventNameOrgListViewed, "", uint32(actor.FromContext(ctx).UID), "", "BACKEND", nil); err != nil {
logger.Error(err)

}
}

return l, nil
}

Expand Down
Loading
Loading