Refreshing current user’s identity

Nette stores current user’s identity in session. There are a few situations when you want to reload the identity or change it completely. For example, the user updates his profile and you want the change reflected in the page header. Or a super administrator is allowed to re-authenticate as a different user without having to know the other user’s password.

NUser has a convenient method called setIdentity() but unfortunately, it’s declared as private so you can’t use it. The solution is either to loop through the current identity and update its fields one by one, or do it nice and clean with a custom authenticator. Let me show you.

Here’s the looping method. It just does the job.

  1.  
  2. $values = array(‘id’ => 123, ‘name’ => ‘Joe Sixpack’, ‘role’ => ‘administrator’);
  3. $currentIdentity = $this->parent->getUser()->getIdentity();
  4.        
  5. foreach ($values as $attribute => $value) {
  6.   $currentIdentity->$attribute = $value;
  7. }
  8.  

And here’s the custom authenticator. One for refreshing updated profile and another one for swapping identities.

  1.  
  2. class DummyAuthenticator implements IAuthenticator {
  3.   public function authenticate(array $credentials) {
  4.     list($values) = $credentials;
  5.     return new NIdentity($values[‘id’], null, $values);
  6.   }
  7. }
  8.  
  9. // in presenter
  10. $user = $this->getUser();
  11. $newValues = UserModel::getById($user->getIdentity()->id);
  12. $user->setAuthenticator(new DummyAuthenticator);
  13. $user->login($newValues);
  14.  

In this example, the authenticator actually does some job – it verifies that the current user is allowed to change his identity. It’s in fact authorization, not authentication, but that’s not the point here.

  1.  
  2. class ReAuthenticator implements IAuthenticator {
  3.   public function authenticate(array $credentials) {
  4.     list($currentIdentity, $newUserId) = $credentials;
  5.     $newUser = UserModel::getById($newUserId);
  6.    
  7.     if (($currentIdentity->role == ‘administrator’) && in_array($newUser[‘role’], array(‘consultant’, ‘manager’))) {
  8.       return new NIdentity($newUser[‘id’], null, $newUser);
  9.     }
  10.     if (($currentIdentity->role == ‘consultant’) && ($newUser[‘role’] == ‘manager’)) {
  11.       return new NIdentity($newUser[‘id’], null, $newUser);
  12.     }
  13.    
  14.     throw new NAuthenticationException("Insufficient permissions.", self::NOT_APPROVED);
  15.   }
  16. }
  17.  
  18. // in presenter
  19. try {
  20.   $user = $this->getUser();
  21.   $user->setAuthenticator(new ReAuthenticator);
  22.   $user->login($user->getIdentity(), 1234);
  23. } catch (NAuthenticationException $e) {
  24.   …
  25. }
  26.  

Tags:

Leave a Reply