Page MenuHomePhorge

D14565.1768935833.diff
No OneTemporary

Size
4 KB
Referenced Files
None
Subscribers
None

D14565.1768935833.diff

diff --git a/keyserver/src/fetchers/thread-permission-fetchers.js b/keyserver/src/fetchers/thread-permission-fetchers.js
--- a/keyserver/src/fetchers/thread-permission-fetchers.js
+++ b/keyserver/src/fetchers/thread-permission-fetchers.js
@@ -28,6 +28,7 @@
ThreadRolePermissionsBlob,
} from 'lib/types/thread-permission-types.js';
import type { ThreadType } from 'lib/types/thread-types-enum.js';
+import { ServerError } from 'lib/utils/errors.js';
import { values } from 'lib/utils/objects.js';
import { fetchThreadInfos } from './thread-fetchers.js';
@@ -107,7 +108,22 @@
permissions: ?ThreadPermissionsBlob,
role: number,
checks: $ReadOnlyArray<Check>,
+ predicate: 'and' | 'or' = 'and',
): boolean {
+ if (predicate === 'or') {
+ for (const check of checks) {
+ if (check.check === 'is_member') {
+ if (role > 0) {
+ return true;
+ }
+ } else if (check.check === 'permission') {
+ if (permissionLookup(permissions, check.permission)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
for (const check of checks) {
if (check.check === 'is_member') {
if (role <= 0) {
@@ -136,6 +152,21 @@
return new Set(threadRows.map(row => row.threadID));
}
+// Like checkThread, but "or" over the checks instead of "and"
+async function checkThreadsOr(
+ viewer: Viewer,
+ threadIDs: $ReadOnlyArray<string>,
+ checks: $ReadOnlyArray<Check>,
+): Promise<Set<string>> {
+ if (viewer.isScriptViewer) {
+ // script viewers are all-powerful
+ return new Set(threadIDs);
+ }
+
+ const threadRows = await getValidThreads(viewer, threadIDs, checks, 'or');
+ return new Set(threadRows.map(row => row.threadID));
+}
+
type PartialMembershipRow = {
+threadID: string,
+role: number,
@@ -145,7 +176,22 @@
viewer: Viewer,
threadIDs: $ReadOnlyArray<string>,
checks: $ReadOnlyArray<Check>,
+ predicate: 'and' | 'or' = 'and',
): Promise<PartialMembershipRow[]> {
+ if (
+ predicate === 'or' &&
+ checks.some(({ check }) => check !== 'permission')
+ ) {
+ // Handling non-permission checks for the "or" case is more complicated.
+ // We'd need to break the separation between isThreadValid and
+ // checkThreadsFrozen, since a a valid non-permission check in isThreadValid
+ // should cause checkThreadsFrozen to be ignored.
+ throw new ServerError(
+ 'getValidThreads only supports the "or" predicate when provided only ' +
+ 'permission checks',
+ );
+ }
+
const query = SQL`
SELECT thread AS threadID, permissions, role
FROM memberships
@@ -161,7 +207,7 @@
const [[result], disabledThreadIDs] = await Promise.all([
dbQuery(query),
- checkThreadsFrozen(viewer, permissionsToCheck, threadIDs),
+ checkThreadsFrozen(viewer, permissionsToCheck, threadIDs, predicate),
]);
return result
@@ -172,7 +218,7 @@
}))
.filter(
row =>
- isThreadValid(row.permissions, row.role, checks) &&
+ isThreadValid(row.permissions, row.role, checks, predicate) &&
!disabledThreadIDs.has(row.threadID),
);
}
@@ -181,12 +227,20 @@
viewer: Viewer,
permissionsToCheck: $ReadOnlyArray<ThreadPermission>,
threadIDs: $ReadOnlyArray<string>,
+ predicate: 'and' | 'or' = 'and',
): Promise<$ReadOnlySet<string>> {
const threadIDsWithDisabledPermissions = new Set<string>();
- const permissionMightBeDisabled = permissionsToCheck.some(permission =>
- permissionsDisabledByBlock.has(permission),
- );
+ let permissionMightBeDisabled;
+ if (predicate === 'and') {
+ permissionMightBeDisabled = permissionsToCheck.some(permission =>
+ permissionsDisabledByBlock.has(permission),
+ );
+ } else {
+ permissionMightBeDisabled = permissionsToCheck.every(permission =>
+ permissionsDisabledByBlock.has(permission),
+ );
+ }
if (!permissionMightBeDisabled) {
return threadIDsWithDisabledPermissions;
}
@@ -463,6 +517,7 @@
viewerIsMember,
viewerIsMemberOfThreads,
checkThreads,
+ checkThreadsOr,
getValidThreads,
checkThread,
checkIfThreadIsBlocked,

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 20, 7:03 PM (4 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5963297
Default Alt Text
D14565.1768935833.diff (4 KB)

Event Timeline