統計
| ブランチ: | リビジョン:

pictcode / lib / Cake / Test / Case / Controller / Component / AuthComponentTest.php @ 635eef61

履歴 | 表示 | アノテート | ダウンロード (49.379 KB)

1
<?php
2
/**
3
 * AuthComponentTest file
4
 *
5
 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14
 * @package       Cake.Test.Case.Controller.Component
15
 * @since         CakePHP(tm) v 1.2.0.5347
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18

    
19
App::uses('Controller', 'Controller');
20
App::uses('AuthComponent', 'Controller/Component');
21
App::uses('AclComponent', 'Controller/Component');
22
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
23
App::uses('FormAuthenticate', 'Controller/Component/Auth');
24
App::uses('CakeEvent', 'Event');
25

    
26
/**
27
 * TestFormAuthenticate class
28
 *
29
 * @package       Cake.Test.Case.Controller.Component
30
 */
31
class TestBaseAuthenticate extends BaseAuthenticate {
32

    
33
/**
34
 * Implemented events
35
 *
36
 * @return array of events => callbacks.
37
 */
38
        public function implementedEvents() {
39
                return array(
40
                        'Auth.afterIdentify' => 'afterIdentify'
41
                );
42
        }
43

    
44
        public $afterIdentifyCallable = null;
45

    
46
/**
47
 * Test function to be used in event dispatching
48
 *
49
 * @return void
50
 */
51
        public function afterIdentify($event) {
52
                call_user_func($this->afterIdentifyCallable, $event);
53
        }
54

    
55
/**
56
 * Authenticate a user based on the request information.
57
 *
58
 * @param CakeRequest $request Request to get authentication information from.
59
 * @param CakeResponse $response A response object that can have headers added.
60
 * @return mixed Either false on failure, or an array of user data on success.
61
 */
62
        public function authenticate(CakeRequest $request, CakeResponse $response) {
63
                return array(
64
                        'id' => 1,
65
                        'username' => 'mark'
66
                );
67
        }
68

    
69
}
70

    
71
/**
72
 * TestAuthComponent class
73
 *
74
 * @package       Cake.Test.Case.Controller.Component
75
 */
76
class TestAuthComponent extends AuthComponent {
77

    
78
/**
79
 * testStop property
80
 *
81
 * @var bool
82
 */
83
        public $testStop = false;
84

    
85
/**
86
 * Helper method to add/set an authenticate object instance
87
 *
88
 * @param int $index The index at which to add/set the object
89
 * @param object $object The object to add/set
90
 * @return void
91
 */
92
        public function setAuthenticateObject($index, $object) {
93
                $this->_authenticateObjects[$index] = $object;
94
        }
95

    
96
/**
97
 * Helper method to get an authenticate object instance
98
 *
99
 * @param int $index The index at which to get the object
100
 * @return object $object
101
 */
102
        public function getAuthenticateObject($index) {
103
                $this->constructAuthenticate();
104
                return isset($this->_authenticateObjects[$index]) ? $this->_authenticateObjects[$index] : null;
105
        }
106

    
107
/**
108
 * Helper method to add/set an authorize object instance
109
 *
110
 * @param int $index The index at which to add/set the object
111
 * @param Object $object The object to add/set
112
 * @return void
113
 */
114
        public function setAuthorizeObject($index, $object) {
115
                $this->_authorizeObjects[$index] = $object;
116
        }
117

    
118
/**
119
 * stop method
120
 *
121
 * @return void
122
 */
123
        protected function _stop($status = 0) {
124
                $this->testStop = true;
125
        }
126

    
127
        public static function clearUser() {
128
                static::$_user = array();
129
        }
130

    
131
}
132

    
133
/**
134
 * AuthUser class
135
 *
136
 * @package       Cake.Test.Case.Controller.Component
137
 */
138
class AuthUser extends CakeTestModel {
139

    
140
/**
141
 * useDbConfig property
142
 *
143
 * @var string
144
 */
145
        public $useDbConfig = 'test';
146

    
147
}
148

    
149
/**
150
 * AuthTestController class
151
 *
152
 * @package       Cake.Test.Case.Controller.Component
153
 */
154
class AuthTestController extends Controller {
155

    
156
/**
157
 * uses property
158
 *
159
 * @var array
160
 */
161
        public $uses = array('AuthUser');
162

    
163
/**
164
 * components property
165
 *
166
 * @var array
167
 */
168
        public $components = array('Session', 'Flash', 'Auth');
169

    
170
/**
171
 * testUrl property
172
 *
173
 * @var mixed
174
 */
175
        public $testUrl = null;
176

    
177
/**
178
 * construct method
179
 */
180
        public function __construct($request, $response) {
181
                $request->addParams(Router::parse('/auth_test'));
182
                $request->here = '/auth_test';
183
                $request->webroot = '/';
184
                Router::setRequestInfo($request);
185
                parent::__construct($request, $response);
186
        }
187

    
188
/**
189
 * login method
190
 *
191
 * @return void
192
 */
193
        public function login() {
194
        }
195

    
196
/**
197
 * admin_login method
198
 *
199
 * @return void
200
 */
201
        public function admin_login() {
202
        }
203

    
204
/**
205
 * admin_add method
206
 *
207
 * @return void
208
 */
209
        public function admin_add() {
210
        }
211

    
212
/**
213
 * logout method
214
 *
215
 * @return void
216
 */
217
        public function logout() {
218
        }
219

    
220
/**
221
 * add method
222
 *
223
 * @return void
224
 */
225
        public function add() {
226
                echo "add";
227
        }
228

    
229
/**
230
 * add method
231
 *
232
 * @return void
233
 */
234
        public function camelCase() {
235
                echo "camelCase";
236
        }
237

    
238
/**
239
 * redirect method
240
 *
241
 * @param string|array $url
242
 * @param mixed $status
243
 * @param mixed $exit
244
 * @return void
245
 */
246
        public function redirect($url, $status = null, $exit = true) {
247
                $this->testUrl = Router::url($url);
248
                return false;
249
        }
250

    
251
/**
252
 * isAuthorized method
253
 *
254
 * @return void
255
 */
256
        public function isAuthorized() {
257
        }
258

    
259
}
260

    
261
/**
262
 * AjaxAuthController class
263
 *
264
 * @package       Cake.Test.Case.Controller.Component
265
 */
266
class AjaxAuthController extends Controller {
267

    
268
/**
269
 * components property
270
 *
271
 * @var array
272
 */
273
        public $components = array('Session', 'TestAuth');
274

    
275
/**
276
 * uses property
277
 *
278
 * @var array
279
 */
280
        public $uses = array();
281

    
282
/**
283
 * testUrl property
284
 *
285
 * @var mixed
286
 */
287
        public $testUrl = null;
288

    
289
/**
290
 * beforeFilter method
291
 *
292
 * @return void
293
 */
294
        public function beforeFilter() {
295
                $this->TestAuth->ajaxLogin = 'test_element';
296
                $this->TestAuth->userModel = 'AuthUser';
297
                $this->TestAuth->RequestHandler->ajaxLayout = 'ajax2';
298
        }
299

    
300
/**
301
 * add method
302
 *
303
 * @return void
304
 */
305
        public function add() {
306
                if ($this->TestAuth->testStop !== true) {
307
                        echo 'Added Record';
308
                }
309
        }
310

    
311
/**
312
 * redirect method
313
 *
314
 * @param string|array $url
315
 * @param mixed $status
316
 * @param mixed $exit
317
 * @return void
318
 */
319
        public function redirect($url, $status = null, $exit = true) {
320
                $this->testUrl = Router::url($url);
321
                return false;
322
        }
323

    
324
}
325

    
326
/**
327
 * Mock class used to test event dispatching
328
 *
329
 * @package Cake.Test.Case.Event
330
 */
331
class AuthEventTestListener {
332

    
333
        public $callStack = array();
334

    
335
/**
336
 * Test function to be used in event dispatching
337
 *
338
 * @return void
339
 */
340
        public function listenerFunction() {
341
                $this->callStack[] = __FUNCTION__;
342
        }
343

    
344
}
345

    
346

    
347
/**
348
 * AuthComponentTest class
349
 *
350
 * @package       Cake.Test.Case.Controller.Component
351
 */
352
class AuthComponentTest extends CakeTestCase {
353

    
354
/**
355
 * name property
356
 *
357
 * @var string
358
 */
359
        public $name = 'Auth';
360

    
361
/**
362
 * fixtures property
363
 *
364
 * @var array
365
 */
366
        public $fixtures = array('core.auth_user');
367

    
368
/**
369
 * initialized property
370
 *
371
 * @var bool
372
 */
373
        public $initialized = false;
374

    
375
/**
376
 * setUp method
377
 *
378
 * @return void
379
 */
380
        public function setUp() {
381
                parent::setUp();
382
                Configure::write('Security.salt', 'YJfIxfs2guVoUubWDYhG93b0qyJfIxfs2guwvniR2G0FgaC9mi');
383
                Configure::write('Security.cipherSeed', 770011223369876);
384

    
385
                $request = new CakeRequest(null, false);
386

    
387
                $this->Controller = new AuthTestController($request, $this->getMock('CakeResponse'));
388

    
389
                $collection = new ComponentCollection();
390
                $collection->init($this->Controller);
391
                $this->Auth = new TestAuthComponent($collection);
392
                $this->Auth->request = $request;
393
                $this->Auth->response = $this->getMock('CakeResponse');
394
                AuthComponent::$sessionKey = 'Auth.User';
395

    
396
                $this->Controller->Components->init($this->Controller);
397

    
398
                $this->initialized = true;
399
                Router::reload();
400
                Router::connect('/:controller/:action/*');
401

    
402
                $User = ClassRegistry::init('AuthUser');
403
                $User->updateAll(array('password' => $User->getDataSource()->value(Security::hash('cake', null, true))));
404
        }
405

    
406
/**
407
 * tearDown method
408
 *
409
 * @return void
410
 */
411
        public function tearDown() {
412
                parent::tearDown();
413

    
414
                TestAuthComponent::clearUser();
415
                $this->Auth->Session->delete('Auth');
416
                $this->Auth->Session->delete('Message.auth');
417
                unset($this->Controller, $this->Auth);
418
        }
419

    
420
/**
421
 * testNoAuth method
422
 *
423
 * @return void
424
 */
425
        public function testNoAuth() {
426
                $this->assertFalse($this->Auth->isAuthorized());
427
        }
428

    
429
/**
430
 * testIsErrorOrTests
431
 *
432
 * @return void
433
 */
434
        public function testIsErrorOrTests() {
435
                $this->Controller->Auth->initialize($this->Controller);
436

    
437
                $this->Controller->name = 'CakeError';
438
                $this->assertTrue($this->Controller->Auth->startup($this->Controller));
439

    
440
                $this->Controller->name = 'Post';
441
                $this->Controller->request['action'] = 'thisdoesnotexist';
442
                $this->assertTrue($this->Controller->Auth->startup($this->Controller));
443

    
444
                $this->Controller->scaffold = null;
445
                $this->Controller->request['action'] = 'index';
446
                $this->assertFalse($this->Controller->Auth->startup($this->Controller));
447
        }
448

    
449
/**
450
 * testLogin method
451
 *
452
 * @return void
453
 */
454
        public function testLogin() {
455
                $AuthLoginFormAuthenticate = $this->getMock('FormAuthenticate', array(), array(), '', false);
456
                $this->Auth->authenticate = array(
457
                        'AuthLoginForm' => array(
458
                                'userModel' => 'AuthUser'
459
                        )
460
                );
461
                $this->Auth->Session = $this->getMock('SessionComponent', array('renew'), array(), '', false);
462

    
463
                $this->Auth->setAuthenticateObject(0, $AuthLoginFormAuthenticate);
464

    
465
                $this->Auth->request->data = array(
466
                        'AuthUser' => array(
467
                                'username' => 'mark',
468
                                'password' => Security::hash('cake', null, true)
469
                        )
470
                );
471

    
472
                $user = array(
473
                        'id' => 1,
474
                        'username' => 'mark'
475
                );
476

    
477
                $AuthLoginFormAuthenticate->expects($this->once())
478
                        ->method('authenticate')
479
                        ->with($this->Auth->request)
480
                        ->will($this->returnValue($user));
481

    
482
                $this->Auth->Session->expects($this->once())
483
                        ->method('renew');
484

    
485
                $result = $this->Auth->login();
486
                $this->assertTrue($result);
487

    
488
                $this->assertTrue($this->Auth->loggedIn());
489
                $this->assertEquals($user, $this->Auth->user());
490
        }
491

    
492
/**
493
 * testLogin afterIdentify event method
494
 *
495
 * @return void
496
 */
497
        public function testLoginAfterIdentify() {
498
                $this->Auth->authenticate = array(
499
                        'TestBase',
500
                );
501

    
502
                $user = array(
503
                        'id' => 1,
504
                        'username' => 'mark'
505
                );
506

    
507
                $auth = $this->Auth->getAuthenticateObject(0);
508
                $listener = $this->getMock('AuthEventTestListener');
509
                $auth->afterIdentifyCallable = array($listener, 'listenerFunction');
510
                $event = new CakeEvent('Auth.afterIdentify', $this->Auth, array('user' => $user));
511
                $listener->expects($this->once())->method('listenerFunction')->with($event);
512

    
513
                $result = $this->Auth->login();
514
                $this->assertTrue($result);
515
                $this->assertTrue($this->Auth->loggedIn());
516
                $this->assertEquals($user, $this->Auth->user());
517
        }
518

    
519
/**
520
 * testRedirectVarClearing method
521
 *
522
 * @return void
523
 */
524
        public function testRedirectVarClearing() {
525
                $this->Controller->request['controller'] = 'auth_test';
526
                $this->Controller->request['action'] = 'admin_add';
527
                $this->Controller->here = '/auth_test/admin_add';
528
                $this->assertNull($this->Auth->Session->read('Auth.redirect'));
529

    
530
                $this->Auth->authenticate = array('Form');
531
                $this->Auth->startup($this->Controller);
532
                $this->assertEquals('/auth_test/admin_add', $this->Auth->Session->read('Auth.redirect'));
533

    
534
                $this->Auth->Session->write('Auth.User', array('username' => 'admad'));
535
                $this->Auth->startup($this->Controller);
536
                $this->assertNull($this->Auth->Session->read('Auth.redirect'));
537
        }
538

    
539
/**
540
 * testAuthorizeFalse method
541
 *
542
 * @return void
543
 */
544
        public function testAuthorizeFalse() {
545
                $this->AuthUser = new AuthUser();
546
                $user = $this->AuthUser->find();
547
                $this->Auth->Session->write('Auth.User', $user['AuthUser']);
548
                $this->Controller->Auth->userModel = 'AuthUser';
549
                $this->Controller->Auth->authorize = false;
550
                $this->Controller->request->addParams(Router::parse('auth_test/add'));
551
                $this->Controller->Auth->initialize($this->Controller);
552
                $result = $this->Controller->Auth->startup($this->Controller);
553
                $this->assertTrue($result);
554

    
555
                $this->Auth->Session->delete('Auth');
556
                $result = $this->Controller->Auth->startup($this->Controller);
557
                $this->assertFalse($result);
558
                $this->assertTrue($this->Auth->Session->check('Message.auth'));
559

    
560
                $this->Controller->request->addParams(Router::parse('auth_test/camelCase'));
561
                $result = $this->Controller->Auth->startup($this->Controller);
562
                $this->assertFalse($result);
563
        }
564

    
565
/**
566
 * @expectedException CakeException
567
 * @return void
568
 */
569
        public function testIsAuthorizedMissingFile() {
570
                $this->Controller->Auth->authorize = 'Missing';
571
                $this->Controller->Auth->isAuthorized(array('User' => array('id' => 1)));
572
        }
573

    
574
/**
575
 * test that isAuthorized calls methods correctly
576
 *
577
 * @return void
578
 */
579
        public function testIsAuthorizedDelegation() {
580
                $AuthMockOneAuthorize = $this->getMock('BaseAuthorize', array('authorize'), array(), '', false);
581
                $AuthMockTwoAuthorize = $this->getMock('BaseAuthorize', array('authorize'), array(), '', false);
582
                $AuthMockThreeAuthorize = $this->getMock('BaseAuthorize', array('authorize'), array(), '', false);
583

    
584
                $this->Auth->setAuthorizeObject(0, $AuthMockOneAuthorize);
585
                $this->Auth->setAuthorizeObject(1, $AuthMockTwoAuthorize);
586
                $this->Auth->setAuthorizeObject(2, $AuthMockThreeAuthorize);
587
                $request = $this->Auth->request;
588

    
589
                $AuthMockOneAuthorize->expects($this->once())
590
                        ->method('authorize')
591
                        ->with(array('User'), $request)
592
                        ->will($this->returnValue(false));
593

    
594
                $AuthMockTwoAuthorize->expects($this->once())
595
                        ->method('authorize')
596
                        ->with(array('User'), $request)
597
                        ->will($this->returnValue(true));
598

    
599
                $AuthMockThreeAuthorize->expects($this->never())
600
                        ->method('authorize');
601

    
602
                $this->assertTrue($this->Auth->isAuthorized(array('User'), $request));
603
        }
604

    
605
/**
606
 * test that isAuthorized will use the session user if none is given.
607
 *
608
 * @return void
609
 */
610
        public function testIsAuthorizedUsingUserInSession() {
611
                $AuthMockFourAuthorize = $this->getMock('BaseAuthorize', array('authorize'), array(), '', false);
612
                $this->Auth->authorize = array('AuthMockFour');
613
                $this->Auth->setAuthorizeObject(0, $AuthMockFourAuthorize);
614

    
615
                $user = array('user' => 'mark');
616
                $this->Auth->Session->write('Auth.User', $user);
617
                $request = $this->Controller->request;
618

    
619
                $AuthMockFourAuthorize->expects($this->once())
620
                        ->method('authorize')
621
                        ->with($user, $request)
622
                        ->will($this->returnValue(true));
623

    
624
                $this->assertTrue($this->Auth->isAuthorized(null, $request));
625
        }
626

    
627
/**
628
 * test that loadAuthorize resets the loaded objects each time.
629
 *
630
 * @return void
631
 */
632
        public function testLoadAuthorizeResets() {
633
                $this->Controller->Auth->authorize = array(
634
                        'Controller'
635
                );
636
                $result = $this->Controller->Auth->constructAuthorize();
637
                $this->assertEquals(1, count($result));
638

    
639
                $result = $this->Controller->Auth->constructAuthorize();
640
                $this->assertEquals(1, count($result));
641
        }
642

    
643
/**
644
 * @expectedException CakeException
645
 * @return void
646
 */
647
        public function testLoadAuthenticateNoFile() {
648
                $this->Controller->Auth->authenticate = 'Missing';
649
                $this->Controller->Auth->identify($this->Controller->request, $this->Controller->response);
650
        }
651

    
652
/**
653
 * test the * key with authenticate
654
 *
655
 * @return void
656
 */
657
        public function testAllConfigWithAuthorize() {
658
                $this->Controller->Auth->authorize = array(
659
                        AuthComponent::ALL => array('actionPath' => 'controllers/'),
660
                        'Actions'
661
                );
662
                $objects = $this->Controller->Auth->constructAuthorize();
663
                $result = $objects[0];
664
                $this->assertEquals('controllers/', $result->settings['actionPath']);
665
        }
666

    
667
/**
668
 * test that loadAuthorize resets the loaded objects each time.
669
 *
670
 * @return void
671
 */
672
        public function testLoadAuthenticateResets() {
673
                $this->Controller->Auth->authenticate = array(
674
                        'Form'
675
                );
676
                $result = $this->Controller->Auth->constructAuthenticate();
677
                $this->assertEquals(1, count($result));
678

    
679
                $result = $this->Controller->Auth->constructAuthenticate();
680
                $this->assertEquals(1, count($result));
681
        }
682

    
683
/**
684
 * test the * key with authenticate
685
 *
686
 * @return void
687
 */
688
        public function testAllConfigWithAuthenticate() {
689
                $this->Controller->Auth->authenticate = array(
690
                        AuthComponent::ALL => array('userModel' => 'AuthUser'),
691
                        'Form'
692
                );
693
                $objects = $this->Controller->Auth->constructAuthenticate();
694
                $result = $objects[0];
695
                $this->assertEquals('AuthUser', $result->settings['userModel']);
696
        }
697

    
698
/**
699
 * test defining the same Authenticate object but with different password hashers
700
 *
701
 * @return void
702
 */
703
        public function testSameAuthenticateWithDifferentHashers() {
704
                $this->Controller->Auth->authenticate = array(
705
                        'FormSimple' => array('className' => 'Form', 'passwordHasher' => 'Simple'),
706
                        'FormBlowfish' => array('className' => 'Form', 'passwordHasher' => 'Blowfish'),
707
                );
708

    
709
                $objects = $this->Controller->Auth->constructAuthenticate();
710
                $this->assertEquals(2, count($objects));
711

    
712
                $this->assertInstanceOf('FormAuthenticate', $objects[0]);
713
                $this->assertInstanceOf('FormAuthenticate', $objects[1]);
714

    
715
                $this->assertInstanceOf('SimplePasswordHasher', $objects[0]->passwordHasher());
716
                $this->assertInstanceOf('BlowfishPasswordHasher', $objects[1]->passwordHasher());
717
        }
718

    
719
/**
720
 * Tests that deny always takes precedence over allow
721
 *
722
 * @return void
723
 */
724
        public function testAllowDenyAll() {
725
                $this->Controller->Auth->initialize($this->Controller);
726

    
727
                $this->Controller->Auth->allow();
728
                $this->Controller->Auth->deny('add', 'camelCase');
729

    
730
                $this->Controller->request['action'] = 'delete';
731
                $this->assertTrue($this->Controller->Auth->startup($this->Controller));
732

    
733
                $this->Controller->request['action'] = 'add';
734
                $this->assertFalse($this->Controller->Auth->startup($this->Controller));
735

    
736
                $this->Controller->request['action'] = 'camelCase';
737
                $this->assertFalse($this->Controller->Auth->startup($this->Controller));
738

    
739
                $this->Controller->Auth->allow();
740
                $this->Controller->Auth->deny(array('add', 'camelCase'));
741

    
742
                $this->Controller->request['action'] = 'delete';
743
                $this->assertTrue($this->Controller->Auth->startup($this->Controller));
744

    
745
                $this->Controller->request['action'] = 'camelCase';
746
                $this->assertFalse($this->Controller->Auth->startup($this->Controller));
747

    
748
                $this->Controller->Auth->allow('*');
749
                $this->Controller->Auth->deny();
750

    
751
                $this->Controller->request['action'] = 'camelCase';
752
                $this->assertFalse($this->Controller->Auth->startup($this->Controller));
753

    
754
                $this->Controller->request['action'] = 'add';
755
                $this->assertFalse($this->Controller->Auth->startup($this->Controller));
756

    
757
                $this->Controller->Auth->allow('camelCase');
758
                $this->Controller->Auth->deny();
759

    
760
                $this->Controller->request['action'] = 'camelCase';
761
                $this->assertFalse($this->Controller->Auth->startup($this->Controller));
762

    
763
                $this->Controller->request['action'] = 'login';
764
                $this->assertFalse($this->Controller->Auth->startup($this->Controller));
765

    
766
                $this->Controller->Auth->deny();
767
                $this->Controller->Auth->allow(null);
768

    
769
                $this->Controller->request['action'] = 'camelCase';
770
                $this->assertTrue($this->Controller->Auth->startup($this->Controller));
771

    
772
                $this->Controller->Auth->allow();
773
                $this->Controller->Auth->deny(null);
774

    
775
                $this->Controller->request['action'] = 'camelCase';
776
                $this->assertFalse($this->Controller->Auth->startup($this->Controller));
777
        }
778

    
779
/**
780
 * test that deny() converts camel case inputs to lowercase.
781
 *
782
 * @return void
783
 */
784
        public function testDenyWithCamelCaseMethods() {
785
                $this->Controller->Auth->initialize($this->Controller);
786
                $this->Controller->Auth->allow();
787
                $this->Controller->Auth->deny('add', 'camelCase');
788

    
789
                $url = '/auth_test/camelCase';
790
                $this->Controller->request->addParams(Router::parse($url));
791
                $this->Controller->request->query['url'] = Router::normalize($url);
792

    
793
                $this->assertFalse($this->Controller->Auth->startup($this->Controller));
794

    
795
                $url = '/auth_test/CamelCase';
796
                $this->Controller->request->addParams(Router::parse($url));
797
                $this->Controller->request->query['url'] = Router::normalize($url);
798
                $this->assertFalse($this->Controller->Auth->startup($this->Controller));
799
        }
800

    
801
/**
802
 * test that allow() and allowedActions work with camelCase method names.
803
 *
804
 * @return void
805
 */
806
        public function testAllowedActionsWithCamelCaseMethods() {
807
                $url = '/auth_test/camelCase';
808
                $this->Controller->request->addParams(Router::parse($url));
809
                $this->Controller->request->query['url'] = Router::normalize($url);
810
                $this->Controller->Auth->initialize($this->Controller);
811
                $this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
812
                $this->Controller->Auth->userModel = 'AuthUser';
813
                $this->Controller->Auth->allow();
814
                $result = $this->Controller->Auth->startup($this->Controller);
815
                $this->assertTrue($result, 'startup() should return true, as action is allowed. %s');
816

    
817
                $url = '/auth_test/camelCase';
818
                $this->Controller->request->addParams(Router::parse($url));
819
                $this->Controller->request->query['url'] = Router::normalize($url);
820
                $this->Controller->Auth->initialize($this->Controller);
821
                $this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
822
                $this->Controller->Auth->userModel = 'AuthUser';
823
                $this->Controller->Auth->allowedActions = array('delete', 'camelCase', 'add');
824
                $result = $this->Controller->Auth->startup($this->Controller);
825
                $this->assertTrue($result, 'startup() should return true, as action is allowed. %s');
826

    
827
                $this->Controller->Auth->allowedActions = array('delete', 'add');
828
                $result = $this->Controller->Auth->startup($this->Controller);
829
                $this->assertFalse($result, 'startup() should return false, as action is not allowed. %s');
830

    
831
                $url = '/auth_test/delete';
832
                $this->Controller->request->addParams(Router::parse($url));
833
                $this->Controller->request->query['url'] = Router::normalize($url);
834
                $this->Controller->Auth->initialize($this->Controller);
835
                $this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
836
                $this->Controller->Auth->userModel = 'AuthUser';
837

    
838
                $this->Controller->Auth->allow(array('delete', 'add'));
839
                $result = $this->Controller->Auth->startup($this->Controller);
840
                $this->assertTrue($result, 'startup() should return true, as action is allowed. %s');
841
        }
842

    
843
        public function testAllowedActionsSetWithAllowMethod() {
844
                $url = '/auth_test/action_name';
845
                $this->Controller->request->addParams(Router::parse($url));
846
                $this->Controller->request->query['url'] = Router::normalize($url);
847
                $this->Controller->Auth->initialize($this->Controller);
848
                $this->Controller->Auth->allow('action_name', 'anotherAction');
849
                $this->assertEquals(array('action_name', 'anotherAction'), $this->Controller->Auth->allowedActions);
850
        }
851

    
852
/**
853
 * testLoginRedirect method
854
 *
855
 * @return void
856
 */
857
        public function testLoginRedirect() {
858
                $_SERVER['HTTP_REFERER'] = false;
859
                $_ENV['HTTP_REFERER'] = false;
860
                putenv('HTTP_REFERER=');
861

    
862
                $this->Auth->Session->write('Auth', array(
863
                        'AuthUser' => array('id' => '1', 'username' => 'nate')
864
                ));
865

    
866
                $this->Auth->request->addParams(Router::parse('users/login'));
867
                $this->Auth->request->url = 'users/login';
868
                $this->Auth->initialize($this->Controller);
869

    
870
                $this->Auth->loginRedirect = array(
871
                        'controller' => 'pages', 'action' => 'display', 'welcome'
872
                );
873
                $this->Auth->startup($this->Controller);
874
                $expected = Router::normalize($this->Auth->loginRedirect);
875
                $this->assertEquals($expected, $this->Auth->redirectUrl());
876

    
877
                $this->Auth->Session->delete('Auth');
878

    
879
                //empty referer no session
880
                $_SERVER['HTTP_REFERER'] = false;
881
                $_ENV['HTTP_REFERER'] = false;
882
                putenv('HTTP_REFERER=');
883
                $url = '/posts/view/1';
884

    
885
                $this->Auth->Session->write('Auth', array(
886
                        'AuthUser' => array('id' => '1', 'username' => 'nate'))
887
                );
888
                $this->Controller->testUrl = null;
889
                $this->Auth->request->addParams(Router::parse($url));
890
                array_push($this->Controller->methods, 'view', 'edit', 'index');
891

    
892
                $this->Auth->initialize($this->Controller);
893
                $this->Auth->authorize = 'controller';
894

    
895
                $this->Auth->loginAction = array(
896
                        'controller' => 'AuthTest', 'action' => 'login'
897
                );
898
                $this->Auth->startup($this->Controller);
899
                $expected = Router::normalize('/AuthTest/login');
900
                $this->assertEquals($expected, $this->Controller->testUrl);
901

    
902
                $this->Auth->Session->delete('Auth');
903
                $_SERVER['HTTP_REFERER'] = $_ENV['HTTP_REFERER'] = Router::url('/admin', true);
904
                $this->Auth->Session->write('Auth', array(
905
                        'AuthUser' => array('id' => '1', 'username' => 'nate')
906
                ));
907
                $this->Auth->request->params['action'] = 'login';
908
                $this->Auth->request->url = 'auth_test/login';
909
                $this->Auth->initialize($this->Controller);
910
                $this->Auth->loginAction = 'auth_test/login';
911
                $this->Auth->loginRedirect = false;
912
                $this->Auth->startup($this->Controller);
913
                $expected = Router::normalize('/admin');
914
                $this->assertEquals($expected, $this->Auth->redirectUrl());
915

    
916
                // Ticket #4750
917
                // Named Parameters
918
                $this->Controller->request = $this->Auth->request;
919
                $this->Auth->Session->delete('Auth');
920
                $url = '/posts/index/year:2008/month:feb';
921
                $this->Auth->request->addParams(Router::parse($url));
922
                $this->Auth->request->url = $this->Auth->request->here = Router::normalize($url);
923
                $this->Auth->initialize($this->Controller);
924
                $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
925
                $this->Auth->startup($this->Controller);
926
                $expected = Router::normalize('posts/index/year:2008/month:feb');
927
                $this->assertEquals($expected, $this->Auth->Session->read('Auth.redirect'));
928

    
929
                // Passed Arguments
930
                $this->Auth->Session->delete('Auth');
931
                $url = '/posts/view/1';
932
                $this->Auth->request->addParams(Router::parse($url));
933
                $this->Auth->request->url = $this->Auth->request->here = Router::normalize($url);
934
                $this->Auth->initialize($this->Controller);
935
                $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
936
                $this->Auth->startup($this->Controller);
937
                $expected = Router::normalize('posts/view/1');
938
                $this->assertEquals($expected, $this->Auth->Session->read('Auth.redirect'));
939

    
940
                // QueryString parameters
941
                $_back = $_GET;
942
                $_GET = array(
943
                        'print' => 'true',
944
                        'refer' => 'menu'
945
                );
946
                $this->Auth->Session->delete('Auth');
947
                $url = '/posts/index/29';
948
                $this->Auth->request->addParams(Router::parse($url));
949
                $this->Auth->request->url = $this->Auth->request->here = Router::normalize($url);
950
                $this->Auth->request->query = $_GET;
951

    
952
                $this->Auth->initialize($this->Controller);
953
                $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
954
                $this->Auth->startup($this->Controller);
955
                $expected = Router::normalize('posts/index/29?print=true&refer=menu');
956
                $this->assertEquals($expected, $this->Auth->Session->read('Auth.redirect'));
957

    
958
                // Different base urls.
959
                $appConfig = Configure::read('App');
960

    
961
                $_GET = array();
962

    
963
                Configure::write('App', array(
964
                        'dir' => APP_DIR,
965
                        'webroot' => WEBROOT_DIR,
966
                        'base' => false,
967
                        'baseUrl' => '/cake/index.php'
968
                ));
969

    
970
                $this->Auth->Session->delete('Auth');
971

    
972
                $url = '/posts/add';
973
                $this->Auth->request = $this->Controller->request = new CakeRequest($url);
974
                $this->Auth->request->addParams(Router::parse($url));
975
                $this->Auth->request->url = Router::normalize($url);
976

    
977
                $this->Auth->initialize($this->Controller);
978
                $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
979
                $this->Auth->startup($this->Controller);
980
                $expected = Router::normalize('/posts/add');
981
                $this->assertEquals($expected, $this->Auth->Session->read('Auth.redirect'));
982

    
983
                $this->Auth->Session->delete('Auth');
984
                Configure::write('App', $appConfig);
985

    
986
                $_GET = $_back;
987

    
988
                // External Authed Action
989
                $_SERVER['HTTP_REFERER'] = 'http://webmail.example.com/view/message';
990
                $this->Auth->Session->delete('Auth');
991
                $url = '/posts/edit/1';
992
                $request = new CakeRequest($url);
993
                $request->query = array();
994
                $this->Auth->request = $this->Controller->request = $request;
995
                $this->Auth->request->addParams(Router::parse($url));
996
                $this->Auth->request->url = $this->Auth->request->here = Router::normalize($url);
997
                $this->Auth->initialize($this->Controller);
998
                $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
999
                $this->Auth->startup($this->Controller);
1000
                $expected = Router::normalize('/posts/edit/1');
1001
                $this->assertEquals($expected, $this->Auth->Session->read('Auth.redirect'));
1002

    
1003
                // External Direct Login Link
1004
                $_SERVER['HTTP_REFERER'] = 'http://webmail.example.com/view/message';
1005
                $this->Auth->Session->delete('Auth');
1006
                $url = '/AuthTest/login';
1007
                $this->Auth->request = $this->Controller->request = new CakeRequest($url);
1008
                $this->Auth->request->addParams(Router::parse($url));
1009
                $this->Auth->request->url = Router::normalize($url);
1010
                $this->Auth->initialize($this->Controller);
1011
                $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
1012
                $this->Auth->startup($this->Controller);
1013
                $expected = Router::normalize('/');
1014
                $this->assertEquals($expected, $this->Auth->Session->read('Auth.redirect'));
1015

    
1016
                $this->Auth->Session->delete('Auth');
1017
        }
1018

    
1019
/**
1020
 * testNoLoginRedirectForAuthenticatedUser method
1021
 *
1022
 * @return void
1023
 */
1024
        public function testNoLoginRedirectForAuthenticatedUser() {
1025
                $this->Controller->request['controller'] = 'auth_test';
1026
                $this->Controller->request['action'] = 'login';
1027
                $this->Controller->here = '/auth_test/login';
1028
                $this->Auth->request->url = 'auth_test/login';
1029

    
1030
                $this->Auth->Session->write('Auth.User.id', '1');
1031
                $this->Auth->authenticate = array('Form');
1032
                $this->getMock('BaseAuthorize', array('authorize'), array(), 'NoLoginRedirectMockAuthorize', false);
1033
                $this->Auth->authorize = array('NoLoginRedirectMockAuthorize');
1034
                $this->Auth->loginAction = array('controller' => 'auth_test', 'action' => 'login');
1035

    
1036
                $return = $this->Auth->startup($this->Controller);
1037
                $this->assertTrue($return);
1038
                $this->assertNull($this->Controller->testUrl);
1039
        }
1040

    
1041
/**
1042
 * Default to loginRedirect, if set, on authError.
1043
 *
1044
 * @return void
1045
 */
1046
        public function testDefaultToLoginRedirect() {
1047
                $_SERVER['HTTP_REFERER'] = false;
1048
                $_ENV['HTTP_REFERER'] = false;
1049
                putenv('HTTP_REFERER=');
1050

    
1051
                $url = '/party/on';
1052
                $this->Auth->request = $CakeRequest = new CakeRequest($url);
1053
                $this->Auth->request->addParams(Router::parse($url));
1054
                $this->Auth->authorize = array('Controller');
1055
                $this->Auth->login(array('username' => 'mariano', 'password' => 'cake'));
1056
                $this->Auth->loginRedirect = array(
1057
                        'controller' => 'something', 'action' => 'else',
1058
                );
1059

    
1060
                $CakeResponse = new CakeResponse();
1061
                $Controller = $this->getMock(
1062
                        'Controller',
1063
                        array('on', 'redirect'),
1064
                        array($CakeRequest, $CakeResponse)
1065
                );
1066

    
1067
                $expected = Router::url($this->Auth->loginRedirect);
1068
                $Controller->expects($this->once())
1069
                        ->method('redirect')
1070
                        ->with($this->equalTo($expected));
1071
                $this->Auth->startup($Controller);
1072
        }
1073

    
1074
/**
1075
 * testRedirectToUnauthorizedRedirect
1076
 *
1077
 * @return void
1078
 */
1079
        public function testRedirectToUnauthorizedRedirect() {
1080
                $url = '/party/on';
1081
                $this->Auth->request = $CakeRequest = new CakeRequest($url);
1082
                $this->Auth->request->addParams(Router::parse($url));
1083
                $this->Auth->authorize = array('Controller');
1084
                $this->Auth->login(array('username' => 'admad', 'password' => 'cake'));
1085
                $this->Auth->unauthorizedRedirect = array(
1086
                        'controller' => 'no_can_do', 'action' => 'jack'
1087
                );
1088

    
1089
                $CakeResponse = new CakeResponse();
1090
                $Controller = $this->getMock(
1091
                        'Controller',
1092
                        array('on', 'redirect'),
1093
                        array($CakeRequest, $CakeResponse)
1094
                );
1095
                $this->Auth->Flash = $this->getMock(
1096
                        'FlashComponent',
1097
                        array('set'),
1098
                        array($Controller->Components)
1099
                );
1100

    
1101
                $expected = array(
1102
                        'controller' => 'no_can_do', 'action' => 'jack'
1103
                );
1104
                $Controller->expects($this->once())
1105
                        ->method('redirect')
1106
                        ->with($this->equalTo($expected));
1107
                $this->Auth->Flash->expects($this->once())
1108
                        ->method('set');
1109
                $this->Auth->startup($Controller);
1110
        }
1111

    
1112
/**
1113
 * testRedirectToUnauthorizedRedirectSuppressedAuthError
1114
 *
1115
 * @return void
1116
 */
1117
        public function testRedirectToUnauthorizedRedirectSuppressedAuthError() {
1118
                $url = '/party/on';
1119
                $this->Auth->request = $CakeRequest = new CakeRequest($url);
1120
                $this->Auth->request->addParams(Router::parse($url));
1121
                $this->Auth->authorize = array('Controller');
1122
                $this->Auth->login(array('username' => 'admad', 'password' => 'cake'));
1123
                $this->Auth->unauthorizedRedirect = array(
1124
                        'controller' => 'no_can_do', 'action' => 'jack'
1125
                );
1126
                $this->Auth->authError = false;
1127

    
1128
                $CakeResponse = new CakeResponse();
1129
                $Controller = $this->getMock(
1130
                        'Controller',
1131
                        array('on', 'redirect'),
1132
                        array($CakeRequest, $CakeResponse)
1133
                );
1134
                $this->Auth->Flash = $this->getMock(
1135
                        'FlashComponent',
1136
                        array('set'),
1137
                        array($Controller->Components)
1138
                );
1139

    
1140
                $expected = array(
1141
                        'controller' => 'no_can_do', 'action' => 'jack'
1142
                );
1143
                $Controller->expects($this->once())
1144
                        ->method('redirect')
1145
                        ->with($this->equalTo($expected));
1146
                $this->Auth->Flash->expects($this->never())
1147
                        ->method('set');
1148
                $this->Auth->startup($Controller);
1149
        }
1150

    
1151
/**
1152
 * Throw ForbiddenException if AuthComponent::$unauthorizedRedirect set to false
1153
 * @expectedException ForbiddenException
1154
 * @return void
1155
 */
1156
        public function testForbiddenException() {
1157
                $url = '/party/on';
1158
                $this->Auth->request = $CakeRequest = new CakeRequest($url);
1159
                $this->Auth->request->addParams(Router::parse($url));
1160
                $this->Auth->authorize = array('Controller');
1161
                $this->Auth->authorize = array('Controller');
1162
                $this->Auth->unauthorizedRedirect = false;
1163
                $this->Auth->login(array('username' => 'baker', 'password' => 'cake'));
1164

    
1165
                $CakeResponse = new CakeResponse();
1166
                $Controller = $this->getMock(
1167
                        'Controller',
1168
                        array('on', 'redirect'),
1169
                        array($CakeRequest, $CakeResponse)
1170
                );
1171

    
1172
                $this->Auth->startup($Controller);
1173
        }
1174

    
1175
/**
1176
 * Test that no redirects or authorization tests occur on the loginAction
1177
 *
1178
 * @return void
1179
 */
1180
        public function testNoRedirectOnLoginAction() {
1181
                $controller = $this->getMock('Controller');
1182
                $controller->methods = array('login');
1183

    
1184
                $url = '/AuthTest/login';
1185
                $this->Auth->request = $controller->request = new CakeRequest($url);
1186
                $this->Auth->request->addParams(Router::parse($url));
1187
                $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
1188
                $this->Auth->authorize = array('Controller');
1189

    
1190
                $controller->expects($this->never())
1191
                        ->method('redirect');
1192

    
1193
                $this->Auth->startup($controller);
1194
        }
1195

    
1196
/**
1197
 * Ensure that no redirect is performed when a 404 is reached
1198
 * And the user doesn't have a session.
1199
 *
1200
 * @return void
1201
 */
1202
        public function testNoRedirectOn404() {
1203
                $this->Auth->Session->delete('Auth');
1204
                $this->Auth->initialize($this->Controller);
1205
                $this->Auth->request->addParams(Router::parse('auth_test/something_totally_wrong'));
1206
                $result = $this->Auth->startup($this->Controller);
1207
                $this->assertTrue($result, 'Auth redirected a missing action %s');
1208
        }
1209

    
1210
/**
1211
 * testAdminRoute method
1212
 *
1213
 * @return void
1214
 */
1215
        public function testAdminRoute() {
1216
                $pref = Configure::read('Routing.prefixes');
1217
                Configure::write('Routing.prefixes', array('admin'));
1218
                Router::reload();
1219
                require CAKE . 'Config' . DS . 'routes.php';
1220

    
1221
                $url = '/admin/auth_test/add';
1222
                $this->Auth->request->addParams(Router::parse($url));
1223
                $this->Auth->request->query['url'] = ltrim($url, '/');
1224
                $this->Auth->request->base = '';
1225

    
1226
                Router::setRequestInfo($this->Auth->request);
1227
                $this->Auth->initialize($this->Controller);
1228

    
1229
                $this->Auth->loginAction = array(
1230
                        'admin' => true, 'controller' => 'auth_test', 'action' => 'login'
1231
                );
1232

    
1233
                $this->Auth->startup($this->Controller);
1234
                $this->assertEquals('/admin/auth_test/login', $this->Controller->testUrl);
1235

    
1236
                Configure::write('Routing.prefixes', $pref);
1237
        }
1238

    
1239
/**
1240
 * testAjaxLogin method
1241
 *
1242
 * @return void
1243
 */
1244
        public function testAjaxLogin() {
1245
                App::build(array(
1246
                        'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
1247
                ));
1248
                $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
1249

    
1250
                App::uses('Dispatcher', 'Routing');
1251

    
1252
                $Response = new CakeResponse();
1253
                ob_start();
1254
                $Dispatcher = new Dispatcher();
1255
                $Dispatcher->dispatch(new CakeRequest('/ajax_auth/add'), $Response, array('return' => 1));
1256
                $result = ob_get_clean();
1257

    
1258
                $this->assertEquals(403, $Response->statusCode());
1259
                $this->assertEquals("Ajax!\nthis is the test element", str_replace("\r\n", "\n", $result));
1260
                unset($_SERVER['HTTP_X_REQUESTED_WITH']);
1261
        }
1262

    
1263
/**
1264
 * testAjaxLoginResponseCode
1265
 *
1266
 * @return void
1267
 */
1268
        public function testAjaxLoginResponseCode() {
1269
                App::build(array(
1270
                        'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
1271
                ));
1272
                $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
1273

    
1274
                $url = '/ajax_auth/add';
1275
                $this->Auth->request->addParams(Router::parse($url));
1276
                $this->Auth->request->query['url'] = ltrim($url, '/');
1277
                $this->Auth->request->base = '';
1278
                $this->Auth->ajaxLogin = 'test_element';
1279

    
1280
                Router::setRequestInfo($this->Auth->request);
1281

    
1282
                $this->Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
1283
                $this->Controller->response->expects($this->at(0))
1284
                        ->method('_sendHeader')
1285
                        ->with('HTTP/1.1 403 Forbidden', null);
1286
                $this->Auth->initialize($this->Controller);
1287

    
1288
                ob_start();
1289
                $result = $this->Auth->startup($this->Controller);
1290
                ob_end_clean();
1291

    
1292
                $this->assertFalse($result);
1293
                $this->assertEquals('this is the test element', $this->Controller->response->body());
1294
                $this->assertArrayNotHasKey('Location', $this->Controller->response->header());
1295
                $this->assertNull($this->Controller->testUrl, 'redirect() not called');
1296
                unset($_SERVER['HTTP_X_REQUESTED_WITH']);
1297
        }
1298

    
1299
/**
1300
 * test ajax login with no element
1301
 *
1302
 * @return void
1303
 */
1304
        public function testAjaxLoginResponseCodeNoElement() {
1305
                $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
1306

    
1307
                $url = '/ajax_auth/add';
1308
                $this->Auth->request->addParams(Router::parse($url));
1309
                $this->Auth->request->query['url'] = ltrim($url, '/');
1310
                $this->Auth->request->base = '';
1311
                $this->Auth->ajaxLogin = false;
1312

    
1313
                Router::setRequestInfo($this->Auth->request);
1314

    
1315
                $this->Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
1316
                $this->Controller->response->expects($this->at(0))
1317
                        ->method('_sendHeader')
1318
                        ->with('HTTP/1.1 403 Forbidden', null);
1319
                $this->Auth->initialize($this->Controller);
1320

    
1321
                $this->Auth->startup($this->Controller);
1322

    
1323
                $this->assertArrayNotHasKey('Location', $this->Controller->response->header());
1324
                $this->assertNull($this->Controller->testUrl, 'redirect() not called');
1325
                unset($_SERVER['HTTP_X_REQUESTED_WITH']);
1326
        }
1327

    
1328
/**
1329
 * testLoginActionRedirect method
1330
 *
1331
 * @return void
1332
 */
1333
        public function testLoginActionRedirect() {
1334
                $admin = Configure::read('Routing.prefixes');
1335
                Configure::write('Routing.prefixes', array('admin'));
1336
                Router::reload();
1337
                require CAKE . 'Config' . DS . 'routes.php';
1338

    
1339
                $url = '/admin/auth_test/login';
1340
                $this->Auth->request->addParams(Router::parse($url));
1341
                $this->Auth->request->url = ltrim($url, '/');
1342
                Router::setRequestInfo(array(
1343
                        array(
1344
                                'pass' => array(), 'action' => 'admin_login', 'plugin' => null, 'controller' => 'auth_test',
1345
                                'admin' => true,
1346
                        ),
1347
                        array(
1348
                                'base' => null, 'here' => $url,
1349
                                'webroot' => '/', 'passedArgs' => array(),
1350
                        )
1351
                ));
1352

    
1353
                $this->Auth->initialize($this->Controller);
1354
                $this->Auth->loginAction = array('admin' => true, 'controller' => 'auth_test', 'action' => 'login');
1355
                $this->Auth->startup($this->Controller);
1356

    
1357
                $this->assertNull($this->Controller->testUrl);
1358

    
1359
                Configure::write('Routing.prefixes', $admin);
1360
        }
1361

    
1362
/**
1363
 * Stateless auth methods like Basic should populate data that can be
1364
 * accessed by $this->user().
1365
 *
1366
 * @return void
1367
 */
1368
        public function testStatelessAuthWorksWithUser() {
1369
                $_SERVER['PHP_AUTH_USER'] = 'mariano';
1370
                $_SERVER['PHP_AUTH_PW'] = 'cake';
1371
                $url = '/auth_test/add';
1372
                $this->Auth->request->addParams(Router::parse($url));
1373

    
1374
                $this->Auth->authenticate = array(
1375
                        'Basic' => array('userModel' => 'AuthUser')
1376
                );
1377
                $this->Auth->startup($this->Controller);
1378

    
1379
                $result = $this->Auth->user();
1380
                $this->assertEquals('mariano', $result['username']);
1381

    
1382
                $result = $this->Auth->user('username');
1383
                $this->assertEquals('mariano', $result);
1384
        }
1385

    
1386
/**
1387
 * test $settings in Controller::$components
1388
 *
1389
 * @return void
1390
 */
1391
        public function testComponentSettings() {
1392
                $request = new CakeRequest(null, false);
1393
                $this->Controller = new AuthTestController($request, $this->getMock('CakeResponse'));
1394

    
1395
                $this->Controller->components = array(
1396
                        'Auth' => array(
1397
                                'loginAction' => array('controller' => 'people', 'action' => 'login'),
1398
                                'logoutRedirect' => array('controller' => 'people', 'action' => 'login'),
1399
                        ),
1400
                        'Session'
1401
                );
1402
                $this->Controller->Components->init($this->Controller);
1403
                $this->Controller->Components->trigger('initialize', array(&$this->Controller));
1404
                Router::reload();
1405

    
1406
                $expected = array(
1407
                        'loginAction' => array('controller' => 'people', 'action' => 'login'),
1408
                        'logoutRedirect' => array('controller' => 'people', 'action' => 'login'),
1409
                );
1410
                $this->assertEquals($expected['loginAction'], $this->Controller->Auth->loginAction);
1411
                $this->assertEquals($expected['logoutRedirect'], $this->Controller->Auth->logoutRedirect);
1412
        }
1413

    
1414
/**
1415
 * test that logout deletes the session variables. and returns the correct URL
1416
 *
1417
 * @return void
1418
 */
1419
        public function testLogout() {
1420
                $this->Auth->Session->write('Auth.User.id', '1');
1421
                $this->Auth->Session->write('Auth.redirect', '/users/login');
1422
                $this->Auth->logoutRedirect = '/';
1423
                $result = $this->Auth->logout();
1424

    
1425
                $this->assertEquals('/', $result);
1426
                $this->assertNull($this->Auth->Session->read('Auth.AuthUser'));
1427
                $this->assertNull($this->Auth->Session->read('Auth.redirect'));
1428
        }
1429

    
1430
/**
1431
 * Logout should trigger a logout method on authentication objects.
1432
 *
1433
 * @return void
1434
 */
1435
        public function testLogoutTrigger() {
1436
                $LogoutTriggerMockAuthenticate = $this->getMock('BaseAuthenticate', array('authenticate', 'logout'), array(), '', false);
1437

    
1438
                $this->Auth->authenticate = array('LogoutTriggerMock');
1439
                $this->Auth->setAuthenticateObject(0, $LogoutTriggerMockAuthenticate);
1440
                $LogoutTriggerMockAuthenticate->expects($this->once())
1441
                        ->method('logout');
1442

    
1443
                $this->Auth->logout();
1444
        }
1445

    
1446
/**
1447
 * Test mapActions as a getter
1448
 *
1449
 * @return void
1450
 */
1451
        public function testMapActions() {
1452
                $MapActionMockAuthorize = $this->getMock(
1453
                        'BaseAuthorize',
1454
                        array('authorize'),
1455
                        array(),
1456
                        '',
1457
                        false
1458
                );
1459
                $this->Auth->authorize = array('MapActionAuthorize');
1460
                $this->Auth->setAuthorizeObject(0, $MapActionMockAuthorize);
1461

    
1462
                $actions = array('my_action' => 'create');
1463
                $this->Auth->mapActions($actions);
1464
                $actions = array(
1465
                        'create' => array('my_other_action'),
1466
                        'update' => array('updater')
1467
                );
1468
                $this->Auth->mapActions($actions);
1469

    
1470
                $actions = $this->Auth->mapActions();
1471

    
1472
                $result = $actions['my_action'];
1473
                $expected = 'create';
1474
                $this->assertEquals($expected, $result);
1475

    
1476
                $result = $actions['my_other_action'];
1477
                $expected = 'create';
1478
                $this->assertEquals($expected, $result);
1479

    
1480
                $result = $actions['updater'];
1481
                $expected = 'update';
1482
                $this->assertEquals($expected, $result);
1483
        }
1484

    
1485
/**
1486
 * test mapActions loading and delegating to authorize objects.
1487
 *
1488
 * @return void
1489
 */
1490
        public function testMapActionsDelegation() {
1491
                $MapActionMockAuthorize = $this->getMock('BaseAuthorize', array('authorize', 'mapActions'), array(), '', false);
1492

    
1493
                $this->Auth->authorize = array('MapActionMock');
1494
                $this->Auth->setAuthorizeObject(0, $MapActionMockAuthorize);
1495
                $MapActionMockAuthorize->expects($this->once())
1496
                        ->method('mapActions')
1497
                        ->with(array('create' => array('my_action')));
1498

    
1499
                $this->Auth->mapActions(array('create' => array('my_action')));
1500
        }
1501

    
1502
/**
1503
 * test logging in with a request.
1504
 *
1505
 * @return void
1506
 */
1507
        public function testLoginWithRequestData() {
1508
                $RequestLoginMockAuthenticate = $this->getMock('FormAuthenticate', array(), array(), '', false);
1509
                $request = new CakeRequest('users/login', false);
1510
                $user = array('username' => 'mark', 'role' => 'admin');
1511

    
1512
                $this->Auth->request = $request;
1513
                $this->Auth->authenticate = array('RequestLoginMock');
1514
                $this->Auth->setAuthenticateObject(0, $RequestLoginMockAuthenticate);
1515
                $RequestLoginMockAuthenticate->expects($this->once())
1516
                        ->method('authenticate')
1517
                        ->with($request)
1518
                        ->will($this->returnValue($user));
1519

    
1520
                $this->assertTrue($this->Auth->login());
1521
                $this->assertEquals($user['username'], $this->Auth->user('username'));
1522
        }
1523

    
1524
/**
1525
 * test login() with user data
1526
 *
1527
 * @return void
1528
 */
1529
        public function testLoginWithUserData() {
1530
                $this->assertFalse($this->Auth->loggedIn());
1531

    
1532
                $user = array(
1533
                        'username' => 'mariano',
1534
                        'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
1535
                        'created' => '2007-03-17 01:16:23',
1536
                        'updated' => '2007-03-17 01:18:31'
1537
                );
1538
                $this->assertTrue($this->Auth->login($user));
1539
                $this->assertTrue($this->Auth->loggedIn());
1540
                $this->assertEquals($user['username'], $this->Auth->user('username'));
1541
        }
1542

    
1543
/**
1544
 * test flash settings.
1545
 *
1546
 * @return void
1547
 */
1548
        public function testFlashSettings() {
1549
                $this->Auth->Flash = $this->getMock('FlashComponent', array(), array(), '', false);
1550
                $this->Auth->Flash->expects($this->once())
1551
                        ->method('set')
1552
                        ->with('Auth failure', array('element' => 'custom', 'params' => array(1), 'key' => 'auth-key'));
1553

    
1554
                $this->Auth->flash = array(
1555
                        'element' => 'custom',
1556
                        'params' => array(1),
1557
                        'key' => 'auth-key'
1558
                );
1559
                $this->Auth->flash('Auth failure');
1560
        }
1561

    
1562
/**
1563
 * test the various states of Auth::redirect()
1564
 *
1565
 * @return void
1566
 */
1567
        public function testRedirectSet() {
1568
                $value = array('controller' => 'users', 'action' => 'home');
1569
                $result = $this->Auth->redirectUrl($value);
1570
                $this->assertEquals('/users/home', $result);
1571
                $this->assertEquals($value, $this->Auth->Session->read('Auth.redirect'));
1572
        }
1573

    
1574
/**
1575
 * test redirect using Auth.redirect from the session.
1576
 *
1577
 * @return void
1578
 */
1579
        public function testRedirectSessionRead() {
1580
                $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
1581
                $this->Auth->Session->write('Auth.redirect', '/users/home');
1582

    
1583
                $result = $this->Auth->redirectUrl();
1584
                $this->assertEquals('/users/home', $result);
1585
                $this->assertFalse($this->Auth->Session->check('Auth.redirect'));
1586
        }
1587

    
1588
/**
1589
 * test redirectUrl with duplicate base.
1590
 *
1591
 * @return void
1592
 */
1593
        public function testRedirectSessionReadDuplicateBase() {
1594
                $this->Auth->request->webroot = '/waves/';
1595
                $this->Auth->request->base = '/waves';
1596

    
1597
                Router::setRequestInfo($this->Auth->request);
1598

    
1599
                $this->Auth->Session->write('Auth.redirect', '/waves/add');
1600

    
1601
                $result = $this->Auth->redirectUrl();
1602
                $this->assertEquals('/waves/add', $result);
1603
        }
1604

    
1605
/**
1606
 * test that redirect does not return loginAction if that is what's stored in Auth.redirect.
1607
 * instead loginRedirect should be used.
1608
 *
1609
 * @return void
1610
 */
1611
        public function testRedirectSessionReadEqualToLoginAction() {
1612
                $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
1613
                $this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'home');
1614
                $this->Auth->Session->write('Auth.redirect', array('controller' => 'users', 'action' => 'login'));
1615

    
1616
                $result = $this->Auth->redirectUrl();
1617
                $this->assertEquals('/users/home', $result);
1618
                $this->assertFalse($this->Auth->Session->check('Auth.redirect'));
1619
        }
