github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/app/role_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package app 5 6 import ( 7 "encoding/csv" 8 "io/ioutil" 9 "os" 10 "strconv" 11 "strings" 12 "testing" 13 14 "github.com/mattermost/mattermost-server/v5/model" 15 "github.com/mattermost/mattermost-server/v5/utils" 16 "github.com/stretchr/testify/require" 17 ) 18 19 type permissionInheritanceTestData struct { 20 channelRole *model.Role 21 permission *model.Permission 22 shouldHavePermission bool 23 channel *model.Channel 24 higherScopedRole *model.Role 25 truthTableRow []string 26 } 27 28 func TestGetRolesByNames(t *testing.T) { 29 testPermissionInheritance(t, func(t *testing.T, th *TestHelper, testData permissionInheritanceTestData) { 30 actualRoles, err := th.App.GetRolesByNames([]string{testData.channelRole.Name}) 31 require.Nil(t, err) 32 require.Len(t, actualRoles, 1) 33 34 actualRole := actualRoles[0] 35 require.NotNil(t, actualRole) 36 require.Equal(t, testData.channelRole.Name, actualRole.Name) 37 38 require.Equal(t, testData.shouldHavePermission, utils.StringInSlice(testData.permission.Id, actualRole.Permissions)) 39 }) 40 } 41 42 func TestGetRoleByName(t *testing.T) { 43 testPermissionInheritance(t, func(t *testing.T, th *TestHelper, testData permissionInheritanceTestData) { 44 actualRole, err := th.App.GetRoleByName(testData.channelRole.Name) 45 require.Nil(t, err) 46 require.NotNil(t, actualRole) 47 require.Equal(t, testData.channelRole.Name, actualRole.Name) 48 require.Equal(t, testData.shouldHavePermission, utils.StringInSlice(testData.permission.Id, actualRole.Permissions), "row: %+v", testData.truthTableRow) 49 }) 50 } 51 52 // testPermissionInheritance tests 48 combinations of scheme, permission, role data. 53 func testPermissionInheritance(t *testing.T, testCallback func(t *testing.T, th *TestHelper, testData permissionInheritanceTestData)) { 54 th := Setup(t).InitBasic() 55 defer th.TearDown() 56 57 th.App.Srv().SetLicense(model.NewTestLicense("")) 58 th.App.SetPhase2PermissionsMigrationStatus(true) 59 60 permissionsDefault := []string{ 61 model.PERMISSION_MANAGE_CHANNEL_ROLES.Id, 62 model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id, 63 } 64 65 // Defer resetting the system scheme permissions 66 systemSchemeRoles, err := th.App.GetRolesByNames([]string{ 67 model.CHANNEL_GUEST_ROLE_ID, 68 model.CHANNEL_USER_ROLE_ID, 69 model.CHANNEL_ADMIN_ROLE_ID, 70 }) 71 require.Nil(t, err) 72 require.Len(t, systemSchemeRoles, 3) 73 74 // defer resetting the system role permissions 75 for _, systemRole := range systemSchemeRoles { 76 defer th.App.PatchRole(systemRole, &model.RolePatch{ 77 Permissions: &systemRole.Permissions, 78 }) 79 } 80 81 // Make a channel scheme, clear its permissions 82 channelScheme, err := th.App.CreateScheme(&model.Scheme{ 83 Name: model.NewId(), 84 DisplayName: model.NewId(), 85 Scope: model.SCHEME_SCOPE_CHANNEL, 86 }) 87 require.Nil(t, err) 88 defer th.App.DeleteScheme(channelScheme.Id) 89 90 team := th.CreateTeam() 91 defer th.App.PermanentDeleteTeamId(team.Id) 92 93 // Make a channel 94 channel := th.CreateChannel(team) 95 defer th.App.PermanentDeleteChannel(channel) 96 97 // Set the channel scheme 98 channel.SchemeId = &channelScheme.Id 99 channel, err = th.App.UpdateChannelScheme(channel) 100 require.Nil(t, err) 101 102 // Get the truth table from CSV 103 file, e := os.Open("tests/channel-role-has-permission.csv") 104 require.Nil(t, e) 105 defer file.Close() 106 107 b, e := ioutil.ReadAll(file) 108 require.Nil(t, e) 109 110 r := csv.NewReader(strings.NewReader(string(b))) 111 records, e := r.ReadAll() 112 require.Nil(t, e) 113 114 test := func(higherScopedGuest, higherScopedUser, higherScopedAdmin string) { 115 for _, roleNameUnderTest := range []string{higherScopedGuest, higherScopedUser, higherScopedAdmin} { 116 for i, row := range records { 117 // skip csv header 118 if i == 0 { 119 continue 120 } 121 122 higherSchemeHasPermission, e := strconv.ParseBool(row[0]) 123 require.Nil(t, e) 124 125 permissionIsModerated, e := strconv.ParseBool(row[1]) 126 require.Nil(t, e) 127 128 channelSchemeHasPermission, e := strconv.ParseBool(row[2]) 129 require.Nil(t, e) 130 131 channelRoleIsChannelAdmin, e := strconv.ParseBool(row[3]) 132 require.Nil(t, e) 133 134 shouldHavePermission, e := strconv.ParseBool(row[4]) 135 require.Nil(t, e) 136 137 // skip some invalid combinations because of the outer loop iterating all 3 channel roles 138 if (channelRoleIsChannelAdmin && roleNameUnderTest != higherScopedAdmin) || (!channelRoleIsChannelAdmin && roleNameUnderTest == higherScopedAdmin) { 139 continue 140 } 141 142 // select the permission to test (moderated or non-moderated) 143 var permission *model.Permission 144 if permissionIsModerated { 145 permission = model.PERMISSION_CREATE_POST // moderated 146 } else { 147 permission = model.PERMISSION_READ_CHANNEL // non-moderated 148 } 149 150 // add or remove the permission from the higher-scoped scheme 151 higherScopedRole, testErr := th.App.GetRoleByName(roleNameUnderTest) 152 require.Nil(t, testErr) 153 154 var higherScopedPermissions []string 155 if higherSchemeHasPermission { 156 higherScopedPermissions = []string{permission.Id} 157 } else { 158 higherScopedPermissions = permissionsDefault 159 } 160 higherScopedRole, testErr = th.App.PatchRole(higherScopedRole, &model.RolePatch{Permissions: &higherScopedPermissions}) 161 require.Nil(t, testErr) 162 163 // get channel role 164 var channelRoleName string 165 switch roleNameUnderTest { 166 case higherScopedGuest: 167 channelRoleName = channelScheme.DefaultChannelGuestRole 168 case higherScopedUser: 169 channelRoleName = channelScheme.DefaultChannelUserRole 170 case higherScopedAdmin: 171 channelRoleName = channelScheme.DefaultChannelAdminRole 172 } 173 channelRole, testErr := th.App.GetRoleByName(channelRoleName) 174 require.Nil(t, testErr) 175 176 // add or remove the permission from the channel scheme 177 var channelSchemePermissions []string 178 if channelSchemeHasPermission { 179 channelSchemePermissions = []string{permission.Id} 180 } else { 181 channelSchemePermissions = permissionsDefault 182 } 183 channelRole, testErr = th.App.PatchRole(channelRole, &model.RolePatch{Permissions: &channelSchemePermissions}) 184 require.Nil(t, testErr) 185 186 testCallback(t, th, permissionInheritanceTestData{ 187 channelRole: channelRole, 188 permission: permission, 189 shouldHavePermission: shouldHavePermission, 190 channel: channel, 191 higherScopedRole: higherScopedRole, 192 truthTableRow: row, 193 }) 194 } 195 } 196 } 197 198 // test 24 combinations where the higher-scoped scheme is the SYSTEM scheme 199 test(model.CHANNEL_GUEST_ROLE_ID, model.CHANNEL_USER_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID) 200 201 // create a team scheme 202 teamScheme, err := th.App.CreateScheme(&model.Scheme{ 203 Name: model.NewId(), 204 DisplayName: model.NewId(), 205 Scope: model.SCHEME_SCOPE_TEAM, 206 }) 207 require.Nil(t, err) 208 defer th.App.DeleteScheme(teamScheme.Id) 209 210 // assign the scheme to the team 211 team.SchemeId = &teamScheme.Id 212 team, err = th.App.UpdateTeamScheme(team) 213 require.Nil(t, err) 214 215 // test 24 combinations where the higher-scoped scheme is a TEAM scheme 216 test(teamScheme.DefaultChannelGuestRole, teamScheme.DefaultChannelUserRole, teamScheme.DefaultChannelAdminRole) 217 }