From d713429d8867c84bd598050dd51cf9729097bc81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Marques?= Date: Mon, 10 Jan 2022 11:29:37 +0000 Subject: [PATCH] [CORE][Nickname] Properly set nickname for existing accounts --- components/Group/Controller/Group.php | 2 +- components/Group/Entity/LocalGroup.php | 31 ++++++++++++++++++++++++++ src/Controller/UserPanel.php | 2 +- src/Entity/LocalUser.php | 10 ++++----- src/Util/Form/ActorForms.php | 7 +++--- src/Util/Nickname.php | 16 +++++++++---- 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/components/Group/Controller/Group.php b/components/Group/Controller/Group.php index 99f36e8ffa..a7dc634e59 100644 --- a/components/Group/Controller/Group.php +++ b/components/Group/Controller/Group.php @@ -166,7 +166,7 @@ class Group extends FeedController return [ '_template' => 'group/settings.html.twig', 'group' => $group, - 'personal_info_form' => ActorForms::personalInfo($request, $group)->createView(), + 'personal_info_form' => ActorForms::personalInfo($request, $actor, $group)->createView(), 'open_details_query' => $this->string('open'), ]; } else { diff --git a/components/Group/Entity/LocalGroup.php b/components/Group/Entity/LocalGroup.php index b747def890..eb04677c6e 100644 --- a/components/Group/Entity/LocalGroup.php +++ b/components/Group/Entity/LocalGroup.php @@ -21,10 +21,18 @@ declare(strict_types = 1); namespace Component\Group\Entity; +use App\Core\Cache; use App\Core\DB\DB; use App\Core\Entity; use App\Entity\Actor; +use App\Util\Exception\NicknameEmptyException; +use App\Util\Exception\NicknameException; +use App\Util\Exception\NicknameInvalidException; +use App\Util\Exception\NicknameNotAllowedException; +use App\Util\Exception\NicknameTakenException; +use App\Util\Exception\NicknameTooLongException; +use App\Util\Nickname; use DateTimeInterface; /** @@ -114,6 +122,29 @@ class LocalGroup extends Entity return $res === [] ? null : $res[0]; } + /** + * Checks if desired nickname is allowed, and in case it is, it sets Actor's nickname cache to newly set nickname + * + * @param string $nickname Desired NEW nickname (do not use in local user creation) + * + * @throws NicknameEmptyException + * @throws NicknameException + * @throws NicknameInvalidException + * @throws NicknameNotAllowedException + * @throws NicknameTakenException + * @throws NicknameTooLongException + * + * @return $this + */ + public function setNicknameSanitizedAndCached(string $nickname): self + { + $nickname = Nickname::normalize($nickname, check_already_used: true, which: Nickname::CHECK_LOCAL_GROUP, check_is_allowed: true); + $this->setNickname($nickname); + $this->getActor()->setNickname($nickname); + /// XXX: cache? + return $this; + } + public static function schemaDef(): array { return [ diff --git a/src/Controller/UserPanel.php b/src/Controller/UserPanel.php index 139fdd168e..85fe80cd46 100644 --- a/src/Controller/UserPanel.php +++ b/src/Controller/UserPanel.php @@ -77,7 +77,7 @@ class UserPanel extends Controller $user = Common::ensureLoggedIn(); $actor = $user->getActor(); - $personal_form = ActorForms::personalInfo($request, $actor); + $personal_form = ActorForms::personalInfo($request, $actor, $user); $email_form = self::email($request); $password_form = self::password($request); $notifications_form_array = self::notifications($request); diff --git a/src/Entity/LocalUser.php b/src/Entity/LocalUser.php index fc5147819f..f86a4fe98d 100644 --- a/src/Entity/LocalUser.php +++ b/src/Entity/LocalUser.php @@ -29,6 +29,7 @@ use App\Core\Entity; use App\Core\UserRoles; use App\Util\Common; use App\Util\Exception\NicknameEmptyException; +use App\Util\Exception\NicknameException; use App\Util\Exception\NicknameInvalidException; use App\Util\Exception\NicknameNotAllowedException; use App\Util\Exception\NicknameTakenException; @@ -349,19 +350,18 @@ class LocalUser extends Entity implements UserInterface, PasswordAuthenticatedUs /** * Checks if desired nickname is allowed, and in case it is, it sets Actor's nickname cache to newly set nickname * - * @param string $nickname Desired new nickname - * + * @param string $nickname Desired NEW nickname (do not use in local user creation) + * @return $this * @throws NicknameEmptyException * @throws NicknameInvalidException * @throws NicknameNotAllowedException * @throws NicknameTakenException * @throws NicknameTooLongException - * - * @return $this + * @throws NicknameException */ public function setNicknameSanitizedAndCached(string $nickname): self { - $nickname = Nickname::normalize($nickname, check_already_used: false, which: Nickname::CHECK_LOCAL_USER, check_is_allowed: true); + $nickname = Nickname::normalize($nickname, check_already_used: true, which: Nickname::CHECK_LOCAL_USER, check_is_allowed: true); $this->setNickname($nickname); $this->getActor()->setNickname($nickname); Cache::delete(self::cacheKeys($this->getId())['nickname']); diff --git a/src/Util/Form/ActorForms.php b/src/Util/Form/ActorForms.php index d84462094e..3f1d724c0f 100644 --- a/src/Util/Form/ActorForms.php +++ b/src/Util/Form/ActorForms.php @@ -46,6 +46,7 @@ use App\Util\Exception\NicknameTakenException; use App\Util\Exception\NicknameTooLongException; use App\Util\Exception\NoLoggedInUser; use App\Util\Exception\ServerException; +use Component\Group\Entity\LocalGroup; use Misd\PhoneNumberBundle\Form\Type\PhoneNumberType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; @@ -65,7 +66,7 @@ class ActorForms * @throws NoLoggedInUser * @throws ServerException */ - public static function personalInfo(Request $request, Actor $target, ?LocalUser $user = null): mixed + public static function personalInfo(Request $request, Actor $target, LocalUser|LocalGroup $user): mixed { // Defining the various form fields $form_definition = [ @@ -80,9 +81,7 @@ class ActorForms // Setting nickname normalised and setting actor cache $extra_step = function ($data, $extra_args) use ($user, $target) { - if (!\is_null($user)) { - $user->setNicknameSanitizedAndCached($data['nickname']); - } + $user->setNicknameSanitizedAndCached($data['nickname']); $cache_keys = Actor::cacheKeys($target->getId()); foreach (['id', 'nickname', 'fullname'] as $key) { diff --git a/src/Util/Nickname.php b/src/Util/Nickname.php index 39103558b1..f234458799 100644 --- a/src/Util/Nickname.php +++ b/src/Util/Nickname.php @@ -24,6 +24,7 @@ declare(strict_types = 1); namespace App\Util; use App\Core\DB\DB; +use App\Entity\LocalUser; use App\Util\Exception\BugFoundException; use App\Util\Exception\DuplicateFoundException; use App\Util\Exception\NicknameEmptyException; @@ -33,7 +34,7 @@ use App\Util\Exception\NicknameNotAllowedException; use App\Util\Exception\NicknameTakenException; use App\Util\Exception\NicknameTooLongException; use App\Util\Exception\NotFoundException; -use App\Util\Exception\NotImplementedException; +use Component\Group\Entity\LocalGroup; use Functional as F; use InvalidArgumentException; @@ -150,7 +151,7 @@ class Nickname switch ($which) { case self::CHECK_LOCAL_USER: try { - $lu = DB::findOneBy('local_user', ['nickname' => $nickname]); + $lu = DB::findOneBy(LocalUser::class, ['nickname' => $nickname]); throw new NicknameTakenException($lu->getActor()); } catch (NotFoundException) { // continue @@ -158,9 +159,16 @@ class Nickname throw new BugFoundException("Duplicate entry in `local_user` for nickname={$nickname}"); } break; - // @codeCoverageIgnoreStart case self::CHECK_LOCAL_GROUP: - throw new NotImplementedException(); + try { + $lg = DB::findOneBy(LocalGroup::class, ['nickname' => $nickname]); + throw new NicknameTakenException($lg->getActor()); + } catch (NotFoundException) { + // continue + } catch (DuplicateFoundException) { + throw new BugFoundException("Duplicate entry in `local_group` for nickname={$nickname}"); + } + break; // @codeCoverageIgnoreStart default: throw new InvalidArgumentException(); // @codeCoverageIgnoreEnd