mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: Auditing group members as part of group resource (#5730)
* added AuditableGroup type * added json tags * Anonymizing gGroup struct * adding support on the FE for nested group diffs * added type for GroupMember * Update coderd/database/modelmethods.go Co-authored-by: Steven Masley <Emyrk@users.noreply.github.com> * Update coderd/database/modelmethods.go Co-authored-by: Steven Masley <Emyrk@users.noreply.github.com> * fetching group members in group.delete * passing through right error * broke out into util function and added tests Co-authored-by: Steven Masley <Emyrk@users.noreply.github.com>
This commit is contained in:
co-authored by
Steven Masley
parent
56b996532f
commit
6b68fbbf18
@@ -3,6 +3,7 @@ import { AuditLog } from "api/typesGenerated"
|
||||
import { colors } from "theme/colors"
|
||||
import { MONOSPACE_FONT_FAMILY } from "theme/constants"
|
||||
import { combineClasses } from "util/combineClasses"
|
||||
import { FC } from "react"
|
||||
|
||||
const getDiffValue = (value: unknown): string => {
|
||||
if (typeof value === "string") {
|
||||
@@ -21,9 +22,7 @@ const getDiffValue = (value: unknown): string => {
|
||||
return value.toString()
|
||||
}
|
||||
|
||||
export const AuditLogDiff: React.FC<{ diff: AuditLog["diff"] }> = ({
|
||||
diff,
|
||||
}) => {
|
||||
export const AuditLogDiff: FC<{ diff: AuditLog["diff"] }> = ({ diff }) => {
|
||||
const styles = useStyles()
|
||||
const diffEntries = Object.entries(diff)
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import userAgentParser from "ua-parser-js"
|
||||
import { AuditLogDiff } from "./AuditLogDiff"
|
||||
import i18next from "i18next"
|
||||
import { AuditLogDescription } from "./AuditLogDescription"
|
||||
import { determineGroupDiff } from "./auditUtils"
|
||||
|
||||
const httpStatusColor = (httpStatus: number): PaletteIndex => {
|
||||
if (httpStatus >= 300 && httpStatus < 500) {
|
||||
@@ -49,6 +50,13 @@ export const AuditLogRow: React.FC<AuditLogRowProps> = ({
|
||||
? `${browser.name} ${browser.version}`
|
||||
: t("auditLog:table.logRow.notAvailable")
|
||||
|
||||
let auditDiff = auditLog.diff
|
||||
|
||||
// groups have nested diffs (group members)
|
||||
if (auditLog.resource_type === "group") {
|
||||
auditDiff = determineGroupDiff(auditLog.diff)
|
||||
}
|
||||
|
||||
const toggle = () => {
|
||||
if (shouldDisplayDiff) {
|
||||
setIsDiffOpen((v) => !v)
|
||||
@@ -153,7 +161,7 @@ export const AuditLogRow: React.FC<AuditLogRowProps> = ({
|
||||
|
||||
{shouldDisplayDiff && (
|
||||
<Collapse in={isDiffOpen}>
|
||||
<AuditLogDiff diff={auditLog.diff} />
|
||||
<AuditLogDiff diff={auditDiff} />
|
||||
</Collapse>
|
||||
)}
|
||||
</TableCell>
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
import { determineGroupDiff } from "./auditUtils"
|
||||
|
||||
const auditDiffForNewGroup = {
|
||||
id: {
|
||||
old: "",
|
||||
new: "e22e0eb9-625a-468b-b962-269b19473789",
|
||||
secret: false,
|
||||
},
|
||||
members: {
|
||||
new: [],
|
||||
secret: false,
|
||||
},
|
||||
name: {
|
||||
old: "",
|
||||
new: "another-test-group",
|
||||
secret: false,
|
||||
},
|
||||
}
|
||||
|
||||
const auditDiffForAddedGroupMember = {
|
||||
members: {
|
||||
old: [],
|
||||
new: [
|
||||
{
|
||||
group_id: "e22e0eb9-625a-468b-b962-269b19473789",
|
||||
user_id: "cea4c2b0-6373-4858-b26a-df3cbfce8845",
|
||||
},
|
||||
],
|
||||
secret: false,
|
||||
},
|
||||
}
|
||||
|
||||
const auditDiffForRemovedGroupMember = {
|
||||
members: {
|
||||
old: [
|
||||
{
|
||||
group_id: "25793395-b093-4a3c-a473-9ecf9b243478",
|
||||
user_id: "84d1cd5a-17e1-4022-898c-52e64256e737",
|
||||
},
|
||||
{
|
||||
group_id: "25793395-b093-4a3c-a473-9ecf9b243478",
|
||||
user_id: "cea4c2b0-6373-4858-b26a-df3cbfce8845",
|
||||
},
|
||||
],
|
||||
new: [
|
||||
{
|
||||
group_id: "25793395-b093-4a3c-a473-9ecf9b243478",
|
||||
user_id: "84d1cd5a-17e1-4022-898c-52e64256e737",
|
||||
},
|
||||
],
|
||||
secret: false,
|
||||
},
|
||||
}
|
||||
|
||||
const AuditDiffForDeletedGroup = {
|
||||
id: {
|
||||
old: "25793395-b093-4a3c-a473-9ecf9b243478",
|
||||
new: "",
|
||||
secret: false,
|
||||
},
|
||||
members: {
|
||||
old: [
|
||||
{
|
||||
group_id: "25793395-b093-4a3c-a473-9ecf9b243478",
|
||||
user_id: "84d1cd5a-17e1-4022-898c-52e64256e737",
|
||||
},
|
||||
],
|
||||
secret: false,
|
||||
},
|
||||
name: {
|
||||
old: "test-group",
|
||||
new: "",
|
||||
secret: false,
|
||||
},
|
||||
}
|
||||
|
||||
describe("determineAuditDiff", () => {
|
||||
it("auditDiffForNewGroup", () => {
|
||||
// there should be no change as members are not added when a group is created
|
||||
expect(determineGroupDiff(auditDiffForNewGroup)).toEqual(
|
||||
auditDiffForNewGroup,
|
||||
)
|
||||
})
|
||||
|
||||
it("auditDiffForAddedGroupMember", () => {
|
||||
const result = {
|
||||
members: {
|
||||
...auditDiffForAddedGroupMember.members,
|
||||
new: ["cea4c2b0-6373-4858-b26a-df3cbfce8845"],
|
||||
},
|
||||
}
|
||||
|
||||
expect(determineGroupDiff(auditDiffForAddedGroupMember)).toEqual(result)
|
||||
})
|
||||
|
||||
it("auditDiffForRemovedGroupMember", () => {
|
||||
const result = {
|
||||
members: {
|
||||
...auditDiffForRemovedGroupMember.members,
|
||||
old: [
|
||||
"84d1cd5a-17e1-4022-898c-52e64256e737",
|
||||
"cea4c2b0-6373-4858-b26a-df3cbfce8845",
|
||||
],
|
||||
new: ["84d1cd5a-17e1-4022-898c-52e64256e737"],
|
||||
},
|
||||
}
|
||||
|
||||
expect(determineGroupDiff(auditDiffForRemovedGroupMember)).toEqual(result)
|
||||
})
|
||||
|
||||
it("AuditDiffForDeletedGroup", () => {
|
||||
const result = {
|
||||
...AuditDiffForDeletedGroup,
|
||||
members: {
|
||||
...AuditDiffForDeletedGroup.members,
|
||||
old: ["84d1cd5a-17e1-4022-898c-52e64256e737"],
|
||||
},
|
||||
}
|
||||
|
||||
expect(determineGroupDiff(AuditDiffForDeletedGroup)).toEqual(result)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,26 @@
|
||||
import { AuditDiff } from "api/typesGenerated"
|
||||
|
||||
interface GroupMember {
|
||||
user_id: string
|
||||
group_id: string
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param auditLogDiff
|
||||
* @returns a diff with the 'members' key flattened to be an array of user_ids
|
||||
*/
|
||||
export const determineGroupDiff = (auditLogDiff: AuditDiff): AuditDiff => {
|
||||
return {
|
||||
...auditLogDiff,
|
||||
members: {
|
||||
old: auditLogDiff.members.old?.map(
|
||||
(groupMember: GroupMember) => groupMember.user_id,
|
||||
),
|
||||
new: auditLogDiff.members.new?.map(
|
||||
(groupMember: GroupMember) => groupMember.user_id,
|
||||
),
|
||||
secret: auditLogDiff.members.secret,
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user