Completed
Push — 316-authentication-manager ( e36a80 )
by Jonathan
01:33
created

DrupalAuthenticationManager   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 6
dl 0
loc 115
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
B logIn() 0 29 5
A logout() 0 4 1
C loggedIn() 0 41 7
1
<?php
2
3
namespace Drupal\DrupalExtension\Manager;
4
5
use Behat\Mink\Exception\DriverException;
6
use Behat\Mink\Mink;
7
use Drupal\DrupalExtension\DrupalParametersTrait;
8
use Drupal\DrupalExtension\MinkAwareTrait;
9
10
/**
11
 * Default implementation of the Drupal authentication manager service.
12
 */
13
class DrupalAuthenticationManager implements DrupalAuthenticationManagerInterface
14
{
15
16
    use DrupalParametersTrait;
17
    use MinkAwareTrait;
18
19
    /**
20
     * The Drupal user manager.
21
     *
22
     * @var \Drupal\DrupalExtension\Manager\DrupalUserManagerInterface
23
     */
24
    protected $userManager;
25
26
    /**
27
     * Constructs a DrupalAuthenticationManager object.
28
     *
29
     * @param \Behat\Mink\Mink $mink
30
     *   The Mink sessions manager.
31
     * @param \Drupal\DrupalExtension\Manager\DrupalUserManagerInterface $drupalUserManager
32
     *   The Drupal user manager.
33
     */
34
    public function __construct(Mink $mink, DrupalUserManagerInterface $drupalUserManager, array $minkParameters, array $drupalParameters)
35
    {
36
        $this->setMink($mink);
37
        $this->userManager = $drupalUserManager;
38
        $this->setMinkParameters($minkParameters);
39
        $this->setDrupalParameters($drupalParameters);
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function logIn(\stdClass $user)
46
    {
47
        // Check if we are already logged in.
48
        if ($this->loggedIn()) {
49
            $this->logout();
50
        }
51
52
        $this->getSession()->visit($this->locatePath('/user'));
53
        $element = $this->getSession()->getPage();
54
        $element->fillField($this->getDrupalText('username_field'), $user->name);
55
        $element->fillField($this->getDrupalText('password_field'), $user->pass);
56
        $submit = $element->findButton($this->getDrupalText('log_in'));
57
        if (empty($submit)) {
58
            throw new \Exception(sprintf("No submit button at %s", $this->getSession()->getCurrentUrl()));
59
        }
60
61
        // Log in.
62
        $submit->click();
63
64
        if (!$this->loggedIn()) {
65
            if (isset($user->role)) {
66
                throw new \Exception(sprintf("Unable to determine if logged in because 'log_out' link cannot be found for user '%s' with role '%s'", $user->name, $user->role));
67
            } else {
68
                throw new \Exception(sprintf("Unable to determine if logged in because 'log_out' link cannot be found for user '%s'", $user->name));
69
            }
70
        }
71
72
        $this->userManager->setCurrentUser($user);
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function logout() {
79
        $this->getSession()->visit($this->locatePath('/user/logout'));
80
        $this->userManager->setCurrentUser(FALSE);
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function loggedIn() {
87
        $session = $this->getSession();
88
89
        // If the session has not been started yet, or no page has yet been loaded,
90
        // then this is a brand new test session and the user is not logged in.
91
        if (!$session->isStarted() || !$page = $session->getPage()) {
92
            return FALSE;
93
        }
94
95
        // Look for a css selector to determine if a user is logged in.
96
        // Default is the logged-in class on the body tag.
97
        // Which should work with almost any theme.
98
        try {
99
            if ($page->has('css', $this->getDrupalSelector('logged_in_selector'))) {
100
                return TRUE;
101
            }
102
        } catch (DriverException $e) {
103
            // This test may fail if the driver did not load any site yet.
104
        }
105
106
        // Some themes do not add that class to the body, so lets check if the
107
        // login form is displayed on /user/login.
108
        $session->visit($this->locatePath('/user/login'));
109
        if (!$page->has('css', $this->getDrupalSelector('login_form_selector'))) {
110
            return TRUE;
111
        }
112
113
        $session->visit($this->locatePath('/'));
114
115
        // As a last resort, if a logout link is found, we are logged in. While not
116
        // perfect, this is how Drupal SimpleTests currently work as well.
117
        if ($page->findLink($this->getDrupalText('log_out'))) {
118
            return TRUE;
119
        }
120
121
        // The user appears to be anonymous. Clear the current user from the user
122
        // manager so this reflects the actual situation.
123
        $this->userManager->setCurrentUser(FALSE);
124
125
        return FALSE;
126
    }
127
}
128