[MM-24891] [MM-24572] Add ability to specify default value when role not found for selector (#4277) (#4287)
* MM-24891 Allow permissions to have defaults set in case where roles not in state * MM-24891 Add tests for haveIPermission * MM-24891 Apply the defaults to more channel permission checks
This commit is contained in:
parent
19a282ad41
commit
613ddc1250
9 changed files with 121 additions and 47 deletions
|
|
@ -34,6 +34,7 @@ function mapStateToProps(state, ownProps) {
|
|||
{
|
||||
channel: currentChannelId,
|
||||
permission: Permissions.USE_CHANNEL_MENTIONS,
|
||||
default: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ export function mapStateToProps(state, ownProps) {
|
|||
channel: currentChannel.id,
|
||||
team: currentChannel.team_id,
|
||||
permission: Permissions.CREATE_POST,
|
||||
default: true,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -68,6 +69,7 @@ export function mapStateToProps(state, ownProps) {
|
|||
{
|
||||
channel: currentChannel.id,
|
||||
permission: Permissions.USE_CHANNEL_MENTIONS,
|
||||
default: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,11 +71,13 @@ describe('mapStateToProps', () => {
|
|||
channel: undefined,
|
||||
team: undefined,
|
||||
permission: Permissions.CREATE_POST,
|
||||
default: true,
|
||||
});
|
||||
|
||||
expect(roleSelectors.haveIChannelPermission).not.toHaveBeenCalledWith(state, {
|
||||
channel: undefined,
|
||||
permission: Permissions.USE_CHANNEL_MENTIONS,
|
||||
default: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -90,11 +92,13 @@ describe('mapStateToProps', () => {
|
|||
channel: undefined,
|
||||
team: undefined,
|
||||
permission: Permissions.CREATE_POST,
|
||||
default: true,
|
||||
});
|
||||
|
||||
expect(roleSelectors.haveIChannelPermission).toHaveBeenCalledWith(state, {
|
||||
channel: undefined,
|
||||
permission: Permissions.USE_CHANNEL_MENTIONS,
|
||||
default: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -43,6 +43,7 @@ function makeMapStateToProps() {
|
|||
team: teamId,
|
||||
channel: channelId,
|
||||
permission: Permissions.ADD_REACTION,
|
||||
default: true,
|
||||
});
|
||||
|
||||
if (reactions) {
|
||||
|
|
@ -54,6 +55,7 @@ function makeMapStateToProps() {
|
|||
team: teamId,
|
||||
channel: channelId,
|
||||
permission: Permissions.REMOVE_REACTION,
|
||||
default: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,12 @@ describe('Selectors.Roles', () => {
|
|||
const team1 = TestHelper.fakeTeamWithId();
|
||||
const team2 = TestHelper.fakeTeamWithId();
|
||||
const team3 = TestHelper.fakeTeamWithId();
|
||||
const team4 = TestHelper.fakeTeamWithId();
|
||||
const myTeamMembers = {};
|
||||
myTeamMembers[team1.id] = {roles: 'test_team1_role1 test_team1_role2'};
|
||||
myTeamMembers[team2.id] = {roles: 'test_team2_role1 test_team2_role2'};
|
||||
myTeamMembers[team3.id] = {};
|
||||
myTeamMembers[team4.id] = {roles: 'test_team4_role_not_found'};
|
||||
|
||||
const channel1 = TestHelper.fakeChannelWithId(team1.id);
|
||||
channel1.display_name = 'Channel Name';
|
||||
|
|
@ -50,6 +52,7 @@ describe('Selectors.Roles', () => {
|
|||
const channel11 = TestHelper.fakeChannelWithId(team1.id);
|
||||
channel11.type = General.PRIVATE_CHANNEL;
|
||||
const channel12 = TestHelper.fakeChannelWithId(team1.id);
|
||||
const channel13 = TestHelper.fakeChannelWithId(team1.id);
|
||||
|
||||
const channels = {};
|
||||
channels[channel1.id] = channel1;
|
||||
|
|
@ -64,6 +67,7 @@ describe('Selectors.Roles', () => {
|
|||
channels[channel10.id] = channel10;
|
||||
channels[channel11.id] = channel11;
|
||||
channels[channel12.id] = channel12;
|
||||
channels[channel13.id] = channel13;
|
||||
|
||||
const channelsInTeam = {};
|
||||
channelsInTeam[team1.id] = [channel1.id, channel2.id, channel5.id, channel6.id, channel8.id, channel10.id, channel11.id];
|
||||
|
|
@ -87,6 +91,7 @@ describe('Selectors.Roles', () => {
|
|||
myChannelMembers[channel10.id] = {roles: 'test_channel_c_role1 test_channel_c_role2'};
|
||||
myChannelMembers[channel11.id] = {roles: 'test_channel_c_role1 test_channel_c_role2'};
|
||||
myChannelMembers[channel12.id] = {};
|
||||
myChannelMembers[channel13.id] = {roles: 'test_channel_not_found_role'};
|
||||
const roles = {
|
||||
test_team1_role1: {permissions: ['team1_role1']},
|
||||
test_team2_role1: {permissions: ['team2_role1']},
|
||||
|
|
@ -124,6 +129,7 @@ describe('Selectors.Roles', () => {
|
|||
const teamsRoles = {};
|
||||
teamsRoles[team1.id] = new Set(['test_team1_role1', 'test_team1_role2']);
|
||||
teamsRoles[team2.id] = new Set(['test_team2_role1', 'test_team2_role2']);
|
||||
teamsRoles[team4.id] = new Set(['test_team4_role_not_found']);
|
||||
const channelsRoles = {};
|
||||
channelsRoles[channel1.id] = new Set(['test_channel_a_role1', 'test_channel_a_role2']);
|
||||
channelsRoles[channel2.id] = new Set(['test_channel_a_role1', 'test_channel_a_role2']);
|
||||
|
|
@ -135,6 +141,7 @@ describe('Selectors.Roles', () => {
|
|||
channelsRoles[channel9.id] = new Set(['test_channel_b_role1', 'test_channel_b_role2']);
|
||||
channelsRoles[channel10.id] = new Set(['test_channel_c_role1', 'test_channel_c_role2']);
|
||||
channelsRoles[channel11.id] = new Set(['test_channel_c_role1', 'test_channel_c_role2']);
|
||||
channelsRoles[channel13.id] = new Set(['test_channel_not_found_role']);
|
||||
const myRoles = {
|
||||
system: new Set(['test_user_role', 'test_user_role2']),
|
||||
team: teamsRoles,
|
||||
|
|
@ -172,10 +179,18 @@ describe('Selectors.Roles', () => {
|
|||
assert.equal(Selectors.haveISystemPermission(testState, {permission: 'invalid_permission'}), false);
|
||||
});
|
||||
|
||||
it('should return my team permission on getMyTeamPermissions', () => {
|
||||
assert.deepEqual(Selectors.getMyTeamPermissions(testState, {team: team1.id}), new Set([
|
||||
'user_role2', 'team1_role1',
|
||||
]));
|
||||
it('should return my team permissions on getMyTeamPermissions', () => {
|
||||
const {permissions, roleFound} = Selectors.getMyTeamPermissions(testState, {team: team1.id});
|
||||
const expectedPermissions = new Set(['user_role2', 'team1_role1']);
|
||||
assert.deepEqual(permissions, expectedPermissions);
|
||||
assert.equal(roleFound, true);
|
||||
});
|
||||
|
||||
it('should return system permissions on getMyTeamPermissions when team not found', () => {
|
||||
const {permissions, roleFound} = Selectors.getMyTeamPermissions(testState, {team: team4.id});
|
||||
const expectedPermissions = new Set(['user_role2']);
|
||||
assert.deepEqual(permissions, expectedPermissions);
|
||||
assert.equal(roleFound, false);
|
||||
});
|
||||
|
||||
it('should return if i have a team permission on haveITeamPermission', () => {
|
||||
|
|
@ -185,10 +200,17 @@ describe('Selectors.Roles', () => {
|
|||
assert.equal(Selectors.haveITeamPermission(testState, {team: team1.id, permission: 'invalid_permission'}), false);
|
||||
});
|
||||
|
||||
it('should return default if role not found in state on haveITeamPermission for team scoped permission', () => {
|
||||
assert.equal(Selectors.haveITeamPermission(testState, {team: team4.id, permission: 'any_permission', default: true}), true);
|
||||
assert.equal(Selectors.haveITeamPermission(testState, {team: team4.id, permission: 'any_permission', default: false}), false);
|
||||
assert.equal(Selectors.haveITeamPermission(testState, {team: team1.id, permission: 'user_role2'}), true);
|
||||
});
|
||||
|
||||
it('should return my team permission on getMyCurrentTeamPermissions', () => {
|
||||
assert.deepEqual(Selectors.getMyCurrentTeamPermissions(testState), new Set([
|
||||
'user_role2', 'team1_role1',
|
||||
]));
|
||||
const {permissions, roleFound} = Selectors.getMyCurrentTeamPermissions(testState);
|
||||
const expectedPermissions = new Set(['user_role2', 'team1_role1']);
|
||||
assert.deepEqual(permissions, expectedPermissions);
|
||||
assert.equal(roleFound, true);
|
||||
});
|
||||
|
||||
it('should return if i have a team permission on haveICurrentTeamPermission', () => {
|
||||
|
|
@ -199,9 +221,24 @@ describe('Selectors.Roles', () => {
|
|||
});
|
||||
|
||||
it('should return my channel permission on getMyChannelPermissions', () => {
|
||||
assert.deepEqual(Selectors.getMyChannelPermissions(testState, {team: team1.id, channel: channel1.id}), new Set([
|
||||
'user_role2', 'team1_role1', 'channel_a_role1', 'channel_a_role2',
|
||||
]));
|
||||
const {permissions, roleFound} = Selectors.getMyChannelPermissions(testState, {team: team1.id, channel: channel1.id});
|
||||
const expectedPermissions = new Set(['user_role2', 'team1_role1', 'channel_a_role1', 'channel_a_role2']);
|
||||
assert.deepEqual(permissions, expectedPermissions);
|
||||
assert.equal(roleFound, true);
|
||||
});
|
||||
|
||||
it('should only return my team permissions on getMyChannelPermissions when role not found', () => {
|
||||
const {permissions, roleFound} = Selectors.getMyChannelPermissions(testState, {team: team1.id, channel: channel13.id});
|
||||
const expectedPermissions = new Set(['user_role2', 'team1_role1']);
|
||||
assert.deepEqual(permissions, expectedPermissions);
|
||||
assert.equal(roleFound, false);
|
||||
});
|
||||
|
||||
it('should return my channel permission on getMyChannelPermissions when channel roles not found', () => {
|
||||
const {permissions, roleFound} = Selectors.getMyChannelPermissions(testState, {team: team1.id, channel: channel1.id});
|
||||
const expectedPermissions = new Set(['user_role2', 'team1_role1', 'channel_a_role1', 'channel_a_role2']);
|
||||
assert.deepEqual(permissions, expectedPermissions);
|
||||
assert.equal(roleFound, true);
|
||||
});
|
||||
|
||||
it('should return if i have a channel permission on haveIChannelPermission', () => {
|
||||
|
|
@ -212,10 +249,11 @@ describe('Selectors.Roles', () => {
|
|||
assert.equal(Selectors.haveIChannelPermission(testState, {team: team1.id, channel: channel1.id, permission: 'channel_b_role1'}), false);
|
||||
});
|
||||
|
||||
it('should return my current channel permission on getMyCurrentChannelPermissions', () => {
|
||||
assert.deepEqual(Selectors.getMyCurrentChannelPermissions(testState), new Set([
|
||||
'user_role2', 'team1_role1', 'channel_a_role1', 'channel_a_role2',
|
||||
]));
|
||||
it('should return default if role not found in state on haveIChannelPermission for channel scoped permission', () => {
|
||||
assert.equal(Selectors.haveIChannelPermission(testState, {team: team1.id, channel: channel13.id, permission: 'any_permission', default: true}), true);
|
||||
assert.equal(Selectors.haveIChannelPermission(testState, {team: team1.id, channel: channel13.id, permission: 'any_permission', default: false}), false);
|
||||
assert.equal(Selectors.haveIChannelPermission(testState, {team: team1.id, channel: channel13.id, permission: 'user_role2'}), true);
|
||||
assert.equal(Selectors.haveIChannelPermission(testState, {team: team1.id, channel: channel13.id, permission: 'team1_role1'}), true);
|
||||
});
|
||||
|
||||
it('should return if i have a channel permission on haveICurrentChannelPermission', () => {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import * as reselect from 'reselect';
|
||||
import {getCurrentUser, getCurrentChannelId} from '@mm-redux/selectors/entities/common';
|
||||
import {getCurrentChannelId} from '@mm-redux/selectors/entities/common';
|
||||
import {getTeamMemberships, getCurrentTeamId} from './teams';
|
||||
import * as types from '@mm-redux/types';
|
||||
import {getMySystemPermissions, getMySystemRoles, getRoles, PermissionsOptions} from '@mm-redux/selectors/entities/roles_helpers';
|
||||
import {GlobalState} from '@mm-redux/types/store';
|
||||
import {Dictionary} from '@mm-redux/types/utilities';
|
||||
import {Role} from '@mm-redux/types/roles';
|
||||
import {Channel} from '@mm-redux/types/channels';
|
||||
import {Team} from '@mm-redux/types/teams';
|
||||
|
||||
export {getMySystemPermissions, getMySystemRoles, getRoles};
|
||||
|
||||
|
|
@ -73,21 +71,23 @@ export const getMyCurrentTeamPermissions = reselect.createSelector(
|
|||
getMySystemPermissions,
|
||||
getCurrentTeamId,
|
||||
(myTeamRoles, roles, systemPermissions, teamId) => {
|
||||
const permissions = new Set();
|
||||
const permissions = new Set<string>();
|
||||
let roleFound = false;
|
||||
if (myTeamRoles[teamId]) {
|
||||
for (const roleName of myTeamRoles[teamId]) {
|
||||
if (roles[roleName]) {
|
||||
for (const permission of roles[roleName].permissions) {
|
||||
permissions.add(permission);
|
||||
}
|
||||
roleFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const permission of systemPermissions) {
|
||||
permissions.add(permission);
|
||||
}
|
||||
return permissions;
|
||||
}
|
||||
return {permissions, roleFound};
|
||||
},
|
||||
);
|
||||
|
||||
export const getMyCurrentChannelPermissions = reselect.createSelector(
|
||||
|
|
@ -95,22 +95,24 @@ export const getMyCurrentChannelPermissions = reselect.createSelector(
|
|||
getRoles,
|
||||
getMyCurrentTeamPermissions,
|
||||
getCurrentChannelId,
|
||||
(myChannelRoles, roles, teamPermissions, channelId) => {
|
||||
const permissions = new Set();
|
||||
(myChannelRoles, roles, {permissions: teamPermissions, roleFound: teamRoleFound}, channelId) => {
|
||||
const permissions = new Set<string>();
|
||||
let roleFound = false;
|
||||
if (myChannelRoles[channelId]) {
|
||||
for (const roleName of myChannelRoles[channelId]) {
|
||||
if (roles[roleName]) {
|
||||
for (const permission of roles[roleName].permissions) {
|
||||
permissions.add(permission);
|
||||
}
|
||||
roleFound = true && teamRoleFound;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const permission of teamPermissions) {
|
||||
permissions.add(permission);
|
||||
}
|
||||
return permissions;
|
||||
}
|
||||
return {permissions, roleFound};
|
||||
},
|
||||
);
|
||||
|
||||
export const getMyTeamPermissions = reselect.createSelector(
|
||||
|
|
@ -119,21 +121,23 @@ export const getMyTeamPermissions = reselect.createSelector(
|
|||
getMySystemPermissions,
|
||||
(state: GlobalState, options: PermissionsOptions) => options.team,
|
||||
(myTeamRoles, roles, systemPermissions, teamId) => {
|
||||
const permissions = new Set();
|
||||
const permissions = new Set<string>();
|
||||
let roleFound = false;
|
||||
if (myTeamRoles[teamId!]) {
|
||||
for (const roleName of myTeamRoles[teamId!]) {
|
||||
if (roles[roleName]) {
|
||||
for (const permission of roles[roleName].permissions) {
|
||||
permissions.add(permission);
|
||||
}
|
||||
roleFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const permission of systemPermissions) {
|
||||
permissions.add(permission);
|
||||
}
|
||||
return permissions;
|
||||
}
|
||||
return {permissions, roleFound};
|
||||
},
|
||||
);
|
||||
|
||||
export const getMyChannelPermissions = reselect.createSelector(
|
||||
|
|
@ -141,22 +145,24 @@ export const getMyChannelPermissions = reselect.createSelector(
|
|||
getRoles,
|
||||
getMyTeamPermissions,
|
||||
(state, options: PermissionsOptions) => options.channel,
|
||||
(myChannelRoles, roles, teamPermissions, channelId) => {
|
||||
const permissions = new Set();
|
||||
(myChannelRoles, roles, {permissions: teamPermissions, roleFound: teamRoleFound}, channelId) => {
|
||||
const permissions = new Set<string>();
|
||||
let roleFound = false;
|
||||
if (myChannelRoles[channelId!]) {
|
||||
for (const roleName of myChannelRoles[channelId!]) {
|
||||
if (roles[roleName]) {
|
||||
for (const permission of roles[roleName].permissions) {
|
||||
permissions.add(permission);
|
||||
}
|
||||
roleFound = true && teamRoleFound;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const permission of teamPermissions) {
|
||||
permissions.add(permission);
|
||||
}
|
||||
return permissions;
|
||||
}
|
||||
return {permissions, roleFound};
|
||||
},
|
||||
);
|
||||
|
||||
export const haveISystemPermission = reselect.createSelector(
|
||||
|
|
@ -169,32 +175,48 @@ export const haveISystemPermission = reselect.createSelector(
|
|||
|
||||
export const haveITeamPermission = reselect.createSelector(
|
||||
getMyTeamPermissions,
|
||||
(state, options) => options.permission,
|
||||
(permissions, permission) => {
|
||||
return permissions.has(permission);
|
||||
}
|
||||
(state, options) => options,
|
||||
({permissions, roleFound}, options) => {
|
||||
const hasPermission = permissions.has(options.permission);
|
||||
if (roleFound) {
|
||||
return hasPermission;
|
||||
}
|
||||
return options.default === true || hasPermission;
|
||||
},
|
||||
);
|
||||
|
||||
export const haveIChannelPermission = reselect.createSelector(
|
||||
getMyChannelPermissions,
|
||||
(state, options) => options.permission,
|
||||
(permissions, permission) => {
|
||||
return permissions.has(permission);
|
||||
}
|
||||
(state, options) => options,
|
||||
({permissions, roleFound}, options) => {
|
||||
const hasPermission = permissions.has(options.permission);
|
||||
if (roleFound) {
|
||||
return hasPermission;
|
||||
}
|
||||
return options.default === true || hasPermission;
|
||||
},
|
||||
);
|
||||
|
||||
export const haveICurrentTeamPermission = reselect.createSelector(
|
||||
getMyCurrentTeamPermissions,
|
||||
(state: GlobalState, options: PermissionsOptions) => options.permission,
|
||||
(permissions, permission) => {
|
||||
return permissions.has(permission);
|
||||
}
|
||||
(state: GlobalState, options: PermissionsOptions) => options,
|
||||
({permissions, roleFound}, options) => {
|
||||
const hasPermission = permissions.has(options.permission);
|
||||
if (roleFound) {
|
||||
return hasPermission;
|
||||
}
|
||||
return options.default === true || hasPermission;
|
||||
},
|
||||
);
|
||||
|
||||
export const haveICurrentChannelPermission = reselect.createSelector(
|
||||
getMyCurrentChannelPermissions,
|
||||
(state: GlobalState, options: PermissionsOptions) => options.permission,
|
||||
(permissions, permission) => {
|
||||
return permissions.has(permission);
|
||||
}
|
||||
(state: GlobalState, options: PermissionsOptions) => options,
|
||||
({permissions, roleFound}, options) => {
|
||||
const hasPermission = permissions.has(options.permission);
|
||||
if (roleFound) {
|
||||
return hasPermission;
|
||||
}
|
||||
return options.default === true || hasPermission;
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ export type PermissionsOptions = {
|
|||
channel?: string;
|
||||
team?: string;
|
||||
permission: string;
|
||||
default?: boolean;
|
||||
};
|
||||
|
||||
export function getRoles(state: GlobalState) {
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ export function makeMapStateToProps() {
|
|||
channel: post.channel_id,
|
||||
team: channel.team_id,
|
||||
permission: Permissions.CREATE_POST,
|
||||
default: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -74,6 +75,7 @@ export function makeMapStateToProps() {
|
|||
team: currentTeamId,
|
||||
channel: post.channel_id,
|
||||
permission: Permissions.ADD_REACTION,
|
||||
default: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ describe('makeMapStateToProps', () => {
|
|||
channel: undefined,
|
||||
team: undefined,
|
||||
permission: Permissions.CREATE_POST,
|
||||
default: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -176,6 +177,7 @@ describe('makeMapStateToProps', () => {
|
|||
channel: undefined,
|
||||
team: undefined,
|
||||
permission: Permissions.CREATE_POST,
|
||||
default: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue