Merge branch '2013.10' into 2014.11
[tine20] / tests / tine20 / Tinebase / User / LdapTest.php
1 <?php
2 /**
3  * Tine 2.0 - http://www.tine20.org
4  * 
5  * @package     Tinebase
6  * @subpackage  User
7  * @license     http://www.gnu.org/licenses/agpl.html
8  * @copyright   Copyright (c) 2008-2016 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Lars Kneschke <l.kneschke@metaways.de>
10  */
11
12 /**
13  * Test class for Tinebase_User_Ldap
14  */
15 class Tinebase_User_LdapTest extends TestCase
16 {
17     /**
18      * ldap group backend
19      *
20      * @var Tinebase_User_LDAP
21      */
22     protected $_backend = NULL;
23         
24     /**
25      * Sets up the fixture.
26      * This method is called before a test is executed.
27      *
28      * @access protected
29      */
30     protected function setUp()
31     {
32         if (Tinebase_User::getConfiguredBackend() !== Tinebase_User::LDAP) {
33             $this->markTestSkipped('LDAP backend not enabled');
34         }
35         $this->_backend = Tinebase_User::factory(Tinebase_User::LDAP);
36
37         parent::setUp();
38     }
39
40     /**
41      * tear down tests
42      */
43     protected function tearDown()
44     {
45         Tinebase_Config::getInstance()->set(Tinebase_Config::LDAP_OVERWRITE_CONTACT_FIELDS, array());
46
47         parent::tearDown();
48     }
49
50     /**
51      * try to add an user
52      * 
53      * @return Tinebase_Model_FullUser
54      */
55     public function testAddUser()
56     {
57         $user = $this->getTestRecord();
58
59         $this->_usernamesToDelete[] = $user->accountLoginName;
60         $testUser = $this->_backend->addUser($user);
61
62         $this->assertEquals($user->accountLoginName, $testUser->accountLoginName);
63         $this->assertEquals('Tinebase_Model_FullUser', get_class($testUser), 'wrong type');
64         
65         return $user;
66     }
67     
68     /**
69      * try to get all users containing phpunit in there name
70      */
71     public function testGetUsers()
72     {
73         $this->testAddUser();
74         
75         $users = $this->_backend->getUsers('phpunit', 'accountStatus');
76         
77         $this->assertGreaterThanOrEqual(1, count($users));
78     }
79     
80     /**
81      * try to get an user by loginname
82      *
83      */
84     public function testGetUserByLoginName()
85     {
86         // add a test user
87         $user = $this->testAddUser();
88         
89         $testUser = $this->_backend->getFullUserByLoginName($user->accountLoginName);
90         
91         $this->assertEquals($user->accountLoginName, $testUser->accountLoginName);
92         $this->assertEquals('Tinebase_Model_FullUser', get_class($testUser), 'wrong type');
93     }
94     
95     /**
96      * try to get an user by userId
97      *
98      */
99     public function testGetUserById()
100     {
101         $user = $this->testAddUser();
102         
103         $testUser = $this->_backend->getFullUserById($user->getId());
104         
105         $this->assertEquals($user->accountLoginName, $testUser->accountLoginName);
106         $this->assertEquals('Tinebase_Model_FullUser', get_class($testUser), 'wrong type');
107     }
108         
109     /**
110      * try to update an user
111      *
112      */
113     public function testUpdateUser()
114     {
115         $groupsBackend = Tinebase_Group::factory(Tinebase_Group::LDAP);
116         
117         $user = $this->testAddUser();
118         $groupsBackend->addGroupMemberInSyncBackend($user->accountPrimaryGroup, $user);
119         $groupsBeforeUpdate = $groupsBackend->getGroupMembershipsFromSyncBackend($user);
120         
121         $user->accountLoginName = 'tine20phpunituser-updated';
122         $this->_usernamesToDelete[] = $user->accountLoginName;
123         $testUser = $this->_backend->updateUser($user);
124         $groupsAfterUpdate = $groupsBackend->getGroupMembershipsFromSyncBackend($testUser);
125         
126         sort($groupsBeforeUpdate);
127         sort($groupsAfterUpdate);
128         
129         $this->assertEquals($user->accountLoginName, $testUser->accountLoginName);
130         $this->assertEquals($groupsBeforeUpdate, $groupsAfterUpdate);
131     }
132     
133     /**
134      * try to enable an account
135      *
136      */
137     public function testSetStatus()
138     {
139         $user = $this->testAddUser();
140
141         $this->_backend->setStatus($user, Tinebase_User::STATUS_DISABLED);
142         
143         $testUser = $this->_backend->getUserById($user, 'Tinebase_Model_FullUser');
144         
145         $this->assertEquals(Tinebase_User::STATUS_DISABLED, $testUser->accountStatus);
146         
147         
148         $this->_backend->setStatus($user, Tinebase_User::STATUS_ENABLED);
149         
150         $testUser = $this->_backend->getUserById($user, 'Tinebase_Model_FullUser');
151         
152         $this->assertEquals(Tinebase_User::STATUS_ENABLED, $testUser->accountStatus);
153     }
154     
155     /**
156      * try to update the logintimestamp
157      *
158      */
159     public function testSetLoginTime()
160     {
161         $user = $this->testAddUser();
162         
163         $this->_backend->setLoginTime($user, '127.0.0.1');
164         
165         $testUser = $this->_backend->getUserById($user, 'Tinebase_Model_FullUser');
166         
167         $this->assertNotEquals($user->accountLastLogin, $testUser->accountLastLogin);
168     }
169     
170     /**
171      * try to set password
172      *
173      */
174     public function testSetPassword()
175     {
176         $user = $this->testAddUser();
177
178         $this->_backend->setPassword($user, Tinebase_Record_Abstract::generateUID());
179         
180         $testUser = $this->_backend->getUserById($user, 'Tinebase_Model_FullUser');
181         
182         $this->assertNotEquals($user->accountLastPasswordChange, $testUser->accountLastPasswordChange);
183     }
184     
185     /**
186      * try to set the expirydate
187      *
188      */
189     public function testSetExpiryDate()
190     {
191         $user = $this->testAddUser();
192         
193         $this->_backend->setExpiryDate($user, Tinebase_DateTime::now()->subDay(1));
194         
195         $testUser = $this->_backend->getUserById($user, 'Tinebase_Model_FullUser');
196         
197         $this->assertEquals('Tinebase_DateTime', get_class($testUser->accountExpires), 'wrong type');
198         $this->assertEquals(Tinebase_User::STATUS_EXPIRED, $testUser->accountStatus);
199
200         $this->_backend->setExpiryDate($user, NULL);
201         
202         $testUser = $this->_backend->getUserById($user, 'Tinebase_Model_FullUser');
203         
204         $this->assertEquals(NULL, $testUser->accountExpires);
205         $this->assertEquals(Tinebase_User::STATUS_ENABLED, $testUser->accountStatus);
206     }
207     
208     /**
209      * try to delete an user
210      *
211      */
212     public function testDeleteUser()
213     {
214         $user = $this->testAddUser();
215         
216         $this->_backend->deleteUser($user);
217         unset($this->objects['users']['testUser']);
218         
219         $this->setExpectedException('Tinebase_Exception_NotFound');
220         
221         $this->_backend->getUserById($user, 'Tinebase_Model_FullUser');
222     }
223     
224     /**
225      * execute Tinebase_User::syncUser
226      *
227      * TODO test bday
228      */
229     public function testSyncUsersContactData()
230     {
231         Tinebase_Config::getInstance()->set(Tinebase_Config::LDAP_OVERWRITE_CONTACT_FIELDS, array(
232             'tel_work',
233             'jpegphoto'
234         ));
235
236         // add user in LDAP
237         $user = $this->_backend->addUserToSyncBackend(self::getTestRecord());
238         $this->_usernamesToDelete[] = $user->accountLoginName;
239
240         $syncedUser = Tinebase_User::syncUser($user);
241
242         // check if user is synced
243         $this->assertEquals(Tinebase_Model_User::VISIBILITY_DISPLAYED, $syncedUser->visibility,
244             print_r($syncedUser->toArray(), true));
245
246         // add+remove phone data in ldap and check if it is removed in adb, too
247         $syncOptions = array(
248             'syncContactData' => true,
249             'syncContactPhoto' => true,
250         );
251         $ldap = $this->_backend->getLdap();
252         $dn = $this->_backend->generateDn($syncedUser);
253         $number = '040-428457634';
254         $jpegImage = file_get_contents(dirname(dirname(dirname(dirname(__DIR__))))
255             . '/tine20/Admin/Setup/DemoData/persona_sclever.jpg');
256         $ldap->updateProperty($dn, array(
257             'telephonenumber' => $number,
258             'jpegphoto'       => $jpegImage,
259             //'birthdate'       => '2000-09-09'
260         ));
261         $syncedUser = Tinebase_User::syncUser($user, $syncOptions);
262         $contact = Addressbook_Controller_Contact::getInstance()->getContactByUserId($syncedUser->getId());
263         $this->assertEquals($number, $contact->tel_work);
264         $this->assertEquals(1, $contact->jpegphoto);
265         //$this->assertEquals('2000-09-09 00:00:00', $contact->bday->toString());
266
267         // remove number + photo and sync again
268         $ldap->updateProperty($dn, array(
269             'telephonenumber' => '',
270             'jpegphoto'       => '',
271         ));
272         $syncedUser = Tinebase_User::syncUser($user, $syncOptions);
273         $contact = Addressbook_Controller_Contact::getInstance()->getContactByUserId($syncedUser->getId());
274         $this->assertEquals('', $contact->tel_work);
275         $this->assertEquals(0, $contact->jpegphoto);
276     }
277
278     /**
279      * @return Tinebase_Model_FullUser
280      */
281     public static function getTestRecord()
282     {
283         $config = Zend_Registry::get('testConfig');
284         $emailDomain = ($config->maildomain) ? $config->maildomain : 'tine20.org';
285         
286         $user  = new Tinebase_Model_FullUser(array(
287             'accountLoginName'      => 'tine20phpunituser',
288             'accountStatus'         => 'enabled',
289             'accountExpires'        => NULL,
290             'accountPrimaryGroup'   => Tinebase_Group::getInstance()->getDefaultGroup()->id,
291             'accountLastName'       => 'Tine 2.0',
292             'accountFirstName'      => 'PHPUnit User',
293             'accountEmailAddress'   => 'phpunit@' . $emailDomain,
294         ));
295         
296         return $user;
297     }
298
299     /**
300      * @see 0011192: LDAP sync should delete contacts
301      */
302     public function testSyncDeleted()
303     {
304         $user = $this->testAddUser();
305
306         // add user contact
307         $contact = Admin_Controller_User::getInstance()->createOrUpdateContact($user);
308         $user->contact_id = $contact->getId();
309         Tinebase_User::getInstance()->updateUser($user);
310
311         // delete user in ldap
312         Tinebase_User::getInstance()->deleteUserInSyncBackend($user->getId());
313
314         // check if still in tine20 db
315         $sqlUser = Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountId', $user->getId());
316         $this->assertEquals($user->getId(), $sqlUser->getId());
317
318         // set sync config/option + start user sync
319         $syncOptions = array('deleteUsers' => true);
320         Tinebase_User::syncUsers($syncOptions);
321
322         $now = Tinebase_DateTime::now();
323         $user = Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountId', $user->getId(), 'Tinebase_Model_FullUser');
324         $this->assertEquals($now->toString(), $user->accountExpires->toString(), 'user should be expired');
325
326         sleep(1);
327         Tinebase_User::syncUsers($syncOptions);
328         $user = Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountId', $user->getId(), 'Tinebase_Model_FullUser');
329         $this->assertEquals($now->toString(), $user->accountExpires->toString(), 'expiry date should still be the same');
330
331         // set expired to -1 year -> user should be deleted
332         $user->accountExpires = $now->subYear(1);
333         Tinebase_User::getInstance()->updateUserInSqlBackend($user);
334
335         // sync again
336         sleep(1);
337         Tinebase_User::syncUsers($syncOptions);
338
339         // check if user is deleted in tine, too
340         try {
341             Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountId', $user->getId());
342             $this->fail('user should be deleted from tine20 db');
343         } catch (Tinebase_Exception_NotFound $tenf) {
344             $this->assertContains('User with accountId = ' . $sqlUser->getId(), $tenf->getMessage());
345         }
346
347         // check if user contact is deleted, too
348         try {
349             Addressbook_Controller_Contact::getInstance()->get($sqlUser->contact_id);
350             $this->fail('user contact should be deleted from tine20 db');
351         } catch (Tinebase_Exception_NotFound $tenf) {
352             $this->assertContains('Addressbook_Model_Contact record with id = ' . $sqlUser->contact_id, $tenf->getMessage());
353         }
354     }
355
356     /**
357      * test user status sync tine <-> ldap
358      *
359      * @see 0011554: improve ldap account status handling
360      */
361     public function testSyncUserStatus()
362     {
363         $user = $this->testAddUser();
364
365         // set user status in tine (disabled, expired, enabled)
366         $statusToTest = array(
367             Tinebase_Model_User::ACCOUNT_STATUS_EXPIRED,
368             Tinebase_Model_User::ACCOUNT_STATUS_DISABLED,
369             Tinebase_Model_User::ACCOUNT_STATUS_EXPIRED,
370             Tinebase_Model_User::ACCOUNT_STATUS_ENABLED,
371         );
372
373         foreach($statusToTest as $status) {
374             Tinebase_User::getInstance()->setStatus($user, $status);
375
376             // sync user -> user status should be the same
377             $syncedUser = Tinebase_User::syncUser($user, array('syncAccountStatus' => true));
378             $this->assertEquals($status, $syncedUser->accountStatus, print_r($syncedUser->toArray(), true));
379         }
380     }
381 }