1620

    
1621
/**
1622
 * test that the returned URL doesn't contain the base URL.
1623
 *
1624
 * @see https://cakephp.lighthouseapp.com/projects/42648/tickets/3922-authcomponentredirecturl-prepends-appbaseurl
1625
 *
1626
 * @return void This test method doesn't return anything.
1627
 */
1628
        public function testRedirectUrlWithBaseSet() {
1629
                $App = Configure::read('App');
1630

    
1631
                Configure::write('App', array(
1632
                        'dir' => APP_DIR,
1633
                        'webroot' => WEBROOT_DIR,
1634
                        'base' => false,
1635
                        'baseUrl' => '/cake/index.php'
1636
                ));
1637

    
1638
                $url = '/users/login';
1639
                $this->Auth->request = $this->Controller->request = new CakeRequest($url);
1640
                $this->Auth->request->addParams(Router::parse($url));
1641
                $this->Auth->request->url = Router::normalize($url);
1642

    
1643
                Router::setRequestInfo($this->Auth->request);
1644

    
1645
                $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
1646
                $this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'home');
1647

    
1648
                $result = $this->Auth->redirectUrl();
1649
                $this->assertEquals('/users/home', $result);
1650
                $this->assertFalse($this->Auth->Session->check('Auth.redirect'));
