CasTest.php 6.62 KB
Newer Older
1
2
3
4
5
6
7
8
9
<?php
namespace UnicaenAuthTest\Authentication\Adapter;

use CAS_GracefullTerminationException;
use PHPUnit_Framework_TestCase;
use UnicaenApp\Exception;
use UnicaenAuth\Authentication\Adapter\Cas;
use Zend\EventManager\EventManager;
use ZfcUser\Authentication\Adapter\AdapterChainEvent;
10
use Zend\Authentication\Result;
11
12
13

define ('__VENDOR_DIR__', __DIR__ . '/../../../../vendor');

14
require_once __VENDOR_DIR__ . '/intouch/phpcas/CAS.php';
15

16
17
18
19
20
21
22
23
24
/**
 * Description of CasTest
 *
 * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
 */
class CasTest extends PHPUnit_Framework_TestCase
{
    protected $adapter;
    protected $moduleOptions;
25

26
27
28
29
30
31
    /**
     * Sets up the fixture, for example, open a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp()
    {
32
33
34
35
36
        $this->moduleOptions = $moduleOptions = new \UnicaenAuth\Options\ModuleOptions([
            'cas' => [
                'connection' => [
                    'default' => [
                        'params' => [
37
38
39
40
41
                            'hostname' => 'cas.unicaen.fr',
                            'port' => 443,
                            'version' => "2.0",
                            'uri' => "",
                            'debug' => false,
42
43
44
45
46
47
48
                        ],
                    ],
                ],
            ],
        ]);

        $serviceManager = $this->getMock('Zend\ServiceManager\ServiceManager', ['get']);
49
50
51
52
53
54
55
56
57
58
        $serviceManager->expects($this->any())
                       ->method('get')
                       ->will($this->returnCallback(function($serviceName) use ($moduleOptions) {
                           if ('zfcuser_module_options' === $serviceName) {
                               return new \ZfcUser\Options\ModuleOptions();
                           }
                           if ('unicaen-auth_module_options' === $serviceName) {
                               return $moduleOptions;
                           }
                           if ('router' === $serviceName) {
59
                               $router = new \Zend\Router\Http\TreeRouteStack();
60
61
62
63
64
                               $router->setBaseUrl('/appli')->setRequestUri(new \Zend\Uri\Http('/request'));
                               return $router;
                           }
                           return null;
                       }));
65

66
67
68
69
        $this->adapter = new Cas();
        $this->adapter->setServiceManager($serviceManager)
                      ->setEventManager(new EventManager());
    }
70

71
72
    public function getInvalidCasOptions()
    {
73
74
75
76
77
78
        return [
            [['other' => []]],
            [['connection' => []]],
            [['connection' => ['default'=> []]]],
            [['connection' => ['default'=> ['params' => []]]]],
        ];
79
    }
80

81
82
83
84
85
86
87
88
89
    /**
     * @dataProvider getInvalidCasOptions
     * @expectedException Exception
     */
    public function testThrowsExceptionIfNoCasParamSpecified($config)
    {
        $this->moduleOptions->setCas($config);
        $this->adapter->authenticate(new AdapterChainEvent());
    }
90

91
92
    public function testAuthenticateReturnsNullIfNoCasConfigSpecified()
    {
93
        $this->moduleOptions->setCas([]);
94
95
96
        $result = $this->adapter->authenticate(new AdapterChainEvent());
        $this->assertNull($result);
    }
97

98
99
    public function testCanActivateCasDebugMode()
    {
100
101
102
103
        $this->moduleOptions->setCas([
            'connection' => [
                'default' => [
                    'params' => [
104
105
106
107
108
                        'hostname' => 'cas.unicaen.fr',
                        'port' => 443,
                        'version' => "2.0",
                        'uri' => "",
                        'debug' => true, // debug mode
109
110
111
112
113
114
                    ],
                ],
            ],
        ]);

        $casClient = $this->getMock('phpCAS', ['setDebug', 'client', 'setNoCasServerValidation']);
115
116
117
118
119
120
        $casClient->staticExpects($this->once())
                  ->method('setDebug');
        $this->adapter->setCasClient($casClient);

        $this->adapter->getCasClient();
    }
121

122
123
124
    public function testCanRedirectToCasIfNotAuthenticated()
    {
        CAS_GracefullTerminationException::throwInsteadOfExiting();
125

126
127
128
129
130
131
        ob_start();
        try {
            $result = $this->adapter->authenticate(new AdapterChainEvent());
            $this->fail("Exception CAS_GracefullTerminationException non levée.");
        }
        catch (CAS_GracefullTerminationException $e) {
132

133
134
        }
        $result = ob_get_clean();
135

136
        $expected = <<<EOS
137
<html><head><title>CAS Authentication wanted!</title></head><body><h1>CAS Authentication wanted!</h1><p>You should already have been redirected to the CAS server. Click <a href="https://cas.unicaen.fr/login?service=http%3A%2F%2F%3A">here</a> to continue.</p><hr><address>phpCAS 1.3.2+ using server <a href="https://cas.unicaen.fr/">https://cas.unicaen.fr/</a> (CAS 2.0)</a></address></body></html>
138
139
140
EOS;
        $this->assertEquals($expected, $result);
    }
141

142
143
    public function testAuthenticateReturnsTrueWhenAuthenticationSucceeds()
    {
144
        $casClient = $this->getMock('phpCAS', ['client', 'forceAuthentication', 'getUser']);
145
146
147
        $casClient->staticExpects($this->once())
                  ->method('getUser')
                  ->will($this->returnValue($username = 'username'));
148

149
        $this->adapter->setCasClient($casClient);
150

151
        $event = new AdapterChainEvent();
152

153
        $result = $this->adapter->authenticate($event);
154

155
156
        $this->assertTrue($result);
        $this->assertTrue($this->adapter->isSatisfied());
157
158
        $this->assertEquals(['is_satisfied' => true, 'identity' => $username], $this->adapter->getStorage()->read());

159
        $this->assertEquals("userAuthenticated", $event->getName());
160
161
        $this->assertEquals(Result::SUCCESS, $event->getCode());
        $this->assertEquals($username, $event->getIdentity());
162
163
        $this->assertTrue($event->propagationIsStopped());
    }
164

165
166
    public function testLogoutReturnsNullIfNoCasConfigSpecified()
    {
167
        $this->moduleOptions->setCas([]);
168
169
170
        $result = $this->adapter->logout(new AdapterChainEvent());
        $this->assertNull($result);
    }
171

172
173
    public function testCanLogoutFromCasWithRedirectService()
    {
174
        $casClient = $this->getMock('phpCAS', ['client', 'isAuthenticated', 'logoutWithRedirectService']);
175
176
177
178
179
        $casClient->staticExpects($this->once())
                  ->method('isAuthenticated')
                  ->will($this->returnValue(true));
        $casClient->staticExpects($this->once())
                  ->method('logoutWithRedirectService');
180

181
        $this->adapter->setCasClient($casClient);
182

183
184
185
        $this->adapter->logout(new AdapterChainEvent());
    }
}