1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
9 #ifndef anna_ldap_Engine_hpp
10 #define anna_ldap_Engine_hpp
15 #include <anna/app/Component.hpp>
24 Gestor general de conexiones realizadas a diversos servidores LDAP.
26 Optimiza la creacion, busqueda y liberacion de las sesiónes establecidas contra un
27 numero indeterminado de servidores LDAP.
29 El siguiente codigo muestra un ejemplo de implementacion:
33 class MyEngine : public ldap::Engine {
38 anna::Recycler<MySession> a_sessions;
40 anna::ldap::Session* allocateSession (const int category) throw () { return a_sessions.create (); }
42 void releaseSession (anna::ldap::Session* session) throw () {
43 MySession* aux = static_cast <MySession*> (session);
44 a_sessions.release (aux);
50 class Engine : public app::Component {
53 * Máscara de los niveles de depuración que pueden ser usados en el método #setDebugLevel
56 struct DebugLevel { enum _v { All = -1, None = 0 }; };
59 * Devuelve el valor del indicador de conexión automática. Por defecto este indicador será \em true.
60 * \return el valor del indicador de conexión automática.
62 bool getAutoBind() const throw() { return a_autoBind; }
65 * Establece el indicador de conexión automática. En caso de no indicarse será \em true.
66 * \param autoBind Valor que tomará el indicador de conexión automática.
68 * Si es necesario cambiar el temporizador del Bind de una sesión LDAP, primero habrá que
69 * crearla sin conexión automática, cambiar el temporizador asociado e invocar al Bind invocando
70 * implícitamente al método ldap::Session::bind.
72 void setAutoBind(const bool autoBind) throw() { a_autoBind = autoBind; }
75 Crea o reusa una sesión LDAP con los parámetros recibidos.
77 Las sesiónes LDAP estaran definidas univocamente por la pareja (url, user) si al
78 invocar a este metodo ya existiera una sesión identificada por los mismos parámetros
79 recibidos, se devolvera su instancia.
81 Si no existe una sesión identificada por la pareja (url, user) se creara mediate la llamada
82 al metodo virtual puro (#allocateSession), se realizara la peticion de conexion y se devolvera
85 Dependiendo del indicador de conexión automática se solicitará la conexión al servidor
86 o será el programador quien tenga que invocarlo mediate la llamada al método ldap::Session::bind.
88 \param url Direccion donde atiende peticiones el servidor LDAP.
89 \param user Usuario requerido para establecer la conexion contra el servidor LDAP.
90 \param password Password requerido para establecer la conexion contra el servidor LDAP.
91 \param category Identifica el tipo de sesión a crear.
93 \return La session identificada por la \em url y \em user indicados como parametro.
95 \warning La conexion no estara totalmente operativa hasta que no se reciba la notificacion
96 correspondiente en el metodo Session::eventResponse confirmando que el ClassCode::Bind se ha
97 realizado correctamente.
99 Session* createSession(const char* url, const char* user, const char* password, const int category = 0)
100 throw(RuntimeException);
103 Crea o reusa una sesión LDAP con los parámetros recibidos.
105 Las sesiónes LDAP estaran definidas univocamente por la pareja (url, id) si al
106 invocar a este metodo ya existiera una sesión identificada por los mismos parámetros
107 recibidos, se devolvera su instancia.
109 Si no existe una sesión identificada por la pareja (url, id) se creara mediate la llamada
110 al metodo virtual puro (#allocateSession), se realizara la peticion de conexion y se devolvera
111 esta nueva instancia.
113 Dependiendo del indicador de conexión automática se solicitará la conexión al servidor
114 o será el programador quien tenga que invocarlo mediate la llamada al método ldap::Session::bind.
116 \param url Direccion donde atiende peticiones el servidor LDAP.
117 \param id Identificador usado para identificar la sesión.
118 \param user Usuario requerido para establecer la conexion contra el servidor LDAP.
119 \param password Password requerido para establecer la conexion contra el servidor LDAP.
120 \param category Identifica el tipo de sesión a crear.
122 \return La session identificada por la \em url y \em id indicados como parametro.
124 \warning La conexion no estara totalmente operativa hasta que no se reciba la notificacion
125 correspondiente en el metodo Session::eventResponse confirmando que el ClassCode::Bind se ha
126 realizado correctamente.
128 Session* createSession(const char* url, const int id, const char* user, const char* password, const int category = 0)
129 throw(RuntimeException);
132 Crea o reusa una sesión LDAP con los parámetros recibidos a un servidor que no requiera identificar
133 el usuario que solicita la conexion.
135 Las sesiónes LDAP estaran definidas univocamente por la pareja (url, user="") si al
136 invocar a este metodo ya existiera una sesión identificada por los mismos parámetros
137 recibidos, se devolvera su instancia.
139 Si no existe una sesión identificada por la pareja (url, user="") se creara mediate la llamada
140 al metodo virtual puro (#allocateSession), se realizara la peticion de conexion y se devolvera
141 esta nueva instancia.
143 \param url Direccion donde atiende peticiones el servidor LDAP.
144 \param category Identifica el tipo de sesión a crear.
146 \return La session identificada por la \em url indicada como parametro.
148 \warning La conexion no estara totalmente operativa hasta que no se reciba la notificacion
149 correspondiente en el metodo Session::eventResponse confirmando que el ClassCode::Bind se ha
150 realizado correctamente.
152 Session* createSession(const char* url, const int category = 0) throw(RuntimeException) {
153 return createSession(url, NULL, NULL, category);
157 Devuelve la instancia de la sesión identificada por la pareja (url, user) recibidos como parámetros.
159 \param url Direccion de la maquina donde atiendo peticiones el servidor LDAP.
160 \param user Usuario requerido para establecer la conexion contra el servidor LDAP.
161 \param emode Modo de actuar en caso de que no exista una sesión que coincida con los parámetros indicados.
163 \return La instancia de la sesión identificada por la pareja (url, user) recibidos como parámetros.
165 \warning Si no hay ninguna sesión identificada por la pareja (url, user) se devolvera una excepción.
167 Session* findSession(const char* url, const char* user, Exception::Mode::_v emode = Exception::Mode::Throw) throw(RuntimeException);
170 Devuelve la instancia de la sesión identificada por la pareja (url, id) recibidos como parámetros.
172 \param url Direccion de la maquina donde atiendo peticiones el servidor LDAP.
173 \param id Identificador indicado para establecer la conexion contra el servidor LDAP.
174 \param emode Modo de actuar en caso de que no exista una sesión que coincida con los parámetros indicados.
176 \return La instancia de la sesión identificada por la pareja (url, id) recibidos como parámetros.
178 \warning Si no hay ninguna sesión identificada por la pareja (url, id) se devolvera una excepción.
180 Session* findSession(const char* url, const int id, Exception::Mode::_v emode = Exception::Mode::Throw) throw(RuntimeException);
183 Devuelve la instancia de la sesión identificada por la pareja (url, user="") recibidos como parámetros.
185 \param url Direccion de la maquina donde atiendo peticiones el servidor LDAP.
186 \param emode Modo de actuar en caso de que no exista una sesión que coincida con los parámetros indicados.
188 \return La instancia de la sesión identificada por la pareja (url, user="") recibidos como parámetros.
190 \warning Si no hay ninguna sesión identificada por la pareja (url, user) se devolvera una excepción.
192 Session* findSession(const char* url, Exception::Mode::_v emode = Exception::Mode::Throw) throw(RuntimeException) {
193 return findSession(url, (const char*) NULL, emode);
197 * Libera todos los recursos asociados a una sesión LDAP, creada previemante con createSession. Si la sesión
198 * fuera NULL esta operación no tendrá ningún efecto.
199 * \param session Session LDAP a liberar.
201 void closeSession(Session* session) throw(RuntimeException);
204 Devuelve un documento XML con la informacion relevante sobre esta instancia.
205 \param parent Nodo XML del que colgar la informacion referente a esta instancia.
206 \return Un documento XML con la informacion relevante sobre esta instancia.
208 virtual xml::Node* asXML(xml::Node* parent) const throw();
211 Devuelve el nombre lógico de este anna::app::Component.
212 \return El nombre lógico de este anna::app::Component.
214 static const char* getClassName() throw() { return "anna::ldap::Engine"; }
217 * Establece el nivel de depuración de las operaciones del OpenLDAP.
218 * \param level Máscara que indica los elementos a depurar. Básicamente 0 para desactivar las trazas de depuración y -1 para
219 * activar el trazado de todo.
220 * \return El nivel de depuración anterior.
221 * \see http://www.openldap.org/doc/admin23/runningslapd.html para más niveles.
224 static int setDebugLevel(const int level) throw(RuntimeException);
233 Metodo invocado para instanciar sesiónes.
235 Para la creacion y liberacion de sesiónes es muy aconsejable usar el patron anna::Recycler.
237 \param category Identifica la categoria o clase de sesión que deseamos instanciar. Este paremetro
238 es el mismo indicado en el #createSession. Facilita que una misma aplicacion pueda crear un numero
239 indeterminado de sesiónes de distintos tipos, es decir, que actuen de forma distinta a la hora
240 de recoger los resultados de las peticiones.
244 virtual Session* allocateSession(const int category) throw() = 0;
247 Metodo invocado para liberar sesiónes. En caso de que nuestra aplicacion requiera varios tipos de
248 sesiónes LDAP habra que tener en cuenta el valor devuelto por ldap::Session::getCategory y liberar
249 el tipo adecuado de sesión.
252 virtual void releaseSession(Session*) throw() = 0;
255 typedef std::pair <std::string, std::string> session_key;
256 typedef std::map <session_key, Session*> session_container;
257 typedef session_container::value_type session_value_type;
258 typedef session_container::iterator session_iterator;
259 typedef session_container::const_iterator const_session_iterator;
261 session_container a_sessions;
262 std::string a_auxURL; // Usada para contenar el ldap:// si fuera necesario
265 void do_initialize() throw() {;}
266 void do_stop() throw();
268 const char* completeURL(const char* url) throw();
270 session_iterator session_find(const char* url, const char* user) throw() {
271 return a_sessions.find(session_key(url, user));
273 session_iterator session_find(const std::string& url, const std::string& user) throw() {
274 return a_sessions.find(session_key(url, user));
276 session_iterator session_find(const char* url, const int id) throw();
278 session_iterator session_begin() throw() { return a_sessions.begin(); }
279 session_iterator session_end() throw() { return a_sessions.end(); }
280 static Session* session(session_iterator ii) throw() { return ii->second; }
282 const_session_iterator session_begin() const throw() { return a_sessions.begin(); }
283 const_session_iterator session_end() const throw() { return a_sessions.end(); }
284 static const Session* session(const_session_iterator ii) throw() { return ii->second; }
286 // Para el truco de poner a la alarma antes de invocar al ldap_result
287 static void alarmnCatcher(int) throw();