Skip to content

Commit 7069c9e

Browse files
committed
Implement CloudFederationProvider
Signed-off-by: Gary Kim <[email protected]>
1 parent 8f3e737 commit 7069c9e

10 files changed

+431
-20
lines changed

Diff for: appinfo/routes.php

+21
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,27 @@
505505
],
506506
],
507507

508+
/**
509+
* Remote
510+
*/
511+
512+
[
513+
'name' => 'Remote#acceptShare',
514+
'url' => 'api/{apiVersion}/remote/pending/{id}',
515+
'verb' => 'POST',
516+
'requirements' => [
517+
'apiVersion' => 'v1',
518+
],
519+
],
520+
[
521+
'name' => 'Remote#rejectShare',
522+
'url' => 'api/{apiVersion}/remote/pending/{id}',
523+
'verb' => 'DELETE',
524+
'requirements' => [
525+
'apiVersion' => 'v1',
526+
],
527+
],
528+
508529
/**
509530
* PublicShareAuth
510531
*/

Diff for: lib/Controller/FederationController.php

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* @copyright Copyright (c) 2021, Gary Kim <[email protected]>
6+
*
7+
* @author Gary Kim <[email protected]>
8+
*
9+
* @license GNU AGPL version 3 or any later version
10+
*
11+
* This program is free software: you can redistribute it and/or modify
12+
* it under the terms of the GNU Affero General Public License as
13+
* published by the Free Software Foundation, either version 3 of the
14+
* License, or (at your option) any later version.
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Affero General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Affero General Public License
22+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23+
*
24+
*/
25+
26+
namespace OCA\Talk\Controller;
27+
28+
use OCP\AppFramework\Http\DataResponse;
29+
use OCP\AppFramework\OCSController;
30+
use OCP\IRequest;
31+
32+
class FederationController extends OCSController {
33+
public function __construct(string $appName, IRequest $request) {
34+
parent::__construct($appName, $request);
35+
}
36+
37+
/**
38+
* @param string $id
39+
* @return DataResponse
40+
*/
41+
public function acceptShare(string $id): DataResponse {
42+
43+
}
44+
45+
/**
46+
* @param string $id
47+
* @return DataResponse
48+
*/
49+
public function rejectShare(string $id): DataResponse {
50+
51+
}
52+
}

Diff for: lib/Federation/CloudFederationProviderTalk.php

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* @copyright Copyright (c) 2021, Gary Kim <[email protected]>
6+
*
7+
* @author Gary Kim <[email protected]>
8+
*
9+
* @license GNU AGPL version 3 or any later version
10+
*
11+
* This program is free software: you can redistribute it and/or modify
12+
* it under the terms of the GNU Affero General Public License as
13+
* published by the Free Software Foundation, either version 3 of the
14+
* License, or (at your option) any later version.
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Affero General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Affero General Public License
22+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23+
*
24+
*/
25+
26+
namespace OCA\Talk\Federation;
27+
28+
use OC\AppFramework\Http;
29+
use OC\HintException;
30+
use OCA\FederatedFileSharing\AddressHandler;
31+
use OCA\Talk\AppInfo\Application;
32+
use OCA\Talk\Federation\FederationManager;
33+
use OCP\DB\Exception as DBException;
34+
use OCP\Federation\Exceptions\ProviderCouldNotAddShareException;
35+
use OCP\Federation\ICloudFederationProvider;
36+
use OCP\Federation\ICloudFederationShare;
37+
use OCP\IURLGenerator;
38+
use OCP\IUserManager;
39+
use OCP\Notification\IManager as INotificationManager;
40+
use OCP\Share\IShare;
41+
42+
class CloudFederationProviderTalk implements ICloudFederationProvider {
43+
44+
/** @var IUserManager */
45+
private IUserManager $userManager;
46+
47+
/** @var AddressHandler */
48+
private AddressHandler $addressHandler;
49+
50+
/** @var FederationManager */
51+
private FederationManager $federationManager;
52+
53+
/** @var INotificationManager */
54+
private INotificationManager $notificationManager;
55+
56+
/** @var IURLGenerator */
57+
private IURLGenerator $urlGenerator;
58+
59+
public function __construct(
60+
IUserManager $userManager,
61+
AddressHandler $addressHandler,
62+
FederationManager $federationManager,
63+
INotificationManager $notificationManager,
64+
IURLGenerator $urlGenerator
65+
) {
66+
$this->userManager = $userManager;
67+
$this->addressHandler = $addressHandler;
68+
$this->federationManager = $federationManager;
69+
$this->notificationManager = $notificationManager;
70+
$this->urlGenerator = $urlGenerator;
71+
}
72+
73+
/**
74+
* @inheritDoc
75+
*/
76+
public function getShareType(): string {
77+
return 'talk-room';
78+
}
79+
80+
/**
81+
* @inheritDoc
82+
* @throws HintException
83+
* @throws DBException
84+
*/
85+
public function shareReceived(ICloudFederationShare $share): string {
86+
if (!$this->federationManager->isEnabled()) {
87+
throw new ProviderCouldNotAddShareException('Server does not support talk federation', '', Http::STATUS_SERVICE_UNAVAILABLE);
88+
}
89+
if ($share->getShareType() !== 'user') {
90+
throw new ProviderCouldNotAddShareException('support for sharing with non-groups not implemented yet', '', Http::STATUS_NOT_IMPLEMENTED);
91+
}
92+
93+
$shareSecret = $share->getShareSecret();
94+
$shareWith = $share->getShareWith();
95+
$roomToken = $share->getProviderId();
96+
$roomName = $share->getResourceName();
97+
$roomType = (int) $share->getShareType();
98+
[, $remote] = $this->addressHandler->splitUserRemote($share->getOwner());
99+
100+
if ($roomType === 0) {
101+
throw new ProviderCouldNotAddShareException('RoomType is not a number', '', Http::STATUS_BAD_REQUEST);
102+
}
103+
104+
if ($remote && $shareSecret && $shareWith) {
105+
$shareWith = $this->userManager->get($shareWith);
106+
if ($shareWith === null) {
107+
throw new ProviderCouldNotAddShareException('User does not exist', '',Http::STATUS_BAD_REQUEST);
108+
}
109+
110+
$shareId = $this->federationManager->addRemoteRoom($shareWith, $roomType, $roomName, $roomToken, $remote, $shareSecret);
111+
return (string) $shareId;
112+
}
113+
throw new ProviderCouldNotAddShareException('required request data not found', '', Http::STATUS_BAD_REQUEST);
114+
// TODO: Finish implementing shareReceived() method.
115+
}
116+
117+
/**
118+
* @inheritDoc
119+
*/
120+
public function notificationReceived($notificationType, $providerId, array $notification) {
121+
122+
// TODO: Implement notificationReceived() method.
123+
}
124+
125+
private function notifyAboutNewShare(string $shareWith, string $shareId, string $ownerFederatedId, string $sharedByFederatedId, string $name) {
126+
$notification = $this->notificationManager->createNotification();
127+
$notification->setApp(Application::APP_ID)
128+
->setUser($shareWith)
129+
->setDateTime(new \DateTime());
130+
131+
$declineAction = $notification->createAction();
132+
$declineAction->setLabel('decline')
133+
->setLink($this->urlGenerator->linkToOCSRouteAbsolute('spreed.Remote.rejectShare', ['id' => $shareId]), 'DELETE');
134+
$notification->addAction($declineAction);
135+
136+
$acceptAction = $notification->createAction();
137+
$acceptAction->setLabel('accept')
138+
->setLink($this->urlGenerator->linkToOCSRouteAbsolute('spreed.Remote.acceptShare', ['id' => $shareId]), 'POST');
139+
$notification->addAction($acceptAction);
140+
141+
$this->notificationManager->notify($notification);
142+
}
143+
144+
/**
145+
* @inheritDoc
146+
*/
147+
public function getSupportedShareTypes() {
148+
return ['user'];
149+
}
150+
}

Diff for: lib/Federation/FederationManager.php

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* @copyright Copyright (c) 2021, Gary Kim <[email protected]>
6+
*
7+
* @author Gary Kim <[email protected]>
8+
*
9+
* @license GNU AGPL version 3 or any later version
10+
*
11+
* This program is free software: you can redistribute it and/or modify
12+
* it under the terms of the GNU Affero General Public License as
13+
* published by the Free Software Foundation, either version 3 of the
14+
* License, or (at your option) any later version.
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Affero General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Affero General Public License
22+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23+
*
24+
*/
25+
26+
namespace OCA\Talk\Federation;
27+
28+
use OCA\Talk\Exceptions\RoomNotFoundException;
29+
use OCA\Talk\Exceptions\UnauthorizedException;
30+
use OCA\Talk\Manager;
31+
use OCA\Talk\Model\Attendee;
32+
use OCA\Talk\Model\AttendeeMapper;
33+
use OCA\Talk\Service\ParticipantService;
34+
use OCA\Talk\Service\RoomService;
35+
use OCP\DB\Exception as DBException;
36+
use OCP\DB\QueryBuilder\IQueryBuilder;
37+
use OCP\IConfig;
38+
use OCP\IDBConnection;
39+
use OCP\IUser;
40+
41+
class FederationManager {
42+
/** @var IDBConnection */
43+
private $db;
44+
45+
/** @var IConfig */
46+
private $config;
47+
48+
/** @var Manager */
49+
private $manager;
50+
51+
/** @var ParticipantService */
52+
private $participantService;
53+
54+
/** @var AttendeeMapper */
55+
private $attendeeMapper;
56+
57+
/** @var RoomService */
58+
private $roomService;
59+
60+
public function __construct (
61+
IDBConnection $db,
62+
IConfig $config,
63+
Manager $manager,
64+
ParticipantService $participantService,
65+
AttendeeMapper $attendeeMapper,
66+
RoomService $roomService
67+
) {
68+
$this->db = $db;
69+
$this->config = $config;
70+
$this->manager = $manager;
71+
$this->participantService = $participantService;
72+
$this->attendeeMapper = $attendeeMapper;
73+
$this->roomService = $roomService;
74+
}
75+
76+
/**
77+
* Determine if Talk federation is enabled on this instance
78+
* @return bool
79+
*/
80+
public function isEnabled(): bool {
81+
// TODO: Set to default true once implementation is complete
82+
return $this->config->getSystemValueBool('talk_federation_enabled', false);
83+
}
84+
85+
/**
86+
* @param IUser $user
87+
* @param int $roomType
88+
* @param string $roomName
89+
* @param string $roomToken
90+
* @param string $remoteUrl
91+
* @param string $sharedSecret
92+
* @return int share id for this specific remote room share
93+
*/
94+
public function addRemoteRoom(IUser $user, int $roomType, string $roomName, string $roomToken, string $remoteUrl, string $sharedSecret): int {
95+
try {
96+
$room = $this->manager->getRoomByToken($roomToken, null, $remoteUrl);
97+
} catch (RoomNotFoundException $e) {
98+
$room = $this->manager->createRemoteRoom($roomType, $roomName, $roomToken, $remoteUrl);
99+
}
100+
$participant = [
101+
[
102+
'actorType' => Attendee::ACTOR_USERS,
103+
'actorId' => $user->getUID(),
104+
'displayName' => $user->getDisplayName(),
105+
'accessToken' => $sharedSecret,
106+
]
107+
];
108+
$this->participantService->addUsers($room, $participant);
109+
return $room->getId();
110+
}
111+
112+
/**
113+
* @throws DBException
114+
* @throws UnauthorizedException
115+
*/
116+
public function acceptRemoteRoomShare(IUser $user, int $shareId) {
117+
118+
}
119+
120+
/**
121+
* @throws DBException
122+
* @throws UnauthorizedException
123+
*/
124+
public function rejectRemoteRoomShare(IUser $user, int $shareId) {
125+
// TODO: do we require a room id to be able to remove the user and reject the share?
126+
}
127+
}

0 commit comments

Comments
 (0)