Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3511961
D9897.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
D9897.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D9897: [lib] Introduce getUniversalCommunityRootPermissionsBlob
Attached
Detach File
Event Timeline
Log In to Comment