Skip to content

Commit 783095b

Browse files
committed
Implement CloudFederationProvider
Signed-off-by: Gary Kim <gary@garykim.dev>
1 parent 8f3e737 commit 783095b

5 files changed

Lines changed: 389 additions & 4 deletions

File tree

appinfo/routes.php

Lines changed: 21 additions & 0 deletions
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
*/
Lines changed: 52 additions & 0 deletions
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 <gary@garykim.dev>
6+
*
7+
* @author Gary Kim <gary@garykim.dev>
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 RemoteController 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+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* @copyright Copyright (c) 2021, Gary Kim <gary@garykim.dev>
6+
*
7+
* @author Gary Kim <gary@garykim.dev>
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\UnauthorizedException;
29+
use OCA\Talk\Room;
30+
use OCP\DB\Exception as DBException;
31+
use OCP\DB\QueryBuilder\IQueryBuilder;
32+
use OCP\IConfig;
33+
use OCP\IDBConnection;
34+
use OCP\IUser;
35+
36+
class FederationManager {
37+
/** @var IDBConnection */
38+
private $db;
39+
/** @var IConfig */
40+
private $config;
41+
42+
public function __construct (
43+
IDBConnection $db,
44+
IConfig $config
45+
) {
46+
$this->db = $db;
47+
$this->config = $config;
48+
}
49+
50+
/**
51+
* Determine if Talk federation is enabled on this instance
52+
* @return bool
53+
*/
54+
public function isEnabled(): bool {
55+
// TODO: Set to true once implementation is complete
56+
return $this->config->getSystemValueBool('talk_federation_enabled', false);
57+
}
58+
59+
/**
60+
* @param IUser $user
61+
* @param string $roomToken
62+
* @param string $remoteUrl
63+
* @param string $sharedSecret
64+
* @return int share id for this specific remote room share
65+
* @throws DBException
66+
*/
67+
public function addRemoteRoom(IUser $user, string $roomToken, string $remoteUrl, string $sharedSecret): int {
68+
$qb = $this->db->getQueryBuilder();
69+
70+
$query = $qb->insert('talk_rooms_external')
71+
->values([
72+
'user_id' => $qb->createNamedParameter($user->getUID(), IQueryBuilder::PARAM_STR),
73+
'room_id' => $qb->createNamedParameter($roomToken, IQueryBuilder::PARAM_STR),
74+
'remote_url' => $qb->createNamedParameter($remoteUrl, IQueryBuilder::PARAM_STR),
75+
'shareToken' => $qb->createNamedParameter($sharedSecret, IQueryBuilder::PARAM_STR),
76+
])
77+
->executeQuery();
78+
79+
$row = $query->fetch();
80+
return (int)($row['id']);
81+
}
82+
83+
/**
84+
* @throws DBException
85+
* @throws UnauthorizedException
86+
*/
87+
public function acceptRemoteRoomShare(IUser $user, int $shareId) {
88+
$share = this->$this->getShare($shareId);
89+
if ($share['user_id'] !== $user->getUID()) {
90+
throw new UnauthorizedException();
91+
}
92+
93+
$qb = $this->db->getQueryBuilder();
94+
95+
$qb->update('talk_rooms_external')
96+
->set('accepted', true)
97+
->where(
98+
$qb->expr()->eq('id', $qb->createNamedParameter($shareId, IQueryBuilder::PARAM_INT))
99+
)
100+
->executeQuery();
101+
}
102+
103+
/**
104+
* @throws DBException
105+
* @throws UnauthorizedException
106+
*/
107+
public function rejectRemoteRoomShare(IUser $user, int $shareId) {
108+
$share = this->$this->getShare($shareId);
109+
if ($share['user_id'] !== $user->getUID()) {
110+
throw new UnauthorizedException();
111+
}
112+
113+
$qb = $this->db->getQueryBuilder();
114+
115+
$qb->delete('talk_rooms_external')
116+
->where(
117+
$qb->expr()->eq('id', $qb->createNamedParameter($shareId, IQueryBuilder::PARAM_INT))
118+
)
119+
->executeQuery();
120+
}
121+
122+
/**
123+
* @throws DBException
124+
*/
125+
public function getShare(int $shareId): array {
126+
$qb = $this->db->getQueryBuilder();
127+
128+
$query = $qb->select('*')
129+
->from('talk_rooms_external')
130+
->where(
131+
$qb->expr()->eq('id', $qb->createNamedParameter($shareId, IQueryBuilder::PARAM_INT))
132+
)
133+
->executeQuery();
134+
135+
return $query->fetch();
136+
}
137+
}

lib/Migration/Version12000Date20210610232111.php

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
namespace OCA\Talk\Migration;
2727

2828
use Closure;
29+
use Doctrine\DBAL\Schema\SchemaException;
2930
use Doctrine\DBAL\Types\Types;
3031
use OCP\DB\ISchemaWrapper;
3132
use OCP\Migration\IOutput;
@@ -38,13 +39,14 @@ class Version12000Date20210610232111 extends SimpleMigrationStep {
3839
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
3940
* @param array $options
4041
* @return null|ISchemaWrapper
42+
* @throws SchemaException
4143
*/
42-
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
44+
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
4345
/** @var ISchemaWrapper $schema */
4446
$schema = $schemaClosure();
4547

46-
if (!$schema->hasTable('talk_federated_rooms')) {
47-
$table = $schema->createTable('talk_federated_rooms');
48+
if (!$schema->hasTable('talk_federated_servers')) {
49+
$table = $schema->createTable('talk_federated_servers');
4850
$table->addColumn('id', Types::BIGINT, [
4951
'autoincrement' => true,
5052
'notnull' => true,
@@ -59,7 +61,38 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
5961
$table->addColumn('password', Types::TEXT, [
6062
'notnull' => true,
6163
]);
62-
$table->setPrimaryKey('id');
64+
$table->addColumn('accepted', Types::BOOLEAN, [
65+
'notnull' => true,
66+
'default' => false,
67+
])
68+
$table->setPrimaryKey(['id']);
69+
}
70+
71+
if (!$schema->hasTable('talk_rooms_external')) {
72+
$table = $schema->createTable('talk_rooms_external');
73+
$table->addColumn('id', Types::BIGINT, [
74+
'autoincrement' => true,
75+
'notnull' => true,
76+
]);
77+
$table->addColumn('room_id', Types::BIGINT, [
78+
'notnull' => true,
79+
'unsigned' => true,
80+
]);
81+
$table->addColumn('remote_url', Types::TEXT, [
82+
'notnull' => true,
83+
]);
84+
$table->addColumn('accepted', Types::BOOLEAN, [
85+
'notnull' => true,
86+
'default' => false,
87+
]);
88+
$table->addColumn('shareToken', Types::STRING, [
89+
'notnull' => true,
90+
]);
91+
$table->addColumn('userId', Types::STRING, [
92+
'notnull' => false,
93+
'length' => 255,
94+
]);
95+
$table->setPrimaryKey(['id']);
6396
}
6497

6598
return $schema;

0 commit comments

Comments
 (0)