From 06eaf00c48fc563245b85c2be4b8b5a03ef2cfe9 Mon Sep 17 00:00:00 2001 From: Michael Krelin Date: Thu, 11 Jan 2007 00:57:06 +0000 Subject: introduced extension hooks framework --- diff --git a/include/Makefile.am b/include/Makefile.am index b014752..72931eb 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -5,7 +5,8 @@ nobase_include_HEADERS = \ opkele/association.h \ opkele/exception.h \ opkele/server.h \ - opkele/consumer.h + opkele/consumer.h \ + opkele/extension.h EXTRA_DIST = \ opkele/data.h \ opkele/util.h diff --git a/include/opkele/consumer.h b/include/opkele/consumer.h index 9932315..f9939cf 100644 --- a/include/opkele/consumer.h +++ b/include/opkele/consumer.h @@ -2,6 +2,7 @@ #define __OPKELE_CONSUMER_H #include +#include /** * @file @@ -82,20 +83,22 @@ namespace opkele { * @param identity the identity to verify * @param return_to the return_to url to pass with the request * @param trust_root the trust root to advertise with the request + * @param ext pointer to an extension(s) hooks object * @return the location string * @throw exception in case of error */ - string checkid_immediate(const string& identity,const string& return_to,const string& trust_root=""); + string checkid_immediate(const string& identity,const string& return_to,const string& trust_root="",extension_t *ext=0); /** * prepare the parameters for the checkid_setup * request. * @param identity the identity to verify * @param return_to the return_to url to pass with the request * @param trust_root the trust root to advertise with the request + * @param ext pointer to an extension(s) hooks object * @return the location string * @throw exception in case of error */ - string checkid_setup(const string& identity,const string& return_to,const string& trust_root=""); + string checkid_setup(const string& identity,const string& return_to,const string& trust_root="",extension_t *ext=0); /** * the actual implementation behind checkid_immediate() and * checkid_setup() functions. @@ -103,24 +106,24 @@ namespace opkele { * @param identity the identity to verify * @param return_to the return_to url to pass with the request * @param trust_root the trust root to advertise with the request + * @param ext pointer to an extension(s) hooks object * @return the location string * @throw exception in case of error */ - string checkid_(mode_t mode,const string& identity,const string& return_to,const string& trust_root=""); + string checkid_(mode_t mode,const string& identity,const string& return_to,const string& trust_root="",extension_t *ext=0); /** * verify the id_res response * @param pin the response parameters - * @param identity the identity being checked (if not specified, extracted - * from the openid.identity parameter - * @throw id_res_mismatch in case of signature - * mismatch - * @throw id_res_setup in case of - * openid.user_setup_url failure (supposedly - * checkid_immediate only) + * @param identity the identity being checked (if not specified, + * @param ext pointer to an extension(s) hooks object + * extracted from the openid.identity parameter + * @throw id_res_mismatch in case of signature mismatch + * @throw id_res_setup in case of openid.user_setup_url failure + * (supposedly checkid_immediate only) * @throw id_res_failed in case of failure * @throw exception in case of other failures */ - void id_res(const params_t& pin,const string& identity=""); + void id_res(const params_t& pin,const string& identity="",extension_t *ext=0); /** * perform a check_authentication request. * @param server the OpenID server diff --git a/include/opkele/exception.h b/include/opkele/exception.h index c5f5811..9fc9bd3 100644 --- a/include/opkele/exception.h +++ b/include/opkele/exception.h @@ -205,6 +205,16 @@ namespace opkele { ~exception_curl() throw() { } }; + /** + * not implemented (think pure virtual) member function executed, signfies + * programmer error + */ + class not_implemented : public exception { + public: + not_implemented(OPKELE_E_PARS) + : exception(OPKELE_E_CONS) { } + }; + } #endif /* __OPKELE_EXCEPTION_H */ diff --git a/include/opkele/extension.h b/include/opkele/extension.h new file mode 100644 index 0000000..3fb5f6e --- a/dev/null +++ b/include/opkele/extension.h @@ -0,0 +1,59 @@ +#ifndef __OPKELE_EXTENSIONS_H +#define __OPKELE_EXTENSIONS_H + +/** + * @file + * @brief extensions framework basics + */ + +#include + +/** + * @brief the main opkele namespace + */ +namespace opkele { + + /** + * OpenID consumer extension hooks base class + */ + class extension_t { + public: + /** + * hook called by consumer before submitting data to OpenID server. + * It is supposed to manipulate parameters list. + * @param p parameters about to be submitted to server + * @param identity identity being verified. It may differ from the + * one available in parameters list in case of delegation + */ + virtual void checkid_hook(params_t& p,const string& identity); + /** + * hook called by consumer after identity information received from + * OpenID server is verified. + * @param p parameters received from server + * @param sp signed parameters received from server with 'openid.' + * leader stripped + * @param identity identity confirmed. May differ from the one + * available in parameters list in case of delegation. May also be + * empty which means - extract one from parameters + */ + virtual void id_res_hook(const params_t& p,const params_t& sp,const string& identity); + + /** + * hook called by server before returning information to consumer. + * The hook may manipulate output parameters. It is important to + * note that modified pout["signed"] is used for signing response. + * @param pin request parameters list + * @param put response parameters list + */ + virtual void checkid_hook(const params_t& pin,params_t& pout); + + /** + * Casts the object to pointer to itself. For convenient passing + * of pointer. + */ + operator extension_t*(void) { return this; } + }; + +} + +#endif /* __OPKELE_EXTENSIONS_H */ diff --git a/include/opkele/server.h b/include/opkele/server.h index fe07448..bf131d8 100644 --- a/include/opkele/server.h +++ b/include/opkele/server.h @@ -7,6 +7,7 @@ */ #include +#include /** * @brief the main opkele namespace @@ -60,17 +61,19 @@ namespace opkele { * @param pin the incoming request parameters * @param return_to reference to the object to store return_to url to * @param pout the response parameters + * @param ext pointer to the extension hooks object * @throw exception in case of errors or negative reply */ - void checkid_immediate(const params_t& pin,string& return_to,params_t& pout); + void checkid_immediate(const params_t& pin,string& return_to,params_t& pout,extension_t *ext=0); /** * process the checkid_setup request. * @param pin the incoming request parameters * @param return_to reference to the object to store return_to url to * @param pout the response parameters + * @param ext pointer to the extension hooks object * @throw exception in case of errors or negative reply */ - void checkid_setup(const params_t& pin,string& return_to,params_t& pout); + void checkid_setup(const params_t& pin,string& return_to,params_t& pout,extension_t *ext=0); /** * the actual functionality behind checkid_immediate() and * checkid_setup() @@ -79,9 +82,10 @@ namespace opkele { * @param pin the incoming request parameters * @param return_to reference to the object to store return_to url to * @param pout the response parameters + * @param ext pointer to the extension hooks object * @throw exception in case of errors or negative reply */ - void checkid_(mode_t mode,const params_t& pin,string& return_to,params_t& pout); + void checkid_(mode_t mode,const params_t& pin,string& return_to,params_t& pout,extension_t *ext=0); /** * process the check_authentication request. * @param pin incoming request parameters diff --git a/lib/Makefile.am b/lib/Makefile.am index 6f3f9f3..69c749e 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -21,4 +21,5 @@ libopkele_la_SOURCES = \ secret.cc \ data.cc \ consumer.cc \ - exception.cc + exception.cc \ + extension.cc diff --git a/lib/consumer.cc b/lib/consumer.cc index bb6358c..10c2fa0 100644 --- a/lib/consumer.cc +++ b/lib/consumer.cc @@ -123,13 +123,13 @@ namespace opkele { return store_assoc(server,p.get_param("assoc_handle"),secret,expires_in); } - string consumer_t::checkid_immediate(const string& identity,const string& return_to,const string& trust_root) { - return checkid_(mode_checkid_immediate,identity,return_to,trust_root); + string consumer_t::checkid_immediate(const string& identity,const string& return_to,const string& trust_root,extension_t *ext) { + return checkid_(mode_checkid_immediate,identity,return_to,trust_root,ext); } - string consumer_t::checkid_setup(const string& identity,const string& return_to,const string& trust_root) { - return checkid_(mode_checkid_setup,identity,return_to,trust_root); + string consumer_t::checkid_setup(const string& identity,const string& return_to,const string& trust_root,extension_t *ext) { + return checkid_(mode_checkid_setup,identity,return_to,trust_root,ext); } - string consumer_t::checkid_(mode_t mode,const string& identity,const string& return_to,const string& trust_root) { + string consumer_t::checkid_(mode_t mode,const string& identity,const string& return_to,const string& trust_root,extension_t *ext) { params_t p; if(mode==mode_checkid_immediate) p["mode"]="checkid_immediate"; @@ -153,14 +153,16 @@ namespace opkele { p["assoc_handle"] = ah; } }catch(exception& e) { } + if(ext) ext->checkid_hook(p,identity); return p.append_query(server); } - void consumer_t::id_res(const params_t& pin,const string& identity) { + void consumer_t::id_res(const params_t& pin,const string& identity,extension_t *ext) { if(pin.has_param("openid.user_setup_url")) throw id_res_setup(OPKELE_CP_ "assertion failed, setup url provided",pin.get_param("openid.user_setup_url")); string server,delegate; retrieve_links(identity.empty()?pin.get_param("openid.identity"):canonicalize(identity),server,delegate); + params_t ps; try { assoc_t assoc = retrieve_assoc(server,pin.get_param("openid.assoc_handle")); const string& sigenc = pin.get_param("openid.sig"); @@ -180,6 +182,7 @@ namespace opkele { f.insert(0,"openid."); kv += pin.get_param(f); kv += '\n'; + if(ext) ps[f.substr(sizeof("openid."))] = pin.get_param(f); if(co==string::npos) break; p = co+1; @@ -219,6 +222,7 @@ namespace opkele { throw id_res_failed(OPKELE_CP_ "failed to check_authentication()"); } } + if(ext) ext->id_res_hook(pin,ps,identity); } void consumer_t::check_authentication(const string& server,const params_t& p) { diff --git a/lib/extension.cc b/lib/extension.cc new file mode 100644 index 0000000..bd2195d --- a/dev/null +++ b/lib/extension.cc @@ -0,0 +1,15 @@ +#include +#include + +namespace opkele { + + void extension_t::checkid_hook(params_t& p,const string& identity) { + throw not_implemented(OPKELE_CP_ "Consumer checkid_hook not implemented"); + } + void id_res_hook(const params_t& p,const params_t& sp,const string& identity) { + throw not_implemented(OPKELE_CP_ "Consumer id_res_hook not implemented"); + } + void checkid_hook(const params_t& pin,params_t& pout) { + throw not_implemented(OPKELE_CP_ "Server checkid_hook not implemented"); + } +} diff --git a/lib/server.cc b/lib/server.cc index 5eee1f3..8c29abb 100644 --- a/lib/server.cc +++ b/lib/server.cc @@ -67,15 +67,15 @@ namespace opkele { } } - void server_t::checkid_immediate(const params_t& pin,string& return_to,params_t& pout) { - checkid_(mode_checkid_immediate,pin,return_to,pout); + void server_t::checkid_immediate(const params_t& pin,string& return_to,params_t& pout,extension_t *ext) { + checkid_(mode_checkid_immediate,pin,return_to,pout,ext); } - void server_t::checkid_setup(const params_t& pin,string& return_to,params_t& pout) { - checkid_(mode_checkid_setup,pin,return_to,pout); + void server_t::checkid_setup(const params_t& pin,string& return_to,params_t& pout,extension_t *ext) { + checkid_(mode_checkid_setup,pin,return_to,pout,ext); } - void server_t::checkid_(mode_t mode,const params_t& pin,string& return_to,params_t& pout) { + void server_t::checkid_(mode_t mode,const params_t& pin,string& return_to,params_t& pout,extension_t *ext) { if(mode!=mode_checkid_immediate && mode!=mode_checkid_setup) throw bad_input(OPKELE_CP_ "invalid checkid_* mode"); pout.clear(); @@ -106,7 +106,9 @@ namespace opkele { pout["issued"] = util::time_to_w3c(now); pout["valid_to"] = util::time_to_w3c(now+120); pout["exipres_in"] = "120"; - pout.sign(assoc->secret(),pout["sig"],pout["signed"]="mode,identity,return_to"); + pout["signed"]="mode,identity,return_to"; + if(ext) ext->checkid_hook(pin,pout); + pout.sign(assoc->secret(),pout["sig"],pout["signed"]); } void server_t::check_authentication(const params_t& pin,params_t& pout) { -- cgit v0.9.0.2