Skip to content

Commit

Permalink
🐛 Fix auth level check for protected tags (bluesky-social#3205)
Browse files Browse the repository at this point in the history
  • Loading branch information
foysalit authored Dec 7, 2024
1 parent 0bec389 commit 32baddf
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 43 deletions.
106 changes: 63 additions & 43 deletions packages/ozone/src/api/moderation/emitEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,49 +99,7 @@ const handleModerationEvent = async ({
)

if (protectedTags) {
status.tags.forEach((tag) => {
if (!Object.hasOwn(protectedTags, tag)) return
if (
protectedTags[tag]['moderators'] &&
!protectedTags[tag]['moderators'].includes(createdBy)
) {
throw new InvalidRequestError(
`Not allowed to action on protected tag: ${tag}`,
)
}
if (protectedTags[tag]['roles']) {
if (
auth.credentials.isAdmin &&
!protectedTags[tag]['roles'].includes(
'tools.ozone.team.defs#roleAdmin',
)
) {
throw new InvalidRequestError(
`Not allowed to action on protected tag: ${tag}`,
)
}
if (
auth.credentials.isModerator &&
!protectedTags[tag]['roles'].includes(
'tools.ozone.team.defs#roleModerator',
)
) {
throw new InvalidRequestError(
`Not allowed to action on protected tag: ${tag}`,
)
}
if (
auth.credentials.isTriage &&
!protectedTags[tag]['roles'].includes(
'tools.ozone.team.defs#roleTriage',
)
) {
throw new InvalidRequestError(
`Not allowed to action on protected tag: ${tag}`,
)
}
}
})
assertProtectedTagAction(protectedTags, status.tags, createdBy, auth)
}
}

Expand Down Expand Up @@ -291,6 +249,68 @@ export default function (server: Server, ctx: AppContext) {
})
}

const assertProtectedTagAction = (
protectedTags: ProtectedTagSetting,
subjectTags: string[],
actionAuthor: string,
auth: ModeratorOutput | AdminTokenOutput,
) => {
subjectTags.forEach((tag) => {
if (!Object.hasOwn(protectedTags, tag)) return
if (
protectedTags[tag]['moderators'] &&
!protectedTags[tag]['moderators'].includes(actionAuthor)
) {
throw new InvalidRequestError(
`Not allowed to action on protected tag: ${tag}`,
)
}

if (protectedTags[tag]['roles']) {
if (auth.credentials.isAdmin) {
if (
protectedTags[tag]['roles'].includes(
'tools.ozone.team.defs#roleAdmin',
)
) {
return
}
throw new InvalidRequestError(
`Not allowed to action on protected tag: ${tag}`,
)
}

if (auth.credentials.isModerator) {
if (
protectedTags[tag]['roles'].includes(
'tools.ozone.team.defs#roleModerator',
)
) {
return
}

throw new InvalidRequestError(
`Not allowed to action on protected tag: ${tag}`,
)
}

if (auth.credentials.isTriage) {
if (
protectedTags[tag]['roles'].includes(
'tools.ozone.team.defs#roleTriage',
)
) {
return
}

throw new InvalidRequestError(
`Not allowed to action on protected tag: ${tag}`,
)
}
}
})
}

const assertTagAuth = async (
settingService: SettingService,
serviceDid: string,
Expand Down
16 changes: 16 additions & 0 deletions packages/ozone/tests/protected-tags.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,22 @@ describe('protected-tags', () => {
},
}),
).rejects.toThrow(/Can not manage tag vip/gi)

// Verify that since admins are configured to manage this tag, admin actions go through
const removeTag = await modClient.emitEvent(
{
subject: {
$type: 'com.atproto.admin.defs#repoRef',
did: sc.dids.bob,
},
event: {
$type: 'tools.ozone.moderation.defs#modEventTakedown',
},
},
'admin',
)

expect(removeTag.id).toBeTruthy()
})
it('only allows configured moderators to add/remove protected tags', async () => {
await modClient.upsertSettingOption({
Expand Down

0 comments on commit 32baddf

Please sign in to comment.