Skip to content

Commit 275463a

Browse files
committed
feat(federation): unassign users
Signed-off-by: grnd-alt <git@belakkaf.net>
1 parent d1c46d4 commit 275463a

File tree

8 files changed

+56
-11
lines changed

8 files changed

+56
-11
lines changed

appinfo/routes.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
['name' => 'card_ocs#update', 'url' => '/api/v{apiVersion}/cards/{cardId}', 'verb' => 'PUT'],
144144
['name' => 'card_ocs#assignLabel', 'url' => '/api/v{apiVersion}/cards/{cardId}/label/{labelId}', 'verb' => 'POST'],
145145
['name' => 'card_ocs#assignUser', 'url' => '/api/v{apiVersion}/cards/{cardId}/assign', 'verb' => 'POST'],
146+
['name' => 'card_ocs#unAssignUser', 'url' => '/api/v{apiVersion}/cards/{cardId}/unassign', 'verb' => 'PUT'],
146147
['name' => 'card_ocs#removeLabel', 'url' => '/api/v{apiVersion}/cards/{cardId}/label/{labelId}', 'verb' => 'DELETE'],
147148

148149
['name' => 'stack_ocs#create', 'url' => '/api/v{apiVersion}/stacks', 'verb' => 'POST'],

lib/Controller/CardOcsController.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,19 @@ public function assignUser(?int $boardId, int $cardId, string $userId, int $type
9292
return new DataResponse($this->assignmentService->assignUser($cardId, $userId, $type));
9393
}
9494

95+
#[NoAdminRequired]
96+
#[PublicPage]
97+
#[NoCSRFRequired]
98+
public function unAssignUser(?int $boardId, int $cardId, string $userId, int $type = 0): DataResponse {
99+
if ($boardId) {
100+
$localBoard = $this->boardService->find($boardId, false);
101+
if ($localBoard->getExternalId()) {
102+
return new DataResponse($this->externalBoardService->unAssignUserOnRemote($localBoard, $cardId, $userId, $type));
103+
}
104+
}
105+
return new DataResponse($this->assignmentService->unAssignUser($cardId, $userId, $type));
106+
}
107+
95108
#[NoAdminRequired]
96109
#[PublicPage]
97110
#[NoCSRFRequired]

lib/Service/ExternalBoardService.php

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
namespace OCA\Deck\Service;
99

10-
use OC\Federation\CloudIdManager;
1110
use OCA\Deck\Db\Acl;
1211
use OCA\Deck\Db\Assignment;
1312
use OCA\Deck\Db\Board;
@@ -56,10 +55,10 @@ public function getExternalStacksFromRemote(Board $localBoard):DataResponse {
5655
return new DataResponse($this->LocalizeRemoteStacks($ocs, $localBoard));
5756
}
5857

59-
public function localizeRemoteUser(Board $localBoard, array $user): array | User | FederatedUser | null {
58+
public function localizeRemoteUser(Board $localBoard, array $user): array|User|FederatedUser|null {
6059
// skip invalid users
6160
if (!$user['uid']) {
62-
return null;;
61+
return null;
6362
}
6463
// if it's already a valid cloud id the user originates from a third instance and we pass it as is
6564
if ($this->cloudIdManager->isValidCloudId($user['uid'])) {
@@ -81,7 +80,7 @@ public function localizeRemoteUser(Board $localBoard, array $user): array | User
8180
public function LocalizeRemoteStacks(array $stacks, Board $localBoard) {
8281
foreach ($stacks as $i => $stack) {
8382
$stack['boardId'] = $localBoard->getId();
84-
foreach($stack['cards'] as $j => $card) {
83+
foreach ($stack['cards'] as $j => $card) {
8584
$stack['cards'][$j]['assignedUsers'] = array_map(function ($assignment) use ($localBoard) {
8685
$assignment['participant'] = $this->localizeRemoteUser($localBoard, $assignment['participant']);
8786
return $assignment;
@@ -234,6 +233,32 @@ public function assignUserOnRemote(Board $localBoard, int $cardId, string $userI
234233
return $result;
235234
}
236235

236+
public function unAssignUserOnRemote(Board $localBoard, int $cardId, string $userId, int $type = 0): array {
237+
$this->configService->ensureFederationEnabled();
238+
239+
$ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner());
240+
241+
if ($this->cloudIdManager->isValidCloudId($userId)) {
242+
$cloudId = $this->cloudIdManager->resolveCloudId($userId);
243+
// assignee's origin is the same as the board owner's origin: send as local user
244+
if ($cloudId->getRemote() === $ownerCloudId->getRemote()) {
245+
$userId = $cloudId->getUser();
246+
$type = Assignment::TYPE_USER;
247+
}
248+
} else {
249+
// local user for us = remote user for remote
250+
$userId = $this->cloudIdManager->getCloudId($userId, null)->getId();
251+
$type = Assignment::TYPE_REMOTE;
252+
}
253+
$shareToken = $localBoard->getShareToken();
254+
$url = $ownerCloudId->getRemote() . '/ocs/v2.php/apps/deck/api/v1.0/cards/' . $cardId . '/unassign';
255+
$resp = $this->proxy->put($ownerCloudId->getId(), $shareToken, $url, [
256+
'userId' => $userId,
257+
'type' => $type,
258+
'boardId' => $localBoard->getExternalId(),
259+
]);
260+
return $this->proxy->getOcsData($resp);
261+
}
237262

238263
public function createStackOnRemote(
239264
Board $localBoard,

lib/Service/PermissionService.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
class PermissionService {
3131

32-
/** @var array<string, array<string, User>> */
32+
/** @var array<string, array<string, User|FederatedUser>> */
3333
private $users = [];
3434

3535
// accessToken to check permission for federated shares
@@ -266,7 +266,7 @@ public function getUserId(): ?string {
266266
*
267267
* @param $boardId
268268
* @param $refresh
269-
* @return array<string, User>
269+
* @return array<string, User | FederatedUser>
270270
* */
271271
public function findUsers($boardId, $refresh = false) {
272272
// cache users of a board so we don't query them for every cards

src/components/board/SharingTabSidebar.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ const SOURCE_TO_SHARE_TYPE = {
9090
groups: 1,
9191
emails: 4,
9292
remotes: 6,
93-
teams: 7,
93+
circles: 7,
9494
}
9595
9696
export default {
@@ -139,6 +139,7 @@ export default {
139139
displayName: item.displayname || item.name || item.label || item.id,
140140
user: item.id,
141141
subname: item.shareWithDisplayNameUnique || item.subline || item.id, // NcSelectUser does its own pattern matching to filter things out
142+
type: SOURCE_TO_SHARE_TYPE[item.source]
142143
}
143144
return res
144145
}).slice(0, 10)

src/services/CardApi.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,11 @@ export class CardApi {
125125
})
126126
}
127127

128-
removeUser(cardId, id, type) {
129-
return axios.put(this.url(`/cards/${cardId}/unassign`), { userId: id, type })
128+
removeUser(cardId, id, type, boardId) {
129+
return axios.put(this.ocsUrl(`/cards/${cardId}/unassign`), { userId: id, type, boardId })
130130
.then(
131131
(response) => {
132-
return Promise.resolve(response.data)
132+
return Promise.resolve(response.data.ocs.data)
133133
},
134134
(err) => {
135135
return Promise.reject(err)

src/store/card.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,8 @@ export default function cardModuleFactory() {
347347
commit('assignCardToUser', user)
348348
},
349349
async removeUserFromCard({ commit }, { card, assignee }) {
350-
const user = await apiClient.removeUser(card.id, assignee.userId, assignee.type)
350+
const boardId = this.state.currentBoard.id
351+
const user = await apiClient.removeUser(card.id, assignee.userId, assignee.type, boardId)
351352
commit('removeUserFromCard', user)
352353
},
353354
async addLabel({ commit }, data) {

tests/unit/Service/PermissionServiceTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use OCA\Deck\Db\User;
3333
use OCA\Deck\NoPermissionException;
3434
use OCP\AppFramework\Db\DoesNotExistException;
35+
use OCP\Federation\ICloudIdManager;
3536
use OCP\IConfig;
3637
use OCP\IGroup;
3738
use OCP\IGroupManager;
@@ -53,6 +54,7 @@ class PermissionServiceTest extends \Test\TestCase {
5354
private IGroupManager|MockObject $groupManager;
5455
private MockObject|IManager $shareManager;
5556
private IConfig|MockObject $config;
57+
private ICloudIdManager|MockObject $cloudIdManager;
5658

5759
public function setUp(): void {
5860
parent::setUp();
@@ -65,6 +67,7 @@ public function setUp(): void {
6567
$this->groupManager = $this->createMock(IGroupManager::class);
6668
$this->shareManager = $this->createMock(IManager::class);
6769
$this->config = $this->createMock(IConfig::class);
70+
$this->cloudIdManager = $this->createMock(ICloudIdManager::class);
6871

6972
$this->service = new PermissionService(
7073
$this->logger,
@@ -76,6 +79,7 @@ public function setUp(): void {
7679
$this->groupManager,
7780
$this->shareManager,
7881
$this->config,
82+
$this->cloudIdManager,
7983
'admin'
8084
);
8185
}

0 commit comments

Comments
 (0)