Page MenuHomePhabricator

D9897.diff
No OneTemporary

D9897.diff

diff --git a/keyserver/src/creators/role-creator.js b/keyserver/src/creators/role-creator.js
--- a/keyserver/src/creators/role-creator.js
+++ b/keyserver/src/creators/role-creator.js
@@ -1,14 +1,14 @@
// @flow
-import { getRolePermissionBlobs } from 'lib/permissions/thread-permissions.js';
import {
- universalCommunityPermissions,
+ getRolePermissionBlobs,
+ getThreadPermissionBlobFromUserSurfacedPermissions,
+} from 'lib/permissions/thread-permissions.js';
+import {
userSurfacedPermissionsSet,
- configurableCommunityPermissions,
threadPermissions,
} from 'lib/types/thread-permission-types.js';
import type { ThreadType } from 'lib/types/thread-types-enum.js';
-import { threadTypes } from 'lib/types/thread-types-enum.js';
import type {
RoleInfo,
RoleModificationRequest,
@@ -105,32 +105,16 @@
const [id] = await createIDs('roles', 1);
const time = Date.now();
- const configuredPermissions = permissions
- .map(permission => [...configurableCommunityPermissions[permission]])
- .flat();
-
- const rolePermissions = [
- ...universalCommunityPermissions,
- ...configuredPermissions,
- ];
-
- // For communities of the type `COMMUNITY_ANNOUNCEMENT_ROOT`, the ability for
- // the role to be voiced needs to be configured (i.e. the parameters should
- // include the user-facing permission VOICED_IN_ANNOUNCEMENT_CHANNELS). This
- // means we do not give 'voiced' permissions by default to all new roles. As
- // a result, if the thread type is `COMMUNITY_ROOT`, we want to ensure that
- // the role has the voiced permission.
const { threadInfos } = await fetchThreadInfos(viewer, {
threadID: community,
});
const threadInfo = threadInfos[community];
- if (threadInfo.type === threadTypes.COMMUNITY_ROOT) {
- rolePermissions.push(threadPermissions.VOICED);
- }
-
const permissionsBlob = JSON.stringify(
- Object.fromEntries(rolePermissions.map(permission => [permission, true])),
+ getThreadPermissionBlobFromUserSurfacedPermissions(
+ permissions,
+ threadInfo.type,
+ ),
);
const row = [id, community, name, permissionsBlob, time];
diff --git a/keyserver/src/scripts/validate-role-permissions.js b/keyserver/src/scripts/validate-role-permissions.js
--- a/keyserver/src/scripts/validate-role-permissions.js
+++ b/keyserver/src/scripts/validate-role-permissions.js
@@ -1,10 +1,12 @@
// @flow
-import { getRolePermissionBlobs } from 'lib/permissions/thread-permissions.js';
+import {
+ getRolePermissionBlobs,
+ getUniversalCommunityRootPermissionsBlob,
+} from 'lib/permissions/thread-permissions.js';
import {
configurableCommunityPermissions,
userSurfacedPermissions,
- universalCommunityPermissions,
} from 'lib/types/thread-permission-types.js';
import { threadTypes } from 'lib/types/thread-types-enum.js';
import { deepDiff, values } from 'lib/utils/objects.js';
@@ -35,6 +37,9 @@
const threadType = result.type;
const threadDefaultRole = result.default_role.toString();
+ const universalCommunityPermissions =
+ getUniversalCommunityRootPermissionsBlob(threadType);
+
// Get the 'expected permissions' set for the role. If the role is
// default (Members) or Admins, these permission blobs can be retrieved
// by calling getRolePermissionBlobs with the threadType. Otherwise, the
@@ -48,9 +53,7 @@
} else if (roleName === 'Admins') {
baseExpectedPermissionBlob = expectedPermissionBlobs.Admins;
} else if (roleName) {
- baseExpectedPermissionBlob = Object.fromEntries(
- universalCommunityPermissions.map(permission => [permission, true]),
- );
+ baseExpectedPermissionBlob = universalCommunityPermissions;
} else {
baseExpectedPermissionBlob = {};
}
diff --git a/lib/permissions/thread-permissions.js b/lib/permissions/thread-permissions.js
--- a/lib/permissions/thread-permissions.js
+++ b/lib/permissions/thread-permissions.js
@@ -1,13 +1,17 @@
// @flow
+import invariant from 'invariant';
+
import {
parseThreadPermissionString,
includeThreadPermissionForThreadType,
} from './prefixes.js';
import {
+ configurableCommunityPermissions,
threadPermissionFilterPrefixes,
threadPermissionPropagationPrefixes,
threadPermissions,
+ userSurfacedPermissions,
} from '../types/thread-permission-types.js';
import type {
ThreadPermission,
@@ -15,6 +19,7 @@
ThreadPermissionsBlob,
ThreadPermissionsInfo,
ThreadRolePermissionsBlob,
+ UserSurfacedPermission,
} from '../types/thread-permission-types.js';
import { type ThreadType, threadTypes } from '../types/thread-types-enum.js';
@@ -153,6 +158,27 @@
}
}
+function getThreadPermissionBlobFromUserSurfacedPermissions(
+ communityUserSurfacedPermissions: $ReadOnlyArray<UserSurfacedPermission>,
+ threadType: ThreadType,
+): ThreadRolePermissionsBlob {
+ const mappedUserSurfacedPermissions = communityUserSurfacedPermissions
+ .map(permission => [...configurableCommunityPermissions[permission]])
+ .flat();
+
+ const userSurfacedPermissionsObj = Object.fromEntries(
+ mappedUserSurfacedPermissions.map(p => [p, true]),
+ );
+
+ const universalCommunityPermissions =
+ getUniversalCommunityRootPermissionsBlob(threadType);
+
+ return {
+ ...universalCommunityPermissions,
+ ...userSurfacedPermissionsObj,
+ };
+}
+
export type RolePermissionBlobs = {
+Members: ThreadRolePermissionsBlob,
+Admins?: ThreadRolePermissionsBlob,
@@ -165,57 +191,36 @@
const TOP_LEVEL_DESCENDANT = DESCENDANT + TOP_LEVEL;
const OPEN_TOP_LEVEL_DESCENDANT = DESCENDANT + OPEN_TOP_LEVEL;
-const voicedPermissions = {
- [threadPermissions.VOICED]: true,
- [threadPermissions.EDIT_ENTRIES]: true,
- [threadPermissions.EDIT_THREAD_NAME]: true,
- [threadPermissions.EDIT_THREAD_COLOR]: true,
- [threadPermissions.EDIT_THREAD_DESCRIPTION]: true,
- [threadPermissions.EDIT_THREAD_AVATAR]: true,
- [threadPermissions.CREATE_SUBCHANNELS]: true,
- [threadPermissions.ADD_MEMBERS]: true,
-};
+const baseMemberUserSurfacedPermissions = [
+ userSurfacedPermissions.REACT_TO_MESSAGES,
+ userSurfacedPermissions.EDIT_MESSAGES,
+ userSurfacedPermissions.ADD_MEMBERS,
+];
+const baseVoicedUserSurfacedPermissions = [
+ userSurfacedPermissions.EDIT_CALENDAR,
+ userSurfacedPermissions.CREATE_AND_EDIT_CHANNELS,
+];
function getRolePermissionBlobsForCommunity(
threadType: ThreadType,
): RolePermissionBlobs {
- const openDescendantKnowOf = OPEN_DESCENDANT + threadPermissions.KNOW_OF;
- const openDescendantVisible = OPEN_DESCENDANT + threadPermissions.VISIBLE;
- const openTopLevelDescendantJoinThread =
- OPEN_TOP_LEVEL_DESCENDANT + threadPermissions.JOIN_THREAD;
- const openChildJoinThread = OPEN_CHILD + threadPermissions.JOIN_THREAD;
- const openChildAddMembers = OPEN_CHILD + threadPermissions.ADD_MEMBERS;
-
- const genesisMemberPermissions = {
- [threadPermissions.KNOW_OF]: true,
- [threadPermissions.VISIBLE]: true,
- [openDescendantKnowOf]: true,
- [openDescendantVisible]: true,
- [openTopLevelDescendantJoinThread]: true,
- };
- const baseMemberPermissions = {
- ...genesisMemberPermissions,
- [threadPermissions.REACT_TO_MESSAGE]: true,
- [threadPermissions.EDIT_MESSAGE]: true,
- [threadPermissions.LEAVE_THREAD]: true,
- [threadPermissions.CREATE_SIDEBARS]: true,
- [threadPermissions.ADD_MEMBERS]: true,
- [openChildJoinThread]: true,
- [openChildAddMembers]: true,
- };
-
- let memberPermissions;
- if (threadType === threadTypes.COMMUNITY_ANNOUNCEMENT_ROOT) {
- memberPermissions = baseMemberPermissions;
- } else if (threadType === threadTypes.GENESIS) {
- memberPermissions = genesisMemberPermissions;
+ let memberUserSurfacedPermissions;
+ if (threadType === threadTypes.GENESIS) {
+ memberUserSurfacedPermissions = [];
+ } else if (threadType === threadTypes.COMMUNITY_ANNOUNCEMENT_ROOT) {
+ memberUserSurfacedPermissions = baseMemberUserSurfacedPermissions;
} else {
- memberPermissions = {
- ...baseMemberPermissions,
- ...voicedPermissions,
- };
+ memberUserSurfacedPermissions = [
+ ...baseMemberUserSurfacedPermissions,
+ ...baseVoicedUserSurfacedPermissions,
+ ];
}
+ const memberPermissions = getThreadPermissionBlobFromUserSurfacedPermissions(
+ memberUserSurfacedPermissions,
+ threadType,
+ );
+
const descendantKnowOf = DESCENDANT + threadPermissions.KNOW_OF;
const descendantVisible = DESCENDANT + threadPermissions.VISIBLE;
const topLevelDescendantJoinThread =
@@ -298,6 +303,17 @@
};
}
+const nonCommunityVoicedPermissions = {
+ [threadPermissions.VOICED]: true,
+ [threadPermissions.EDIT_ENTRIES]: true,
+ [threadPermissions.EDIT_THREAD_NAME]: true,
+ [threadPermissions.EDIT_THREAD_COLOR]: true,
+ [threadPermissions.EDIT_THREAD_DESCRIPTION]: true,
+ [threadPermissions.EDIT_THREAD_AVATAR]: true,
+ [threadPermissions.CREATE_SUBCHANNELS]: true,
+ [threadPermissions.ADD_MEMBERS]: true,
+};
+
function getRolePermissionBlobs(threadType: ThreadType): RolePermissionBlobs {
if (threadType === threadTypes.SIDEBAR) {
const memberPermissions = {
@@ -386,7 +402,7 @@
[threadPermissions.REMOVE_MEMBERS]: true,
[threadPermissions.EDIT_PERMISSIONS]: true,
...subthreadBasePermissions,
- ...voicedPermissions,
+ ...nonCommunityVoicedPermissions,
};
return {
Members: memberPermissions,
@@ -405,11 +421,53 @@
return getRolePermissionBlobsForCommunity(threadType);
}
+// ESLint doesn't recognize that invariant always throws
+// eslint-disable-next-line consistent-return
+function getUniversalCommunityRootPermissionsBlob(
+ threadType: ThreadType,
+): ThreadRolePermissionsBlob {
+ const openDescendantKnowOf = OPEN_DESCENDANT + threadPermissions.KNOW_OF;
+ const openDescendantVisible = OPEN_DESCENDANT + threadPermissions.VISIBLE;
+ const openChildJoinThread = OPEN_CHILD + threadPermissions.JOIN_THREAD;
+ const openTopLevelDescendantJoinThread =
+ OPEN_TOP_LEVEL_DESCENDANT + threadPermissions.JOIN_THREAD;
+
+ const genesisUniversalCommunityPermissions = {
+ [threadPermissions.KNOW_OF]: true,
+ [threadPermissions.VISIBLE]: true,
+ [openDescendantKnowOf]: true,
+ [openDescendantVisible]: true,
+ [openTopLevelDescendantJoinThread]: true,
+ };
+
+ const baseUniversalCommunityPermissions = {
+ ...genesisUniversalCommunityPermissions,
+ [threadPermissions.CREATE_SIDEBARS]: true,
+ [threadPermissions.LEAVE_THREAD]: true,
+ [openChildJoinThread]: true,
+ };
+
+ if (threadType === threadTypes.GENESIS) {
+ return genesisUniversalCommunityPermissions;
+ } else if (threadType === threadTypes.COMMUNITY_ANNOUNCEMENT_ROOT) {
+ return baseUniversalCommunityPermissions;
+ } else if (threadType === threadTypes.COMMUNITY_ROOT) {
+ return {
+ ...baseUniversalCommunityPermissions,
+ [threadPermissions.VOICED]: true,
+ };
+ }
+
+ invariant(false, 'invalid threadType parameter');
+}
+
export {
permissionLookup,
getAllThreadPermissions,
makePermissionsBlob,
makePermissionsForChildrenBlob,
getRoleForPermissions,
+ getThreadPermissionBlobFromUserSurfacedPermissions,
getRolePermissionBlobs,
+ getUniversalCommunityRootPermissionsBlob,
};

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 22, 5:34 PM (18 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2692004
Default Alt Text
D9897.diff (11 KB)

Event Timeline