graphql_core_schema-1.0.x-dev/src/Plugin/GraphQL/DataProducer/User/PasswordChange.php

src/Plugin/GraphQL/DataProducer/User/PasswordChange.php
<?php

declare(strict_types=1);

namespace Drupal\graphql_core_schema\Plugin\GraphQL\DataProducer\User;

use Drupal\graphql_core_schema\Plugin\GraphQL\UserMutationBase;
use Drupal\user\UserInterface;
use Symfony\Component\Validator\ConstraintViolationInterface;

/**
 * Change a users password.
 *
 * Either the currentPassword or the passResetToken must be provided.
 *
 * @DataProducer(
 *   id = "user_password_change",
 *   name = @Translation("User Password Change"),
 *   description = @Translation("Change the password of a user."),
 *   produces = @ContextDefinition("any",
 *     label = @Translation("The password change result."),
 *     required = FALSE,
 *   ),
 *   consumes = {
 *     "user" = @ContextDefinition("entity:user",
 *       label = @Translation("The user to change the password for."),
 *     ),
 *     "newPassword" = @ContextDefinition("string",
 *       label = @Translation("The user's desired new password."),
 *     ),
 *     "currentPassword" = @ContextDefinition("string",
 *       label = @Translation("The user's current password."),
 *       required = FALSE,
 *     ),
 *     "passResetToken" = @ContextDefinition("string",
 *       label = @Translation("The pass-reset-token query param."),
 *       required = FALSE,
 *     ),
 *   }
 * )
 */
class PasswordChange extends UserMutationBase {

  /**
   * The resolver.
   *
   * @param UserInterface $user
   *   The user to change the password for.
   * @param string $newPassword
   *   The new password.
   * @param string|null $currentPassword
   *   The current password of the user.
   * @param string|null $passResetToken
   *   The pass-reset-token value.
   *
   * @return array
   *   The error message array.
   */
  public function resolve(UserInterface $user, string $newPassword, ?string $currentPassword, ?string $passResetToken) {
    $error = $this->changePassword($user, $newPassword, $currentPassword, $passResetToken);

    return [
      'success' => empty($error),
      'error' => $error,
    ];
  }

  /**
   * The resolver.
   *
   * @param UserInterface $user
   *   The user to change the password for.
   * @param string $newPassword
   *   The new password.
   * @param string|null $currentPassword
   *   The current password of the user.
   * @param string|null $passResetToken
   *   The pass-reset-token value.
   *
   * @return string
   *   The error message.
   */
  public function changePassword(UserInterface $user, string $newPassword, ?string $currentPassword, ?string $passResetToken) {
    // Make sure either current password or the reset token are provided.
    if (!$currentPassword && !$passResetToken) {
      return $this->t('Either currentPassword or passResetToken must be provided.');
    }

    // Check if the user is allowed to edit the password.
    $access = $user->pass->access('edit', NULL, TRUE);

    if (!$access->isAllowed()) {
      return $this->t('Access denied');
    }

    $currentRequest = $this->requestStack->getCurrentRequest();
    $session = $currentRequest->getSession();
    $uid = $user->id();
    $sessionKey = 'pass_reset_' . $uid;

    if ($passResetToken) {
      // Make sure the token provided by the user is the same as the one in
      // the session.
      $tokenFromSession = $session->get($sessionKey);
      $tokenIsValid = $tokenFromSession && hash_equals($tokenFromSession, $passResetToken);

      if (!$tokenIsValid) {
        return $this->t('The provided passResetToken is invalid.');
      }

      // @see \Drupal\user\AccountForm::buildEntity
      // This is the magic that allows us to set a new password without
      // providing the existing one. We can do that here because we have made
      // sure that the passResetToken is valid.
      //
      // This value is checked here:
      // \Drupal\user\Plugin\Validation\Constraint\ProtectedUserFieldConstraintValidator::validate
      $user->_skipProtectedUserFieldConstraint = TRUE;
    }
    else {
      $user->setExistingPassword($currentPassword);
    }

    $user->setPassword($newPassword);
    $validations = $user->validate();
    if ($validations->count() === 0) {
      $session->remove($sessionKey);
      $user->save();

      // Set to false again because we're done with our stuff.
      $user->_skipProtectedUserFieldConstraint = FALSE;
      return '';
    }

    $messages = array_map(function (ConstraintViolationInterface $violation) {
      return $violation->getMessage();
    }, iterator_to_array($validations));

    return strip_tags(implode(', ', $messages));
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc