Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I know I should use services and patterns to refactor this controller action, but I can't imagine one that could fit/be appropriate for this problem.

It seems a strategy or template, but a strategy is supposed to be changed if needed; in my case, it should be always the same:

  1. Get the customer
    1. If doesn't exist store the error key (and dispatch/redirect)
    2. Otherwise continue
  2. Get current agent permission
    1. If special privileges, just continue
    2. Otherwise, check customer agent against current logged agent. In case of error, store the errore key (and dispatch/redirect)
  3. Check if customer is enabled, otherwise store the error key (and dispatch/redirect)
  4. Get customer users
    1. If there are no users, store the error key (and dispatch/redirect)
    2. Otherwise continue
  5. Pick the first user and check his privileges
    1. In case of errors, store the error key (and dispatch/redirect)
    2. Success, redirect

Actual code:

public function impersonateAction($id, Request $request)
{
    $referer = $this->redirect($request->headers->get('referer'));

    /** @var \CommonBundle\Model\CustomerInterface $customer */
    $customer = $this->get('common.repository.customer')
        ->find($id);

    /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher */
    $dispatcher = $this->get('event_dispatcher');

    $error = false;

    // Customer doesn't exist
    if (!$error && empty($customer)) {
        $error = Impersonate::CUSTOMER_NOT_FOUND_ERROR;
    }

    // Check current agent privileges
    if (!$error && !$this->isGranted(AgentInterface::ROLE_SUPER_AGENT)
        && $customer->getAgent() !== $this->getUser()) {
        $error = Impersonate::DENIED_ERROR;
    }

    // Customer is disabled
    if (!$error && !$customer->isEnabled()) {
        $error = Impersonate::CUSTOMER_DISABLED_ERRROR;
    }

    // There are no users for this customer
    /** @var \CommonBundle\Entity\Repository\UserRepositoryInterface $repository */
    $repository = $this->get('common.repository.user');
    if (!$error && !($users = $repository->findByCustomer($customer))) {
        $error = Impersonate::NO_USERS_ERROR;
    }

    // We have a candidate, forward the check to Symfony user checker
    if (!$error) {
        try {
            $this->get('security.user_checker')->checkPreAuth(current($users));
        } catch (\Exception $e) {
            $error = Impersonate::USER_UNKOWN_ERROR;

            if ($e instanceof LockedException) {
                $error = Impersonate::USER_LOCKED_ERROR;
            }

            if ($e instanceof DisabledException) {
                $error = Impersonate::USER_DISABLED_ERROR;
            }

            if ($e instanceof AccountExpiredException) {
                $error = Impersonate::USER_ACCOUNT_EXPIRED;
            }
        }
    }

    // Dispatch the error and redirect to referer
    if ($error) {
        $dispatcher->dispatch(
            AgentEvents::CUSTOMER_IMPERSONATE_ERROR,
            new ImpersonateEvent($this->trans($error))
        );
    }

    // Success
    $this->loginUser(
        $user,
        $this->container->getParameter('agent.impersonate.firewall_name')
    );

    return $this->redirect($this->generateUrl(
        $this->container->getParameter('agent.impersonate.target_path')
    ));
}
share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.