chore: implement organization scoped audit log requests (#13663)

* chore: add organization_id filter to audit logs
* chore: implement organization scoped audit log requests
This commit is contained in:
Steven Masley
2024-06-26 12:38:46 -05:00
committed by GitHub
parent 20e59e0797
commit 08e728bcb2
13 changed files with 123 additions and 25 deletions
+13 -4
View File
@@ -1200,12 +1200,21 @@ func (q *querier) GetApplicationName(ctx context.Context) (string, error) {
}
func (q *querier) GetAuditLogsOffset(ctx context.Context, arg database.GetAuditLogsOffsetParams) ([]database.GetAuditLogsOffsetRow, error) {
// To optimize audit logs, we only check the global audit log permission once.
// This is because we expect a large unbounded set of audit logs, and applying a SQL
// filter would slow down the query for no benefit.
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceAuditLog); err != nil {
// To optimize the authz checks for audit logs, do not run an authorize
// check on each individual audit log row. In practice, audit logs are either
// fetched from a global or an organization scope.
// Applying a SQL filter would slow down the query for no benefit on how this query is
// actually used.
object := rbac.ResourceAuditLog
if arg.OrganizationID != uuid.Nil {
object = object.InOrg(arg.OrganizationID)
}
if err := q.authorizeContext(ctx, policy.ActionRead, object); err != nil {
return nil, err
}
return q.db.GetAuditLogsOffset(ctx, arg)
}
+3
View File
@@ -1928,6 +1928,9 @@ func (q *FakeQuerier) GetAuditLogsOffset(_ context.Context, arg database.GetAudi
arg.Offset--
continue
}
if arg.OrganizationID != uuid.Nil && arg.OrganizationID != alog.OrganizationID {
continue
}
if arg.Action != "" && !strings.Contains(string(alog.Action), arg.Action) {
continue
}
+24 -16
View File
@@ -500,52 +500,58 @@ WHERE
resource_id = $4
ELSE true
END
-- Filter organization_id
AND CASE
WHEN $5 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
audit_logs.organization_id = $5
ELSE true
END
-- Filter by resource_target
AND CASE
WHEN $5 :: text != '' THEN
resource_target = $5
WHEN $6 :: text != '' THEN
resource_target = $6
ELSE true
END
-- Filter action
AND CASE
WHEN $6 :: text != '' THEN
action = $6 :: audit_action
WHEN $7 :: text != '' THEN
action = $7 :: audit_action
ELSE true
END
-- Filter by user_id
AND CASE
WHEN $7 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
user_id = $7
WHEN $8 :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
user_id = $8
ELSE true
END
-- Filter by username
AND CASE
WHEN $8 :: text != '' THEN
user_id = (SELECT id FROM users WHERE lower(username) = lower($8) AND deleted = false)
WHEN $9 :: text != '' THEN
user_id = (SELECT id FROM users WHERE lower(username) = lower($9) AND deleted = false)
ELSE true
END
-- Filter by user_email
AND CASE
WHEN $9 :: text != '' THEN
users.email = $9
WHEN $10 :: text != '' THEN
users.email = $10
ELSE true
END
-- Filter by date_from
AND CASE
WHEN $10 :: timestamp with time zone != '0001-01-01 00:00:00Z' THEN
"time" >= $10
WHEN $11 :: timestamp with time zone != '0001-01-01 00:00:00Z' THEN
"time" >= $11
ELSE true
END
-- Filter by date_to
AND CASE
WHEN $11 :: timestamp with time zone != '0001-01-01 00:00:00Z' THEN
"time" <= $11
WHEN $12 :: timestamp with time zone != '0001-01-01 00:00:00Z' THEN
"time" <= $12
ELSE true
END
-- Filter by build_reason
AND CASE
WHEN $12::text != '' THEN
workspace_builds.reason::text = $12
WHEN $13::text != '' THEN
workspace_builds.reason::text = $13
ELSE true
END
ORDER BY
@@ -561,6 +567,7 @@ type GetAuditLogsOffsetParams struct {
Offset int32 `db:"offset" json:"offset"`
ResourceType string `db:"resource_type" json:"resource_type"`
ResourceID uuid.UUID `db:"resource_id" json:"resource_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
ResourceTarget string `db:"resource_target" json:"resource_target"`
Action string `db:"action" json:"action"`
UserID uuid.UUID `db:"user_id" json:"user_id"`
@@ -611,6 +618,7 @@ func (q *sqlQuerier) GetAuditLogsOffset(ctx context.Context, arg GetAuditLogsOff
arg.Offset,
arg.ResourceType,
arg.ResourceID,
arg.OrganizationID,
arg.ResourceTarget,
arg.Action,
arg.UserID,
+6
View File
@@ -59,6 +59,12 @@ WHERE
resource_id = @resource_id
ELSE true
END
-- Filter organization_id
AND CASE
WHEN @organization_id :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
audit_logs.organization_id = @organization_id
ELSE true
END
-- Filter by resource_target
AND CASE
WHEN @resource_target :: text != '' THEN