44
55use Illuminate \Foundation \Testing \RefreshDatabase ;
66use Illuminate \Support \Facades \Cache ;
7+ use Illuminate \Support \Facades \Hash ;
8+ use Illuminate \Support \Facades \Redis ;
9+ use Laravel \Passport \Passport ;
10+ use ProcessMaker \Models \Group ;
11+ use ProcessMaker \Models \GroupMember ;
712use ProcessMaker \Models \Permission ;
813use ProcessMaker \Models \User ;
914use ProcessMaker \Services \PermissionServiceManager ;
@@ -23,7 +28,7 @@ protected function setUp(): void
2328 // Ensure the user is created by the trait
2429 if (!$ this ->user ) {
2530 $ this ->user = User::factory ()->create ([
26- 'password ' => \ Illuminate \ Support \ Facades \ Hash::make ('password ' ),
31+ 'password ' => Hash::make ('password ' ),
2732 'is_administrator ' => true ,
2833 ]);
2934 }
@@ -114,4 +119,65 @@ public function test_permission_cache_is_invalidated_when_user_permissions_remov
114119 $ this ->assertContains ('permission-1 ' , $ freshPermissions );
115120 $ this ->assertNotContains ('permission-2 ' , $ freshPermissions );
116121 }
122+
123+ public function test_group_permission_update_does_not_logout_redis_backed_session ()
124+ {
125+ $ this ->ensureRedisSessionAndCacheAreAvailable ();
126+
127+ $ originalPermission = Permission::factory ()->create (['name ' => 'redis-group-permission ' ]);
128+ Permission::factory ()->create (['name ' => 'redis-group-permission-updated ' ]);
129+ $ group = Group::factory ()->create (['name ' => 'Redis Permission Group ' ]);
130+ $ affectedUser = User::factory ()->create ([
131+ 'password ' => Hash::make ('password ' ),
132+ 'is_administrator ' => false ,
133+ ]);
134+
135+ GroupMember::factory ()->create ([
136+ 'group_id ' => $ group ->id ,
137+ 'member_type ' => User::class,
138+ 'member_id ' => $ affectedUser ->id ,
139+ ]);
140+
141+ $ group ->permissions ()->sync ([$ originalPermission ->id ]);
142+
143+ $ this ->permissionService ->warmUpUserCache ($ affectedUser ->id );
144+
145+ $ cachedPermissions = Cache::get ("user_permissions: {$ affectedUser ->id }" );
146+ $ this ->assertNotNull ($ cachedPermissions );
147+ $ this ->assertContains ('redis-group-permission ' , $ cachedPermissions );
148+
149+ $ this ->actingAs ($ this ->user , 'web ' )
150+ ->post (route ('keep-alive ' ))
151+ ->assertNoContent ();
152+
153+ Passport::actingAs ($ this ->user );
154+
155+ $ this ->json ('PUT ' , '/api/1.0/permissions ' , [
156+ 'group_id ' => $ group ->id ,
157+ 'permission_names ' => ['redis-group-permission-updated ' ],
158+ ])->assertNoContent ();
159+
160+ $ this ->post (route ('keep-alive ' ))->assertNoContent ();
161+ $ this ->assertAuthenticatedAs ($ this ->user , 'web ' );
162+
163+ $ freshPermissions = $ this ->permissionService ->getUserPermissions ($ affectedUser ->id );
164+ $ this ->assertContains ('redis-group-permission-updated ' , $ freshPermissions );
165+ $ this ->assertNotContains ('redis-group-permission ' , $ freshPermissions );
166+ }
167+
168+ private function ensureRedisSessionAndCacheAreAvailable (): void
169+ {
170+ config ()->set ('cache.default ' , 'redis ' );
171+ config ()->set ('session.driver ' , 'redis ' );
172+ config ()->set ('session.connection ' , 'default ' );
173+
174+ try {
175+ Redis::connection ('default ' )->ping ();
176+ Redis::connection ('cache ' )->ping ();
177+ } catch (\Throwable $ e ) {
178+ $ this ->markTestSkipped (
179+ 'Redis is not available for the permission cache invalidation regression test: ' . $ e ->getMessage ()
180+ );
181+ }
182+ }
117183}
0 commit comments