Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/lookup-server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2022-09-05 16:03:36 +0300
committerMaxence Lange <maxence@artificial-owl.com>2022-09-05 16:03:50 +0300
commit8a63ca346de6edf53b2409b73ae8dad5f10632f2 (patch)
tree4c97ba91526c36892fc7593b688518ac9b010706 /server
parent1cfe97fe50d3279620b98eb8e3b27bebeb7d2dac (diff)
switch to php 7.4
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
Diffstat (limited to 'server')
-rw-r--r--server/composer.lock16
-rwxr-xr-xserver/config/version.php3
-rw-r--r--server/index.php155
-rw-r--r--server/init.php58
-rw-r--r--server/lib/BruteForceMiddleware.php3
-rw-r--r--server/lib/Replication.php145
-rw-r--r--server/lib/Service/DependenciesService.php55
-rw-r--r--server/lib/SignatureHandler.php40
-rw-r--r--server/lib/Status.php15
-rw-r--r--server/lib/Tools/Exceptions/ArrayNotFoundException.php43
-rw-r--r--server/lib/Tools/Exceptions/ItemNotFoundException.php43
-rw-r--r--server/lib/Tools/Exceptions/MalformedArrayException.php43
-rw-r--r--server/lib/Tools/Exceptions/UnknownTypeException.php42
-rw-r--r--server/lib/Tools/Traits/TArrayTools.php20
-rw-r--r--server/lib/Tools/Traits/TDebug.php (renamed from server/lib/TDebug.php)2
-rw-r--r--server/lib/UserManager.php225
-rw-r--r--server/lib/Validator/Email.php101
-rw-r--r--server/lib/Validator/Twitter.php59
-rw-r--r--server/lib/Validator/Website.php20
-rwxr-xr-xserver/replicationcron.php17
-rw-r--r--server/verifycron.php19
21 files changed, 794 insertions, 330 deletions
diff --git a/server/composer.lock b/server/composer.lock
index cbec160..c4d8992 100644
--- a/server/composer.lock
+++ b/server/composer.lock
@@ -69,16 +69,16 @@
},
{
"name": "composer/ca-bundle",
- "version": "1.3.2",
+ "version": "1.3.3",
"source": {
"type": "git",
"url": "https://github.com/composer/ca-bundle.git",
- "reference": "fd5dd441932a7e10ca6e5b490e272d34c8430640"
+ "reference": "30897edbfb15e784fe55587b4f73ceefd3c4d98c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/ca-bundle/zipball/fd5dd441932a7e10ca6e5b490e272d34c8430640",
- "reference": "fd5dd441932a7e10ca6e5b490e272d34c8430640",
+ "url": "https://api.github.com/repos/composer/ca-bundle/zipball/30897edbfb15e784fe55587b4f73ceefd3c4d98c",
+ "reference": "30897edbfb15e784fe55587b4f73ceefd3c4d98c",
"shasum": ""
},
"require": {
@@ -125,7 +125,7 @@
"support": {
"irc": "irc://irc.freenode.org/composer",
"issues": "https://github.com/composer/ca-bundle/issues",
- "source": "https://github.com/composer/ca-bundle/tree/1.3.2"
+ "source": "https://github.com/composer/ca-bundle/tree/1.3.3"
},
"funding": [
{
@@ -141,7 +141,7 @@
"type": "tidelift"
}
],
- "time": "2022-05-24T11:56:16+00:00"
+ "time": "2022-07-20T07:14:26+00:00"
},
{
"name": "guzzlehttp/guzzle",
@@ -1281,7 +1281,7 @@
},
{
"name": "symfony/deprecation-contracts",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
@@ -1328,7 +1328,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2"
},
"funding": [
{
diff --git a/server/config/version.php b/server/config/version.php
deleted file mode 100755
index 97aba47..0000000
--- a/server/config/version.php
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
-
-$VERSION = '0.3.1';
diff --git a/server/index.php b/server/index.php
index 816df3d..52c3284 100644
--- a/server/index.php
+++ b/server/index.php
@@ -1,78 +1,127 @@
<?php
-use DI\Container;
-use LookupServer\Service\DependenciesService;
-use LookupServer\UserManager;
+declare(strict_types=1);
+
+
+/**
+ * lookup-server - Standalone Lookup Server.
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2022
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace LookupServer;
+
+
+use LookupServer\Validator\Email;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
-use Slim\Factory\AppFactory;
-require __DIR__ . '/vendor/autoload.php';
+require __DIR__ . '/init.php';
-$container = new Container();
-AppFactory::setContainer($container);
-$app = AppFactory::create();
+if (!isset($app) || !isset($container)) {
+ return;
+}
-$settings = require __DIR__ . '/src/config.php';
-$container->set('Settings', function ($c) use ($settings) {
- return $settings;
-});
+$r_search = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
+ /** @var UserManager $userManager */
+ $userManager = $this->get('UserManager');
+ return $userManager->search($request, $response, $args);
+};
+$app->get('/users', $r_search);
+$app->get('/index.php/users', $r_search);
-$container->set('DependenciesService', function ($c) {
- return new DependenciesService($c->get('Settings'));
-});
+$r_register = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
+ /** @var UserManager $userManager */
+ $userManager = $this->get('UserManager');
+ return $userManager->register($request, $response, $args);
+};
+$app->post('/users', $r_register);
+$app->post('/index.php/users', $r_register);
-$container->get('DependenciesService')->initContainer($container);
-//require __DIR__ . '/src/dependencies.php';
+$r_delete = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
+ /** @var UserManager $userManager */
+ $userManager = $this->get('UserManager');
-//
-//
+ return $userManager->delete($request, $response, $args);
+};
+$app->delete('/users', $r_delete);
+$app->delete('/index.php/users', $r_delete);
-//$container->set('BruteForceMiddleware', function (Container $c) {
-// return new \LookupServer\BruteForceMiddleware($c->get('db'));
-//});
+$r_batchRegister = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
+ /** @var UserManager $userManager */
+ $userManager = $this->get('UserManager');
-//$app->add(function (
-// \Psr\Http\Message\ServerRequestInterface $request,
-// \Psr\Http\Server\RequestHandlerInterface $handler,
-// $next
-//) {
-// return $next($request, $handler);
-//});
+ return $userManager->batchRegister($request, $response, $args);
+};
+$app->post('/gs/users', $r_batchRegister);
+$app->post('/index.php/gs/users', $r_batchRegister);
-$app->setBasePath('/index.php');
-$app->get(
- '/users',
- function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
- /** @var UserManager $userManager */
- $userManager = $this->get('UserManager');
+$r_batchDelete = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
+ /** @var UserManager $userManager */
+ $userManager = $this->get('UserManager');
- return $userManager->search($request, $response, $args);
- }
-);
+ return $userManager->batchDelete($request, $response, $args);
+};
+$app->delete('/gs/users', $r_batchDelete);
+$app->delete('/index.php/gs/users', $r_batchDelete);
-$app->post(
- '/users',
- function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
- /** @var UserManager $userManager */
- $userManager = $this->get('UserManager');
- return $userManager->register($request, $response, $args);
- }
-);
+$r_validateEmail = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
+ /** @var Email $emailValidator */
+ $emailValidator = $this->get('EmailValidator');
+ return $emailValidator->validate($request, $response, $args);
+};
+$app->get('/validate/email/{token}', $r_validateEmail);
+$app->get('/index.php/validate/email/{token}', $r_validateEmail);
+
+
+$r_status = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
+ $response->getBody()->write(
+ json_encode(
+ ['version' => VERSION]
+ )
+ );
+
+ return $response;
+};
+$app->get('/status', $r_status);
+$app->get('/index.php/status', $r_status);
+
+
+$r_export = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
+ /** @var Replication $replication */
+ $replication = $this->get('Replication');
+
+ return $replication->export($request, $response, $args);
+};
+$app->get('/replication', $r_export);
+$app->get('/index.php/replication', $r_export);
-//$app->post('/gs/users', 'UserManager:batchRegister');
-//$app->delete('/gs/users', 'UserManager:batchDelete');
-//$app->delete('/users', 'UserManager:delete');
-//$app->get('/validate/email/{token}', 'EmailValidator:validate')->setName('validateEmail');
-//$app->get('/status', 'Status:status');
-//
-//$app->get('/replication', 'Replication:export');
$app->run();
diff --git a/server/init.php b/server/init.php
new file mode 100644
index 0000000..454513a
--- /dev/null
+++ b/server/init.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+
+/**
+ * lookup-server - Standalone Lookup Server.
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2022
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace LookupServer;
+
+
+use DI\Container;
+use LookupServer\Service\DependenciesService;
+use Slim\Factory\AppFactory;
+
+
+define('VERSION', '1.0.0');
+
+
+require __DIR__ . '/vendor/autoload.php';
+
+$container = new Container();
+AppFactory::setContainer($container);
+$app = AppFactory::create();
+$app->setBasePath('');
+
+$settings = require __DIR__ . '/src/config.php';
+$container->set('Settings', function (Container $c) use ($settings) {
+ return $settings;
+});
+
+$container->set('DependenciesService', function (Container $c) {
+ return new DependenciesService($c->get('Settings'));
+});
+$container->get('DependenciesService')->initContainer($container, $app);
+
diff --git a/server/lib/BruteForceMiddleware.php b/server/lib/BruteForceMiddleware.php
index af1080b..4a9c4d7 100644
--- a/server/lib/BruteForceMiddleware.php
+++ b/server/lib/BruteForceMiddleware.php
@@ -2,6 +2,9 @@
namespace LookupServer;
+/**
+ * @deprecated
+ */
class BruteForceMiddleware {
/**
* Brute force middleware
diff --git a/server/lib/Replication.php b/server/lib/Replication.php
index 931ee87..04a8e45 100644
--- a/server/lib/Replication.php
+++ b/server/lib/Replication.php
@@ -1,73 +1,112 @@
<?php
+declare(strict_types=1);
+
+/**
+ * lookup-server - Standalone Lookup Server.
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bjoern Schiessle <bjoern@schiessle.org>
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ *
+ * @copyright 2017
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
namespace LookupServer;
use GuzzleHttp\Client;
-use Slim\Http\Request;
-use Slim\Http\Response;
+use PDO;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\ServerRequestInterface as Request;
class Replication {
- /** @var \PDO */
- private $db;
-
- /** @var string */
- private $auth;
-
- /** @var string[] */
- private $replicationHosts;
+ private PDO $db;
+ private string $auth;
+ private array $replicationHosts;
- public function __construct(\PDO $db, $auth, $replicationHosts) {
+ public function __construct(PDO $db, string $auth, array $replicationHosts) {
$this->db = $db;
$this->auth = $auth;
$this->replicationHosts = $replicationHosts;
}
- public function export(Request $request, Response $response) {
+
+ /**
+ * @param ServerRequestInterface $request
+ * @param ResponseInterface $response
+ * @param array $args
+ *
+ * @return ResponseInterface
+ */
+ public function export(Request $request, Response $response, array $args = []): Response {
$userInfo = $request->getUri()->getUserInfo();
$userInfo = explode(':', $userInfo, 2);
- if (count($userInfo) !== 2 || $userInfo[0] !== 'lookup' || $userInfo[1] !== $this->auth) {
+ if (count($userInfo) !== 2 || $userInfo[0] !== 'lookup' || $userInfo[1] !== $this->auth) {
return $response->withStatus(401);
}
$params = $request->getQueryParams();
- if (!isset($params['timestamp'], $params['page']) || !ctype_digit($params['timestamp']) ||
- !ctype_digit($params['page'])) {
+ if (!isset($params['timestamp'], $params['page']) || !ctype_digit($params['timestamp'])
+ || !ctype_digit($params['page'])) {
return $response->withStatus(400);
}
$timestamp = (int)$params['timestamp'];
$page = (int)$params['page'];
- $stmt = $this->db->prepare('SELECT id, federationId, UNIX_TIMESTAMP(timestamp) AS timestamp
+ $stmt = $this->db->prepare(
+ 'SELECT id, federationId, UNIX_TIMESTAMP(timestamp) AS timestamp
FROM users
WHERE UNIX_TIMESTAMP(timestamp) >= :timestamp
ORDER BY timestamp, id
LIMIT :limit
- OFFSET :offset');
+ OFFSET :offset'
+ );
$stmt->bindParam('timestamp', $timestamp);
- $stmt->bindValue('limit', 100, \PDO::PARAM_INT);
- $stmt->bindValue('offset', 100 * $page, \PDO::PARAM_INT);
+ $stmt->bindValue('limit', 100, PDO::PARAM_INT);
+ $stmt->bindValue('offset', 100 * $page, PDO::PARAM_INT);
$stmt->execute();
$result = [];
- while($data = $stmt->fetch()) {
+ while ($data = $stmt->fetch()) {
$user = [
'cloudId' => $data['federationId'],
'timestamp' => (int)$data['timestamp'],
'data' => [],
];
- $stmt2 = $this->db->prepare('SELECT *
+ $stmt2 = $this->db->prepare(
+ 'SELECT *
FROM store
- WHERE userId = :uid');
+ WHERE userId = :uid'
+ );
$stmt2->bindValue('uid', $data['id']);
$stmt2->execute();
- while($userData = $stmt2->fetch()) {
+ while ($userData = $stmt2->fetch()) {
$user['data'][] = [
'key' => $userData['k'],
'value' => $userData['v'],
@@ -80,14 +119,17 @@ class Replication {
}
$response->getBody()->write(json_encode($result));
+
return $response;
}
- public function import(Request $request, Response $response) {
+
+ public function import(): void {
$replicationStatus = [];
if (file_exists(__DIR__ . '/../config/replication.json')) {
- $replicationStatus = json_decode(file_get_contents(__DIR__ . '/../config/replication.json'), true);
+ $replicationStatus =
+ json_decode(file_get_contents(__DIR__ . '/../config/replication.json'), true);
}
foreach ($this->replicationHosts as $replicationHost) {
@@ -98,16 +140,18 @@ class Replication {
}
$page = 0;
- while(true) {
+ while (true) {
// Retrieve public key && store
- $req = new \GuzzleHttp\Psr7\Request('GET', $replicationHost . '?timestamp=' . $timestamp . '&page=' . $page);
+ $req = new \GuzzleHttp\Psr7\Request(
+ 'GET', $replicationHost . '?timestamp=' . $timestamp . '&page=' . $page
+ );
$client = new Client();
$resp = $client->send($req, [
'timeout' => 5,
]);
- $data = json_decode($resp->getBody(), true);
+ $data = json_decode($resp->getBody()->getContents(), true);
if (count($data) === 0) {
break;
}
@@ -120,16 +164,22 @@ class Replication {
$page++;
}
- file_put_contents(__DIR__. '/../config/replication.json', json_encode($replicationStatus, JSON_PRETTY_PRINT));
+ file_put_contents(
+ __DIR__ . '/../config/replication.json', json_encode($replicationStatus, JSON_PRETTY_PRINT)
+ );
}
-
- return $response;
}
- private function parseUser($user) {
- $stmt = $this->db->prepare('SELECT id, UNIX_TIMESTAMP(timestamp) AS timestamp
+
+ /**
+ * @param array $user
+ */
+ private function parseUser(array $user): void {
+ $stmt = $this->db->prepare(
+ 'SELECT id, UNIX_TIMESTAMP(timestamp) AS timestamp
FROM users
- WHERE federationId = :id');
+ WHERE federationId = :id'
+ );
$stmt->bindParam('id', $user['cloudId']);
$stmt->execute();
@@ -139,11 +189,14 @@ class Replication {
$data = $stmt->fetch();
if ($data['timestamp'] > $user['timestamp']) {
$stmt->closeCursor();
+
return;
}
- $stmt2 = $this->db->prepare('DELETE FROM users
- WHERE federationId = :id');
+ $stmt2 = $this->db->prepare(
+ 'DELETE FROM users
+ WHERE federationId = :id'
+ );
$stmt2->bindParam('id', $user['cloudId']);
$stmt2->execute();
$stmt2->closeCursor();
@@ -151,19 +204,23 @@ class Replication {
$stmt->closeCursor();
- $stmt = $this->db->prepare('INSERT INTO users (federationId, timestamp) VALUES (:federationId, FROM_UNIXTIME(:timestamp))');
- $stmt->bindParam(':federationId', $user['cloudId'], \PDO::PARAM_STR);
- $stmt->bindParam(':timestamp', $user['timestamp'], \PDO::PARAM_INT);
+ $stmt = $this->db->prepare(
+ 'INSERT INTO users (federationId, timestamp) VALUES (:federationId, FROM_UNIXTIME(:timestamp))'
+ );
+ $stmt->bindParam(':federationId', $user['cloudId'], PDO::PARAM_STR);
+ $stmt->bindParam(':timestamp', $user['timestamp'], PDO::PARAM_INT);
$stmt->execute();
$id = $this->db->lastInsertId();
$stmt->closeCursor();
foreach ($user['data'] as $data) {
- $stmt = $this->db->prepare('INSERT INTO store (userId, k, v, valid) VALUES (:userId, :k, :v, :valid)');
- $stmt->bindParam(':userId', $id, \PDO::PARAM_INT);
- $stmt->bindParam(':k', $data['key'], \PDO::PARAM_STR);
- $stmt->bindParam(':v', $data['value'], \PDO::PARAM_STR);
- $stmt->bindParam(':valid', $data['validated'], \PDO::PARAM_INT);
+ $stmt = $this->db->prepare(
+ 'INSERT INTO store (userId, k, v, valid) VALUES (:userId, :k, :v, :valid)'
+ );
+ $stmt->bindParam(':userId', $id, PDO::PARAM_INT);
+ $stmt->bindParam(':k', $data['key'], PDO::PARAM_STR);
+ $stmt->bindParam(':v', $data['value'], PDO::PARAM_STR);
+ $stmt->bindParam(':valid', $data['validated'], PDO::PARAM_INT);
$stmt->execute();
$stmt->closeCursor();
diff --git a/server/lib/Service/DependenciesService.php b/server/lib/Service/DependenciesService.php
index 7f53b08..a6e9990 100644
--- a/server/lib/Service/DependenciesService.php
+++ b/server/lib/Service/DependenciesService.php
@@ -1,5 +1,33 @@
<?php
+declare(strict_types=1);
+
+
+/**
+ * lookup-server - Standalone Lookup Server.
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2022
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
namespace LookupServer\Service;
@@ -8,25 +36,29 @@ use DI\Container;
use Exception;
use LookupServer\Replication;
use LookupServer\SignatureHandler;
-use LookupServer\Status;
use LookupServer\Tools\Traits\TArrayTools;
use LookupServer\UserManager;
use LookupServer\Validator\Email;
use LookupServer\Validator\Twitter;
use LookupServer\Validator\Website;
use PDO;
+use Slim\App;
class DependenciesService {
use TArrayTools;
private array $settings;
- public function __construct(array $settings) {
+ public function __construct(array $settings = []) {
$this->settings = $settings;
}
- public function initContainer(Container $container): void {
+ /**
+ * @param Container $container
+ * @param App $app
+ */
+ public function initContainer(Container $container, App $app): void {
$container->set('db', function (Container $c) {
$db = $this->getArray('settings.db', $c->get('Settings'));
@@ -62,7 +94,7 @@ class DependenciesService {
return new SignatureHandler();
});
- $container->set('TwitterOAuth', function ($c) {
+ $container->set('TwitterOAuth', function (Container $c) {
/** @var array $settings */
$settings = $c->get('Settings');
@@ -75,24 +107,24 @@ class DependenciesService {
});
- $container->set('EmailValidator', function ($c) {
+ $container->set('EmailValidator', function (Container $c) use ($app) {
$settings = $c->get('Settings');
return new Email(
$c->get('db'),
-// $c->get('RouterInterface'),
+ $app->getRouteCollector()->getRouteParser(),
$this->get('settings.host', $settings),
$this->get('settings.emailfrom', $settings),
$this->getBool('settings.global_scale', $settings)
);
});
- $container->set('WebsiteValidator', function ($c) {
+ $container->set('WebsiteValidator', function (Container $c) {
return new Website($c->get('SignatureHandler'));
});
- $container->set('TwitterValidator', function ($c) {
+ $container->set('TwitterValidator', function (Container $c) {
return new Twitter(
$c->get('TwitterOAuth'),
$c->get('SignatureHandler'),
@@ -101,12 +133,7 @@ class DependenciesService {
});
- $container->set('Status', function ($c) {
- return new Status();
- });
-
-
- $container->set('Replication', function ($c) {
+ $container->set('Replication', function (Container $c) {
$settings = $c->get('Settings');
return new Replication(
diff --git a/server/lib/SignatureHandler.php b/server/lib/SignatureHandler.php
index bf308d4..7d42bb3 100644
--- a/server/lib/SignatureHandler.php
+++ b/server/lib/SignatureHandler.php
@@ -1,7 +1,13 @@
<?php
+
+declare(strict_types=1);
+
+
/**
* @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org>
*
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ *
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
@@ -22,7 +28,10 @@
namespace LookupServer;
+use BadMethodCallException;
+use Exception;
use GuzzleHttp\Client;
+use GuzzleHttp\Exception\GuzzleException;
class SignatureHandler {
@@ -32,57 +41,60 @@ class SignatureHandler {
* @param string $cloudId
* @param string $message
* @param string $signature
+ *
* @return bool
- * @throws \Exception
+ * @throws GuzzleException
*/
- public function verify($cloudId, $message, $signature) {
+ public function verify(string $cloudId, string $message, string $signature): bool {
// Get fed id
list($user, $host) = $this->splitCloudId($cloudId);
// Retrieve public key && store
$ocsreq = new \GuzzleHttp\Psr7\Request(
'GET',
- 'http://'.$host . '/ocs/v2.php/identityproof/key/' . $user,
+ 'http://' . $host . '/ocs/v2.php/identityproof/key/' . $user,
[
'OCS-APIREQUEST' => 'true',
'Accept' => 'application/json',
- ]);
+ ]
+ );
$client = new Client();
$ocsresponse = $client->send($ocsreq, ['timeout' => 10]);
- $ocsresponse = json_decode($ocsresponse->getBody(), true);
+ $ocsresponse = json_decode($ocsresponse->getBody()->getContents(), true);
- if ($ocsresponse === null || !isset($ocsresponse['ocs']) ||
- !isset($ocsresponse['ocs']['data']) || !isset($ocsresponse['ocs']['data']['public'])) {
- throw new \BadMethodCallException();
+ if ($ocsresponse === null || !isset($ocsresponse['ocs'])
+ || !isset($ocsresponse['ocs']['data'])
+ || !isset($ocsresponse['ocs']['data']['public'])) {
+ throw new BadMethodCallException();
}
$key = $ocsresponse['ocs']['data']['public'];
// verify message
$message = json_encode($message);
- $signature= base64_decode($signature);
+ $signature = base64_decode($signature);
$res = openssl_verify($message, $signature, $key, OPENSSL_ALGO_SHA512);
return $res === 1;
-
}
/**
* Split a cloud id in a user and host post
*
- * @param $cloudId
+ * @param string $cloudId
+ *
* @return string[]
*/
- private function splitCloudId($cloudId) {
+ private function splitCloudId(string $cloudId): array {
$loc = strrpos($cloudId, '@');
$user = substr($cloudId, 0, $loc);
- $host = substr($cloudId, $loc+1);
+ $host = substr($cloudId, $loc + 1);
+
return [$user, $host];
}
-
}
diff --git a/server/lib/Status.php b/server/lib/Status.php
deleted file mode 100644
index 69c87de..0000000
--- a/server/lib/Status.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-namespace LookupServer;
-
-use \Psr\Http\Message\ServerRequestInterface as Request;
-use \Psr\Http\Message\ResponseInterface as Response;
-
-class Status {
-
- public function status(Request $request, Response $response) {
- require __DIR__ . '/../config/version.php';
-
- $response->getBody()->write(json_encode(array('version'=>$VERSION)));
- }
-}
diff --git a/server/lib/Tools/Exceptions/ArrayNotFoundException.php b/server/lib/Tools/Exceptions/ArrayNotFoundException.php
new file mode 100644
index 0000000..196a869
--- /dev/null
+++ b/server/lib/Tools/Exceptions/ArrayNotFoundException.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+
+
+/**
+ * lookup-server - Standalone Lookup Server.
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2022
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace LookupServer\Tools\Exceptions;
+
+use Exception;
+
+/**
+ * Class ArrayNotFoundException
+ *
+ * @package LookupServer\Tools\Exceptions
+ */
+class ArrayNotFoundException extends Exception {
+}
diff --git a/server/lib/Tools/Exceptions/ItemNotFoundException.php b/server/lib/Tools/Exceptions/ItemNotFoundException.php
new file mode 100644
index 0000000..833507e
--- /dev/null
+++ b/server/lib/Tools/Exceptions/ItemNotFoundException.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+
+
+/**
+ * lookup-server - Standalone Lookup Server.
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2022
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace LookupServer\Tools\Exceptions;
+
+use Exception;
+
+/**
+ * Class ItemNotFoundException
+ *
+ * @package LookupServer\Tools\Exceptions
+ */
+class ItemNotFoundException extends Exception {
+}
diff --git a/server/lib/Tools/Exceptions/MalformedArrayException.php b/server/lib/Tools/Exceptions/MalformedArrayException.php
new file mode 100644
index 0000000..713b2d7
--- /dev/null
+++ b/server/lib/Tools/Exceptions/MalformedArrayException.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+
+
+/**
+ * lookup-server - Standalone Lookup Server.
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2022
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace LookupServer\Tools\Exceptions;
+
+use Exception;
+
+/**
+ * Class MalformedArrayException
+ *
+ * @package LookupServer\Tools\Exceptions
+ */
+class MalformedArrayException extends Exception {
+}
diff --git a/server/lib/Tools/Exceptions/UnknownTypeException.php b/server/lib/Tools/Exceptions/UnknownTypeException.php
new file mode 100644
index 0000000..2e8aa62
--- /dev/null
+++ b/server/lib/Tools/Exceptions/UnknownTypeException.php
@@ -0,0 +1,42 @@
+<?php
+
+declare(strict_types=1);
+
+
+/**
+ * lookup-server - Standalone Lookup Server.
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2022
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace LookupServer\Tools\Exceptions;
+
+use Exception;
+
+/**
+ * Class UnknownTypeException
+ *
+ * @package LookupServer\Tools\Exceptions
+ */
+class UnknownTypeException extends Exception {
+}
diff --git a/server/lib/Tools/Traits/TArrayTools.php b/server/lib/Tools/Traits/TArrayTools.php
index 8d60a26..f41a925 100644
--- a/server/lib/Tools/Traits/TArrayTools.php
+++ b/server/lib/Tools/Traits/TArrayTools.php
@@ -33,18 +33,18 @@ namespace LookupServer\Tools\Traits;
use Exception;
use JsonSerializable;
-use OCA\Circles\Tools\Exceptions\ArrayNotFoundException;
-use OCA\Circles\Tools\Exceptions\ItemNotFoundException;
-use OCA\Circles\Tools\Exceptions\MalformedArrayException;
-use OCA\Circles\Tools\Exceptions\UnknownTypeException;
+use LookupServer\Tools\Exceptions\ArrayNotFoundException;
+use LookupServer\Tools\Exceptions\ItemNotFoundException;
+use LookupServer\Tools\Exceptions\MalformedArrayException;
+use LookupServer\Tools\Exceptions\UnknownTypeException;
trait TArrayTools {
- public static $TYPE_NULL = 'Null';
- public static $TYPE_STRING = 'String';
- public static $TYPE_ARRAY = 'Array';
- public static $TYPE_BOOLEAN = 'Boolean';
- public static $TYPE_INTEGER = 'Integer';
- public static $TYPE_SERIALIZABLE = 'Serializable';
+ public static string $TYPE_NULL = 'Null';
+ public static string $TYPE_STRING = 'String';
+ public static string $TYPE_ARRAY = 'Array';
+ public static string $TYPE_BOOLEAN = 'Boolean';
+ public static string $TYPE_INTEGER = 'Integer';
+ public static string $TYPE_SERIALIZABLE = 'Serializable';
/**
diff --git a/server/lib/TDebug.php b/server/lib/Tools/Traits/TDebug.php
index 789e5f8..73c9d12 100644
--- a/server/lib/TDebug.php
+++ b/server/lib/Tools/Traits/TDebug.php
@@ -1,6 +1,6 @@
<?php
-namespace LookupServer;
+namespace LookupServer\Tools\Traits;
trait TDebug {
diff --git a/server/lib/UserManager.php b/server/lib/UserManager.php
index 9a36d8f..d08212f 100644
--- a/server/lib/UserManager.php
+++ b/server/lib/UserManager.php
@@ -2,44 +2,34 @@
namespace LookupServer;
+use Exception;
+use GuzzleHttp\Exception\GuzzleException;
+use LookupServer\Tools\Traits\TArrayTools;
+use LookupServer\Tools\Traits\TDebug;
use LookupServer\Validator\Email;
use LookupServer\Validator\Twitter;
use LookupServer\Validator\Website;
+use PDO;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class UserManager {
use TDebug;
+ use TArrayTools;
-
- /** @var \PDO */
- private $db;
-
- /** @var Email */
- private $emailValidator;
-
- /** @var Website */
- private $websiteValidator;
-
- /** @var Twitter */
- private $twitterValidator;
-
- /** @var SignatureHandler */
- private $signatureHandler;
-
- /** @var int try max. 10 times to verify a account */
- private $maxVerifyTries = 10;
-
- /** @var bool */
- private $globalScaleMode;
-
- /** @var string */
- private $authKey;
+ private PDO $db;
+ private Email $emailValidator;
+ private Website $websiteValidator;
+ private Twitter $twitterValidator;
+ private SignatureHandler $signatureHandler;
+ private int $maxVerifyTries = 10;
+ private bool $globalScaleMode;
+ private string $authKey;
/**
* UserManager constructor.
*
- * @param \PDO $db
+ * @param PDO $db
* @param Email $emailValidator
* @param Website $websiteValidator
* @param Twitter $twitterValidator
@@ -48,13 +38,13 @@ class UserManager {
* @param string $authKey
*/
public function __construct(
- \PDO $db,
+ PDO $db,
Email $emailValidator,
Website $websiteValidator,
Twitter $twitterValidator,
SignatureHandler $signatureHandler,
- $globalScaleMode,
- $authKey
+ bool $globalScaleMode,
+ string $authKey
) {
$this->db = $db;
$this->emailValidator = $emailValidator;
@@ -65,33 +55,45 @@ class UserManager {
$this->authKey = $authKey;
}
+
+ /**
+ * @param string $input
+ *
+ * @return string
+ */
private function escapeWildcard(string $input): string {
//Escape %
$output = str_replace('%', '\%', $input);
- $output = str_replace('_', '\_', $output);
- return $output;
+ return str_replace('_', '\_', $output);
}
+ /**
+ * @param Request $request
+ * @param Response $response
+ * @param array $args
+ *
+ * @return Response
+ */
public function search(Request $request, Response $response, array $args = []): Response {
$params = $request->getQueryParams();
- if (!isset($params['search']) || $params['search'] === '') {
+ if ($this->get('search', $params) === '') {
return $response->withStatus(404);
}
- $search = $params['search'];
+ $search = (string)$params['search'];
// search for a specific federated cloud ID
- $searchCloudId = isset($params['exactCloudId']) ? $params['exactCloudId'] === '1' : '0';
+ $searchCloudId = $this->getBool('exactCloudId', $params);
// return unique exact match, e.g. the user with a specific email address
- $exactMatch = isset($params['exact']) ? $params['exact'] === '1' : false;
+ $exactMatch = $this->getBool('exact', $params);
// parameters allow you to specify which keys should be checked for a search query
// by default we check all keys, this way you can for example search for email addresses only
$parameters = [];
if ($exactMatch === true) {
- $keys = isset($params['keys']) ? $params['keys'] : '{}';
+ $keys = $this->get('keys', $params, '{}');
$keysDecoded = json_decode($keys, false, 2);
if (is_array($keysDecoded)) {
$parameters = $keysDecoded;
@@ -132,7 +134,12 @@ class UserManager {
*
* @return array
*/
- private function performSearch($search, $exactMatch, $parameters, $minKarma) {
+ private function performSearch(
+ string $search,
+ bool $exactMatch,
+ array $parameters,
+ int $minKarma
+ ): array {
$operator = $exactMatch ? ' = ' : ' LIKE ';
$limit = $exactMatch ? 1 : 50;
@@ -166,16 +173,17 @@ ORDER BY karma
LIMIT :limit'
);
- $stmt->bindParam(':karma', $minKarma, \PDO::PARAM_INT);
- $stmt->bindParam(':limit', $limit, \PDO::PARAM_INT);
+ $stmt->bindParam(':karma', $minKarma, PDO::PARAM_INT);
+ $stmt->bindParam(':limit', $limit, PDO::PARAM_INT);
$search = $exactMatch ? $search : '%' . $this->escapeWildcard($search) . '%';
- $stmt->bindParam('search', $search, \PDO::PARAM_STR);
+ $stmt->bindParam('search', $search, PDO::PARAM_STR);
// bind parameters
foreach ($parameters as $parameter) {
$i = 0;
- $stmt->bindParam(':key' . $i, $this->db->quote($parameter));
+ $q = $this->db->quote($parameter);
+ $stmt->bindParam(':key' . $i, $q);
}
$stmt->execute();
@@ -194,7 +202,7 @@ LIMIT :limit'
}
- private function getExactCloudId($cloudId) {
+ private function getExactCloudId(string $cloudId): array {
$stmt = $this->db->prepare('SELECT id FROM users WHERE federationId = :id');
$stmt->bindParam(':id', $cloudId);
$stmt->execute();
@@ -205,12 +213,17 @@ LIMIT :limit'
}
return $this->getForUserId((int)$data['id']);
-
}
- private function getForUserId($userId) {
+
+ /**
+ * @param int $userId
+ *
+ * @return array
+ */
+ private function getForUserId(int $userId): array {
$stmt = $this->db->prepare('SELECT * FROM users WHERE id = :id');
- $stmt->bindParam(':id', $userId, \PDO::PARAM_INT);
+ $stmt->bindParam(':id', $userId, PDO::PARAM_INT);
$stmt->execute();
$data = $stmt->fetch();
$stmt->closeCursor();
@@ -224,7 +237,7 @@ LIMIT :limit'
];
$stmt = $this->db->prepare('SELECT * FROM store WHERE userId = :id');
- $stmt->bindParam(':id', $userId, \PDO::PARAM_INT);
+ $stmt->bindParam(':id', $userId, PDO::PARAM_INT);
$stmt->execute();
while ($data = $stmt->fetch()) {
@@ -244,12 +257,12 @@ LIMIT :limit'
* @param string[] $data
* @param int $timestamp
*/
- private function insert($cloudId, $data, $timestamp) {
+ private function insert(string $cloudId, array $data, int $timestamp): void {
$stmt = $this->db->prepare(
'INSERT INTO users (federationId, timestamp) VALUES (:federationId, FROM_UNIXTIME(:timestamp))'
);
- $stmt->bindParam(':federationId', $cloudId, \PDO::PARAM_STR);
- $stmt->bindParam(':timestamp', $timestamp, \PDO::PARAM_INT);
+ $stmt->bindParam(':federationId', $cloudId, PDO::PARAM_STR);
+ $stmt->bindParam(':timestamp', $timestamp, PDO::PARAM_INT);
$stmt->execute();
$id = $this->db->lastInsertId();
$stmt->closeCursor();
@@ -265,9 +278,9 @@ LIMIT :limit'
}
$stmt = $this->db->prepare('INSERT INTO store (userId, k, v) VALUES (:userId, :k, :v)');
- $stmt->bindParam(':userId', $id, \PDO::PARAM_INT);
- $stmt->bindParam(':k', $field, \PDO::PARAM_STR);
- $stmt->bindParam(':v', $data[$field], \PDO::PARAM_STR);
+ $stmt->bindParam(':userId', $id, PDO::PARAM_INT);
+ $stmt->bindParam(':k', $field, PDO::PARAM_STR);
+ $stmt->bindParam(':v', $data[$field], PDO::PARAM_STR);
$stmt->execute();
$storeId = $this->db->lastInsertId();
$stmt->closeCursor();
@@ -283,10 +296,10 @@ LIMIT :limit'
* @param string[] $data
* @param int $timestamp
*/
- private function update($id, $data, $timestamp) {
+ private function update(int $id, array $data, int $timestamp): void {
$stmt = $this->db->prepare('UPDATE users SET timestamp = FROM_UNIXTIME(:timestamp) WHERE id = :id');
- $stmt->bindParam(':id', $id, \PDO::PARAM_STR);
- $stmt->bindParam(':timestamp', $timestamp, \PDO::PARAM_INT);
+ $stmt->bindParam(':id', $id, PDO::PARAM_STR);
+ $stmt->bindParam(':timestamp', $timestamp, PDO::PARAM_INT);
$stmt->execute();
$stmt->closeCursor();
$fields = [
@@ -295,7 +308,7 @@ LIMIT :limit'
];
$stmt = $this->db->prepare('SELECT * FROM store WHERE userId = :userId');
- $stmt->bindParam(':userId', $id, \PDO::PARAM_INT);
+ $stmt->bindParam(':userId', $id, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll();
$stmt->closeCursor();
@@ -306,14 +319,12 @@ LIMIT :limit'
unset($fields[$loc]);
}
- if (!isset($data[$key]) || $data[$key] === '') {
+ if ($this->get($key, $data) === '') {
// key not present in new data so delete
$stmt = $this->db->prepare('DELETE FROM store WHERE id = :id');
$stmt->bindParam(':id', $row['id']);
$stmt->execute();
$stmt->closeCursor();
- // remove verification request if correspondig data was deleted
- $this->removeOpenVerificationRequestByStoreId($row['id']);
} else {
// Key present check if we need to update
if ($data[$key] === $value) {
@@ -328,23 +339,24 @@ LIMIT :limit'
if ($key === 'email') {
$this->emailValidator->emailUpdated($data[$key], $row['id']);
}
- // remove verification request from old data
- $this->removeOpenVerificationRequestByStoreId($row['id']);
}
+
+ // remove verification request if correspondig data was deleted
+ $this->removeOpenVerificationRequestByStoreId($row['id']);
}
//Check for new fields
foreach ($fields as $field) {
// Not set or empty field
- if (!isset($data[$field]) || $data[$field] === '') {
+ if ($this->get($field, $data) === '') {
continue;
}
// Insert
$stmt = $this->db->prepare('INSERT INTO store (userId, k, v) VALUES (:userId, :k, :v)');
- $stmt->bindParam(':userId', $id, \PDO::PARAM_INT);
- $stmt->bindParam(':k', $field, \PDO::PARAM_STR);
- $stmt->bindParam(':v', $data[$field], \PDO::PARAM_STR);
+ $stmt->bindParam(':userId', $id, PDO::PARAM_INT);
+ $stmt->bindParam(':k', $field, PDO::PARAM_STR);
+ $stmt->bindParam(':v', $data[$field], PDO::PARAM_STR);
$stmt->execute();
$storeId = $this->db->lastInsertId();
$stmt->closeCursor();
@@ -355,9 +367,16 @@ LIMIT :limit'
}
}
- private function needToVerify($userId, $storeId, $data, $key) {
+
+ /**
+ * @param string $userId
+ * @param int $storeId
+ * @param array $data
+ * @param string $key
+ */
+ private function needToVerify(string $userId, int $storeId, array $data, string $key): void {
$stmt = $this->db->prepare('SELECT * FROM toVerify WHERE storeId = :storeId');
- $stmt->bindParam(':storeId', $storeId, \PDO::PARAM_INT);
+ $stmt->bindParam(':storeId', $storeId, PDO::PARAM_INT);
$stmt->execute();
$alreadyExists = $stmt->fetch();
@@ -367,23 +386,24 @@ LIMIT :limit'
$stmt = $this->db->prepare(
'INSERT INTO toVerify (userId, storeId, property, location, tries) VALUES (:userId, :storeId, :property, :location, :tries)'
);
- $stmt->bindParam(':userId', $userId, \PDO::PARAM_INT);
- $stmt->bindParam(':storeId', $storeId, \PDO::PARAM_INT);
+ $stmt->bindParam(':userId', $userId, PDO::PARAM_INT);
+ $stmt->bindParam(':storeId', $storeId, PDO::PARAM_INT);
$stmt->bindParam(':property', $key);
$stmt->bindParam(':location', $data[$key]);
- $stmt->bindParam(':tries', $tries, \PDO::PARAM_INT);
+ $stmt->bindParam(':tries', $tries, PDO::PARAM_INT);
$stmt->execute();
$stmt->closeCursor();
}
}
- public function register(Request $request, Response $response, array $args = []) {
+ public function register(Request $request, Response $response, array $args = []): Response {
$body = json_decode($request->getBody(), true);
- if ($body === null || !isset($body['message']) || !isset($body['message']['data']) ||
- !isset($body['message']['data']['federationId']) || !isset($body['signature']) ||
- !isset($body['message']['timestamp'])) {
+ if ($body === null || !isset($body['message']) || !isset($body['message']['data'])
+ || !isset($body['message']['data']['federationId'])
+ || !isset($body['signature'])
+ || !isset($body['message']['timestamp'])) {
return $response->withStatus(400);
}
@@ -391,7 +411,7 @@ LIMIT :limit'
try {
$verified = $this->signatureHandler->verify($cloudId, $body['message'], $body['signature']);
- } catch(\Exception $e) {
+ } catch (Exception $e) {
return $response->withStatus(400);
}
@@ -399,7 +419,7 @@ LIMIT :limit'
$result =
$this->insertOrUpdate($cloudId, $body['message']['data'], $body['message']['timestamp']);
if ($result === false) {
- return $response->withStatus(403);
+ return $response->withStatus(403);
}
} else {
// ERROR OUT
@@ -414,10 +434,11 @@ LIMIT :limit'
*
* @param Request $request
* @param Response $response
+ * @param array $args
*
* @return Response
*/
- public function batchRegister(Request $request, Response $response) {
+ public function batchRegister(Request $request, Response $response, array $args = []): Response {
$body = json_decode($request->getBody(), true);
@@ -442,10 +463,11 @@ LIMIT :limit'
*
* @param Request $request
* @param Response $response
+ * @param array $args
*
* @return Response
*/
- public function batchDelete(Request $request, Response $response) {
+ public function batchDelete(Request $request, Response $response, array $args = []): Response {
$body = json_decode($request->getBody(), true);
@@ -466,12 +488,21 @@ LIMIT :limit'
}
- public function delete(Request $request, Response $response) {
+ /**
+ * @param Request $request
+ * @param Response $response
+ * @param array $args
+ *
+ * @return Response
+ * @throws GuzzleException
+ */
+ public function delete(Request $request, Response $response, array $args = []): Response {
$body = json_decode($request->getBody(), true);
- if ($body === null || !isset($body['message']) || !isset($body['message']['data']) ||
- !isset($body['message']['data']['federationId']) || !isset($body['signature']) ||
- !isset($body['message']['timestamp'])) {
+ if ($body === null || !isset($body['message']) || !isset($body['message']['data'])
+ || !isset($body['message']['data']['federationId'])
+ || !isset($body['signature'])
+ || !isset($body['message']['timestamp'])) {
return $response->withStatus(400);
}
@@ -479,7 +510,7 @@ LIMIT :limit'
try {
$verified = $this->signatureHandler->verify($cloudId, $body['message'], $body['signature']);
- } catch(\Exception $e) {
+ } catch (Exception $e) {
return $response->withStatus(400);
}
@@ -497,7 +528,19 @@ LIMIT :limit'
return $response;
}
- public function verify(Request $request, Response $response) {
+
+ /**
+ * @param Request|null $request
+ * @param Response|null $response
+ * @param array $args
+ *
+ * @return Response|null
+ */
+ public function verify(
+ ?Request $request = null,
+ ?Response $response = null,
+ array $args = []
+ ): ?Response {
$verificationRequests = $this->getOpenVerificationRequests();
foreach ($verificationRequests as $verificationData) {
$success = false;
@@ -518,14 +561,16 @@ LIMIT :limit'
$this->incMaxTries($verificationData);
}
}
+
+ return $response;
}
/**
* increase number of max tries to verify account data
*
- * @param $verificationData
+ * @param array $verificationData
*/
- private function incMaxTries($verificationData) {
+ private function incMaxTries(array $verificationData): void {
$tries = (int)$verificationData['tries'];
$tries++;
@@ -546,9 +591,9 @@ LIMIT :limit'
/**
* if data could be verified successfully we update the information in the store table
*
- * @param $storeId
+ * @param int $storeId
*/
- private function updateVerificationStatus($storeId) {
+ private function updateVerificationStatus(int $storeId): void {
$stmt = $this->db->prepare('UPDATE store SET valid = 1 WHERE id = :storeId');
$stmt->bindParam('storeId', $storeId);
$stmt->execute();
@@ -585,7 +630,7 @@ LIMIT :limit'
*
* @return array
*/
- private function getOpenVerificationRequests() {
+ private function getOpenVerificationRequests(): array {
$stmt = $this->db->prepare('SELECT * FROM toVerify LIMIT 10');
$stmt->execute();
$result = $stmt->fetchAll();
@@ -601,7 +646,7 @@ LIMIT :limit'
*
* @return bool
*/
- private function insertOrUpdate($cloudId, $data, $timestamp) {
+ private function insertOrUpdate(string $cloudId, array $data, int $timestamp): bool {
$stmt = $this->db->prepare('SELECT * FROM users WHERE federationId = :federationId');
$stmt->bindParam(':federationId', $cloudId);
$stmt->execute();
@@ -633,7 +678,7 @@ LIMIT :limit'
*
* @return bool
*/
- private function deleteDBRecord($cloudId) {
+ private function deleteDBRecord(string $cloudId): bool {
$stmt = $this->db->prepare('SELECT * FROM users WHERE federationId = :federationId');
$stmt->bindParam(':federationId', $cloudId);
diff --git a/server/lib/Validator/Email.php b/server/lib/Validator/Email.php
index a71dd22..06c63c0 100644
--- a/server/lib/Validator/Email.php
+++ b/server/lib/Validator/Email.php
@@ -1,49 +1,77 @@
<?php
+declare(strict_types=1);
+
+
+/**
+ * lookup-server - Standalone Lookup Server.
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bjoern Schiessle <bjoern@schiessle.org>
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ *
+ * @copyright 2017
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
namespace LookupServer\Validator;
+use Exception;
+use PDO;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
+use Slim\Interfaces\RouteParserInterface;
+use Slim\Routing\Route;
class Email {
- /** @var \PDO */
- private $db;
-
- /** @var \Slim\Interfaces\RouterInterface */
- private $router;
-
- /** @var string */
- private $host;
-
- /** @var string */
- private $from;
+ private PDO $db;
+ private RouteParserInterface $routeParser;
+ private string $host;
+ private string $from;
+ private bool $globalScale;
- /** @var bool */
- private $globalScale;
/**
- * Email constructor.
- * @param \PDO $db
- * @param \Slim\Interfaces\RouterInterface $router
+ * @param PDO $db
+ * @param RouteParserInterface $routeParser
* @param string $host
* @param string $from
* @param bool $globalScale
*/
- public function __construct(\PDO $db,
-// \Slim\Interfaces\RouterInterface $router,
- $host,
- $from,
- $globalScale) {
+ public function __construct(
+ PDO $db,
+ RouteParserInterface $routeParser,
+ string $host,
+ string $from,
+ bool $globalScale
+ ) {
$this->db = $db;
-// $this->router = $router;
+ $this->routeParser = $routeParser;
$this->host = $host;
$this->from = $from;
$this->globalScale = $globalScale;
}
- public function validate(Request $request, Response $response, array $args = []) {
- /** @var $route \Slim\Route */
+ public function validate(Request $request, Response $response, array $args = []): Response {
+ /** @var Route $route */
$route = $request->getAttribute('route');
$token = $route->getArgument('token');
@@ -72,7 +100,7 @@ class Email {
return $response;
}
- public function emailUpdated($email, $storeId) {
+ public function emailUpdated(string $email, int $storeId): void {
if ($this->globalScale) {
// When in global scale mode we should not send e-mails
return;
@@ -95,23 +123,34 @@ class Email {
$stmt->closeCursor();
// Actually send e-mail
- $link = $this->host . $this->router->pathFor('validateEmail', ['token' => $token]);
+ $link = $this->host . $this->routeParser->urlFor('validateEmail', ['token' => $token]);
$text = 'Please click this link to confirm your e-mail address: ' . $link;
- $headers = 'From: '.$this->from."\r\n" .'X-Mailer: PHP/' . phpversion();
+ $headers = 'From: ' . $this->from . "\r\n" . 'X-Mailer: PHP/' . phpversion();
mail($email, 'Email confirmation', $text, $headers);
}
- private function generate($length,
- $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
+
+ /**
+ * @param int $length
+ * @param string $characters
+ *
+ * @return string
+ * @throws Exception
+ */
+ private function generate(
+ int $length,
+ string $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
+ ): string {
$maxCharIndex = strlen($characters) - 1;
$randomString = '';
- while($length > 0) {
- $randomNumber = \random_int(0, $maxCharIndex);
+ while ($length > 0) {
+ $randomNumber = random_int(0, $maxCharIndex);
$randomString .= $characters[$randomNumber];
$length--;
}
+
return $randomString;
}
}
diff --git a/server/lib/Validator/Twitter.php b/server/lib/Validator/Twitter.php
index 7cd3724..b86a661 100644
--- a/server/lib/Validator/Twitter.php
+++ b/server/lib/Validator/Twitter.php
@@ -1,7 +1,12 @@
<?php
+
+declare(strict_types=1);
+
/**
* @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org>
*
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ *
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
@@ -24,27 +29,24 @@ namespace LookupServer\Validator;
use Abraham\TwitterOAuth\TwitterOAuth;
+use Exception;
use LookupServer\SignatureHandler;
+use PDO;
class Twitter {
- /** @var TwitterOAuth */
- private $twitterOAuth;
-
- /** @var SignatureHandler */
- private $signatureHandler;
-
- /** @var \PDO */
- private $db;
+ private TwitterOAuth $twitterOAuth;
+ private SignatureHandler $signatureHandler;
+ private PDO $db;
/**
* Twitter constructor.
*
* @param TwitterOAuth $twitterOAuth
* @param SignatureHandler $signatureHandler
- * @param \PDO $db
+ * @param PDO $db
*/
- public function __construct(TwitterOAuth $twitterOAuth, SignatureHandler $signatureHandler, \PDO $db) {
+ public function __construct(TwitterOAuth $twitterOAuth, SignatureHandler $signatureHandler, PDO $db) {
$this->twitterOAuth = $twitterOAuth;
$this->signatureHandler = $signatureHandler;
$this->db = $db;
@@ -55,9 +57,10 @@ class Twitter {
*
* @param array $verificationData from toVerify table
* @param array $userData stored user data
+ *
* @return bool
*/
- public function verify(array $verificationData, array $userData) {
+ public function verify(array $verificationData, array $userData): bool {
$twitterHandle = $verificationData['location'];
$isValid = $this->isValidTwitterHandle($twitterHandle);
$result = false;
@@ -76,8 +79,8 @@ class Twitter {
$result = $this->signatureHandler->verify($cloudId, $message, $signature);
$result = $result && md5($signature) === $md5signature;
}
- } catch (\Exception $e) {
- // do nothing, just return false;
+ } catch (Exception $e) {
+ return false;
}
if ($result === true) {
@@ -91,9 +94,10 @@ class Twitter {
* get tweet text and id
*
* @param string $userName user name without the '@'
+ *
* @return array
*/
- private function getTweet($userName) {
+ private function getTweet(string $userName): array {
try {
$search = 'from:' . $userName . ' Use my Federated Cloud ID to share with me';
@@ -101,7 +105,7 @@ class Twitter {
$id = $statuses->statuses[0]->id;
$text = $statuses->statuses[0]->text;
- } catch (\Exception $e) {
+ } catch (Exception $e) {
return [null, null];
}
@@ -111,11 +115,13 @@ class Twitter {
/**
* check if we have a correct twitter Handle
*
- * @param $twitterHandle
+ * @param string $twitterHandle
+ *
* @return bool
*/
- private function isValidTwitterHandle($twitterHandle) {
+ private function isValidTwitterHandle(string $twitterHandle): bool {
$result = preg_match('/^@[A-Za-z0-9_]+$/', $twitterHandle);
+
return $result === 1;
}
@@ -123,9 +129,10 @@ class Twitter {
* split message and signature
*
* @param string $proof
+ *
* @return array
*/
- private function splitMessageSignature($proof) {
+ private function splitMessageSignature(string $proof): array {
$signature = substr($proof, -32);
$message = substr($proof, 0, -32);
@@ -135,25 +142,25 @@ class Twitter {
/**
* store reference to tweet
*
- * @param $userId
- * @param $tweetId
+ * @param int $userId
+ * @param string $tweetId
*/
- private function storeReference($userId, $tweetId) {
+ private function storeReference(int $userId, string $tweetId) {
$key = 'tweet_id';
// delete old value, if exists
$stmt = $this->db->prepare('DELETE FROM store WHERE userId = :userId AND k = :k');
- $stmt->bindParam(':userId', $userId, \PDO::PARAM_INT);
- $stmt->bindParam(':k', $key, \PDO::PARAM_STR);
+ $stmt->bindParam(':userId', $userId, PDO::PARAM_INT);
+ $stmt->bindParam(':k', $key, PDO::PARAM_STR);
$stmt->execute();
$stmt->closeCursor();
// add new value
$stmt = $this->db->prepare('INSERT INTO store (userId, k, v) VALUES (:userId, :k, :v)');
- $stmt->bindParam(':userId', $userId, \PDO::PARAM_INT);
- $stmt->bindParam(':k', $key, \PDO::PARAM_STR);
- $stmt->bindParam(':v', $tweetId, \PDO::PARAM_STR);
+ $stmt->bindParam(':userId', $userId, PDO::PARAM_INT);
+ $stmt->bindParam(':k', $key, PDO::PARAM_STR);
+ $stmt->bindParam(':v', $tweetId, PDO::PARAM_STR);
$stmt->execute();
$stmt->closeCursor();
}
diff --git a/server/lib/Validator/Website.php b/server/lib/Validator/Website.php
index e43bfb0..0fa904f 100644
--- a/server/lib/Validator/Website.php
+++ b/server/lib/Validator/Website.php
@@ -1,7 +1,12 @@
<?php
+
+declare(strict_types=1);
+
/**
* @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org>
*
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ *
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
@@ -23,12 +28,12 @@
namespace LookupServer\Validator;
+use Exception;
use LookupServer\SignatureHandler;
class Website {
- /** @var SignatureHandler */
- private $signatureHandler;
+ private SignatureHandler $signatureHandler;
public function __construct(SignatureHandler $signatureHandler) {
$this->signatureHandler = $signatureHandler;
@@ -39,9 +44,10 @@ class Website {
*
* @param array $verificationData from toVerify table
* @param array $userData stored user data
+ *
* @return bool
*/
- public function verify($verificationData, $userData) {
+ public function verify(array $verificationData, array $userData): bool {
$url = $this->getValidUrl($verificationData['location']);
$proof = @file_get_contents($url);
$result = false;
@@ -52,7 +58,7 @@ class Website {
list($message, $signature) = $this->splitMessageSignature($proofSanitized);
$result = $this->signatureHandler->verify($cloudId, $message, $signature);
}
- } catch (\Exception $e) {
+ } catch (Exception $e) {
// do nothing, just return false
}
@@ -63,9 +69,10 @@ class Website {
* construct valid URL to proof
*
* @param string $url
+ *
* @return string
*/
- private function getValidUrl($url) {
+ private function getValidUrl(string $url): string {
$url = trim($url);
$url = rtrim($url, '/');
if (strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0) {
@@ -79,9 +86,10 @@ class Website {
* split message and signature
*
* @param string $proof
+ *
* @return array
*/
- private function splitMessageSignature($proof) {
+ private function splitMessageSignature(string $proof): array {
$signature = substr($proof, -344);
$message = substr($proof, 0, -344);
diff --git a/server/replicationcron.php b/server/replicationcron.php
index 5b1555c..96d95d7 100755
--- a/server/replicationcron.php
+++ b/server/replicationcron.php
@@ -1,19 +1,20 @@
<?php
+use LookupServer\Replication;
+
require __DIR__ . '/vendor/autoload.php';
if (PHP_SAPI !== 'cli') {
return;
}
-$env = \Slim\Http\Environment::mock(['REQUEST_URI' => '/import']);
-$settings = require __DIR__ . '/src/config.php';
-$settings['environment'] = $env;
-$container = new \Slim\Container($settings);
-require __DIR__ . '/src/dependencies.php';
+require __DIR__ . '/init.php';
-$app = new \Slim\App($container);
+if (!isset($app) || !isset($container)) {
+ return;
+}
-$app->map(['GET'], '/import', 'Replication:import');
-$app->run();
+/** @var Replication $replication */
+$replication = $container->get('Replication');
+$replication->import();
diff --git a/server/verifycron.php b/server/verifycron.php
index ad4dc48..85c4e4a 100644
--- a/server/verifycron.php
+++ b/server/verifycron.php
@@ -19,20 +19,25 @@
*
*/
+use LookupServer\UserManager;
+
require __DIR__ . '/vendor/autoload.php';
if (PHP_SAPI !== 'cli') {
- return;
+ return;
}
-$env = \Slim\Http\Environment::mock(['REQUEST_URI' => '/verify']);
-$settings = require __DIR__ . '/src/config.php';
-$settings['environment'] = $env;
-$container = new \Slim\Container($settings);
-require __DIR__ . '/src/dependencies.php';
+require __DIR__ . '/init.php';
+
+if (!isset($app) || !isset($container)) {
+ return;
+}
+
+/** @var UserManager $userManager */
+$userManager = $container->get('UserManager');
+$userManager->verify();
-$app = new \Slim\App($container);
$app->map(['GET'], '/verify', 'UserManager:verify');
$app->run();