Endpoints added and refactored - permissions added

This commit is contained in:
Mal 2020-08-24 22:19:46 +02:00
parent 6b2abc1f89
commit ef7f7c4b4a
27 changed files with 604 additions and 126 deletions

View File

@ -41,6 +41,10 @@ paths:
$ref: '#/components/schemas/Username' $ref: '#/components/schemas/Username'
jabberAddress: jabberAddress:
$ref: '#/components/schemas/JabberAddress' $ref: '#/components/schemas/JabberAddress'
isAdmin:
type: boolean
description: Returns if the user has admin permissions.
example: true
fingerprintIds: fingerprintIds:
type: array type: array
items: items:
@ -88,6 +92,134 @@ paths:
default: default:
$ref: '#/components/responses/Error' $ref: '#/components/responses/Error'
'/api/v1/user/{userId}/fingerprints':
get:
tags:
- User
summary: A list containing all fingerprints of the user
responses:
200:
description: Returns the success state and a list with all fingerprints of the user.
content:
application/json:
schema:
properties:
success:
$ref: '#/components/schemas/Success'
fingerprints:
type: array
items:
type: object
example:
- fingerprintId: 8
fingerprint: '5BDF1668E59F2184582591699F55D9158DEF400A48772887A8F61531ED36B2A'
userId: 25
- fingerprintId: 42
fingerprint: '6FF8842B6D17F5C2098A3DD8AB55D9158DEF400A48772887A8F61531ED36B2A'
userId: 25
'/api/v1/user/{userId}/email':
get:
tags:
- User
parameters:
- $ref: '#/components/parameters/UserId'
summary: Returns the user's email address
responses:
200:
description: Contains a JSON object with the success state and the email address.
content:
application/json:
schema:
type: object
properties:
success:
$ref: '#/components/schemas/Success'
email:
$ref: '#/components/schemas/EmailAddress'
default:
$ref: '#/components/responses/Error'
put:
tags:
- User
summary: Changes the user's email address
parameters:
- $ref: '#/components/parameters/UserId'
requestBody:
content:
application/json:
schema:
type: object
properties:
email:
$ref: '#/components/schemas/EmailAddress'
allOf:
- required:
- email
responses:
200:
description: Returns the success state for the change request.
content:
application/json:
schema:
type: object
properties:
success:
$ref: '#/components/schemas/Success'
default:
$ref: '#/components/responses/Error'
'/api/v1/user/{userId}/password':
put:
tags:
- User
summary: Changes the password of the user
parameters:
- $ref: '#/components/parameters/UserId'
requestBody:
description: The password inside a json object.
content:
application/json:
schema:
type: object
properties:
password:
type: string
description: The new password.
example: '12345'
allOf:
- required:
- password
responses:
200:
$ref: '#/components/responses/Success'
default:
$ref: '#/components/responses/Error'
'/api/v1/user/{userId}/admin':
post:
tags:
- User
summary: Gives the user admin permissions
parameters:
- $ref: '#/components/parameters/UserId'
responses:
200:
$ref: '#/components/responses/Success'
default:
$ref: '#/components/responses/Error'
delete:
tags:
- User
summary: Removes the user's admin permissions
parameters:
- $ref: '#/components/parameters/UserId'
responses:
200:
$ref: '#/components/responses/Success'
default:
$ref: '#/components/responses/Error'
'/api/v1/user': '/api/v1/user':
post: post:
tags: tags:
@ -193,16 +325,7 @@ paths:
content: content:
application/json: application/json:
schema: schema:
type: object $ref: '#/components/schemas/FingerprintData'
properties:
fingerprintId:
$ref: '#/components/schemas/FingerprintId'
fingerprint:
$ref: '#/components/schemas/Fingerprint'
userId:
type: integer
description: The id of the user that owns this fingerprint.
example: 25
default: default:
$ref: '#/components/responses/Error' $ref: '#/components/responses/Error'
put: put:
@ -450,7 +573,7 @@ components:
EmailAddress: EmailAddress:
type: string type: string
description: The registered email address for the user. description: The registered email address for the user.
example: kevin@gmail.com example: kevin42@gmail.com
FingerprintId: FingerprintId:
type: integer type: integer
@ -463,6 +586,18 @@ components:
description: The jabber fingerprint description: The jabber fingerprint
example: '5BDF1668E59F2184582591699F55D9158DEF400A48772887A8F61531ED36B2A' example: '5BDF1668E59F2184582591699F55D9158DEF400A48772887A8F61531ED36B2A'
FingerprintData:
type: object
properties:
fingerprintId:
$ref: '#/components/schemas/FingerprintId'
fingerprint:
$ref: '#/components/schemas/Fingerprint'
userId:
type: integer
description: The id of the user that owns this fingerprint.
example: 25
SharingId: SharingId:
type: integer type: integer
description: The id for the sharing. description: The id for the sharing.

View File

@ -18,6 +18,11 @@ final class ApiJsonResponse extends ApiResponse
$this->setParameter('result', $result->jsonSerialize()); $this->setParameter('result', $result->jsonSerialize());
} }
public function setSuccess(bool $success): void
{
$this->setParameter('success', $success);
}
public function respond(): void public function respond(): void
{ {
parent::respond(); parent::respond();

View File

@ -31,14 +31,18 @@ final class FingerprintDeleteController extends AbstractController
$db = new MySqlDatabase(); $db = new MySqlDatabase();
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();
$db->startTransaction();
$fingerprint = new Fingerprint($this->fingerprintId, $db); $fingerprint = new Fingerprint($this->fingerprintId, $db);
if (!$this->hasUserPermission($fingerprint->getUserId())) { if (!$this->hasUserPermission($fingerprint->getUserId())) {
return; return;
} }
$db->startTransaction();
if (!$this->hasUserPermission($fingerprint->getUserId())) {
return;
}
$qrCode = new QrCode($fingerprint->getFingerprintId(), $fingerprint->getFingerprint()); $qrCode = new QrCode($fingerprint->getFingerprintId(), $fingerprint->getFingerprint());
$fingerprint->Delete(); $fingerprint->Delete();
$qrCode->delete(); $qrCode->delete();

View File

@ -25,7 +25,9 @@ final class FingerprintGetController extends AbstractController
$fingerprint = new Fingerprint($this->fingerprintId); $fingerprint = new Fingerprint($this->fingerprintId);
if (!$this->hasUserPermission($fingerprint->getUserId())) { if (!$this->hasUserPermission($fingerprint->getUserId())) {
return; if (!$fingerprint->isSharedWith($this->session->getUserId())) {
return;
}
} }
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();

View File

@ -12,24 +12,24 @@ final class FingerprintPostController extends AbstractController
public function handle(): void public function handle(): void
{ {
if (!$this->isUserLoggedIn()) { parent::handle();
if (!$this->isUserLoggedIn() || $this->response->getStatus() !== ServerStatus::OK) {
return; return;
} }
parent::handle();
$db = new MySqlDatabase(); $db = new MySqlDatabase();
$json = json_decode($this->requestBody);
$fingerprint = new Fingerprint(null, $db); $fingerprint = new Fingerprint(null, $db);
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();
try { try {
if (!$this->hasUserPermission((int)$json->userId)) { if (!$this->hasUserPermission((int)$this->jsonBody->userId)) {
return; return;
} }
$fingerprint->setFingerprint((string)$json->fingerprint); $fingerprint->setFingerprint((string)$this->jsonBody->fingerprint);
$fingerprint->setUserId((int)$json->userId); $fingerprint->setUserId((int)$this->jsonBody->userId);
if (!$db->hasTransaction()) { if (!$db->hasTransaction()) {
$db->startTransaction(); $db->startTransaction();
@ -49,7 +49,7 @@ final class FingerprintPostController extends AbstractController
$this->response->setParameter('success', false); $this->response->setParameter('success', false);
$this->response->setMessage('An error occured during QR code creation!'); $this->response->setMessage('An error occured during QR code creation!');
} catch (Throwable $e) { } catch (Throwable $e) {
$this->catchDatabaseException($e->getMessage(), $json); $this->catchDatabaseException($e->getMessage(), $this->jsonBody);
} }
} }

View File

@ -26,18 +26,12 @@ final class FingerprintPutController extends AbstractController
parent::handle(); parent::handle();
if ($this->response->getStatus() !== ServerStatus::OK) {
return;
}
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();
try { try {
$json = json_decode($this->requestBody, true);
$fingerprint = new Fingerprint($this->fingerprintId); $fingerprint = new Fingerprint($this->fingerprintId);
if ($this->hasUserPermission($fingerprint->getUserId()) || $this->handleFingerprint($fingerprint, $json)) { if ($this->hasUserPermission($fingerprint->getUserId()) || $this->handleFingerprint($fingerprint)) {
return; return;
} }
@ -49,15 +43,13 @@ final class FingerprintPutController extends AbstractController
} }
} }
public function handleFingerprint(Fingerprint $fingerprint, array $json): bool public function handleFingerprint(Fingerprint $fingerprint): bool
{ {
if (isset($json['fingerprint'])) { if ($fingerprint->getFingerprint() !== $this->jsonBody->fingerprint) {
if ($fingerprint->getFingerprint() !== $json['fingerprint']) { $fingerprint->setFingerprint($this->jsonBody->fingerprint);
$fingerprint->setFingerprint($json['fingerprint']); $fingerprint->Save();
$fingerprint->Save();
return true; return true;
}
} }
return false; return false;

View File

@ -17,17 +17,23 @@ final class QrCodeGetController extends AbstractController
public function handle(): void public function handle(): void
{ {
$filename = Setting::PATH_QR_CODES . (string)$this->fingerprintId . '.svg';
if (!is_file($filename)) {
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
$this->response->setParameter('success', false);
$this->response->setMessage(sprintf('No QR code for fingerprint id %d found!', $this->fingerprintId));
return;
}
try { try {
$fingerprint = new Fingerprint($this->fingerprintId);
if (!$this->isUserLoggedIn() || !$this->hasUserPermission($fingerprint->getUserId())) {
return;
}
$filename = Setting::PATH_QR_CODES . (string)$this->fingerprintId . '.svg';
if (!is_file($filename)) {
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
$this->response->setParameter('success', false);
$this->response->setMessage(sprintf('No QR code for fingerprint id %d found!', $this->fingerprintId));
return;
}
$this->response = new ApiSvgResponse(); $this->response = new ApiSvgResponse();
$file = @fopen($filename, 'r'); $file = @fopen($filename, 'r');

View File

@ -25,6 +25,11 @@ final class SharingDeleteController extends AbstractController
try { try {
$sharing = new Sharing($this->sharingId); $sharing = new Sharing($this->sharingId);
if (!$this->isUserLoggedIn() || !$this->hasUserPermission($sharing->getUserId())) {
return;
}
$sharing->Delete(); $sharing->Delete();
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();

View File

@ -26,6 +26,10 @@ final class SharingGetController extends AbstractController
try { try {
$sharing = new Sharing($this->sharingId); $sharing = new Sharing($this->sharingId);
if (!$this->isUserLoggedIn() || !$this->hasUserPermission($sharing->getUserId())) {
return;
}
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();
$this->response->setParameter('success', true); $this->response->setParameter('success', true);
$this->response->setResult($sharing); $this->response->setResult($sharing);

View File

@ -5,6 +5,8 @@ declare(strict_types=1);
final class SharingPostController extends AbstractController final class SharingPostController extends AbstractController
{ {
protected string $route = '/api/v1/sharing'; protected string $route = '/api/v1/sharing';
/** @var string[] */
protected array $mandatoryAttributes = [ protected array $mandatoryAttributes = [
'userId', 'userId',
'userSharedId', 'userSharedId',
@ -18,12 +20,14 @@ final class SharingPostController extends AbstractController
return; return;
} }
$json = json_decode($this->requestBody); if (!$this->isUserLoggedIn() || !$this->hasUserPermission($this->jsonBody->userId)) {
return;
}
try { try {
$sharing = new Sharing(); $sharing = new Sharing();
$sharing->setUserId($json->userId); $sharing->setUserId($this->jsonBody->userId);
$sharing->setUserShared($json->userSharedId); $sharing->setUserShared($this->jsonBody->userSharedId);
$sharing->Save(); $sharing->Save();
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();

View File

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
final class UserAdminDeleteController extends AbstractController
{
protected string $route = '/api/v1/user/{userId}/admin';
private int $userId;
public function __construct(string $url)
{
parent::__construct($url);
$this->userId = (int)$this->getUrlParamInt('userId');
}
public function handle(): void
{
$this->response = new ApiJsonResponse();
if (!$this->isUserLoggedIn()) {
return;
}
if (!$this->session->isAdmin()) {
$this->response->setStatus(ServerStatus::UNAUTHORIZED);
$this->response->setSuccess(false);
$this->response->setMessage('You have no permission!');
return;
}
try {
$user = new User($this->userId);
$user->setAdmin(false);
$user->Save();
} catch (Throwable $e) {
$this->response->setSuccess(false);
$this->response->setStatus($e->getCode() !== 0 ? $e->getCode() : ServerStatus::BAD_REQUEST);
$this->response->setMessage($e->getMessage());
}
}
}

View File

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
final class UserAdminPostController extends AbstractController
{
protected string $route = '/api/v1/user/{userId}/admin';
private int $userId;
public function __construct(string $url)
{
parent::__construct($url);
$this->userId = (int)$this->getUrlParamInt('userId');
}
public function handle(): void
{
$this->response = new ApiJsonResponse();
if (!$this->isUserLoggedIn()) {
return;
}
if (!$this->session->isAdmin()) {
$this->response->setStatus(ServerStatus::UNAUTHORIZED);
$this->response->setSuccess(false);
$this->response->setMessage('You have no permission!');
return;
}
try {
$user = new User($this->userId);
$user->setAdmin(true);
$user->Save();
} catch (Throwable $e) {
$this->response->setSuccess(false);
$this->response->setStatus($e->getCode() !== 0 ? $e->getCode() : ServerStatus::BAD_REQUEST);
$this->response->setMessage($e->getMessage());
}
}
}

View File

@ -17,9 +17,13 @@ final class UserDeleteController extends AbstractController
public function handle(): void public function handle(): void
{ {
if (!$this->isUserLoggedIn()) {
return;
}
parent::handle(); parent::handle();
if ($this->response->getStatus() !== ServerStatus::OK) { if ($this->response->getStatus() !== ServerStatus::OK || !$this->hasUserPermission($this->userId)) {
return; return;
} }

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
final class UserEmailGetController extends AbstractController
{
protected string $route = '/api/v1/user/{userId}/email';
private int $userId;
public function __construct(string $url)
{
parent::__construct($url);
$this->userId = (int)$this->getUrlParamInt('userId');
}
public function handle(): void
{
if (!$this->isUserLoggedIn()) {
return;
}
parent::handle();
if (!$this->hasUserPermission($this->userId)) {
return;
}
try {
$user = new User($this->userId);
$this->response->setParameter('email', $user->getEmail());
} catch (Throwable $e) {
$this->response->setParameter('success', false);
$this->response->setMessage($e->getMessage());
$this->response->setStatus($e->getCode() !== 0 ? $e->getCode() : ServerStatus::BAD_REQUEST);
}
}
}

View File

@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
final class UserEmailPutController extends AbstractController
{
protected string $route = '/api/v1/user/{userId}/email';
protected array $mandatoryAttributes = [
'email',
];
private int $userId;
public function __construct(string $url)
{
parent::__construct($url);
$this->userId = (int)$this->getUrlParamInt('userId');
}
public function handle(): void
{
if (!$this->isUserLoggedIn() || !$this->hasUserPermission($this->userId)) {
return;
}
parent::handle();
$this->response = new ApiJsonResponse();
try {
$json = json_decode($this->requestBody);
$user = new User($this->userId);
if ($user->getEmail() !== $json->email) {
$user->setEmail($json->email);
$user->Save();
}
} catch (Throwable $e) {
$this->response->setStatus($e->getCode() !== 0 ? $e->getCode() : ServerStatus::BAD_REQUEST);
$this->response->setParameter('success', false);
$this->response->setMessage($e->getMessage());
}
}
}

View File

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
final class UserFingerprintsGetController extends AbstractController
{
protected string $route = '/api/v1/user/{userId}/fingerprints';
private int $userId;
public function __construct(string $url)
{
parent::__construct($url);
$this->userId = (int)$this->getUrlParamInt('userId');
}
public function handle(): void
{
if (!$this->isUserLoggedIn() ) {
return;
}
try {
$this->response = new ApiJsonResponse();
$user = new User($this->userId);
if (!$this->hasUserPermission($this->userId)) {
if (!$user->isSharingWith($this->session->getUserId())) {
return;
}
}
$fingerprints = new FingerprintCollection();
foreach ($user->getFingerprintIds() as $fingerprintId) {
$fingerprints->add(new Fingerprint($fingerprintId));
}
$this->response->setParameter('fingerprints', $fingerprints->jsonSerialize());
} catch (Throwable $e) {
$this->response->setParameter('success', false);
$this->response->setMessage($e->getMessage());
$this->response->setStatus($e->getCode() !== 0 ? $e->getCode() : ServerStatus::BAD_REQUEST);
}
}
}

View File

@ -17,6 +17,10 @@ final class UserGetController extends AbstractController
public function handle(): void public function handle(): void
{ {
if (!$this->isUserLoggedIn()) {
return;
}
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();
try { try {

View File

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
final class UserPasswordPutController extends AbstractController
{
protected string $route = '/api/v1/user/{userId}/password';
/** @var string[] */
protected array $mandatoryAttributes= [
'password',
];
private int $userId;
public function __construct(string $url)
{
parent::__construct($url);
$this->userId = (int)$this->getUrlParamInt('userId');
}
public function handle(): void
{
if (!$this->isUserLoggedIn() || !$this->hasUserPermission($this->userId)) {
return;
}
parent::handle();
if ($this->response->getStatus() !== ServerStatus::OK) {
return;
}
$this->response = new ApiJsonResponse();
try {
$user = new User($this->userId);
$user->setPassword(Password::GetHash($this->jsonBody->password));
$user->Save();
} catch (Throwable $e) {
$this->response->setSuccess(false);
$this->response->setStatus($e->getCode() !== 0 ? $e->getCode() : ServerStatus::BAD_REQUEST);
$this->response->setMessage($e->getMessage());
}
}
}

View File

@ -14,37 +14,37 @@ final class UserPostController extends AbstractController
public function handle(): void public function handle(): void
{ {
if (!$this->isUserLoggedIn()) {
return;
}
if (!$this->session->isAdmin()) {
$this->response = new ApiJsonResponse(ServerStatus::UNAUTHORIZED);
$this->response->setSuccess(false);
$this->response->setMessage('You have no permission!');
}
parent::handle(); parent::handle();
if ($this->response->getStatus() !== ServerStatus::OK) { if ($this->response->getStatus() !== ServerStatus::OK) {
return; return;
} }
$json = json_decode($this->requestBody);
try { try {
$user = new User(); $user = new User();
$user->setUsername($json->username); $user->setUsername($this->jsonBody->username);
$user->setPassword(Password::GetHash($json->password)); $user->setPassword(Password::GetHash($this->jsonBody->password));
$user->setEmail($json->email); $user->setEmail($this->jsonBody->email);
$user->setJabberAddress($json->jabberAddress); $user->setJabberAddress($this->jsonBody->jabberAddress);
$user->Save(); $user->Save();
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();
$this->response->setParameter('userId', $user->getUserId()); $this->response->setParameter('userId', $user->getUserId());
} catch (DatabaseException $e) { } catch (DatabaseException $e) {
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse(ServerStatus::INTERNAL_ERROR);
$this->response->setParameter('success', false); $this->response->setParameter('success', false);
$this->response->setMessage($e->getMessage()); $this->response->setMessage($e->getMessage());
switch ($e->getCode()) {
case DatabaseException::CONNECTION_FAILED:
$this->response->setStatus(ServerStatus::INTERNAL_ERROR);
break;
default:
$this->response->setStatus(ServerStatus::INTERNAL_ERROR);
}
} catch (Throwable $e) { } catch (Throwable $e) {
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST); $this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
$this->response->setParameter('success', false); $this->response->setParameter('success', false);

View File

@ -17,28 +17,26 @@ final class UserPutController extends AbstractController
public function handle(): void public function handle(): void
{ {
parent::handle(); if (!$this->isUserLoggedIn()) {
if ($this->response->getStatus() !== ServerStatus::OK) {
return; return;
} }
if ($this->requestBody === null) { parent::handle();
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
$this->response->setParameter('success', false); if ($this->response->getStatus() !== ServerStatus::OK || !$this->hasUserPermission($this->userId)) {
$this->response->setMessage('No JSON body with changed parametesrs found!'); return;
} }
try { try {
$json = json_decode($this->requestBody, true);
$user = new User($this->userId); $user = new User($this->userId);
$hasChanged = $this->handleUserData($user, $json); $hasChanged = $this->handleUserData($user);
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();
if ($hasChanged) { if ($hasChanged) {
$user->Save(); $user->Save();
return; return;
} }
@ -50,62 +48,45 @@ final class UserPutController extends AbstractController
} }
} }
private function setUsername(User $user, array $json): bool private function setUsername(User $user): bool
{ {
if (isset($json['username'])) { $hasChanged = $user->getUsername() !== $this->jsonBody->username;
$hasChanged = $user->getUsername() !== $json['username']; $user->setUsername($this->jsonBody->username);
$user->setUsername($json['username']);
return $hasChanged; return $hasChanged;
}
return false;
} }
private function setPassword(User $user, array $json): bool private function setPassword(User $user): bool
{ {
if (isset($json['password'])) { $hasChanged = !Password::IsValid($this->jsonBody->password, $user->getPassword());
$hasChanged = !Password::IsValid($json['password'], $user->getPassword()); $user->setPassword(Password::GetHash($this->jsonBody->password));
$user->setPassword(Password::GetHash($json['password'])); return $hasChanged;
return $hasChanged;
}
return false;
} }
private function setEmail(User $user, array $json): bool private function setEmail(User $user): bool
{ {
if (isset($json['email'])) { $hasChanged = $user->getEmail() !== $this->jsonBody->email;
$hasChanged = $user->getEmail() !== $json['email']; $user->setEmail($this->jsonBody->email);
$user->setEmail($json['email']);
return $hasChanged; return $hasChanged;
}
return false;
} }
private function setJabberAddress(User $user, array $json): bool private function setJabberAddress(User $user): bool
{ {
if (isset($json['jabberAddress'])) { $hasChanged = $user->getJabberAddress() !== $this->jsonBody->jabberAddress;
$hasChanged = $user->getJabberAddress() !== $json['jabberAddress']; $user->setJabberAddress($this->jsonBody->jabberAddress);
$user->setJabberAddress($json['jabberAddress']);
return $hasChanged; return $hasChanged;
}
return false;
} }
private function handleUserData(User $user, array $json): bool private function handleUserData(User $user): bool
{ {
$hasChanged = $this->setUsername($user, $json) || false; $hasChanged = $this->setUsername($user) || false;
$hasChanged = $this->setPassword($user, $json) || $hasChanged; $hasChanged = $this->setPassword($user) || $hasChanged;
$hasChanged = $this->setEmail($user, $json) || $hasChanged; $hasChanged = $this->setEmail($user) || $hasChanged;
$hasChanged = $this->setJabberAddress($user, $json) || $hasChanged; $hasChanged = $this->setJabberAddress($user) || $hasChanged;
return $hasChanged; return $hasChanged;
} }

View File

@ -10,9 +10,7 @@ final class UserSessionDeleteController extends AbstractController
{ {
parent::handle(); parent::handle();
$session = new Session(); if (!$this->session->IsLoggedIn()) {
if (!$session->IsLoggedIn()) {
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST); $this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
$this->response->setParameter('success', false); $this->response->setParameter('success', false);
$this->response->setMessage('No session to delete!'); $this->response->setMessage('No session to delete!');
@ -20,7 +18,7 @@ final class UserSessionDeleteController extends AbstractController
return; return;
} }
$session->Destroy(); $this->session->Destroy();
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();
$this->response->setParameter('success', true); $this->response->setParameter('success', true);

View File

@ -18,11 +18,7 @@ final class UserSessionPostController extends AbstractController
return; return;
} }
$json = json_decode($this->requestBody); if ($this->session->IsLoggedIn()) {
$session = new Session();
if ($session->IsLoggedIn()) {
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST); $this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
$this->response->setParameter('success', false); $this->response->setParameter('success', false);
$this->response->setMessage('You are already logged in!'); $this->response->setMessage('You are already logged in!');
@ -30,7 +26,7 @@ final class UserSessionPostController extends AbstractController
return; return;
} }
if (!$session->Login($json->username, $json->password)) { if (!$this->session->Login($this->jsonBody->username, $this->jsonBody->password)) {
$this->response = new ApiJsonResponse(ServerStatus::UNAUTHORIZED); $this->response = new ApiJsonResponse(ServerStatus::UNAUTHORIZED);
$this->response->setParameter('success', false); $this->response->setParameter('success', false);
$this->response->setMessage('Login failed!'); $this->response->setMessage('Login failed!');
@ -39,6 +35,6 @@ final class UserSessionPostController extends AbstractController
} }
$this->response = new ApiJsonResponse(); $this->response = new ApiJsonResponse();
$this->response->setParameter('userId', $session->getUserId()); $this->response->setParameter('userId', $this->session->getUserId());
} }
} }

View File

@ -10,7 +10,10 @@ abstract class AbstractController
protected Session $session; protected Session $session;
protected string $requestUrl; protected string $requestUrl;
protected ?string $requestBody = null; protected ?string $requestBody = null;
protected ?object $jsonBody = null;
protected ?string $contentType = null; protected ?string $contentType = null;
/** @var string[] */
protected array $mandatoryAttributes = []; protected array $mandatoryAttributes = [];
public function __construct(string $url) public function __construct(string $url)
@ -35,7 +38,7 @@ abstract class AbstractController
{ {
if (!$this->validateJsonBody()) { if (!$this->validateJsonBody()) {
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST); $this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
$this->response->setParameter('success', false); $this->response->setSuccess(false);
$this->response->setMessage('The request body has not the required json attributes!'); $this->response->setMessage('The request body has not the required json attributes!');
} }
} }
@ -79,8 +82,8 @@ abstract class AbstractController
$hasPermission = $this->session->isAdmin() || $this->session->getUserId() === $userId; $hasPermission = $this->session->isAdmin() || $this->session->getUserId() === $userId;
if (!$hasPermission) { if (!$hasPermission) {
$this->response->setParameter('success', false); $this->response->setSuccess(false);
$this->response->setMessage('You don\'t have the permission to do that!'); $this->response->setMessage('You don\'t have the permission!');
$this->response->setStatus(ServerStatus::UNAUTHORIZED); $this->response->setStatus(ServerStatus::UNAUTHORIZED);
} }
@ -106,6 +109,8 @@ abstract class AbstractController
} }
} }
$this->jsonBody = $json;
return true; return true;
} catch (Throwable $e) { } catch (Throwable $e) {
return false; return false;

View File

@ -42,6 +42,14 @@ final class Fingerprint extends MySqlTable implements JsonSerializable
$this->setField(self::FIELD_USER, $userId); $this->setField(self::FIELD_USER, $userId);
} }
public function isSharedWith(int $userId): bool
{
return (bool)$this->database->Count(
Sharing::class,
[Sharing::FIELD_USER => $this->getUserId(), Sharing::FIELD_USER_SHARED => $userId]
);
}
public function jsonSerialize(): array public function jsonSerialize(): array
{ {
return [ return [

View File

@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
final class FingerprintCollection implements Iterator, JsonSerializable
{
private int $position = 0;
/** @var Fingerprint[] */
private array $fingerprints = [];
public function add(Fingerprint $fingerprint): void
{
$this->fingerprints[] = $fingerprint;
}
public function current(): Fingerprint
{
return $this->fingerprints[$this->position];
}
public function next(): void
{
$this->position++;
}
public function key(): int
{
return $this->position;
}
public function valid(): bool
{
return isset($this->fingerprints[$this->position]);
}
public function rewind(): void
{
$this->position = 0;
}
public function jsonSerialize(): array
{
$fingerprints = [];
foreach ($this->fingerprints as $fingerprint) {
$fingerprints[] = $fingerprint->jsonSerialize();
}
return $fingerprints;
}
}

View File

@ -132,12 +132,21 @@ final class User extends MySqlTable implements JsonSerializable
return $ids; return $ids;
} }
public function isSharingWith(int $userId): bool
{
return (bool)$this->database->Count(
Sharing::class,
[Sharing::FIELD_USER => $this->getUserId(), Sharing::FIELD_USER_SHARED => $userId]
);
}
public function jsonSerialize() public function jsonSerialize()
{ {
return [ return [
'userId' => $this->getUserId(), 'userId' => $this->getUserId(),
'username' => $this->getUsername(), 'username' => $this->getUsername(),
'jabberAddress' => $this->getJabberAddress(), 'jabberAddress' => $this->getJabberAddress(),
'isAdmin' => $this->isAdmin(),
'fingerprintIds' => $this->getFingerprintIds() 'fingerprintIds' => $this->getFingerprintIds()
]; ];
} }

View File

@ -8,6 +8,7 @@ CREATE TABLE User (
Password varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL, Password varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL,
Email varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL, Email varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
JabberAddress varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL, JabberAddress varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
IsAdmin BOOL NOT NULL DEFAULT 0,
PRIMARY KEY (UserId), PRIMARY KEY (UserId),
UNIQUE KEY Username (Username), UNIQUE KEY Username (Username),
UNIQUE KEY Email (Email), UNIQUE KEY Email (Email),