Details

    • [2.1] Sprint 5

    Description

      Public API UserService is missing methods to manipulate User tokens stored in ezuser_accountkey.

      Spec for UserService API:

      public function loadUserByToken(string $hash, array $prioritizedLanguages = []);
      
      public function updateUserToken(User $user, UserTokenUpdateStruct $userTokenUpdateStruct);
      
      public function expireUserToken(string $hash);
      
      class UserTokenUpdateStruct extends ValueObject
      {
          /** @var string */
          public $hashKey;
      
          /** @var \DateTime|null */
          public $time;
      }
      

      Instead of "accountkey", "token" was used as this name was self-explanatory and "accountkey" wasn't, at least to me. We did the same thing with ContentClass -> ContentType earlier, so it shouldn't be a problem.

      Since password is updated by UserService::updateUser which internally uses ContentService, some changes are required in order to avoid a very common use case where user who changes his password doesn't have content / edit permission.

      1. In the Core UserService constructor set PermissionResolver property (obtained from Repository).
      2. In UserService::updateUser wrap content / edit permission check with the conditions that are needed for content to be updated (as discussed internally).
      3. Check user / password policy if UserUpdateStruct has new password.
      4. To keep BC allow updating password if user has content / edit policy.

      Possible pieces of the puzzle:

      // ...
      
      $canEditContent = $this->permissionResolver->canUser('content', 'edit', $loadedUser);
      if ($userUpdateStruct->contentUpdateStruct !== null || $userUpdateStruct->contentMetadataUpdateStruct !== null) {
          if (!$canEditContent) {
              throw new UnauthorizedException('content', 'edit');
          }
      }
      
      // ...
      
      if ($userUpdateStruct->password !== null) {
          // BC: if user can edit content, he also can update password
          if (!$canEditContent && !$this->permissionResolver->canUser('user', 'password', $loadedUser)) {
              throw new UnauthorizedException('user', 'password');
          }
      }
      

      Note: I now see that userHandler->update updates more properties, so I think in that case also content / edit check is needed, since there are no other policies for that (email, enabled, maxLogin). Feel free to adjust and reorganize code to make it more clear and readable.

      Attachments

        Activity

          People

            Unassigned Unassigned
            andrew.longosz@ibexa.co Andrew Longosz
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: