Skip to content

Commit 7ece4d7

Browse files
Support remove operations by specifying path with a filter (limosa-io#113)
1 parent 6c31ac7 commit 7ece4d7

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

src/Attribute/MutableCollection.php

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,39 @@ public function add($value, Model &$object)
3131
$object->load($this->attribute);
3232
}
3333

34-
public function remove($value, Model &$object, Path $path = null)
34+
public function remove($value, Model &$object, ?Path $path = null)
3535
{
36-
$values = collect($value)->pluck('value')->all();
36+
if ($path?->getValuePathFilter()?->getComparisonExpression() != null) {
37+
$attributes = $path?->getValuePathFilter()?->getComparisonExpression()?->attributePath?->attributeNames;
38+
$operator = $path?->getValuePathFilter()?->getComparisonExpression()?->operator;
39+
$compareValue = $path?->getValuePathFilter()?->getComparisonExpression()?->compareValue;
40+
41+
if ($value != null) {
42+
throw new SCIMException('Remove operation with filter requires a null value parameter', 400);
43+
}
44+
45+
if (count($attributes) != 1) {
46+
throw new SCIMException(sprintf('Filter must specify exactly one attribute, found %d attributes', count($attributes)), 400);
47+
}
48+
49+
if ($operator != 'eq') {
50+
throw new SCIMException(sprintf('Unsupported filter operator "%s" - only "eq" is supported', $operator), 400);
51+
}
52+
53+
if ($attributes[0] != 'value') {
54+
throw new SCIMException(sprintf('Cannot filter on "%s" - only filtering on "value" attribute is supported', $attributes[0]), 400);
55+
}
56+
57+
if ($value != null) {
58+
throw new SCIMException('Cannot specify both a filter path and a value parameter simultaneously', 400);
59+
}
60+
61+
$object->{$this->attribute}()->detach([$compareValue]);
62+
} else {
63+
$values = collect($value)->pluck('value')->all();
3764

38-
$object->{$this->attribute}()->detach($values);
65+
$object->{$this->attribute}()->detach($values);
66+
}
3967

4068
$object->load($this->attribute);
4169
}

tests/BasicTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use ArieTimmerman\Laravel\SCIMServer\ResourceType;
66
use ArieTimmerman\Laravel\SCIMServer\SCIMConfig;
7+
use ArieTimmerman\Laravel\SCIMServer\Tests\Model\Group;
78
use Illuminate\Support\Arr;
89

910
class BasicTest extends TestCase
@@ -239,6 +240,23 @@ public function testFilterByGroup()
239240
]);
240241

241242
$response->assertStatus(200);
243+
244+
$this->assertTrue(Group::find($groupValue)->members->pluck('id')->contains($userValue), 'User was not added to the group');
245+
246+
// SCIM Patch remove member request
247+
$response = $this->patch('/scim/v2/Groups/' . $groupValue, [
248+
"schemas" => [
249+
"urn:ietf:params:scim:api:messages:2.0:PatchOp",
250+
],
251+
"Operations" => [[
252+
"op" => "remove",
253+
"path" => sprintf("members[value eq \"%s\"]", $userValue),
254+
]]
255+
]);
256+
257+
$response->assertStatus(200);
258+
259+
$this->assertFalse(Group::find($groupValue)->members->pluck('id')->contains($userValue), 'User was not removed from the group');
242260
}
243261

244262
public function testSearch()

0 commit comments

Comments
 (0)