edit displayName/description

Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
This commit is contained in:
Maxence Lange 2021-04-22 11:42:41 -01:00
parent 7ab38e90c9
commit bfe211566e
8 changed files with 437 additions and 18 deletions

View file

@ -69,6 +69,7 @@ Users won't be able to find this Circle using Nextcloud search engine.
<command>OCA\Circles\Command\CirclesRemote</command>
<command>OCA\Circles\Command\MembersList</command>
<command>OCA\Circles\Command\MembersSearch</command>
<command>OCA\Circles\Command\CirclesEdit</command>
<command>OCA\Circles\Command\CirclesMemberships</command>

View file

@ -49,9 +49,9 @@ return [
['name' => 'Local#circleJoin', 'url' => '/circles/{circleId}/join', 'verb' => 'PUT'],
['name' => 'Local#circleLeave', 'url' => '/circles/{circleId}/leave', 'verb' => 'PUT'],
// to implement
['name' => 'Local#getSettings', 'url' => '/circles/{circleId}/settings', 'verb' => 'GET'],
['name' => 'Local#setSettings', 'url' => '/circles/{circleId}/settings', 'verb' => 'PUT']
['name' => 'Local#editDisplayName', 'url' => '/circles/{circleId}/displayName', 'verb' => 'PUT'],
['name' => 'Local#editDescription', 'url' => '/circles/{circleId}/description', 'verb' => 'PUT'],
['name' => 'Local#editSettings', 'url' => '/circles/{circleId}/settings', 'verb' => 'PUT']
],
'routes' => [

166
lib/Command/CirclesEdit.php Normal file
View file

@ -0,0 +1,166 @@
<?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 2021
* @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\Command;
use OC\Core\Command\Base;
use OCA\Circles\Exceptions\CircleNotFoundException;
use OCA\Circles\Exceptions\FederatedItemException;
use OCA\Circles\Exceptions\FederatedUserException;
use OCA\Circles\Exceptions\FederatedUserNotFoundException;
use OCA\Circles\Exceptions\InvalidIdException;
use OCA\Circles\Exceptions\MemberNotFoundException;
use OCA\Circles\Exceptions\OwnerNotFoundException;
use OCA\Circles\Exceptions\RemoteInstanceException;
use OCA\Circles\Exceptions\RemoteNotFoundException;
use OCA\Circles\Exceptions\RemoteResourceNotFoundException;
use OCA\Circles\Exceptions\SingleCircleNotFoundException;
use OCA\Circles\Exceptions\UnknownRemoteException;
use OCA\Circles\Exceptions\UserTypeNotFoundException;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\FederatedUserService;
use OCP\IL10N;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class CirclesEdit
*
* @package OCA\Circles\Command
*/
class CirclesEdit extends Base {
/** @var FederatedUserService */
private $federatedUserService;
/** @var CircleService */
private $circleService;
/**
* CirclesEdit constructor.
*
* @param IL10N $l10n
* @param FederatedUserService $federatedUserService
* @param CircleService $circlesService
* @param ConfigService $configService
*/
public function __construct(
IL10N $l10n, FederatedUserService $federatedUserService, CircleService $circlesService,
ConfigService $configService
) {
parent::__construct();
$this->federatedUserService = $federatedUserService;
$this->circleService = $circlesService;
}
/**
*
*/
protected function configure() {
parent::configure();
$this->setName('circles:manage:edit')
->setDescription('edit displayName or description of a Circle')
->addArgument('circle_id', InputArgument::REQUIRED, 'ID of the circle')
->addArgument('edit', InputArgument::REQUIRED, 'displayName or description')
->addArgument('value', InputArgument::REQUIRED, 'new value')
->addOption('initiator', '', InputOption::VALUE_REQUIRED, 'set an initiator to the request', '')
->addOption('status-code', '', InputOption::VALUE_NONE, 'display status code on exception');
}
/**
* @param InputInterface $input
* @param OutputInterface $output
*
* @return int
* @throws FederatedItemException
* @throws CircleNotFoundException
* @throws FederatedUserException
* @throws FederatedUserNotFoundException
* @throws InvalidIdException
* @throws MemberNotFoundException
* @throws OwnerNotFoundException
* @throws RemoteInstanceException
* @throws RemoteNotFoundException
* @throws RemoteResourceNotFoundException
* @throws SingleCircleNotFoundException
* @throws UnknownRemoteException
* @throws UserTypeNotFoundException
*/
protected function execute(InputInterface $input, OutputInterface $output): int {
$circleId = (string)$input->getArgument('circle_id');
$edit = strtolower((string)$input->getArgument('edit'));
$newValue = (string)$input->getArgument('value');
try {
$this->federatedUserService->commandLineInitiator(
$input->getOption('initiator'), $circleId, false
);
switch ($edit) {
case 'displayname':
$outcome = $this->circleService->updateDisplayName($circleId, $newValue);
break;
case 'description':
$outcome = $this->circleService->updateDescription($circleId, $newValue);
break;
default:
throw new InvalidArgumentException('edit can only be \'displayName\' or \'description\'');
}
} catch (FederatedItemException $e) {
if ($input->getOption('status-code')) {
throw new FederatedItemException(
' [' . get_class($e) . ', ' . $e->getStatus() . ']' . "\n" . $e->getMessage()
);
}
throw $e;
}
$output->writeln(json_encode($outcome, JSON_PRETTY_PRINT));
return 0;
}
}

View file

@ -366,6 +366,53 @@ class LocalController extends OcsController {
}
/**
* @param string $circleId
* @param string $displayName
*
* @return DataResponse
* @throws OCSException
*/
public function editDisplayName(string $circleId, string $displayName): DataResponse {
try {
$this->circleService->updateDisplayName($circleId, $displayName);
} catch (Exception $e) {
throw new OCSException($e->getMessage(), $e->getCode());
}
}
/**
* @param array $settings
*
* @return DataResponse
* @throws OCSException
*/
public function editDescription(string $circleId, string $description): DataResponse {
try {
$this->circleService->updateDescription($circleId, $description);
} catch (Exception $e) {
throw new OCSException($e->getMessage(), $e->getCode());
}
}
/**
* @param string $circleId
* @param array $settings
*
* @return DataResponse
* @throws OCSException
*/
public function editSettings(string $circleId, array $settings): DataResponse {
try {
$this->circleService->updateSettings($circleId, $settings);
} catch (Exception $e) {
throw new OCSException($e->getMessage(), $e->getCode());
}
}
/**
* @throws FederatedUserNotFoundException
* @throws InvalidIdException

View file

@ -78,6 +78,19 @@ class CircleRequest extends CircleRequestBuilder {
}
/**
* @param Circle $circle
*/
public function edit(Circle $circle): void {
$qb = $this->getCircleUpdateSql();
$qb->set('display_name', $qb->createNamedParameter($circle->getDisplayName()))
->set('description', $qb->createNamedParameter($circle->getDescription()));
$qb->limitToUniqueId($circle->getSingleId());
$qb->execute();
}
/**
* @param Circle $circle
*/

View file

@ -33,14 +33,12 @@ namespace OCA\Circles\FederatedItems;
use OCA\Circles\Db\CircleRequest;
use OCA\Circles\Db\MemberRequest;
use OCA\Circles\Exceptions\FederatedItemBadRequestException;
use OCA\Circles\Exceptions\FederatedItemException;
use OCA\Circles\IFederatedItem;
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\Federated\FederatedEvent;
use OCA\Circles\Model\Helpers\MemberHelper;
use OCA\Circles\Service\ConfigService;
/**
@ -54,26 +52,14 @@ class CircleConfig implements IFederatedItem {
/** @var CircleRequest */
private $circleRequest;
/** @var MemberRequest */
private $memberRequest;
/** @var ConfigService */
private $configService;
/**
* CircleConfig constructor.
*
* @param CircleRequest $circleRequest
* @param MemberRequest $memberRequest
* @param ConfigService $configService
*/
public function __construct(
CircleRequest $circleRequest, MemberRequest $memberRequest, ConfigService $configService
) {
public function __construct(CircleRequest $circleRequest) {
$this->circleRequest = $circleRequest;
$this->memberRequest = $memberRequest;
$this->configService = $configService;
}

View 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 2021
* @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\FederatedItems;
use OCA\Circles\Db\CircleRequest;
use OCA\Circles\IFederatedItem;
use OCA\Circles\Model\Federated\FederatedEvent;
use OCA\Circles\Model\Helpers\MemberHelper;
/**
* Class CircleEdit
*
* @package OCA\Circles\FederatedItems
*/
class CircleEdit implements IFederatedItem {
/** @var CircleRequest */
private $circleRequest;
/**
* CircleEdit constructor.
*
* @param CircleRequest $circleRequest
*/
public function __construct(CircleRequest $circleRequest) {
$this->circleRequest = $circleRequest;
}
/**
* @param FederatedEvent $event
*/
public function verify(FederatedEvent $event): void {
$circle = $event->getCircle();
$initiatorHelper = new MemberHelper($circle->getInitiator());
$initiatorHelper->mustBeOwner();
$data = $event->getData();
$new = clone $circle;
if ($data->hasKey('displayName')) {
$new->setDisplayName($data->g('displayName'));
}
if ($data->hasKey('description')) {
$new->setDisplayName($data->g('description'));
}
$event->setOutcome($new->jsonSerialize());
}
/**
* @param FederatedEvent $event
*/
public function manage(FederatedEvent $event): void {
$circle = clone $event->getCircle();
$data = $event->getData();
// TODO: verify that event->GetCircle() is updated by the instance that owns the Circle so we can
// use it as a thrustable base
if ($data->hasKey('displayName')) {
$circle->setDisplayName($data->g('displayName'));
}
if ($data->hasKey('description')) {
$circle->setDescription($data->g('description'));
}
$this->circleRequest->edit($circle);
}
/**
* @param FederatedEvent $event
* @param array $results
*/
public function result(FederatedEvent $event, array $results): void {
}
}

View file

@ -52,8 +52,10 @@ use OCA\Circles\Exceptions\UnknownRemoteException;
use OCA\Circles\FederatedItems\CircleConfig;
use OCA\Circles\FederatedItems\CircleCreate;
use OCA\Circles\FederatedItems\CircleDestroy;
use OCA\Circles\FederatedItems\CircleEdit;
use OCA\Circles\FederatedItems\CircleJoin;
use OCA\Circles\FederatedItems\CircleLeave;
use OCA\Circles\FederatedItems\CircleSettings;
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\Federated\FederatedEvent;
use OCA\Circles\Model\FederatedUser;
@ -233,6 +235,94 @@ class CircleService {
}
/**
* @param string $circleId
* @param string $displayName
*
* @return array
* @throws CircleNotFoundException
* @throws FederatedEventException
* @throws FederatedItemException
* @throws InitiatorNotConfirmedException
* @throws InitiatorNotFoundException
* @throws OwnerNotFoundException
* @throws RemoteInstanceException
* @throws RemoteNotFoundException
* @throws RemoteResourceNotFoundException
* @throws RequestBuilderException
* @throws UnknownRemoteException
*/
public function updateDisplayName(string $circleId, string $displayName) {
$circle = $this->getCircle($circleId);
$event = new FederatedEvent(CircleEdit::class);
$event->setCircle($circle);
$event->setData(new SimpleDataStore(['displayName' => $displayName]));
$this->federatedEventService->newEvent($event);
return $event->getOutcome();
}
/**
* @param string $circleId
* @param string $description
*
* @return array
* @throws CircleNotFoundException
* @throws FederatedEventException
* @throws FederatedItemException
* @throws InitiatorNotConfirmedException
* @throws InitiatorNotFoundException
* @throws OwnerNotFoundException
* @throws RemoteInstanceException
* @throws RemoteNotFoundException
* @throws RemoteResourceNotFoundException
* @throws RequestBuilderException
* @throws UnknownRemoteException
*/
public function updateDescription(string $circleId, string $description) {
$circle = $this->getCircle($circleId);
$event = new FederatedEvent(CircleEdit::class);
$event->setCircle($circle);
$event->setData(new SimpleDataStore(['description' => $description]));
$this->federatedEventService->newEvent($event);
return $event->getOutcome();
}
/**
* @param string $circleId
* @param array $settings
*
* @return array
* @throws CircleNotFoundException
* @throws FederatedEventException
* @throws FederatedItemException
* @throws InitiatorNotConfirmedException
* @throws InitiatorNotFoundException
* @throws OwnerNotFoundException
* @throws RemoteInstanceException
* @throws RemoteNotFoundException
* @throws RemoteResourceNotFoundException
* @throws RequestBuilderException
* @throws UnknownRemoteException
*/
public function updateSettings(string $circleId, array $settings) {
$circle = $this->getCircle($circleId);
$event = new FederatedEvent(CircleSettings::class);
$event->setCircle($circle);
$event->setData(new SimpleDataStore(['settings' => $settings]));
$this->federatedEventService->newEvent($event);
return $event->getOutcome();
}
/**
* @param string $circleId
*