1651

    
1652
                Configure::write('App', $App);
1653
                Router::reload();
1654
        }
1655

    
1656
/**
1657
 * test password hashing
1658
 *
1659
 * @return void
1660
 */
1661
        public function testPassword() {
1662
                $result = $this->Auth->password('password');
1663
                $expected = Security::hash('password', null, true);
1664
                $this->assertEquals($expected, $result);
1665
        }
1666

    
1667
/**
1668
 * testUser method
1669
 *
1670
 * @return void
1671
 */
1672
        public function testUser() {
1673
                $data = array(
1674
                        'User' => array(
1675
                                'id' => '2',
1676
                                'username' => 'mark',
1677
                                'group_id' => 1,
1678
                                'Group' => array(
1679
                                        'id' => '1',
1680
                                        'name' => 'Members'
1681
                                ),
1682
                                'is_admin' => false,
1683
                ));
1684
                $this->Auth->Session->write('Auth', $data);
1685

    
1686
                $result = $this->Auth->user();
1687
                $this->assertEquals($data['User'], $result);
1688

    
1689
                $result = $this->Auth->user('username');
1690
                $this->assertEquals($data['User']['username'], $result);
1691

    
1692
                $result = $this->Auth->user('Group.name');
1693
                $this->assertEquals($data['User']['Group']['name'], $result);
1694

    
1695
                $result = $this->Auth->user('invalid');
1696
                $this->assertEquals(null, $result);
1697

    
1698
                $result = $this->Auth->user('Company.invalid');
1699
                $this->assertEquals(null, $result);
1700

    
1701
                $result = $this->Auth->user('is_admin');
1702
                $this->assertFalse($result);
1703
        }
1704

    
1705
/**
1706
 * testStatelessAuthNoRedirect method
1707
 *
1708
 * @expectedException UnauthorizedException
1709
 * @expectedExceptionCode 401
1710
 * @return void
1711
 */
1712
        public function testStatelessAuthNoRedirect() {
1713
                if (CakeSession::id()) {
1714
                        session_destroy();
1715
                        CakeSession::$id = null;
1716
                }
1717
                $_SESSION = null;
1718

    
1719
                AuthComponent::$sessionKey = false;
1720
                $this->Auth->authenticate = array('Basic');
1721
                $this->Controller->request['action'] = 'admin_add';
1722

    
1723
                $this->Auth->startup($this->Controller);
1724
        }
1725

    
1726
/**
1727
 * testStatelessAuthNoSessionStart method
1728
 *
1729
 * @return void
1730
 */
1731
        public function testStatelessAuthNoSessionStart() {
1732
                if (CakeSession::id()) {
1733
                        session_destroy();
1734
                        CakeSession::$id = null;
1735
                }
1736
                $_SESSION = null;
1737

    
1738
                $_SERVER['PHP_AUTH_USER'] = 'mariano';
1739
                $_SERVER['PHP_AUTH_PW'] = 'cake';
1740

    
1741
                AuthComponent::$sessionKey = false;
1742
                $this->Auth->authenticate = array(
1743
                        'Basic' => array('userModel' => 'AuthUser')
1744
                );
1745
                $this->Controller->request['action'] = 'admin_add';
1746

    
1747
                $result = $this->Auth->startup($this->Controller);
1748
                $this->assertTrue($result);
1749

    
1750
                $this->assertNull(CakeSession::id());
1751
        }
1752

    
1753
/**
1754
 * testStatelessAuthRedirect method
1755
 *
1756
 * @return void
1757
 */
1758
        public function testStatelessFollowedByStatefulAuth() {
1759
                $this->Auth->authenticate = array('Basic', 'Form');
1760
                $this->Controller->request['action'] = 'admin_add';
1761

    
1762
                $this->Auth->response->expects($this->never())->method('statusCode');
1763
                $this->Auth->response->expects($this->never())->method('send');
1764

    
1765
                $result = $this->Auth->startup($this->Controller);
1766
                $this->assertFalse($result);
1767

    
1768
                $this->assertEquals('/users/login', $this->Controller->testUrl);
1769
        }
1770
}