mirror of
https://github.com/netzbegruenung/circles.git
synced 2024-05-14 09:06:06 +02:00
fully importing mspt
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
This commit is contained in:
parent
2e14f5f034
commit
7f246a395c
418
lib/Tools/ActivityPub/NCSignature.php
Normal file
418
lib/Tools/ActivityPub/NCSignature.php
Normal file
|
@ -0,0 +1,418 @@
|
|||
<?php
|
||||
/*
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\ActivityPub;
|
||||
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use OC;
|
||||
use OCA\Circles\Tools\Exceptions\InvalidOriginException;
|
||||
use OCA\Circles\Tools\Exceptions\ItemNotFoundException;
|
||||
use OCA\Circles\Tools\Exceptions\MalformedArrayException;
|
||||
use OCA\Circles\Tools\Exceptions\SignatoryException;
|
||||
use OCA\Circles\Tools\Exceptions\SignatureException;
|
||||
use OCA\Circles\Tools\Model\NCRequest;
|
||||
use OCA\Circles\Tools\Model\NCSignatory;
|
||||
use OCA\Circles\Tools\Model\NCSignedRequest;
|
||||
use OCA\Circles\Tools\Model\SimpleDataStore;
|
||||
use OCA\Circles\Tools\Traits\TNCSignatory;
|
||||
use OCP\IRequest;
|
||||
|
||||
class NCSignature {
|
||||
|
||||
|
||||
const DATE_HEADER = 'D, d M Y H:i:s T';
|
||||
const DATE_OBJECT = 'Y-m-d\TH:i:s\Z';
|
||||
|
||||
const DATE_TTL = 300;
|
||||
|
||||
|
||||
use TNCSignatory;
|
||||
|
||||
|
||||
/** @var int */
|
||||
private $ttl = self::DATE_TTL;
|
||||
private $dateHeader = self::DATE_HEADER;
|
||||
|
||||
|
||||
/**
|
||||
* @param string $body
|
||||
*
|
||||
* @return NCSignedRequest
|
||||
* @throws InvalidOriginException
|
||||
* @throws MalformedArrayException
|
||||
* @throws SignatoryException
|
||||
* @throws SignatureException
|
||||
*/
|
||||
public function incomingSignedRequest(string $body = ''): NCSignedRequest {
|
||||
if ($body === '') {
|
||||
$body = file_get_contents('php://input');
|
||||
}
|
||||
|
||||
$this->debug('[<<] incoming', ['body' => $body]);
|
||||
|
||||
$signedRequest = new NCSignedRequest($body);
|
||||
$signedRequest->setIncomingRequest(OC::$server->get(IRequest::class));
|
||||
|
||||
$this->verifyIncomingRequestTime($signedRequest);
|
||||
$this->verifyIncomingRequestContent($signedRequest);
|
||||
$this->setIncomingSignatureHeader($signedRequest);
|
||||
$this->setIncomingClearSignature($signedRequest);
|
||||
$this->parseIncomingSignatureHeader($signedRequest);
|
||||
$this->verifyIncomingRequestSignature($signedRequest);
|
||||
|
||||
return $signedRequest;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCRequest $request
|
||||
* @param NCSignatory $signatory
|
||||
*
|
||||
* @return NCSignedRequest
|
||||
* @throws SignatoryException
|
||||
*/
|
||||
public function signOutgoingRequest(NCRequest $request, NCSignatory $signatory): NCSignedRequest {
|
||||
$signedRequest = new NCSignedRequest($request->getDataBody());
|
||||
$signedRequest->setOutgoingRequest($request)
|
||||
->setSignatory($signatory);
|
||||
|
||||
$this->setOutgoingSignatureHeader($signedRequest);
|
||||
$this->setOutgoingClearSignature($signedRequest);
|
||||
$this->setOutgoingSignedSignature($signedRequest);
|
||||
$this->signingOutgoingRequest($signedRequest);
|
||||
|
||||
return $signedRequest;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*
|
||||
* @throws SignatureException
|
||||
*/
|
||||
private function verifyIncomingRequestTime(NCSignedRequest $signedRequest): void {
|
||||
$request = $signedRequest->getIncomingRequest();
|
||||
|
||||
try {
|
||||
$dTime = new DateTime($request->getHeader('date'));
|
||||
$signedRequest->setTime($dTime->getTimestamp());
|
||||
} catch (Exception $e) {
|
||||
$this->e($e, ['header' => $request->getHeader('date')]);
|
||||
throw new SignatureException('datetime exception');
|
||||
}
|
||||
|
||||
if ($signedRequest->getTime() < (time() - $this->ttl)) {
|
||||
throw new SignatureException('object is too old');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*
|
||||
* @throws SignatureException
|
||||
*/
|
||||
private function verifyIncomingRequestContent(NCSignedRequest $signedRequest): void {
|
||||
$request = $signedRequest->getIncomingRequest();
|
||||
|
||||
if (strlen($signedRequest->getBody()) !== (int)$request->getHeader('content-length')) {
|
||||
throw new SignatureException('issue with content-length');
|
||||
}
|
||||
|
||||
if ($request->getHeader('digest') !== ''
|
||||
&& $signedRequest->getDigest() !== $request->getHeader('digest')) {
|
||||
throw new SignatureException('issue with digest');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*/
|
||||
private function setIncomingSignatureHeader(NCSignedRequest $signedRequest): void {
|
||||
$sign = [];
|
||||
$request = $signedRequest->getIncomingRequest();
|
||||
foreach (explode(',', $request->getHeader('Signature')) as $entry) {
|
||||
if ($entry === '' || !strpos($entry, '=')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
list($k, $v) = explode('=', $entry, 2);
|
||||
preg_match('/"([^"]+)"/', $v, $varr);
|
||||
if ($varr[0] !== null) {
|
||||
$v = trim($varr[0], '"');
|
||||
}
|
||||
$sign[$k] = $v;
|
||||
}
|
||||
|
||||
$signedRequest->setSignatureHeader(new SimpleDataStore($sign));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*
|
||||
* @throws SignatureException
|
||||
*/
|
||||
private function setIncomingClearSignature(NCSignedRequest $signedRequest): void {
|
||||
$request = $signedRequest->getIncomingRequest();
|
||||
$headers = explode(' ', $signedRequest->getSignatureHeader()->g('headers'));
|
||||
|
||||
$enforceHeaders = array_merge(
|
||||
['content-length', 'date', 'host'],
|
||||
$this->setupArray('enforceSignatureHeaders')
|
||||
);
|
||||
if (!empty(array_diff($enforceHeaders, $headers))) {
|
||||
throw new SignatureException('missing elements in \'headers\'');
|
||||
}
|
||||
|
||||
$target = strtolower($request->getMethod()) . " " . $request->getRequestUri();
|
||||
$estimated = ['(request-target): ' . $target];
|
||||
|
||||
foreach ($headers as $key) {
|
||||
$value = $request->getHeader($key);
|
||||
if (strtolower($key) === 'host') {
|
||||
$value = $signedRequest->getIncomingRequest()->getServerHost();
|
||||
}
|
||||
if ($value === '') {
|
||||
throw new SignatureException('empty elements in \'headers\'');
|
||||
}
|
||||
|
||||
$estimated[] = $key . ': ' . $value;
|
||||
}
|
||||
$signedRequest->setClearSignature(implode("\n", $estimated));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*
|
||||
* @throws MalformedArrayException
|
||||
* @throws InvalidOriginException
|
||||
*/
|
||||
private function parseIncomingSignatureHeader(NCSignedRequest $signedRequest): void {
|
||||
$data = $signedRequest->getSignatureHeader();
|
||||
$data->hasKeys(['keyId', 'headers', 'signature'], true);
|
||||
|
||||
$signedRequest->setOrigin($this->getKeyOrigin($data->g('keyId')));
|
||||
$signedRequest->setSignedSignature($data->g('signature'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*
|
||||
* @throws SignatoryException
|
||||
* @throws SignatureException
|
||||
*/
|
||||
private function verifyIncomingRequestSignature(NCSignedRequest $signedRequest) {
|
||||
$data = $signedRequest->getSignatureHeader();
|
||||
|
||||
try {
|
||||
$signedRequest->setSignatory($this->retrieveSignatory($data->g('keyId'), false));
|
||||
$this->verifySignedRequest($signedRequest);
|
||||
} catch (SignatoryException $e) {
|
||||
$signedRequest->setSignatory($this->retrieveSignatory($data->g('keyId'), true));
|
||||
$this->verifySignedRequest($signedRequest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*
|
||||
* @throws SignatureException
|
||||
*/
|
||||
private function verifySignedRequest(NCSignedRequest $signedRequest) {
|
||||
$publicKey = $signedRequest->getSignatory()->getPublicKey();
|
||||
if ($publicKey === '') {
|
||||
throw new SignatureException('empty public key');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->verifyString(
|
||||
$signedRequest->getClearSignature(),
|
||||
base64_decode($signedRequest->getSignedSignature()),
|
||||
$publicKey,
|
||||
$this->getUsedEncryption($signedRequest)
|
||||
);
|
||||
} catch (SignatureException $e) {
|
||||
$this->debug('signature issue', ['signed' => $signedRequest]);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*/
|
||||
private function setOutgoingSignatureHeader(NCSignedRequest $signedRequest): void {
|
||||
$request = $signedRequest->getOutgoingRequest();
|
||||
|
||||
$data = new SimpleDataStore();
|
||||
$data->s('(request-target)', NCRequest::method($request->getType()) . ' ' . $request->getPath())
|
||||
->sInt('content-length', strlen($signedRequest->getBody()))
|
||||
->s('date', gmdate($this->dateHeader))
|
||||
->s('digest', $signedRequest->getDigest())
|
||||
->s('host', $request->getHost());
|
||||
|
||||
$signedRequest->setSignatureHeader($data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*/
|
||||
private function setOutgoingClearSignature(NCSignedRequest $signedRequest): void {
|
||||
$signing = [];
|
||||
$data = $signedRequest->getSignatureHeader();
|
||||
foreach ($data->keys() as $element) {
|
||||
try {
|
||||
$value = $data->gItem($element);
|
||||
$signing[] = $element . ': ' . $value;
|
||||
if ($element !== '(request-target)') {
|
||||
$signedRequest->getOutgoingRequest()->addHeader($element, $value);
|
||||
}
|
||||
} catch (ItemNotFoundException $e) {
|
||||
}
|
||||
}
|
||||
|
||||
$signedRequest->setClearSignature(implode("\n", $signing));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*
|
||||
* @throws SignatoryException
|
||||
*/
|
||||
private function setOutgoingSignedSignature(NCSignedRequest $signedRequest): void {
|
||||
$clear = $signedRequest->getClearSignature();
|
||||
$signed = $this->signString($clear, $signedRequest->getSignatory());
|
||||
$signedRequest->setSignedSignature($signed);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function signingOutgoingRequest(NCSignedRequest $signedRequest): void {
|
||||
$headers = array_diff($signedRequest->getSignatureHeader()->keys(), ['(request-target)']);
|
||||
$signatory = $signedRequest->getSignatory();
|
||||
$signatureElements = [
|
||||
'keyId="' . $signatory->getKeyId() . '"',
|
||||
'algorithm="' . $this->getChosenEncryption($signatory) . '"',
|
||||
'headers="' . implode(' ', $headers) . '"',
|
||||
'signature="' . $signedRequest->getSignedSignature() . '"'
|
||||
];
|
||||
|
||||
$signedRequest->getOutgoingRequest()->addHeader('Signature', implode(',', $signatureElements));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignedRequest $signedRequest
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getUsedEncryption(NCSignedRequest $signedRequest): string {
|
||||
switch ($signedRequest->getSignatureHeader()->g('algorithm')) {
|
||||
case 'rsa-sha512':
|
||||
return NCSignatory::SHA512;
|
||||
|
||||
case 'rsa-sha256':
|
||||
default:
|
||||
return NCSignatory::SHA256;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param NCSignatory $signatory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getChosenEncryption(NCSignatory $signatory): string {
|
||||
switch ($signatory->getAlgorithm()) {
|
||||
case NCSignatory::SHA512:
|
||||
return 'ras-sha512';
|
||||
|
||||
case NCSignatory::SHA256:
|
||||
default:
|
||||
return 'ras-sha256';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignatory $signatory
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getOpenSSLAlgo(NCSignatory $signatory): int {
|
||||
switch ($signatory->getAlgorithm()) {
|
||||
case NCSignatory::SHA512:
|
||||
return OPENSSL_ALGO_SHA512;
|
||||
|
||||
case NCSignatory::SHA256:
|
||||
default:
|
||||
return OPENSSL_ALGO_SHA256;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
1166
lib/Tools/Db/ExtendedQueryBuilder.php
Normal file
1166
lib/Tools/Db/ExtendedQueryBuilder.php
Normal file
File diff suppressed because it is too large
Load diff
49
lib/Tools/Db/IQueryRow.php
Normal file
49
lib/Tools/Db/IQueryRow.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Db;
|
||||
|
||||
/**
|
||||
* Interface IQueryRow
|
||||
*
|
||||
* @package OCA\Circles\Tools\Db
|
||||
*/
|
||||
interface IQueryRow {
|
||||
|
||||
/**
|
||||
* import data to feed the model.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return IQueryRow
|
||||
*/
|
||||
public function importFromDatabase(array $data): self;
|
||||
}
|
42
lib/Tools/Exceptions/ArrayNotFoundException.php
Normal file
42
lib/Tools/Exceptions/ArrayNotFoundException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class ArrayNotFoundException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class ArrayNotFoundException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/DateTimeException.php
Normal file
42
lib/Tools/Exceptions/DateTimeException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class DateTimeException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class DateTimeException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/InvalidItemException.php
Normal file
42
lib/Tools/Exceptions/InvalidItemException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class InvalidItemException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class InvalidItemException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/InvalidOriginException.php
Normal file
42
lib/Tools/Exceptions/InvalidOriginException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class InvalidOriginException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class InvalidOriginException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/ItemNotFoundException.php
Normal file
42
lib/Tools/Exceptions/ItemNotFoundException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class ItemNotFoundException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class ItemNotFoundException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/MalformedArrayException.php
Normal file
42
lib/Tools/Exceptions/MalformedArrayException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class MalformedArrayException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class MalformedArrayException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/RequestContentException.php
Normal file
42
lib/Tools/Exceptions/RequestContentException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class RequestContentException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class RequestContentException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/RequestNetworkException.php
Normal file
42
lib/Tools/Exceptions/RequestNetworkException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class RequestNetworkException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class RequestNetworkException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/RequestResultNotJsonException.php
Normal file
42
lib/Tools/Exceptions/RequestResultNotJsonException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class RequestResultNotJsonException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class RequestResultNotJsonException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/RequestResultSizeException.php
Normal file
42
lib/Tools/Exceptions/RequestResultSizeException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class RequestResultSizeException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class RequestResultSizeException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/RequestServerException.php
Normal file
42
lib/Tools/Exceptions/RequestServerException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class RequestServerException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class RequestServerException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/RowNotFoundException.php
Normal file
42
lib/Tools/Exceptions/RowNotFoundException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class RowNotFoundException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class RowNotFoundException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/SignatoryException.php
Normal file
42
lib/Tools/Exceptions/SignatoryException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class SignatoryException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class SignatoryException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/SignatureException.php
Normal file
42
lib/Tools/Exceptions/SignatureException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class SignatureException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class SignatureException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/UnknownTypeException.php
Normal file
42
lib/Tools/Exceptions/UnknownTypeException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class UnknownTypeException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class UnknownTypeException extends Exception {
|
||||
}
|
42
lib/Tools/Exceptions/WellKnownLinkNotFoundException.php
Normal file
42
lib/Tools/Exceptions/WellKnownLinkNotFoundException.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class WellKnownLinkNotFoundException
|
||||
*
|
||||
* @package OCA\Circles\Tools\Exceptions
|
||||
*/
|
||||
class WellKnownLinkNotFoundException extends Exception {
|
||||
}
|
42
lib/Tools/IDeserializable.php
Normal file
42
lib/Tools/IDeserializable.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools;
|
||||
|
||||
interface IDeserializable {
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function import(array $data): self;
|
||||
}
|
176
lib/Tools/Model/NCRequest.php
Normal file
176
lib/Tools/Model/NCRequest.php
Normal file
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Model;
|
||||
|
||||
|
||||
use OCP\Http\Client\IClient;
|
||||
|
||||
class NCRequest extends Request {
|
||||
|
||||
|
||||
/** @var IClient */
|
||||
private $client;
|
||||
|
||||
/** @var array */
|
||||
private $clientOptions = [];
|
||||
|
||||
/** @var bool */
|
||||
private $localAddressAllowed = false;
|
||||
|
||||
/** @var NCRequestResult */
|
||||
private $result;
|
||||
|
||||
/** @var NCRequestResult[] */
|
||||
private $previousResults = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param IClient $client
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setClient(IClient $client): self {
|
||||
$this->client = $client;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IClient
|
||||
*/
|
||||
public function getClient(): IClient {
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getClientOptions(): array {
|
||||
return $this->clientOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $clientOptions
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setClientOptions(array $clientOptions): self {
|
||||
$this->clientOptions = $clientOptions;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isLocalAddressAllowed(): bool {
|
||||
return $this->localAddressAllowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $allowed
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setLocalAddressAllowed(bool $allowed): self {
|
||||
$this->localAddressAllowed = $allowed;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasResult(): bool {
|
||||
return ($this->result !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NCRequestResult
|
||||
*/
|
||||
public function getResult(): NCRequestResult {
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param NCRequestResult $result
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setResult(NCRequestResult $result): self {
|
||||
if (!is_null($this->result)) {
|
||||
$this->previousResults[] = $this->result;
|
||||
}
|
||||
|
||||
$this->result = $result;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NCRequestResult[]
|
||||
*/
|
||||
public function getPreviousResults(): array {
|
||||
return $this->previousResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NCRequestResult[]
|
||||
*/
|
||||
public function getAllResults(): array {
|
||||
return array_values(array_merge([$this->getResult()], $this->previousResults));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize(): array {
|
||||
$result = null;
|
||||
if ($this->hasResult()) {
|
||||
$result = $this->getResult();
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
parent::jsonSerialize(),
|
||||
[
|
||||
'clientOptions' => $this->getClientOptions(),
|
||||
'localAddressAllowed' => $this->isLocalAddressAllowed(),
|
||||
'result' => $result
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
325
lib/Tools/Model/NCRequestResult.php
Normal file
325
lib/Tools/Model/NCRequestResult.php
Normal file
|
@ -0,0 +1,325 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Model;
|
||||
|
||||
|
||||
use GuzzleHttp\Exception\BadResponseException;
|
||||
use JsonSerializable;
|
||||
use OCA\Circles\Tools\Exceptions\RequestContentException;
|
||||
use OCA\Circles\Tools\Traits\TArrayTools;
|
||||
use OCP\Http\Client\IResponse;
|
||||
|
||||
class NCRequestResult implements JsonSerializable {
|
||||
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
const TYPE_STRING = 0;
|
||||
const TYPE_BINARY = 1;
|
||||
const TYPE_JSON = 2;
|
||||
const TYPE_XRD = 3;
|
||||
|
||||
|
||||
/** @var int */
|
||||
private $statusCode = 0;
|
||||
|
||||
/** @var array */
|
||||
private $headers = [];
|
||||
|
||||
/** @var mixed */
|
||||
private $content;
|
||||
|
||||
/** @var array */
|
||||
private $contentAsArray = [];
|
||||
|
||||
/** @var int */
|
||||
private $contentType = 0;
|
||||
|
||||
/** @var BadResponseException */
|
||||
private $exception = null;
|
||||
|
||||
|
||||
/**
|
||||
* NCRequestResult constructor.
|
||||
*
|
||||
* @param IResponse|null $response
|
||||
* @param BadResponseException|null $e
|
||||
*/
|
||||
public function __construct(?IResponse $response, ?BadResponseException $e = null) {
|
||||
if (!is_null($response)) {
|
||||
$this->setStatusCode($response->getStatusCode());
|
||||
$this->setContent($response->getBody());
|
||||
$this->setHeaders($response->getHeaders());
|
||||
}
|
||||
|
||||
if (!is_null($e)) {
|
||||
$this->setException($e);
|
||||
}
|
||||
|
||||
$this->generateMeta();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStatusCode(): int {
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $statusCode
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setStatusCode(int $statusCode): self {
|
||||
$this->statusCode = $statusCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders(): array {
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $headers
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setHeaders(array $headers): self {
|
||||
$this->headers = $headers;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeader(string $key): array {
|
||||
return $this->getArray($key, $this->headers);
|
||||
}
|
||||
|
||||
public function withinHeader(string $key, string $needle): bool {
|
||||
foreach ($this->getHeader($key) as $header) {
|
||||
if (strpos($header, $needle) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setContent(string $content): self {
|
||||
$this->content = $content;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws RequestContentException
|
||||
*/
|
||||
public function getContent(): string {
|
||||
if (is_null($this->content) || !is_string($this->content)) {
|
||||
throw new RequestContentException();
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAsArray(): array {
|
||||
if (empty($this->contentAsArray)) {
|
||||
$this->generateContentAsArray();
|
||||
}
|
||||
|
||||
return $this->contentAsArray;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBinary() {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getContentType(): int {
|
||||
return $this->contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setContentType(int $type): self {
|
||||
$this->contentType = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isContentType(int $type): bool {
|
||||
return ($this->contentType === $type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function generateMeta(): void {
|
||||
$this->setContentType($this->discoverContentType());
|
||||
$this->generateContentAsArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function discoverContentType(): int {
|
||||
if ($this->withinHeader('Content-Type', 'application/xrd')) {
|
||||
return self::TYPE_XRD;
|
||||
}
|
||||
|
||||
if ($this->withinHeader('Content-Type', 'application/json')
|
||||
|| $this->withinHeader('Content-Type', 'application/jrd')
|
||||
) {
|
||||
return self::TYPE_JSON;
|
||||
}
|
||||
|
||||
try {
|
||||
$content = $this->getContent();
|
||||
} catch (RequestContentException $e) {
|
||||
return self::TYPE_BINARY;
|
||||
}
|
||||
|
||||
// in case header failure
|
||||
$arr = json_decode($content, true);
|
||||
if (is_array($arr)) {
|
||||
return self::TYPE_JSON;
|
||||
}
|
||||
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function generateContentAsArray(): void {
|
||||
try {
|
||||
$content = $this->getContent();
|
||||
if ($this->isContentType(self::TYPE_XRD)) {
|
||||
$xml = simplexml_load_string($content);
|
||||
$content = json_encode($xml, JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
$arr = json_decode($content, true);
|
||||
if (is_array($arr)) {
|
||||
$this->contentAsArray = $arr;
|
||||
}
|
||||
} catch (RequestContentException $e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param BadResponseException $e
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setException(BadResponseException $e): self {
|
||||
$this->exception = $e;
|
||||
$this->setStatusCode($e->getResponse()->getStatusCode());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BadResponseException
|
||||
*/
|
||||
public function getException(): BadResponseException {
|
||||
return $this->exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasException(): bool {
|
||||
return (!is_null($this->exception));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize(): array {
|
||||
try {
|
||||
$content = $this->getContent();
|
||||
} catch (RequestContentException $e) {
|
||||
$content = 'not a string';
|
||||
}
|
||||
|
||||
return [
|
||||
'statusCode' => $this->getStatusCode(),
|
||||
'headers' => $this->getHeaders(),
|
||||
'content' => $content,
|
||||
'contentAsArray' => $this->contentAsArray,
|
||||
'contentType' => $this->getContentType()
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
297
lib/Tools/Model/NCSignatory.php
Normal file
297
lib/Tools/Model/NCSignatory.php
Normal file
|
@ -0,0 +1,297 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Model;
|
||||
|
||||
|
||||
use JsonSerializable;
|
||||
use OCA\Circles\Tools\Traits\TArrayTools;
|
||||
|
||||
class NCSignatory implements JsonSerializable {
|
||||
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
const SHA256 = 'sha256';
|
||||
const SHA512 = 'sha512';
|
||||
|
||||
|
||||
/** @var string */
|
||||
private $instance = '';
|
||||
|
||||
/** @var string */
|
||||
private $id = '';
|
||||
|
||||
/** @var string */
|
||||
private $keyOwner = '';
|
||||
|
||||
/** @var string */
|
||||
private $keyId = '';
|
||||
|
||||
/** @var string */
|
||||
private $publicKey = '';
|
||||
|
||||
/** @var string */
|
||||
private $privateKey = '';
|
||||
|
||||
/** @var array */
|
||||
private $origData = [];
|
||||
|
||||
/** @var string */
|
||||
private $algorithm = self::SHA256;
|
||||
|
||||
|
||||
/**
|
||||
* NC22Signatory constructor.
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
public function __construct(string $id = '') {
|
||||
$this->id = self::removeFragment($id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $instance
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setInstance(string $instance): self {
|
||||
$this->instance = $instance;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getInstance(): string {
|
||||
return $this->instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getOrigData(): array {
|
||||
return $this->origData;
|
||||
}
|
||||
|
||||
/**
|
||||
* /**
|
||||
* @param array $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOrigData(array $data): self {
|
||||
$this->origData = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getId(): string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setId(string $id): self {
|
||||
$this->id = $id;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $keyId
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setKeyId(string $keyId): self {
|
||||
$this->keyId = $keyId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getKeyId(): string {
|
||||
return $this->keyId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $keyOwner
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setKeyOwner(string $keyOwner): self {
|
||||
$this->keyOwner = $keyOwner;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getKeyOwner(): string {
|
||||
return $this->keyOwner;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $publicKey
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPublicKey(string $publicKey): self {
|
||||
$this->publicKey = $publicKey;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $privateKey
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPrivateKey(string $privateKey): self {
|
||||
$this->privateKey = $privateKey;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPublicKey(): string {
|
||||
return $this->publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPrivateKey(): string {
|
||||
return $this->privateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPublicKey(): bool {
|
||||
return ($this->publicKey !== '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPrivateKey(): bool {
|
||||
return ($this->privateKey !== '');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $algorithm
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setAlgorithm(string $algorithm): self {
|
||||
$this->algorithm = $algorithm;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAlgorithm(): string {
|
||||
return $this->algorithm;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function import(array $data): self {
|
||||
if ($this->getId() === '') {
|
||||
$this->setId($this->get('id', $data));
|
||||
}
|
||||
|
||||
$this->setKeyId($this->get('publicKey.id', $data));
|
||||
$this->setKeyOwner($this->get('publicKey.owner', $data));
|
||||
$this->setPublicKey($this->get('publicKey.publicKeyPem', $data));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize(): array {
|
||||
return [
|
||||
'id' => $this->getId(),
|
||||
'publicKey' =>
|
||||
[
|
||||
'id' => $this->getKeyId(),
|
||||
'owner' => $this->getKeyOwner(),
|
||||
'publicKeyPem' => $this->getPublicKey()
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function removeFragment(string $id): string {
|
||||
$temp = strtok($id, '#');
|
||||
if (is_string($temp)) {
|
||||
$id = $temp;
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
}
|
||||
|
351
lib/Tools/Model/NCSignedRequest.php
Normal file
351
lib/Tools/Model/NCSignedRequest.php
Normal file
|
@ -0,0 +1,351 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Model;
|
||||
|
||||
|
||||
use JsonSerializable;
|
||||
use OCP\IRequest;
|
||||
|
||||
class NCSignedRequest implements JsonSerializable {
|
||||
|
||||
|
||||
/** @var string */
|
||||
private $body = '';
|
||||
|
||||
/** @var int */
|
||||
private $time = 0;
|
||||
|
||||
/** @var IRequest */
|
||||
private $incomingRequest;
|
||||
|
||||
/** @var NCRequest */
|
||||
private $outgoingRequest;
|
||||
|
||||
/** @var string */
|
||||
private $origin = '';
|
||||
|
||||
/** @var string */
|
||||
private $digest = '';
|
||||
|
||||
/** @var SimpleDataStore */
|
||||
private $signatureHeader;
|
||||
|
||||
/** @var string */
|
||||
private $host = '';
|
||||
|
||||
/** @var string */
|
||||
private $clearSignature = '';
|
||||
|
||||
/** @var string */
|
||||
private $signedSignature = '';
|
||||
|
||||
/** @var NCSignatory */
|
||||
private $signatory;
|
||||
|
||||
|
||||
public function __construct(string $body = '') {
|
||||
$this->setBody($body);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* IRequest of the incoming request
|
||||
* incoming
|
||||
*
|
||||
* @return IRequest
|
||||
*/
|
||||
public function getIncomingRequest(): IRequest {
|
||||
return $this->incomingRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IRequest $request
|
||||
*
|
||||
* @return NCSignedRequest
|
||||
*/
|
||||
public function setIncomingRequest(IRequest $request): self {
|
||||
$this->incomingRequest = $request;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NCRequest of the outgoing request
|
||||
* outgoing
|
||||
*
|
||||
* @param NCRequest $request
|
||||
*
|
||||
* @return NCSignedRequest
|
||||
*/
|
||||
public function setOutgoingRequest(NCRequest $request): self {
|
||||
$this->outgoingRequest = $request;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NCRequest
|
||||
*/
|
||||
public function getOutgoingRequest(): NCRequest {
|
||||
return $this->outgoingRequest;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Body content of the request
|
||||
* incoming/outgoing
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBody(): string {
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $body
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setBody(string $body): self {
|
||||
$this->body = $body;
|
||||
$this->setDigest('SHA-256=' . base64_encode(hash("sha256", utf8_encode($body), true)));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Timestamp of the request
|
||||
* incoming (outgoing ?)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTime(): int {
|
||||
return $this->time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $time
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setTime(int $time): self {
|
||||
$this->time = $time;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Origin of the request, based on the keyId
|
||||
* incoming
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOrigin(): string {
|
||||
return $this->origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $origin
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setOrigin(string $origin): self {
|
||||
$this->origin = $origin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDigest(): string {
|
||||
return $this->digest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $digest
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDigest(string $digest): self {
|
||||
$this->digest = $digest;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Data from the 'Signature' header
|
||||
* incoming/outgoing
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function getSignatureHeader(): SimpleDataStore {
|
||||
return $this->signatureHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SimpleDataStore $signatureHeader
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setSignatureHeader(SimpleDataStore $signatureHeader): self {
|
||||
$this->signatureHeader = $signatureHeader;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* _Clear_ value of the Signature.
|
||||
* incoming/outgoing
|
||||
*
|
||||
* - estimated signature on incoming request
|
||||
* - generated signature on outgoing request
|
||||
*
|
||||
* @param string $clearSignature
|
||||
*
|
||||
* @return NCSignedRequest
|
||||
*/
|
||||
public function setClearSignature(string $clearSignature): self {
|
||||
$this->clearSignature = $clearSignature;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClearSignature(): string {
|
||||
return $this->clearSignature;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* _Signed_ value of the signature.
|
||||
* /!\ base64_encoded, not RAW /!\
|
||||
*
|
||||
* incoming/outgoing
|
||||
*
|
||||
* @param string $signedSignature
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setSignedSignature(string $signedSignature): self {
|
||||
$this->signedSignature = $signedSignature;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSignedSignature(): string {
|
||||
return $this->signedSignature;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Host/Address to be used in the signature.
|
||||
* incoming/outgoing
|
||||
*
|
||||
* - incoming should set the local address
|
||||
* - outgoing should set the recipient address
|
||||
*
|
||||
* @param string $host
|
||||
*
|
||||
* @return NCSignedRequest
|
||||
*/
|
||||
public function setHost(string $host): self {
|
||||
$this->host = $host;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHost(): string {
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Signatory used to sign the request
|
||||
* incoming/outgoing
|
||||
*
|
||||
* @param NCSignatory $signatory
|
||||
*/
|
||||
public function setSignatory(NCSignatory $signatory): void {
|
||||
$this->signatory = $signatory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NCSignatory
|
||||
*/
|
||||
public function getSignatory(): NCSignatory {
|
||||
return $this->signatory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasSignatory(): bool {
|
||||
return ($this->signatory !== null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize(): array {
|
||||
return [
|
||||
'body' => $this->getBody(),
|
||||
'time' => $this->getTime(),
|
||||
'incomingRequest' => ($this->incomingRequest !== null),
|
||||
'outgoingRequest' => $this->outgoingRequest !== null ? $this->getOutgoingRequest() : false,
|
||||
'origin' => $this->getOrigin(),
|
||||
'digest' => $this->getDigest(),
|
||||
'signatureHeader' => ($this->signatureHeader !== null) ? $this->getSignatureHeader() : false,
|
||||
'host' => $this->getHost(),
|
||||
'clearSignature' => $this->getClearSignature(),
|
||||
'signedSignature' => base64_encode($this->getSignedSignature()),
|
||||
'signatory' => ($this->hasSignatory()) ? $this->getSignatory() : false,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
201
lib/Tools/Model/NCWebfinger.php
Normal file
201
lib/Tools/Model/NCWebfinger.php
Normal file
|
@ -0,0 +1,201 @@
|
|||
<?php
|
||||
/*
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Model;
|
||||
|
||||
|
||||
use JsonSerializable;
|
||||
use OCA\Circles\Tools\Traits\TArrayTools;
|
||||
|
||||
class NCWebfinger implements JsonSerializable {
|
||||
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
/** @var string */
|
||||
private $subject = '';
|
||||
|
||||
/** @var array */
|
||||
private $aliases = [];
|
||||
|
||||
/** @var array */
|
||||
private $properties = [];
|
||||
|
||||
/** @var NCWellKnownLink[] */
|
||||
private $links = [];
|
||||
|
||||
|
||||
/**
|
||||
* NC22Webfinger constructor.
|
||||
*
|
||||
* @param array $json
|
||||
*/
|
||||
public function __construct(array $json = []) {
|
||||
$this->setSubject($this->get('subject', $json));
|
||||
$this->setAliases($this->getArray('subject', $json));
|
||||
$this->setProperties($this->getArray('properties', $json));
|
||||
|
||||
foreach ($this->getArray('links', $json) as $link) {
|
||||
$this->addLink(new NCWellKnownLink($link));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSubject(): string {
|
||||
return $this->subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $subject
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setSubject(string $subject): self {
|
||||
$this->subject = $subject;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAliases(): array {
|
||||
return $this->aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aliases
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setAliases(array $aliases): self {
|
||||
$this->aliases = $aliases;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getProperties(): array {
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $properties
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setProperties(array $properties): self {
|
||||
$this->properties = $properties;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProperty(string $key): string {
|
||||
return $this->get($key, $this->properties);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return NCWellKnownLink[]
|
||||
*/
|
||||
public function getLinks(): array {
|
||||
return $this->links;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param NCWellKnownLink[] $links
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setLinks(array $links): self {
|
||||
$this->links = $links;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addLink(NCWellKnownLink $link): self {
|
||||
$this->links[] = $link;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize(): array {
|
||||
return array_filter(
|
||||
[
|
||||
'subject' => $this->getSubject(),
|
||||
'aliases' => $this->getAliases(),
|
||||
'properties' => $this->getProperties(),
|
||||
'links' => $this->getLinks()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
226
lib/Tools/Model/NCWellKnownLink.php
Normal file
226
lib/Tools/Model/NCWellKnownLink.php
Normal file
|
@ -0,0 +1,226 @@
|
|||
<?php
|
||||
/*
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Model;
|
||||
|
||||
|
||||
use JsonSerializable;
|
||||
use OCA\Circles\Tools\Traits\TArrayTools;
|
||||
|
||||
class NCWellKnownLink implements JsonSerializable {
|
||||
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
/** @var string */
|
||||
private $rel = '';
|
||||
|
||||
/** @var string */
|
||||
private $type = '';
|
||||
|
||||
/** @var string */
|
||||
private $href = '';
|
||||
|
||||
/** @var array */
|
||||
private $titles = [];
|
||||
|
||||
/** @var array */
|
||||
private $properties = [];
|
||||
|
||||
|
||||
/**
|
||||
* NC22WellKnownLink constructor.
|
||||
*
|
||||
* @param array $json
|
||||
*/
|
||||
public function __construct(array $json = []) {
|
||||
$this->setRel($this->get('rel', $json));
|
||||
$this->setType($this->get('type', $json));
|
||||
$this->setHref($this->get('href', $json));
|
||||
$this->setTitles($this->getArray('titles', $json));
|
||||
$this->setProperties($this->getArray('properties', $json));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRel(): string {
|
||||
return $this->rel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $rel
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setRel(string $rel): self {
|
||||
$this->rel = $rel;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setType(string $type): self {
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHref(): string {
|
||||
return $this->href;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $href
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setHref(string $href): self {
|
||||
$this->href = $href;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTitles(): array {
|
||||
return $this->titles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $titles
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setTitles(array $titles): self {
|
||||
$this->titles = $titles;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(string $key): string {
|
||||
return $this->get($key, $this->properties);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getProperties(): array {
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $properties
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setProperties(array $properties): self {
|
||||
$this->properties = $properties;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProperty(string $key): string {
|
||||
return $this->get($key, $this->properties);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize(): array {
|
||||
return array_filter(
|
||||
[
|
||||
'rel' => $this->getRel(),
|
||||
'type' => $this->getType(),
|
||||
'href' => $this->getHref(),
|
||||
'titles' => $this->getTitles(),
|
||||
'properties' => $this->getProperties()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
836
lib/Tools/Model/Request.php
Normal file
836
lib/Tools/Model/Request.php
Normal file
|
@ -0,0 +1,836 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Model;
|
||||
|
||||
|
||||
use JsonSerializable;
|
||||
use OCA\Circles\Tools\Traits\TArrayTools;
|
||||
|
||||
class Request implements JsonSerializable {
|
||||
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
const TYPE_GET = 0;
|
||||
const TYPE_POST = 1;
|
||||
const TYPE_PUT = 2;
|
||||
const TYPE_DELETE = 3;
|
||||
|
||||
|
||||
const QS_VAR_DUPLICATE = 1;
|
||||
const QS_VAR_ARRAY = 2;
|
||||
|
||||
|
||||
/** @var string */
|
||||
private $protocol = '';
|
||||
|
||||
/** @var array */
|
||||
private $protocols = ['https'];
|
||||
|
||||
/** @var string */
|
||||
private $host = '';
|
||||
|
||||
/** @var int */
|
||||
private $port = 0;
|
||||
|
||||
/** @var string */
|
||||
private $url = '';
|
||||
|
||||
/** @var string */
|
||||
private $baseUrl = '';
|
||||
|
||||
/** @var int */
|
||||
private $type = 0;
|
||||
|
||||
/** @var bool */
|
||||
private $binary = false;
|
||||
|
||||
/** @var bool */
|
||||
private $verifyPeer = true;
|
||||
|
||||
/** @var bool */
|
||||
private $httpErrorsAllowed = false;
|
||||
|
||||
/** @var bool */
|
||||
private $followLocation = true;
|
||||
|
||||
/** @var array */
|
||||
private $headers = [];
|
||||
|
||||
/** @var array */
|
||||
private $cookies = [];
|
||||
|
||||
/** @var array */
|
||||
private $params = [];
|
||||
|
||||
/** @var array */
|
||||
private $data = [];
|
||||
|
||||
/** @var int */
|
||||
private $queryStringType = self::QS_VAR_DUPLICATE;
|
||||
|
||||
/** @var int */
|
||||
private $timeout = 10;
|
||||
|
||||
/** @var string */
|
||||
private $userAgent = '';
|
||||
|
||||
/** @var int */
|
||||
private $resultCode = 0;
|
||||
|
||||
/** @var string */
|
||||
private $contentType = '';
|
||||
|
||||
|
||||
/**
|
||||
* Request constructor.
|
||||
*
|
||||
* @param string $url
|
||||
* @param int $type
|
||||
* @param bool $binary
|
||||
*/
|
||||
public function __construct(string $url = '', int $type = 0, bool $binary = false) {
|
||||
$this->url = $url;
|
||||
$this->type = $type;
|
||||
$this->binary = $binary;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $protocol
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setProtocol(string $protocol): Request {
|
||||
$this->protocols = [$protocol];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $protocols
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setProtocols(array $protocols): Request {
|
||||
$this->protocols = $protocols;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getProtocols(): array {
|
||||
return $this->protocols;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUsedProtocol(): string {
|
||||
return $this->protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $protocol
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setUsedProtocol(string $protocol): Request {
|
||||
$this->protocol = $protocol;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @deprecated - 19 - use getHost();
|
||||
*/
|
||||
public function getAddress(): string {
|
||||
return $this->getHost();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $address
|
||||
*
|
||||
* @return Request
|
||||
* @deprecated - 19 - use setHost();
|
||||
*/
|
||||
public function setAddress(string $address): Request {
|
||||
$this->setHost($address);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHost(): string {
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setHost(string $host): Request {
|
||||
$this->host = $host;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPort(): int {
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $port
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setPort(int $port): Request {
|
||||
$this->port = $port;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $instance
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setInstance(string $instance): Request {
|
||||
if (strpos($instance, ':') === false) {
|
||||
$this->setHost($instance);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
list($host, $port) = explode(':', $instance, 2);
|
||||
$this->setHost($host);
|
||||
if ($port !== '') {
|
||||
$this->setPort((int)$port);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getInstance(): string {
|
||||
$instance = $this->getHost();
|
||||
if ($this->getPort() > 0) {
|
||||
$instance .= ':' . $this->getPort();
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @deprecated - 19 - use basedOnUrl();
|
||||
*/
|
||||
public function setAddressFromUrl(string $url) {
|
||||
$this->basedOnUrl($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*/
|
||||
public function basedOnUrl(string $url) {
|
||||
$protocol = parse_url($url, PHP_URL_SCHEME);
|
||||
if ($protocol === null) {
|
||||
if (strpos($url, '/') > -1) {
|
||||
list($address, $baseUrl) = explode('/', $url, 2);
|
||||
$this->setBaseUrl('/' . $baseUrl);
|
||||
} else {
|
||||
$address = $url;
|
||||
}
|
||||
if (strpos($address, ':') > -1) {
|
||||
list($address, $port) = explode(':', $address, 2);
|
||||
$this->setPort((int)$port);
|
||||
}
|
||||
$this->setHost($address);
|
||||
} else {
|
||||
$this->setProtocols([$protocol]);
|
||||
$this->setUsedProtocol($protocol);
|
||||
$this->setHost(parse_url($url, PHP_URL_HOST));
|
||||
$this->setBaseUrl(parse_url($url, PHP_URL_PATH));
|
||||
if (is_numeric($port = parse_url($url, PHP_URL_PORT))) {
|
||||
$this->setPort($port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $baseUrl
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setBaseUrl(?string $baseUrl): Request {
|
||||
if ($baseUrl !== null) {
|
||||
$this->baseUrl = $baseUrl;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isBinary(): bool {
|
||||
return $this->binary;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param bool $verifyPeer
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setVerifyPeer(bool $verifyPeer): Request {
|
||||
$this->verifyPeer = $verifyPeer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isVerifyPeer(): bool {
|
||||
return $this->verifyPeer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param bool $httpErrorsAllowed
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setHttpErrorsAllowed(bool $httpErrorsAllowed): Request {
|
||||
$this->httpErrorsAllowed = $httpErrorsAllowed;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isHttpErrorsAllowed(): bool {
|
||||
return $this->httpErrorsAllowed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param bool $followLocation
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFollowLocation(bool $followLocation): Request {
|
||||
$this->followLocation = $followLocation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isFollowLocation(): bool {
|
||||
return $this->followLocation;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @deprecated - 19 - use getParametersUrl() + addParam()
|
||||
*/
|
||||
public function getParsedUrl(): string {
|
||||
$url = $this->getPath();
|
||||
$ak = array_keys($this->getData());
|
||||
foreach ($ak as $k) {
|
||||
if (!is_string($this->data[$k])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$url = str_replace(':' . $k, $this->data[$k], $url);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getParametersUrl(): string {
|
||||
$url = $this->getPath();
|
||||
$ak = array_keys($this->getParams());
|
||||
foreach ($ak as $k) {
|
||||
if (!is_string($this->params[$k])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$url = str_replace(':' . $k, $this->params[$k], $url);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPath(): string {
|
||||
return $this->baseUrl . $this->url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @deprecated - 19 - use getPath()
|
||||
*/
|
||||
public function getUrl(): string {
|
||||
return $this->getPath();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCompleteUrl(): string {
|
||||
$port = ($this->getPort() > 0) ? ':' . $this->getPort() : '';
|
||||
|
||||
return $this->getUsedProtocol() . '://' . $this->getHost() . $port . $this->getParametersUrl();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getType(): int {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
|
||||
public function addHeader($key, $value): Request {
|
||||
$header = $this->get($key, $this->headers);
|
||||
if ($header !== '') {
|
||||
$header .= ', ' . $value;
|
||||
} else {
|
||||
$header = $value;
|
||||
}
|
||||
|
||||
$this->headers[$key] = $header;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders(): array {
|
||||
return array_merge(['User-Agent' => $this->getUserAgent()], $this->headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $headers
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setHeaders(array $headers): Request {
|
||||
$this->headers = $headers;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCookies(): array {
|
||||
return $this->cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $cookies
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setCookies(array $cookies): Request {
|
||||
$this->cookies = $cookies;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $queryStringType
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setQueryStringType(int $queryStringType): self {
|
||||
$this->queryStringType = $queryStringType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getQueryStringType(): int {
|
||||
return $this->queryStringType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getData(): array {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setData(array $data): Request {
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $data
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setDataJson(string $data): Request {
|
||||
$this->setData(json_decode($data, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param JsonSerializable $data
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setDataSerialize(JsonSerializable $data): Request {
|
||||
$this->setDataJson(json_encode($data));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParams(): array {
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setParams(array $params): Request {
|
||||
$this->params = $params;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param string $v
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function addParam(string $k, string $v): Request {
|
||||
$this->params[$k] = $v;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param int $v
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function addParamInt(string $k, int $v): Request {
|
||||
$this->params[$k] = $v;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param string $v
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function addData(string $k, string $v): Request {
|
||||
$this->data[$k] = $v;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param int $v
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function addDataInt(string $k, int $v): Request {
|
||||
$this->data[$k] = $v;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDataBody(): string {
|
||||
return json_encode($this->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @deprecated - 19 - use getUrlParams();
|
||||
*/
|
||||
public function getUrlData(): string {
|
||||
if ($this->getData() === []) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return preg_replace(
|
||||
'/([(%5B)]{1})[0-9]+([(%5D)]{1})/', '$1$2', http_build_query($this->getData())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @deprecated - 21 - use getQueryString();
|
||||
*/
|
||||
public function getUrlParams(): string {
|
||||
if ($this->getParams() === []) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return preg_replace(
|
||||
'/([(%5B)]{1})[0-9]+([(%5D)]{1})/', '$1$2', http_build_query($this->getParams())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryString(): string {
|
||||
if (empty($this->getParams())) {
|
||||
return '';
|
||||
}
|
||||
|
||||
switch ($this->getQueryStringType()) {
|
||||
case self::QS_VAR_ARRAY:
|
||||
return '?' . http_build_query($this->getParams());
|
||||
|
||||
case self::QS_VAR_DUPLICATE:
|
||||
default:
|
||||
return '?' . preg_replace(
|
||||
'/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', http_build_query($this->getParams())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTimeout(): int {
|
||||
return $this->timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $timeout
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setTimeout(int $timeout): Request {
|
||||
$this->timeout = $timeout;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUserAgent(): string {
|
||||
return $this->userAgent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $userAgent
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setUserAgent(string $userAgent): Request {
|
||||
$this->userAgent = $userAgent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getResultCode(): int {
|
||||
return $this->resultCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $resultCode
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setResultCode(int $resultCode): Request {
|
||||
$this->resultCode = $resultCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getContentType(): string {
|
||||
return $this->contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $contentType
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function setContentType(string $contentType): Request {
|
||||
$this->contentType = $contentType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize(): array {
|
||||
return [
|
||||
'protocols' => $this->getProtocols(),
|
||||
'used_protocol' => $this->getUsedProtocol(),
|
||||
'port' => $this->getPort(),
|
||||
'host' => $this->getHost(),
|
||||
'url' => $this->getPath(),
|
||||
'timeout' => $this->getTimeout(),
|
||||
'type' => $this->getType(),
|
||||
'cookies' => $this->getCookies(),
|
||||
'headers' => $this->getHeaders(),
|
||||
'params' => $this->getParams(),
|
||||
'data' => $this->getData(),
|
||||
'userAgent' => $this->getUserAgent(),
|
||||
'followLocation' => $this->isFollowLocation(),
|
||||
'verifyPeer' => $this->isVerifyPeer(),
|
||||
'binary' => $this->isBinary()
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function type(string $type): int {
|
||||
switch (strtoupper($type)) {
|
||||
case 'GET':
|
||||
return self::TYPE_GET;
|
||||
case 'POST':
|
||||
return self::TYPE_POST;
|
||||
case 'PUT':
|
||||
return self::TYPE_PUT;
|
||||
case 'DELETE':
|
||||
return self::TYPE_DELETE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public static function method(int $type): string {
|
||||
switch ($type) {
|
||||
case self::TYPE_GET:
|
||||
return 'get';
|
||||
case self::TYPE_POST:
|
||||
return 'post';
|
||||
case self::TYPE_PUT:
|
||||
return 'put';
|
||||
case self::TYPE_DELETE:
|
||||
return 'delete';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
||||
|
488
lib/Tools/Model/SimpleDataStore.php
Normal file
488
lib/Tools/Model/SimpleDataStore.php
Normal file
|
@ -0,0 +1,488 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Model;
|
||||
|
||||
use JsonSerializable;
|
||||
use OCA\Circles\Tools\Exceptions\InvalidItemException;
|
||||
use OCA\Circles\Tools\Exceptions\ItemNotFoundException;
|
||||
use OCA\Circles\Tools\Exceptions\MalformedArrayException;
|
||||
use OCA\Circles\Tools\Exceptions\UnknownTypeException;
|
||||
use OCA\Circles\Tools\IDeserializable;
|
||||
use OCA\Circles\Tools\Traits\TArrayTools;
|
||||
|
||||
class SimpleDataStore implements JsonSerializable {
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
/** @var array|JsonSerializable */
|
||||
private $data;
|
||||
|
||||
|
||||
/**
|
||||
* SimpleDataStore constructor.
|
||||
*
|
||||
* @param array|null $data
|
||||
*/
|
||||
public function __construct(?array $data = []) {
|
||||
if (!is_array($data)) {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $default
|
||||
*/
|
||||
public function default(array $default = []) {
|
||||
$this->data = array_merge($default, $this->data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function s(string $key, string $value): self {
|
||||
$this->data[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function g(string $key): string {
|
||||
return $this->get($key, $this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function u(string $key): self {
|
||||
if ($this->hasKey($key)) {
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function a(string $key, string $value): self {
|
||||
if (!array_key_exists($key, $this->data)) {
|
||||
$this->data[$key] = [];
|
||||
}
|
||||
|
||||
$this->data[$key][] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param int $value
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function sInt(string $key, int $value): self {
|
||||
$this->data[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function gInt(string $key): int {
|
||||
return $this->getInt($key, $this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param int $value
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function aInt(string $key, int $value): self {
|
||||
if (!array_key_exists($key, $this->data)) {
|
||||
$this->data[$key] = [];
|
||||
}
|
||||
|
||||
$this->data[$key][] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param bool $value
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function sBool(string $key, bool $value): self {
|
||||
$this->data[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function gBool(string $key): bool {
|
||||
return $this->getBool($key, $this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param bool $value
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function aBool(string $key, bool $value): self {
|
||||
if (!array_key_exists($key, $this->data)) {
|
||||
$this->data[$key] = [];
|
||||
}
|
||||
|
||||
$this->data[$key][] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param array $values
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function sArray(string $key, array $values): self {
|
||||
$this->data[$key] = $values;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function gArray(string $key): array {
|
||||
return $this->getArray($key, $this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param array $values
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function aArray(string $key, array $values): self {
|
||||
if (!array_key_exists($key, $this->data)) {
|
||||
$this->data[$key] = [];
|
||||
}
|
||||
|
||||
$this->data[$key] = array_merge($this->data[$key], $values);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param JsonSerializable $value
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function sObj(string $key, JsonSerializable $value): self {
|
||||
$this->data[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $class
|
||||
*
|
||||
* @return JsonSerializable[]
|
||||
*/
|
||||
public function gObjs(string $key, string $class = ''): array {
|
||||
$list = $this->gArray($key);
|
||||
$result = [];
|
||||
foreach ($list as $item) {
|
||||
$data = new SimpleDataStore([$key => $item]);
|
||||
$result[] = $data->gObj($key, $class);
|
||||
}
|
||||
|
||||
return array_filter($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $class
|
||||
*
|
||||
* @return null|JsonSerializable
|
||||
* @throws InvalidItemException
|
||||
* @throws UnknownTypeException
|
||||
* @throws ItemNotFoundException
|
||||
*/
|
||||
public function gObj(string $key, string $class = ''): ?JsonSerializable {
|
||||
$type = $this->typeOf($key, $this->data);
|
||||
|
||||
if ($type === self::$TYPE_NULL) {
|
||||
if ($class === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidItemException();
|
||||
}
|
||||
|
||||
if ($type === self::$TYPE_SERIALIZABLE) {
|
||||
return $this->getObj($key, $this->data);
|
||||
}
|
||||
|
||||
if ($type === self::$TYPE_ARRAY && $class !== '') {
|
||||
$item = new $class();
|
||||
if (!$item instanceof IDeserializable && !$item instanceof JsonSerializable) {
|
||||
throw new InvalidItemException(
|
||||
$class . ' does not implement IDeserializable and JsonSerializable'
|
||||
);
|
||||
}
|
||||
|
||||
$item->import($this->getArray($key, $this->data));
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
throw new InvalidItemException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param JsonSerializable $value
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function aObj(string $key, JsonSerializable $value): self {
|
||||
if (!array_key_exists($key, $this->data)) {
|
||||
$this->data[$key] = [];
|
||||
}
|
||||
|
||||
$this->data[$key][] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param SimpleDataStore $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function sData(string $key, SimpleDataStore $data): self {
|
||||
$this->data[$key] = $data->gAll();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param SimpleDataStore $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function aData(string $key, SimpleDataStore $data): self {
|
||||
if (!array_key_exists($key, $this->data) || !is_array($this->data[$key])) {
|
||||
$this->data[$key] = [];
|
||||
}
|
||||
|
||||
$this->data[$key][] = $data->gAll();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function gData(string $key): SimpleDataStore {
|
||||
return new SimpleDataStore($this->getArray($key, $this->data));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
* @throws ItemNotFoundException
|
||||
*/
|
||||
public function gItem(string $key) {
|
||||
if (!array_key_exists($key, $this->data)) {
|
||||
throw new ItemNotFoundException();
|
||||
}
|
||||
|
||||
return $this->data[$key];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function gAll(): array {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function sAll(array $data): self {
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function keys(): array {
|
||||
return array_keys($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasKey(string $key): bool {
|
||||
return (array_key_exists($key, $this->data));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $keys
|
||||
*
|
||||
* @param bool $must
|
||||
*
|
||||
* @return bool
|
||||
* @throws MalformedArrayException
|
||||
*/
|
||||
public function hasKeys(array $keys, bool $must = false): bool {
|
||||
foreach ($keys as $key) {
|
||||
if (!$this->haveKey($key)) {
|
||||
if ($must) {
|
||||
throw new MalformedArrayException($key . ' missing in ' . json_encode($this->keys()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $keys
|
||||
* @param bool $must
|
||||
*
|
||||
* @return bool
|
||||
* @throws MalformedArrayException
|
||||
* @deprecated
|
||||
*/
|
||||
public function haveKeys(array $keys, bool $must = false): bool {
|
||||
return $this->hasKeys($keys, $must);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
* @deprecated
|
||||
*/
|
||||
public function haveKey(string $key): bool {
|
||||
return $this->hasKey($key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $json
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function json(string $json): self {
|
||||
$data = json_decode($json, true);
|
||||
if (is_array($data)) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param JsonSerializable $obj
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function obj(JsonSerializable $obj): self {
|
||||
$this->data = $obj;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize(): array {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
232
lib/Tools/Model/TreeNode.php
Normal file
232
lib/Tools/Model/TreeNode.php
Normal file
|
@ -0,0 +1,232 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Model;
|
||||
|
||||
class TreeNode {
|
||||
|
||||
|
||||
/** @var self[] */
|
||||
private $children = [];
|
||||
|
||||
/** @var self */
|
||||
private $parent;
|
||||
|
||||
/** @var SimpleDataStore */
|
||||
private $item;
|
||||
|
||||
|
||||
/** @var self */
|
||||
private $currentChild;
|
||||
|
||||
/** @var bool */
|
||||
private $displayed = false;
|
||||
|
||||
/** @var bool */
|
||||
private $splited = false;
|
||||
|
||||
|
||||
/**
|
||||
* NC22TreeNode constructor.
|
||||
*
|
||||
* @param self|null $parent
|
||||
* @param SimpleDataStore $item
|
||||
*/
|
||||
public function __construct(?TreeNode $parent, SimpleDataStore $item) {
|
||||
$this->parent = $parent;
|
||||
$this->item = $item;
|
||||
|
||||
if ($this->parent !== null) {
|
||||
$this->parent->addChild($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isRoot(): bool {
|
||||
return (is_null($this->parent));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $children
|
||||
*
|
||||
* @return TreeNode
|
||||
*/
|
||||
public function setChildren(array $children): self {
|
||||
$this->children = $children;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TreeNode $child
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addChild(TreeNode $child): self {
|
||||
$this->children[] = $child;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return SimpleDataStore
|
||||
*/
|
||||
public function getItem(): SimpleDataStore {
|
||||
$this->displayed = true;
|
||||
|
||||
return $this->item;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return TreeNode
|
||||
*/
|
||||
public function getParent(): TreeNode {
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function getRoot(): TreeNode {
|
||||
if ($this->isRoot()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->getParent()->getRoot();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return TreeNode[]
|
||||
*/
|
||||
public function getPath(): array {
|
||||
if ($this->isRoot()) {
|
||||
return [$this];
|
||||
}
|
||||
|
||||
return array_merge($this->parent->getPath(), [$this]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLevel(): int {
|
||||
if ($this->isRoot()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->getParent()->getLevel() + 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return TreeNode|null
|
||||
*/
|
||||
public function current(): ?TreeNode {
|
||||
if (!$this->isDisplayed()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->splited = true;
|
||||
if ($this->initCurrentChild()) {
|
||||
$next = $this->getCurrentChild()->current();
|
||||
if (!is_null($next)) {
|
||||
return $next;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->haveNext()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->next();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return TreeNode
|
||||
*/
|
||||
private function next(): TreeNode {
|
||||
$this->currentChild = array_shift($this->children);
|
||||
|
||||
return $this->currentChild;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function haveNext(): bool {
|
||||
return !empty($this->children);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function initCurrentChild(): bool {
|
||||
if (is_null($this->currentChild)) {
|
||||
if (!$this->haveNext()) {
|
||||
return false;
|
||||
}
|
||||
$this->next();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TreeNode|null
|
||||
*/
|
||||
private function getCurrentChild(): ?TreeNode {
|
||||
return $this->currentChild;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function isDisplayed(): bool {
|
||||
return $this->displayed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSplited(): bool {
|
||||
return $this->splited;
|
||||
}
|
||||
}
|
432
lib/Tools/Traits/TArrayTools.php
Normal file
432
lib/Tools/Traits/TArrayTools.php
Normal file
|
@ -0,0 +1,432 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\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;
|
||||
|
||||
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';
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param array $arr
|
||||
* @param string $default
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get(string $k, array $arr, string $default = ''): string {
|
||||
if (!array_key_exists($k, $arr)) {
|
||||
$subs = explode('.', $k, 2);
|
||||
if (sizeof($subs) > 1) {
|
||||
if (!array_key_exists($subs[0], $arr)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$r = $arr[$subs[0]];
|
||||
if (!is_array($r)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->get($subs[1], $r, $default);
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
if ($arr[$k] === null || !is_string($arr[$k]) && (!is_int($arr[$k]))) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return (string)$arr[$k];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param array $arr
|
||||
* @param int $default
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getInt(string $k, array $arr, int $default = 0): int {
|
||||
if (!array_key_exists($k, $arr)) {
|
||||
$subs = explode('.', $k, 2);
|
||||
if (sizeof($subs) > 1) {
|
||||
if (!array_key_exists($subs[0], $arr)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$r = $arr[$subs[0]];
|
||||
if (!is_array($r)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->getInt($subs[1], $r, $default);
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
if ($arr[$k] === null) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return intval($arr[$k]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param array $arr
|
||||
* @param float $default
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
protected function getFloat(string $k, array $arr, float $default = 0): float {
|
||||
if (!array_key_exists($k, $arr)) {
|
||||
$subs = explode('.', $k, 2);
|
||||
if (sizeof($subs) > 1) {
|
||||
if (!array_key_exists($subs[0], $arr)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$r = $arr[$subs[0]];
|
||||
if (!is_array($r)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->getFloat($subs[1], $r, $default);
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
if ($arr[$k] === null) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return intval($arr[$k]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param array $arr
|
||||
* @param bool $default
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function getBool(string $k, array $arr, bool $default = false): bool {
|
||||
if (!array_key_exists($k, $arr)) {
|
||||
$subs = explode('.', $k, 2);
|
||||
if (sizeof($subs) > 1) {
|
||||
if (!array_key_exists($subs[0], $arr)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->getBool($subs[1], $arr[$subs[0]], $default);
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
if ($arr[$k] === null) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (is_bool($arr[$k])) {
|
||||
return $arr[$k];
|
||||
}
|
||||
|
||||
$sk = (string)$arr[$k];
|
||||
if ($sk === '1' || strtolower($sk) === 'true') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($sk === '0' || strtolower($sk) === 'false') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param array $arr
|
||||
* @param JsonSerializable|null $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getObj(string $k, array $arr, ?JsonSerializable $default = null): ?JsonSerializable {
|
||||
if (!array_key_exists($k, $arr)) {
|
||||
$subs = explode('.', $k, 2);
|
||||
if (sizeof($subs) > 1) {
|
||||
if (!array_key_exists($subs[0], $arr)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->getObj($subs[1], $arr[$subs[0]], $default);
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $arr[$k];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param array $arr
|
||||
* @param array $default
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getArray(string $k, array $arr, array $default = []): array {
|
||||
if (!array_key_exists($k, $arr)) {
|
||||
$subs = explode('.', $k, 2);
|
||||
if (sizeof($subs) > 1) {
|
||||
if (!array_key_exists($subs[0], $arr)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$r = $arr[$subs[0]];
|
||||
if (!is_array($r)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->getArray($subs[1], $r, $default);
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
$r = $arr[$k];
|
||||
if (!is_array($r) && !is_string($r)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (is_string($r)) {
|
||||
$r = json_decode($r, true);
|
||||
}
|
||||
|
||||
if (!is_array($r)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param array $arr
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validKey(string $k, array $arr): bool {
|
||||
if (array_key_exists($k, $arr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$subs = explode('.', $k, 2);
|
||||
if (sizeof($subs) > 1) {
|
||||
if (!array_key_exists($subs[0], $arr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$r = $arr[$subs[0]];
|
||||
if (!is_array($r)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->validKey($subs[1], $r);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param array $arr
|
||||
* @param array $import
|
||||
* @param array $default
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getList(string $k, array $arr, array $import, array $default = []): array {
|
||||
$list = $this->getArray($k, $arr, $default);
|
||||
|
||||
$r = [];
|
||||
[$obj, $method] = $import;
|
||||
foreach ($list as $item) {
|
||||
try {
|
||||
$o = new $obj();
|
||||
$o->$method($item);
|
||||
|
||||
$r[] = $o;
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $k
|
||||
* @param string $value
|
||||
* @param array $list
|
||||
*
|
||||
* @return mixed
|
||||
* @throws ArrayNotFoundException
|
||||
*/
|
||||
protected function extractArray(string $k, string $value, array $list) {
|
||||
foreach ($list as $arr) {
|
||||
if (!array_key_exists($k, $arr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($arr[$k] === $value) {
|
||||
return $arr;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArrayNotFoundException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param array $arr
|
||||
* @param bool $root
|
||||
*
|
||||
* @return string
|
||||
* @throws ItemNotFoundException
|
||||
* @throws UnknownTypeException
|
||||
*/
|
||||
public function typeOf(string $key, array $arr, bool $root = true): string {
|
||||
if (array_key_exists($key, $arr)) {
|
||||
$item = $arr[$key];
|
||||
|
||||
if (is_null($item)) {
|
||||
return self::$TYPE_NULL;
|
||||
}
|
||||
|
||||
if (is_string($item)) {
|
||||
return self::$TYPE_STRING;
|
||||
}
|
||||
|
||||
if (is_array($item)) {
|
||||
return self::$TYPE_ARRAY;
|
||||
}
|
||||
|
||||
if (is_bool($item)) {
|
||||
return self::$TYPE_BOOLEAN;
|
||||
}
|
||||
|
||||
if (is_int($item)) {
|
||||
return self::$TYPE_INTEGER;
|
||||
}
|
||||
|
||||
if ($item instanceof JsonSerializable) {
|
||||
return self::$TYPE_SERIALIZABLE;
|
||||
}
|
||||
|
||||
throw new UnknownTypeException();
|
||||
}
|
||||
|
||||
$subs = explode('.', $key, 2);
|
||||
if (sizeof($subs) > 1) {
|
||||
if (!array_key_exists($subs[0], $arr)) {
|
||||
throw new ItemNotFoundException();
|
||||
}
|
||||
|
||||
$r = $arr[$subs[0]];
|
||||
if (is_array($r)) {
|
||||
return $this->typeOf($subs[1], $r);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ItemNotFoundException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $keys
|
||||
* @param array $arr
|
||||
*
|
||||
* @throws MalformedArrayException
|
||||
*/
|
||||
protected function mustContains(array $keys, array $arr) {
|
||||
foreach ($keys as $key) {
|
||||
if (!array_key_exists($key, $arr)) {
|
||||
throw new MalformedArrayException(
|
||||
'source: ' . json_encode($arr) . ' - missing key: ' . $key
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $arr
|
||||
*/
|
||||
protected function cleanArray(array &$arr) {
|
||||
$arr = array_filter(
|
||||
$arr,
|
||||
function ($v) {
|
||||
if (is_string($v)) {
|
||||
return ($v !== '');
|
||||
}
|
||||
if (is_array($v)) {
|
||||
return !empty($v);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
79
lib/Tools/Traits/TAsync.php
Normal file
79
lib/Tools/Traits/TAsync.php
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Traits;
|
||||
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
trait TAsync {
|
||||
|
||||
use TNCSetup;
|
||||
|
||||
|
||||
/** @var string */
|
||||
public static $SETUP_TIME_LIMIT = 'async_time_limit';
|
||||
|
||||
|
||||
/**
|
||||
* Hacky way to async the rest of the process without keeping client on hold.
|
||||
*
|
||||
* @param string $result
|
||||
*/
|
||||
public function async(string $result = ''): void {
|
||||
if (ob_get_contents() !== false) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
header('Connection: close');
|
||||
header('Content-Encoding: none');
|
||||
ignore_user_abort();
|
||||
$timeLimit = $this->setupInt(self::$SETUP_TIME_LIMIT);
|
||||
set_time_limit(($timeLimit > 0) ? $timeLimit : 0);
|
||||
ob_start();
|
||||
|
||||
echo($result);
|
||||
|
||||
$size = ob_get_length();
|
||||
header('Content-Length: ' . $size);
|
||||
ob_end_flush();
|
||||
flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param JsonSerializable $obj
|
||||
*/
|
||||
public function asyncObj(JsonSerializable $obj): void {
|
||||
$this->async(json_encode($obj));
|
||||
}
|
||||
|
||||
}
|
||||
|
145
lib/Tools/Traits/TConsoleTree.php
Normal file
145
lib/Tools/Traits/TConsoleTree.php
Normal file
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Traits;
|
||||
|
||||
|
||||
use OCA\Circles\Tools\Model\TreeNode;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
|
||||
trait TConsoleTree {
|
||||
|
||||
|
||||
/**
|
||||
* @param TreeNode $root
|
||||
* @param callable $method
|
||||
* @param array $config
|
||||
*/
|
||||
public function drawTree(
|
||||
TreeNode $root,
|
||||
callable $method,
|
||||
array $config = [
|
||||
'height' => 1,
|
||||
'node-spacing' => 0,
|
||||
'item-spacing' => 0,
|
||||
]
|
||||
): void {
|
||||
$config = array_merge(
|
||||
[
|
||||
'height' => 1,
|
||||
'node-spacing' => 0,
|
||||
'item-spacing' => 0
|
||||
], $config
|
||||
);
|
||||
|
||||
$output = new ConsoleOutput();
|
||||
|
||||
while (true) {
|
||||
$node = $root->current();
|
||||
if ($node === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path = $node->getPath();
|
||||
array_pop($path);
|
||||
|
||||
$line = $empty = $spacing = '';
|
||||
$p = 0;
|
||||
foreach ($path as $k => $i) {
|
||||
$line .= ' ';
|
||||
$empty .= ' ';
|
||||
if ($k === array_key_last($path)) {
|
||||
if ($i->haveNext()) {
|
||||
$line .= '├';
|
||||
$empty .= '│';
|
||||
} else {
|
||||
$line .= '└';
|
||||
$empty .= ' ';
|
||||
}
|
||||
$line .= '── ';
|
||||
$empty .= ' ';
|
||||
} else {
|
||||
if ($i->haveNext()) {
|
||||
$line .= '│';
|
||||
$empty .= '│';
|
||||
} else {
|
||||
$line .= ' ';
|
||||
$empty .= ' ';
|
||||
}
|
||||
$line .= ' ';
|
||||
$empty .= ' ';
|
||||
}
|
||||
$p++;
|
||||
}
|
||||
|
||||
if ($p < $prec) {
|
||||
for ($i = 0; $i < $config['node-spacing']; $i++) {
|
||||
$spacing = substr($empty, 0, -3);
|
||||
if (substr($spacing, -1) === ' ') {
|
||||
$spacing = substr($spacing, 0, -1) . '│';
|
||||
}
|
||||
$output->writeln($spacing);
|
||||
}
|
||||
}
|
||||
|
||||
$prec = $p;
|
||||
|
||||
for ($i = 1; $i <= $config['height']; $i++) {
|
||||
$draw = $method($node->getItem(), $i);
|
||||
if ($draw === '') {
|
||||
continue;
|
||||
}
|
||||
if ($i === 1) {
|
||||
$output->write($line);
|
||||
} else {
|
||||
$output->write($empty);
|
||||
}
|
||||
$output->writeln($draw);
|
||||
}
|
||||
|
||||
if ($node->haveNext()) {
|
||||
$empty .= ' │';
|
||||
}
|
||||
|
||||
if (!$node->isSplited() && $node->haveNext()) {
|
||||
for ($i = 0; $i < $config['node-spacing']; $i++) {
|
||||
$output->writeln($empty);
|
||||
}
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $config['item-spacing']; $i++) {
|
||||
$output->writeln($empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
109
lib/Tools/Traits/TDeserialize.php
Normal file
109
lib/Tools/Traits/TDeserialize.php
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Traits;
|
||||
|
||||
use JsonSerializable;
|
||||
use OCA\Circles\Tools\Exceptions\InvalidItemException;
|
||||
use OCA\Circles\Tools\IDeserializable;
|
||||
|
||||
trait TDeserialize {
|
||||
|
||||
|
||||
/**
|
||||
* @param JsonSerializable $model
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function serialize(JsonSerializable $model): array {
|
||||
return json_decode(json_encode($model), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function serializeArray(array $data): array {
|
||||
return json_decode(json_encode($data), true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param string $class
|
||||
*
|
||||
* @return IDeserializable
|
||||
* @throws InvalidItemException
|
||||
*/
|
||||
public function deserialize(array $data, string $class): IDeserializable {
|
||||
if ($class instanceof IDeserializable) {
|
||||
throw new InvalidItemException(get_class($class) . ' does not implement IDeserializable');
|
||||
}
|
||||
|
||||
/** @var IDeserializable $item */
|
||||
$item = new $class;
|
||||
$item->import($data);
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param string $class
|
||||
*
|
||||
* @return IDeserializable[]
|
||||
* @throws InvalidItemException
|
||||
*/
|
||||
public function deserializeArray(array $data, string $class): array {
|
||||
$arr = [];
|
||||
foreach ($data as $entry) {
|
||||
$arr[] = $this->deserialize($entry, $class);
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $json
|
||||
* @param string $class
|
||||
*
|
||||
* @return IDeserializable
|
||||
* @throws InvalidItemException
|
||||
*/
|
||||
public function deserializeJson(string $json, string $class): IDeserializable {
|
||||
$data = json_decode($json, true);
|
||||
|
||||
return $this->deserialize($data, $class);
|
||||
}
|
||||
}
|
116
lib/Tools/Traits/TNCLocalSignatory.php
Normal file
116
lib/Tools/Traits/TNCLocalSignatory.php
Normal file
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Traits;
|
||||
|
||||
|
||||
use OC;
|
||||
use OCA\Circles\Tools\Exceptions\SignatoryException;
|
||||
use OCA\Circles\Tools\Model\NCSignatory;
|
||||
use OCP\IConfig;
|
||||
|
||||
trait TNCLocalSignatory {
|
||||
|
||||
|
||||
use TNCSignatory;
|
||||
|
||||
static $SIGNATORIES_APP = 'signatories';
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignatory $signatory
|
||||
* @param bool $generate
|
||||
*
|
||||
* @throws SignatoryException
|
||||
*/
|
||||
public function fillSimpleSignatory(NCSignatory $signatory, bool $generate = false): void {
|
||||
$app = $this->setup('app', '', self::$SIGNATORIES_APP);
|
||||
$signatories = json_decode(OC::$server->get(IConfig::class)->getAppValue($app, 'key_pairs'), true);
|
||||
if (!is_array($signatories)) {
|
||||
$signatories = [];
|
||||
}
|
||||
|
||||
$sign = $this->getArray($signatory->getId(), $signatories);
|
||||
if (!empty($sign)) {
|
||||
$signatory->setKeyId($this->get('keyId', $sign))
|
||||
->setKeyOwner($this->get('keyOwner', $sign))
|
||||
->setPublicKey($this->get('publicKey', $sign))
|
||||
->setPrivateKey($this->get('privateKey', $sign));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$generate) {
|
||||
throw new SignatoryException('signatory not found');
|
||||
}
|
||||
|
||||
$this->createSimpleSignatory($signatory);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignatory $signatory
|
||||
*/
|
||||
public function createSimpleSignatory(NCSignatory $signatory): void {
|
||||
$app = $this->setup('app', '', self::$SIGNATORIES_APP);
|
||||
$signatory->setKeyId($signatory->getId() . '#main-key');
|
||||
$signatory->setKeyOwner($signatory->getId());
|
||||
$this->generateKeys($signatory);
|
||||
|
||||
$signatories =
|
||||
json_decode(OC::$server->get(IConfig::class)->getAppValue($app, 'key_pairs', '[]'), true);
|
||||
$signatories[$signatory->getId()] = [
|
||||
'keyId' => $signatory->getKeyId(),
|
||||
'keyOwner' => $signatory->getKeyOwner(),
|
||||
'publicKey' => $signatory->getPublicKey(),
|
||||
'privateKey' => $signatory->getPrivateKey()
|
||||
];
|
||||
|
||||
OC::$server->get(IConfig::class)->setAppValue($app, 'key_pairs', json_encode($signatories));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignatory $signatory
|
||||
*/
|
||||
public function removeSimpleSignatory(NCSignatory $signatory): void {
|
||||
$app = $this->setup('app', '', self::$SIGNATORIES_APP);
|
||||
$signatories = json_decode(OC::$server->get(IConfig::class)->getAppValue($app, 'key_pairs'), true);
|
||||
if (!is_array($signatories)) {
|
||||
$signatories = [];
|
||||
}
|
||||
|
||||
unset($signatories[$signatory->getId()]);
|
||||
OC::$server->get(IConfig::class)->setAppValue($app, 'key_pairs', json_encode($signatories));
|
||||
}
|
||||
|
||||
}
|
||||
|
205
lib/Tools/Traits/TNCLogger.php
Normal file
205
lib/Tools/Traits/TNCLogger.php
Normal file
|
@ -0,0 +1,205 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Traits;
|
||||
|
||||
|
||||
use Exception;
|
||||
use OC;
|
||||
use OC\HintException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
trait TNCLogger {
|
||||
|
||||
use TNCSetup;
|
||||
|
||||
|
||||
static $EMERGENCY = 4;
|
||||
static $ALERT = 3;
|
||||
static $CRITICAL = 3;
|
||||
static $ERROR = 3;
|
||||
static $WARNING = 2;
|
||||
static $NOTICE = 1;
|
||||
static $INFO = 1;
|
||||
static $DEBUG = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @param Throwable $t
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function t(Throwable $t, array $serializable = []): void {
|
||||
$this->throwable($t, self::$ERROR, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Throwable $t
|
||||
* @param int $level
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function throwable(Throwable $t, int $level = 3, array $serializable = []): void {
|
||||
$message = '';
|
||||
if (!empty($serializable)) {
|
||||
$message = json_encode($serializable);
|
||||
}
|
||||
|
||||
$this->logger()
|
||||
->log(
|
||||
$level,
|
||||
$message,
|
||||
[
|
||||
'app' => $this->setup('app'),
|
||||
'exception' => $t
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Exception $e
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function e(Exception $e, array $serializable = []): void {
|
||||
$this->exception($e, self::$ERROR, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception $e
|
||||
* @param int|array $level
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function exception(Exception $e, $level = 3, array $serializable = []): void {
|
||||
if (is_array($level) && empty($serializable)) {
|
||||
$serializable = $level;
|
||||
$level = 3;
|
||||
}
|
||||
|
||||
$message = '';
|
||||
if (!empty($serializable)) {
|
||||
$message = json_encode($serializable);
|
||||
}
|
||||
|
||||
if ($level === self::$DEBUG) {
|
||||
$level = (int)$this->appConfig('debug_level');
|
||||
}
|
||||
|
||||
$this->logger()
|
||||
->log(
|
||||
$level,
|
||||
$message,
|
||||
[
|
||||
'app' => $this->setup('app'),
|
||||
'exception' => $e
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param bool $trace
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function emergency(string $message, bool $trace = false, array $serializable = []): void {
|
||||
$this->log(self::$EMERGENCY, '[emergency] ' . $message, $trace, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param bool $trace
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function alert(string $message, bool $trace = false, array $serializable = []): void {
|
||||
$this->log(self::$ALERT, '[alert] ' . $message, $trace, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param bool $trace
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function warning(string $message, bool $trace = false, array $serializable = []): void {
|
||||
$this->log(self::$WARNING, '[warning] ' . $message, $trace, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param bool $trace
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function notice(string $message, bool $trace = false, array $serializable = []): void {
|
||||
$this->log(self::$NOTICE, '[notice] ' . $message, $trace, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function debug(string $message, array $serializable = []): void {
|
||||
$message = '[debug] ' . $message;
|
||||
$debugLevel = (int)$this->appConfig('debug_level');
|
||||
$this->log($debugLevel, $message, ($this->appConfig('debug_trace') === '1'), $serializable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $level
|
||||
* @param string $message
|
||||
* @param bool $trace
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function log(int $level, string $message, bool $trace = false, array $serializable = []): void {
|
||||
$opts = ['app' => $this->setup('app')];
|
||||
if ($trace) {
|
||||
$opts['exception'] = new HintException($message, json_encode($serializable));
|
||||
} elseif (!empty($serializable)) {
|
||||
$message .= ' -- ' . json_encode($serializable);
|
||||
}
|
||||
|
||||
$this->logger()
|
||||
->log($level, $message, $opts);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function logger(): LoggerInterface {
|
||||
if (isset($this->logger) && $this->logger instanceof LoggerInterface) {
|
||||
return $this->logger;
|
||||
} else {
|
||||
return OC::$server->get(LoggerInterface::class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
182
lib/Tools/Traits/TNCRequest.php
Normal file
182
lib/Tools/Traits/TNCRequest.php
Normal file
|
@ -0,0 +1,182 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Traits;
|
||||
|
||||
|
||||
use OCA\Circles\Tools\Model\NCRequest;
|
||||
use Exception;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use OC;
|
||||
use OCA\Circles\Tools\Exceptions\RequestNetworkException;
|
||||
use OCA\Circles\Tools\Model\NCRequestResult;
|
||||
use OCA\Circles\Tools\Model\Request;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\Http\Client\IResponse;
|
||||
|
||||
trait TNCRequest {
|
||||
|
||||
use TNCLogger;
|
||||
|
||||
|
||||
/**
|
||||
* @param int $size
|
||||
*/
|
||||
public function setMaxDownloadSize(int $size) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCRequest $request
|
||||
*
|
||||
* @return array
|
||||
* @throws RequestNetworkException
|
||||
*/
|
||||
public function retrieveJson(NCRequest $request): array {
|
||||
$this->doRequest($request);
|
||||
$requestResult = $request->getResult();
|
||||
|
||||
return $requestResult->getAsArray();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCRequest $request
|
||||
* @param bool $exceptionOnIssue
|
||||
*
|
||||
* @throws RequestNetworkException
|
||||
*/
|
||||
public function doRequest(NCRequest $request, bool $exceptionOnIssue = true): void {
|
||||
$request->setClient(
|
||||
$this->clientService()
|
||||
->newClient()
|
||||
);
|
||||
|
||||
$this->generationClientOptions($request);
|
||||
|
||||
$this->debug('doRequest initiated', ['request' => $request]);
|
||||
foreach ($request->getProtocols() as $protocol) {
|
||||
$request->setUsedProtocol($protocol);
|
||||
try {
|
||||
$response = $this->useClient($request);
|
||||
$request->setResult(new NCRequestResult($response));
|
||||
break;
|
||||
} catch (ClientException $e) {
|
||||
$request->setResult(new NCRequestResult(null, $e));
|
||||
} catch (Exception $e) {
|
||||
$this->exception($e, self::$DEBUG, ['request' => $request]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->debug('doRequest done', ['request' => $request]);
|
||||
|
||||
if ($exceptionOnIssue && (!$request->hasResult() || $request->getResult()->hasException())) {
|
||||
throw new RequestNetworkException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return IClientService
|
||||
*/
|
||||
public function clientService(): IClientService {
|
||||
if (isset($this->clientService) && $this->clientService instanceof IClientService) {
|
||||
return $this->clientService;
|
||||
} else {
|
||||
return OC::$server->get(IClientService::class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCRequest $request
|
||||
*/
|
||||
private function generationClientOptions(NCRequest $request) {
|
||||
$options = [
|
||||
'headers' => $request->getHeaders(),
|
||||
'cookies' => $request->getCookies(),
|
||||
'verify' => $request->isVerifyPeer(),
|
||||
'timeout' => $request->getTimeout(),
|
||||
'http_errors' => !$request->isHttpErrorsAllowed()
|
||||
];
|
||||
|
||||
if (!empty($request->getData())) {
|
||||
$options['body'] = $request->getDataBody();
|
||||
}
|
||||
|
||||
if (!empty($request->getParams())) {
|
||||
$options['form_params'] = $request->getParams();
|
||||
}
|
||||
|
||||
if ($request->isLocalAddressAllowed()) {
|
||||
$options['nextcloud']['allow_local_address'] = true;
|
||||
}
|
||||
|
||||
if ($request->isFollowLocation()) {
|
||||
$options['allow_redirects'] = [
|
||||
'max' => 10,
|
||||
'strict' => true,
|
||||
'referer' => true,
|
||||
];
|
||||
} else {
|
||||
$options['allow_redirects'] = false;
|
||||
}
|
||||
|
||||
$request->setClientOptions($options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCRequest $request
|
||||
*
|
||||
* @return IResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
private function useClient(NCRequest $request): IResponse {
|
||||
$client = $request->getClient();
|
||||
switch ($request->getType()) {
|
||||
case Request::TYPE_POST:
|
||||
return $client->post($request->getCompleteUrl(), $request->getClientOptions());
|
||||
case Request::TYPE_PUT:
|
||||
return $client->put($request->getCompleteUrl(), $request->getClientOptions());
|
||||
case Request::TYPE_DELETE:
|
||||
return $client->delete($request->getCompleteUrl(), $request->getClientOptions());
|
||||
case Request::TYPE_GET:
|
||||
return $client->get(
|
||||
$request->getCompleteUrl() . $request->getQueryString(), $request->getClientOptions()
|
||||
);
|
||||
default:
|
||||
throw new Exception('unknown request type ' . json_encode($request));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
112
lib/Tools/Traits/TNCSetup.php
Normal file
112
lib/Tools/Traits/TNCSetup.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Traits;
|
||||
|
||||
|
||||
use OC;
|
||||
use OCP\IConfig;
|
||||
|
||||
trait TNCSetup {
|
||||
|
||||
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
/** @var array */
|
||||
private $_setup = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*
|
||||
* @param string $default
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function setup(string $key, string $value = '', string $default = ''): string {
|
||||
if ($value !== '') {
|
||||
$this->_setup[$key] = $value;
|
||||
}
|
||||
|
||||
return $this->get($key, $this->_setup, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param array $value
|
||||
* @param array $default
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function setupArray(string $key, array $value = [], array $default = []): array {
|
||||
if (!empty($value)) {
|
||||
$this->_setup[$key] = $value;
|
||||
}
|
||||
|
||||
return $this->getArray($key, $this->_setup, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param int $value
|
||||
* @param int $default
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function setupInt(string $key, int $value = -999, int $default = 0): int {
|
||||
if ($value !== -999) {
|
||||
$this->_setup[$key] = $value;
|
||||
}
|
||||
|
||||
return $this->getInt($key, $this->_setup, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function appConfig(string $key): string {
|
||||
$app = $this->setup('app');
|
||||
if ($app === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
/** @var IConfig $config */
|
||||
$config = OC::$server->get(IConfig::class);
|
||||
|
||||
return $config->getAppValue($app, $key, '');
|
||||
}
|
||||
|
||||
}
|
||||
|
212
lib/Tools/Traits/TNCSignatory.php
Normal file
212
lib/Tools/Traits/TNCSignatory.php
Normal file
|
@ -0,0 +1,212 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Traits;
|
||||
|
||||
|
||||
use OCA\Circles\Tools\Exceptions\InvalidOriginException;
|
||||
use OCA\Circles\Tools\Exceptions\RequestNetworkException;
|
||||
use OCA\Circles\Tools\Exceptions\SignatoryException;
|
||||
use OCA\Circles\Tools\Exceptions\SignatureException;
|
||||
use OCA\Circles\Tools\Model\NCRequest;
|
||||
use OCA\Circles\Tools\Model\NCSignatory;
|
||||
|
||||
trait TNCSignatory {
|
||||
|
||||
use TNCRequest;
|
||||
|
||||
|
||||
/**
|
||||
* return Signatory by its Id from cache or from direct request.
|
||||
* Should be overwritten.
|
||||
*
|
||||
* @param string $keyId
|
||||
* @param bool $refresh
|
||||
*
|
||||
* @return NCSignatory
|
||||
* @throws SignatoryException
|
||||
*/
|
||||
public function retrieveSignatory(string $keyId, bool $refresh = false): NCSignatory {
|
||||
if (!$refresh) {
|
||||
throw new SignatoryException();
|
||||
}
|
||||
|
||||
$signatory = new NCSignatory($keyId);
|
||||
$this->downloadSignatory($signatory, $keyId);
|
||||
|
||||
return $signatory;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignatory $signatory
|
||||
* @param string $keyId
|
||||
* @param array $params
|
||||
* @param NCRequest|null $request
|
||||
*
|
||||
* @throws SignatoryException
|
||||
*/
|
||||
public function downloadSignatory(
|
||||
NCSignatory $signatory,
|
||||
string $keyId = '',
|
||||
array $params = [],
|
||||
?NCRequest $request = null
|
||||
): void {
|
||||
|
||||
if (is_null($request)) {
|
||||
$request = new NCRequest();
|
||||
$request->setFollowLocation(true);
|
||||
$request->setTimeout(5);
|
||||
}
|
||||
|
||||
$request->basedOnUrl(($keyId !== '') ? $keyId : $signatory->getId());
|
||||
$request->setParams($params);
|
||||
$request->addHeader('Accept', 'application/ld+json');
|
||||
|
||||
try {
|
||||
$this->updateSignatory($signatory, $this->retrieveJson($request), $keyId);
|
||||
} catch (RequestNetworkException $e) {
|
||||
$this->debug('network issue while downloading Signatory', ['request' => $request]);
|
||||
throw new SignatoryException('network issue: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignatory $signatory
|
||||
* @param array $json
|
||||
* @param string $keyId
|
||||
*
|
||||
* @throws SignatoryException
|
||||
*/
|
||||
public function updateSignatory(NCSignatory $signatory, array $json, string $keyId = ''): void {
|
||||
$signatory->setOrigData($json)
|
||||
->import($json);
|
||||
|
||||
if ($keyId === '') {
|
||||
$keyId = $signatory->getKeyId();
|
||||
}
|
||||
|
||||
try {
|
||||
if (($signatory->getId() !== $keyId && $signatory->getKeyId() !== $keyId)
|
||||
|| $signatory->getId() !== $signatory->getKeyOwner()
|
||||
|| $this->getKeyOrigin($signatory->getKeyId()) !== $this->getKeyOrigin($signatory->getId())
|
||||
|| $signatory->getPublicKey() === '') {
|
||||
$this->debug('invalid format', ['signatory' => $signatory, 'keyId' => $keyId]);
|
||||
throw new SignatoryException('invalid format');
|
||||
}
|
||||
} catch (InvalidOriginException $e) {
|
||||
throw new SignatoryException('invalid origin');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $keyId
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidOriginException
|
||||
*/
|
||||
public function getKeyOrigin(string $keyId) {
|
||||
$host = parse_url($keyId, PHP_URL_HOST);
|
||||
if (is_string($host) && ($host !== '')) {
|
||||
return $host;
|
||||
}
|
||||
|
||||
throw new InvalidOriginException('cannot retrieve origin from ' . $keyId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param NCSignatory $signatory
|
||||
* @param string $digest
|
||||
* @param int $bits
|
||||
* @param int $type
|
||||
*/
|
||||
public function generateKeys(
|
||||
NCSignatory $signatory,
|
||||
string $digest = 'rsa',
|
||||
int $bits = 2048,
|
||||
int $type = OPENSSL_KEYTYPE_RSA
|
||||
) {
|
||||
$res = openssl_pkey_new(
|
||||
[
|
||||
'digest_alg' => $digest,
|
||||
'private_key_bits' => $bits,
|
||||
'private_key_type' => $type,
|
||||
]
|
||||
);
|
||||
|
||||
openssl_pkey_export($res, $privateKey);
|
||||
$publicKey = openssl_pkey_get_details($res)['key'];
|
||||
|
||||
$signatory->setPublicKey($publicKey);
|
||||
$signatory->setPrivateKey($privateKey);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $clear
|
||||
* @param NCSignatory $signatory
|
||||
*
|
||||
* @return string
|
||||
* @throws SignatoryException
|
||||
*/
|
||||
public function signString(string $clear, NCSignatory $signatory): string {
|
||||
$privateKey = $signatory->getPrivateKey();
|
||||
if ($privateKey === '') {
|
||||
throw new SignatoryException('empty private key');
|
||||
}
|
||||
|
||||
openssl_sign($clear, $signed, $privateKey, $this->getOpenSSLAlgo($signatory));
|
||||
|
||||
return base64_encode($signed);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $clear
|
||||
* @param string $signed
|
||||
* @param string $publicKey
|
||||
* @param string $algo
|
||||
*
|
||||
* @throws SignatureException
|
||||
*/
|
||||
public function verifyString(
|
||||
string $clear, string $signed, string $publicKey, string $algo = NCSignatory::SHA256
|
||||
) {
|
||||
if (openssl_verify($clear, $signed, $publicKey, $algo) !== 1) {
|
||||
throw new SignatureException('signature issue');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
131
lib/Tools/Traits/TNCWellKnown.php
Normal file
131
lib/Tools/Traits/TNCWellKnown.php
Normal file
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Traits;
|
||||
|
||||
|
||||
use OCA\Circles\Tools\Exceptions\RequestNetworkException;
|
||||
use OCA\Circles\Tools\Exceptions\WellKnownLinkNotFoundException;
|
||||
use OCA\Circles\Tools\Model\NCRequest;
|
||||
use OCA\Circles\Tools\Model\NCWebfinger;
|
||||
use OCA\Circles\Tools\Model\NCWellKnownLink;
|
||||
use OCA\Circles\Tools\Model\SimpleDataStore;
|
||||
|
||||
trait TNCWellKnown {
|
||||
use TNCRequest;
|
||||
|
||||
static $WEBFINGER = '/.well-known/webfinger';
|
||||
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
* @param string $subject
|
||||
* @param string $rel
|
||||
*
|
||||
* @return SimpleDataStore
|
||||
* @throws RequestNetworkException
|
||||
* @throws WellKnownLinkNotFoundException
|
||||
*/
|
||||
public function getResourceData(string $host, string $subject, string $rel): SimpleDataStore {
|
||||
$link = $this->getLink($host, $subject, $rel);
|
||||
|
||||
$request = new NCRequest('');
|
||||
$request->basedOnUrl($link->getHref());
|
||||
$request->addHeader('Accept', $link->getType());
|
||||
$request->setFollowLocation(true);
|
||||
$request->setLocalAddressAllowed(true);
|
||||
$request->setTimeout(5);
|
||||
$data = $this->retrieveJson($request);
|
||||
|
||||
return new SimpleDataStore($data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
* @param string $subject
|
||||
* @param string $rel
|
||||
*
|
||||
* @return NCWellKnownLink
|
||||
* @throws RequestNetworkException
|
||||
* @throws WellKnownLinkNotFoundException
|
||||
*/
|
||||
public function getLink(string $host, string $subject, string $rel): NCWellKnownLink {
|
||||
return $this->extractLink($rel, $this->getWebfinger($host, $subject));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
* @param string $subject
|
||||
* @param string $rel
|
||||
*
|
||||
* @return NCWebfinger
|
||||
* @throws RequestNetworkException
|
||||
*/
|
||||
public function getWebfinger(string $host, string $subject, string $rel = ''): NCWebfinger {
|
||||
$request = new NCRequest(self::$WEBFINGER);
|
||||
$request->setHost($host);
|
||||
$request->setProtocols(['https', 'http']);
|
||||
$request->setFollowLocation(true);
|
||||
$request->setLocalAddressAllowed(true);
|
||||
$request->setTimeout(5);
|
||||
|
||||
$request->addParam('resource', $subject);
|
||||
if ($rel !== '') {
|
||||
$request->addParam('rel', $rel);
|
||||
}
|
||||
|
||||
$result = $this->retrieveJson($request);
|
||||
|
||||
return new NCWebfinger($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $rel
|
||||
* @param NCWebfinger $webfinger
|
||||
*
|
||||
* @return NCWellKnownLink
|
||||
* @throws WellKnownLinkNotFoundException
|
||||
*/
|
||||
public function extractLink(string $rel, NCWebfinger $webfinger): NCWellKnownLink {
|
||||
foreach ($webfinger->getLinks() as $link) {
|
||||
if ($link->getRel() === $rel) {
|
||||
return $link;
|
||||
}
|
||||
}
|
||||
|
||||
throw new WellKnownLinkNotFoundException();
|
||||
}
|
||||
|
||||
}
|
||||
|
258
lib/Tools/Traits/TStringTools.php
Normal file
258
lib/Tools/Traits/TStringTools.php
Normal file
|
@ -0,0 +1,258 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Circles - Bring cloud-users closer together.
|
||||
*
|
||||
* 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 OCA\Circles\Tools\Traits;
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
|
||||
trait TStringTools {
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function token(int $length = 15): string {
|
||||
$chars = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890';
|
||||
|
||||
$str = '';
|
||||
$max = strlen($chars);
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
try {
|
||||
$str .= $chars[random_int(0, $max - 2)];
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate uuid: 2b5a7a87-8db1-445f-a17b-405790f91c80
|
||||
*
|
||||
* @param int $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function uuid(int $length = 0): string {
|
||||
$uuid = sprintf(
|
||||
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
|
||||
);
|
||||
|
||||
if ($length > 0) {
|
||||
if ($length <= 16) {
|
||||
$uuid = str_replace('-', '', $uuid);
|
||||
}
|
||||
|
||||
$uuid = substr($uuid, 0, $length);
|
||||
}
|
||||
|
||||
return $uuid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
* @param int $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function cut(string $line, int $length): string {
|
||||
if (strlen($line) < $length) {
|
||||
return $line;
|
||||
}
|
||||
|
||||
return substr($line, 0, $length - 5) . ' (..)';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str1
|
||||
* @param string $str2
|
||||
* @param bool $cs case sensitive ?
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function commonPart(string $str1, string $str2, bool $cs = true): string {
|
||||
for ($i = 0; $i < strlen($str1) && $i < strlen($str2); $i++) {
|
||||
$chr1 = $str1[$i];
|
||||
$chr2 = $str2[$i];
|
||||
|
||||
if (!$cs) {
|
||||
$chr1 = strtolower($chr1);
|
||||
$chr2 = strtolower($chr2);
|
||||
}
|
||||
|
||||
if ($chr1 !== $chr2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return substr($str1, 0, $i);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
* @param array $params
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function feedStringWithParams(string $line, array $params): string {
|
||||
$ak = array_keys($params);
|
||||
foreach ($ak as $k) {
|
||||
$line = str_replace('{' . $k . '}', (string)$params[$k], $line);
|
||||
}
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $words
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateRandomSentence(int $words = 5): string {
|
||||
$sentence = [];
|
||||
for ($i = 0; $i < $words; $i++) {
|
||||
$sentence[] = $this->generateRandomWord(rand(2, 12));
|
||||
}
|
||||
|
||||
return implode(' ', $sentence);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateRandomWord(int $length = 8): string {
|
||||
$c = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 's', 't', 'v'];
|
||||
$v = ['a', 'e', 'i', 'o', 'u', 'y'];
|
||||
|
||||
$word = [];
|
||||
for ($i = 0; $i <= ($length / 2); $i++) {
|
||||
$word[] = $c[array_rand($c)];
|
||||
$word[] = $v[array_rand($v)];
|
||||
}
|
||||
|
||||
return implode('', $word);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $bytes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function humanReadable(int $bytes): string {
|
||||
if ($bytes == 0) {
|
||||
return '0.00 B';
|
||||
}
|
||||
|
||||
$s = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
||||
$e = floor(log($bytes, 1024));
|
||||
|
||||
return round($bytes / pow(1024, $e), 2) . ' ' . $s[$e];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $first
|
||||
* @param int $second
|
||||
* @param bool $short
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getDateDiff(
|
||||
int $first,
|
||||
int $second = 0,
|
||||
bool $short = false,
|
||||
array $words = []
|
||||
): string {
|
||||
if ($second === 0) {
|
||||
$first = time() - $first;
|
||||
$second = time();
|
||||
}
|
||||
|
||||
$f = new DateTime('@' . $first);
|
||||
$s = new DateTime('@' . $second);
|
||||
$duration = $second - $first;
|
||||
if ($short) {
|
||||
$minutes = $this->get('minutes', $words, 'M');
|
||||
$hours = $this->get('hours', $words, 'H');
|
||||
$days = $this->get('days', $words, 'D');
|
||||
|
||||
if ($duration < 60) {
|
||||
return $f->diff($s)->format('<1' . $minutes);
|
||||
}
|
||||
if ($duration < 3600) {
|
||||
return $f->diff($s)->format('%i' . $minutes);
|
||||
}
|
||||
if ($duration < 86400) {
|
||||
return $f->diff($s)->format('%h' . $hours . ', %i' . $minutes);
|
||||
}
|
||||
|
||||
return $f->diff($s)->format('%a' . $days . ', %h' . $hours . ', %i' . $minutes);
|
||||
}
|
||||
|
||||
$seconds = $this->get('seconds', $words, 'seconds');
|
||||
$minutes = $this->get('minutes', $words, 'minutes');
|
||||
$hours = $this->get('hours', $words, 'hours');
|
||||
$days = $this->get('days', $words, 'days');
|
||||
if ($duration < 60) {
|
||||
return $f->diff($s)->format('%s ' . $seconds);
|
||||
}
|
||||
|
||||
if ($duration < 3600) {
|
||||
return $f->diff($s)->format('%i ' . $minutes . ' and %s ' . $seconds);
|
||||
}
|
||||
|
||||
if ($duration < 86400) {
|
||||
return $f->diff($s)->format('%h ' . $hours . ', %i ' . $minutes . ' and %s ' . $seconds);
|
||||
}
|
||||
|
||||
return $f->diff($s)->format(
|
||||
'%a ' . $days .
|
||||
', %h ' . $hours .
|
||||
', %i ' . $minutes .
|
||||
' and %s ' . $seconds
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue