Skip to content

Commit e2692c9

Browse files
committed
test(policy): enforce admin bypass and non-admin block for target user save
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 9d91083 commit e2692c9

1 file changed

Lines changed: 141 additions & 0 deletions

File tree

tests/php/Unit/Service/Policy/PolicyServiceTest.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,147 @@ public function testSaveUserPreferenceForUserIdPersistsForTargetUser(): void {
245245
$this->assertSame('user', $resolved->getSourceScope());
246246
}
247247

248+
public function testSaveUserPreferenceForUserIdAllowsSystemAdminBypassWhenGroupBlocksUsers(): void {
249+
$targetUser = $this->createMock(IUser::class);
250+
$targetUser->method('getUID')->willReturn('user1');
251+
252+
$actor = $this->createMock(IUser::class);
253+
$actor->method('getUID')->willReturn('admin');
254+
$this->userSession
255+
->method('getUser')
256+
->willReturn($actor);
257+
258+
$this->userManager
259+
->expects($this->once())
260+
->method('get')
261+
->with('user1')
262+
->willReturn($targetUser);
263+
264+
$this->groupManager
265+
->expects($this->once())
266+
->method('getUserGroupIds')
267+
->with($targetUser)
268+
->willReturn(['finance']);
269+
270+
$this->groupManager
271+
->expects($this->once())
272+
->method('isAdmin')
273+
->with('admin')
274+
->willReturn(true);
275+
276+
$this->source
277+
->expects($this->once())
278+
->method('saveUserPreference')
279+
->with(
280+
SignatureFlowPolicy::KEY,
281+
$this->callback(static function ($context): bool {
282+
return $context->getUserId() === 'user1';
283+
}),
284+
'ordered_numeric',
285+
);
286+
287+
$this->source
288+
->method('loadSystemPolicy')
289+
->willReturn((new PolicyLayer())
290+
->setScope('system')
291+
->setValue('none')
292+
->setAllowChildOverride(true)
293+
->setVisibleToChild(true));
294+
295+
$this->source
296+
->method('loadGroupPolicies')
297+
->willReturn([(new PolicyLayer())
298+
->setScope('group')
299+
->setValue('ordered_numeric')
300+
->setAllowChildOverride(false)
301+
->setVisibleToChild(true)
302+
->setAllowedValues(['ordered_numeric'])]);
303+
304+
$this->source->method('loadCirclePolicies')->willReturn([]);
305+
$this->source
306+
->method('loadUserPreference')
307+
->willReturn((new PolicyLayer())
308+
->setScope('user')
309+
->setValue('ordered_numeric'));
310+
$this->source->method('loadRequestOverride')->willReturn(null);
311+
312+
$service = new PolicyService(
313+
$this->contextFactory,
314+
$this->source,
315+
$this->registry,
316+
);
317+
318+
$resolved = $service->saveUserPreferenceForUserId(SignatureFlowPolicy::KEY, 'user1', 'ordered_numeric');
319+
320+
$this->assertSame('ordered_numeric', $resolved->getEffectiveValue());
321+
$this->assertSame('group', $resolved->getSourceScope());
322+
}
323+
324+
public function testSaveUserPreferenceForUserIdBlocksNonAdminWhenGroupDisallowsUserOverrides(): void {
325+
$targetUser = $this->createMock(IUser::class);
326+
$targetUser->method('getUID')->willReturn('user1');
327+
328+
$actor = $this->createMock(IUser::class);
329+
$actor->method('getUID')->willReturn('manager');
330+
$this->userSession
331+
->method('getUser')
332+
->willReturn($actor);
333+
334+
$this->userManager
335+
->expects($this->once())
336+
->method('get')
337+
->with('user1')
338+
->willReturn($targetUser);
339+
340+
$this->groupManager
341+
->expects($this->once())
342+
->method('getUserGroupIds')
343+
->with($targetUser)
344+
->willReturn(['finance']);
345+
346+
$this->groupManager
347+
->expects($this->once())
348+
->method('isAdmin')
349+
->with('manager')
350+
->willReturn(false);
351+
352+
$this->source
353+
->expects($this->never())
354+
->method('saveUserPreference');
355+
356+
$this->source
357+
->method('loadSystemPolicy')
358+
->willReturn((new PolicyLayer())
359+
->setScope('system')
360+
->setValue('none')
361+
->setAllowChildOverride(true)
362+
->setVisibleToChild(true));
363+
364+
$this->source
365+
->method('loadGroupPolicies')
366+
->willReturn([(new PolicyLayer())
367+
->setScope('group')
368+
->setValue('ordered_numeric')
369+
->setAllowChildOverride(false)
370+
->setVisibleToChild(true)
371+
->setAllowedValues(['ordered_numeric'])]);
372+
373+
$this->source->method('loadCirclePolicies')->willReturn([]);
374+
$this->source->method('loadUserPreference')->willReturn(null);
375+
$this->source->method('loadRequestOverride')->willReturn(null);
376+
377+
$service = new PolicyService(
378+
$this->contextFactory,
379+
$this->source,
380+
$this->registry,
381+
);
382+
383+
$this->expectException(\InvalidArgumentException::class);
384+
$this->expectExceptionMessage('Saving a user preference is not allowed for signature_flow');
385+
386+
$service->saveUserPreferenceForUserId(SignatureFlowPolicy::KEY, 'user1', 'ordered_numeric');
387+
}
388+
248389
public function testSaveSystemPersistsAllowChildOverrideWhenEnabled(): void {
249390
$this->source
250391
->expects($this->once())

0 commit comments

Comments
 (0)