source: branches/2.2/workflow/inc/class.CachedLDAP.inc.php @ 3225

Revision 3225, 12.0 KB checked in by viani, 14 years ago (diff)

Ticket #1186 - Correção no array de atributos Ldap retornados pela pesquisa de employee

Line 
1<?php
2/**************************************************************************\
3* eGroupWare                                                               *
4* http://www.egroupware.org                                                *
5* --------------------------------------------                             *
6*  This program is free software; you can redistribute it and/or modify it *
7*  under the terms of the GNU General Public License as published by the   *
8*  Free Software Foundation; either version 2 of the License, or (at your  *
9*  option) any later version.                                              *
10\**************************************************************************/
11
12/**
13* Gera um cache do LDAP (em banco de dados) para não perder informações no caso de exclusão de um funcionário
14* @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
15* @version 1.0
16* @license http://www.gnu.org/copyleft/gpl.html GPL
17* @package Workflow
18*/
19class CachedLDAP
20{
21        /**
22        * @var int $OPERATION_MODE_NORMAL Modo de operação normal (acessa primeiro o BD e, se necessário, acessa o LDAP e atualiza o BD)
23        * @access public
24        */
25        public $OPERATION_MODE_NORMAL = 0;
26
27        /**
28        * @var int $OPERATION_MODE_LDAP Modo de operação LDAP (acessa o LDAP e atualiza o BD)
29        * @access public
30        */
31        public $OPERATION_MODE_LDAP = 1;
32
33        /**
34        * @var int $OPERATION_MODE_DATABASE Modo de operação banco de dados (acessa somente o BD)
35        * @access public
36        */
37        public $OPERATION_MODE_DATABASE = 2;
38
39        /**
40        * @var int $OPERATION_MODE_LDAP_DATABASE Modo de operação LDAP e banco de dados. Acessa primeiro o LDAP e, somente se o usuário não existir no LDAP que o banco de dados será consultado.
41        * @access public
42        */
43        public $OPERATION_MODE_LDAP_DATABASE = 3;
44
45        /**
46        * @var string $userContext Contexto do usuário (LDAP)
47        * @access protected
48        */
49        protected $userContext;
50
51        /**
52        * @var string $groupContext Contexto do grupo (LDAP)
53        * @access protected
54        */
55        protected $groupContext;
56
57        /**
58        * @var resource $dataSource Conexão com o LDAP
59        * @access protected
60        */
61        protected $dataSource;
62
63        /**
64        * @var int $operationMode Modo de operação da classe
65        * @access private
66        */
67        private $operationMode;
68
69        /**
70        * @var array $entryAttributes Os atributos que serão buscados (LDAP ou Banco de Dados)
71        * @access private
72        */
73        private $entryAttributes = array('uid', 'cn', 'givenname', 'mail', 'sn', 'accountstatus', 'uidnumber', 'dn', 'employeenumber', 'cpf', 'telephonenumber');
74
75        /**
76         * @var array $entryAttributesLDAP Attributes thats only exists in LDAP.
77         * The attributes mobile and homePhone are not present in databaseCache, because they may have more
78         * This is not the very best approach because the best solution should be store all attributes
79         * from Ldap into databaseCache
80         * than one value
81         * @access private
82         * */
83        private $entryAttributesLDAP = array('mobile','homephone');
84
85        /**
86        * @var resource $DBLink Link com o banco de dados
87        * @access protected
88        */
89        protected $DBLink = null;
90
91        /**
92        * @var int $cacheDays O número de dias antes do cache ser renovado
93        * @access private
94        */
95        private $cacheDays = 2;
96
97        /**
98        * Estabelece uma conexão com o LDAP
99        * @return void
100        * @access protected
101        */
102        protected function loadLDAP()
103        {
104                /* check if the information was already loaded */
105                if (!empty($this->userContext))
106                        return;
107
108                /* load the information and establish a connection */
109                $tmpLDAP =& Factory::getInstance('WorkflowLDAP');
110                $this->userContext  = $tmpLDAP->getUserContext();
111                $this->groupContext = $tmpLDAP->getGroupContext();
112                $this->dataSource =& Factory::getInstance('WorkflowObjects')->getLDAP();
113        }
114
115        /**
116        * Estabelece uma conexão com o Banco de Dados
117        * @return void
118        * @access protected
119        */
120        protected function loadDB()
121        {
122                /* check if the information was already loaded */
123                if (!is_null($this->DBLink))
124                        return;
125
126                /* establish a connection */
127                $this->DBLink =& Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID;
128        }
129
130        /**
131        * Executa uma query no LDAP e, retorna o seu resultado
132        * @param string $ldapQuery A query do LDAP que será executada
133        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
134        * @access private
135        */
136        private function runLDAP($ldapQuery)
137        {
138                /* load the information and establish the connection */
139                $this->loadLDAP();
140
141                $ldapfields = array();
142
143                // Merge the arrays os attributes from databaseCache and Ldap
144                $ldapfields = array_merge($this->entryAttributes,$this->entryAttributesLDAP);
145
146                /* perform the search */
147                $resourceIdentifier = ldap_search($this->dataSource, $this->userContext, $ldapQuery, $ldapfields);
148                $entries = ldap_get_entries($this->dataSource, $resourceIdentifier);
149
150                /* check the returned data */
151                if ($entries['count'] != 1)
152                        return false;
153
154                /* format the output */
155                $output = array();
156                foreach ($ldapfields as $attribute)
157                        if ($attribute == 'dn' or $attribute == 'mobile' or $attribute == 'homePhone')
158                                // Retrieve all occurrencies of mobile and homePhone
159                                $output[$attribute] = $entries[0][$attribute];
160                        else
161                                // Retrieve first occurrence of other attributes
162                                $output[$attribute] = $entries[0][$attribute][0];
163
164                /* insert the timestamp of the last update */
165                $output['last_update'] = mktime();
166
167                return $output;
168        }
169
170        /**
171        * Executa uma query no Banco de Dados para encontrar um usuário
172        * @param string $bdQuery A cláusula WHERE da query
173        * @param array $bindVariables Valores que substituirão o pontos de interrogação na query
174        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
175        * @access private
176        */
177        private function runBD($bdQuery, $bindVariables)
178        {
179                /* establish the connection */
180                $this->loadDB();
181
182                /* perform the search */
183                $resultSet = $this->DBLink->query('SELECT ' . implode(', ', $this->entryAttributes) . ', EXTRACT(EPOCH FROM last_update) AS last_update FROM egw_wf_user_cache WHERE ' . $bdQuery, $bindVariables);
184
185                return $resultSet->fetchRow();
186        }
187
188        /**
189        * Atualiza, em Banco de Dados, os atributos de um usuário
190        * @param mixed $entry Uma array associativa contendo os atributos de um usuário (pode ser um boolean false)
191        * @param string $bdQuery A cláusula WHERE da query
192        * @param array $bindVariables Valores que substituirão o pontos de interrogação na query
193        * @return void
194        * @access private
195        */
196        private function updateDB($entry, $bdQuery, $bindVariables)
197        {
198                /* establish the connection */
199                $this->loadDB();
200
201
202                if ($entry == false)
203                {
204                        /* the user doesn't exist in LDAP anymore */
205                        $this->DBLink->query('UPDATE egw_wf_user_cache SET last_update = NULL WHERE ' . $bdQuery, $bindVariables);
206                }
207                else
208                {
209                        /* unset the timestamp */
210                        unset($entry['last_update']);
211
212                        /* insert/update the user info */
213                        $this->DBLink->query('DELETE FROM egw_wf_user_cache WHERE (uidnumber = ?)', array($entry['uidnumber']));
214                        $this->DBLink->query('INSERT INTO egw_wf_user_cache (' . implode(', ', array_keys($entry)) . ') VALUES (' . implode(', ', array_fill(0, count($entry), '?')) . ')', array_values($entry));
215                }
216        }
217
218        /**
219        * Faz a busca pelo usuário. Levando-se em conta o modo de operação selecionado
220        * @param string $ldapQuery A query do LDAP que será executada
221        * @param string $bdQuery A cláusula WHERE da query (se for utilizado o Banco de Dados)
222        * @param array $bindVariables Valores que substituirão o pontos de interrogação na query de Banco de Dados
223        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
224        * @access private
225        */
226        private function run($ldapQuery, $bdQuery, $bindVariables)
227        {
228                /* LDAP operation mode: load the user info in LDAP and then update the user info in the Database */
229                if (($this->operationMode == $this->OPERATION_MODE_LDAP) || ($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE))
230                {
231                        $entry = $this->runLDAP($ldapQuery);
232                        $this->updateDB($entry, $bdQuery, $bindVariables);
233
234                        /* return only the LDAP info when in LDAP operation mode, or if the user was found (when using the LDAP_DATABASE operation mode) */
235                        if (($this->operationMode == $this->OPERATION_MODE_LDAP) || (($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE) && ($entry !== false)))
236                                return $entry;
237                }
238
239                /* load the user information from the Database */
240                $entry = $this->runBD($bdQuery, $bindVariables);
241
242                /* return the database info when in LDAP_DATABASE operation mode (since the user wasn't found in the LDAP) */
243                if ($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE)
244                        return $entry;
245
246                /* normal operation mode: verify if the information in the Database is still valid; otherwise check it in LDAP */
247                if ($this->operationMode == $this->OPERATION_MODE_NORMAL)
248                {
249                        /* if the user was found in the Database and if the user doesn't exist in LDAP anymore or the information is updated, then return the info. Otherwise update it with LDAP info */
250                        if (($entry !== false) && ((is_null($entry['last_update'])) || (($entry['last_update'] + ($this->cacheDays * 24 * 60 * 60)) > mktime())))
251                                return $entry;
252
253                        /* we need to load info from the LDAP and update the Database record */
254                        $newEntry = $this->runLDAP($ldapQuery);
255                        $this->updateDB($newEntry, $bdQuery, $bindVariables);
256
257                        /* return the information from LDAP if the user was found; otherwise return the entry from the database */
258                        if ($newEntry !== false)
259                                return $newEntry;
260                        else
261                                return $entry;
262                }
263
264                return $entry;
265        }
266
267        /**
268        * Construtor da classe CachedLDAP
269        * @return object Objeto da classe CachedLDAP
270        * @access public
271        */
272        function CachedLDAP()
273        {
274                /* set the default operation mode */
275                $this->setOperationMode($this->OPERATION_MODE_NORMAL);
276        }
277
278        /**
279        * Define o modo como a classe vai operar (se busca somente no LDAP, no Banco de Dados, etc.)
280        * @param int $operationMode O modo de operação da classe
281        * @return void
282        * @access public
283        */
284        function setOperationMode($operationMode)
285        {
286                /* make sure it's an integer */
287                $operationMode = (int) $operationMode;
288                $availableOptions = array(
289                        $this->OPERATION_MODE_LDAP,
290                        $this->OPERATION_MODE_DATABASE,
291                        $this->OPERATION_MODE_NORMAL,
292                        $this->OPERATION_MODE_LDAP_DATABASE);
293
294                /* check if the value is valid and set it */
295                if (in_array($operationMode, $availableOptions, true))
296                        $this->operationMode = $operationMode;
297        }
298
299        /**
300        * Prepara os parâmetros para buscar o usuário
301        * @param string $field O nome do campo pelo qual a busca será feita
302        * @param string $value O valor que será utilizao na busca
303        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
304        * @access private
305        */
306        private function getEntry($field, $value)
307        {
308                /* build the queries */
309                $ldapQuery = "(&({$field}={$value})(phpgwaccounttype=u))";
310                $bdQuery = "({$field} = ?)";
311                $bindVariables = array($value);
312
313                return $this->run($ldapQuery, $bdQuery, $bindVariables);
314        }
315
316        /**
317        * Busca um usuário pelo seu ID
318        * @param int $userID O ID do usuário
319        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
320        * @access public
321        */
322        function getEntryByID($userID)
323        {
324                return $this->getEntry('uidnumber', (int) $userID);
325        }
326
327        /**
328        * Busca um usuário pelo seu CPF
329        * @param string $CPF O CPF do usuário
330        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
331        * @access public
332        */
333        function getEntryByCPF($CPF)
334        {
335                return $this->getEntry('cpf', $CPF);
336        }
337
338        /**
339        * Busca um usuário pelo seu e-mail
340        * @param string $email O e-mail do usuário
341        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
342        * @access public
343        */
344        function getEntryByEmail($email)
345        {
346                return $this->getEntry('mail', $email);
347        }
348
349        /**
350        * Busca um usuário pela sua matrícula
351        * @param int $employNumber A matrícula do usuário
352        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
353        * @access public
354        */
355        function getEntryByEmployeeNumber($employNumber)
356        {
357                return $this->getEntry('employeenumber', (int) $employNumber);
358        }
359
360        /**
361        * Busca um usuário pelo seu uid
362        * @param string $uid O uid do usuário
363        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
364        * @access public
365        */
366        function getEntryByUid($uid)
367        {
368                return $this->getEntry('uid', $uid);
369        }
370
371}
372?>
Note: See TracBrowser for help on using the repository browser.