diff options
author | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2012-12-11 04:03:29 +0000 |
---|---|---|
committer | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2012-12-11 04:03:29 +0000 |
commit | 86b1de85536e93c59a25702a5a2d3e384202ffd2 (patch) | |
tree | c61d91970980199c597304ddcb01919993fbeb82 /sca-cpp/trunk/modules/oauth | |
parent | 5f29c3b769fcdb2532d4948aa1c649d4330304b9 (diff) |
More changes to port to C++11, adjust to use the new JSON support, and cleanup rest of the modules.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1419987 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r-- | sca-cpp/trunk/modules/oauth/Makefile.am | 4 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/oauth/mod-oauth1.cpp | 187 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/oauth/mod-oauth2.cpp | 167 |
3 files changed, 163 insertions, 195 deletions
diff --git a/sca-cpp/trunk/modules/oauth/Makefile.am b/sca-cpp/trunk/modules/oauth/Makefile.am index 9e8eb5a0dd..d72a584f49 100644 --- a/sca-cpp/trunk/modules/oauth/Makefile.am +++ b/sca-cpp/trunk/modules/oauth/Makefile.am @@ -26,12 +26,12 @@ mod_LTLIBRARIES = libmod_tuscany_oauth1.la libmod_tuscany_oauth2.la noinst_DATA = libmod_tuscany_oauth1${libsuffix} libmod_tuscany_oauth2${libsuffix} libmod_tuscany_oauth1_la_SOURCES = mod-oauth1.cpp -libmod_tuscany_oauth1_la_LDFLAGS = -L${LIBOAUTH_LIB} -R${LIBOAUTH_LIB} -loauth -lxml2 -lcurl -lmozjs +libmod_tuscany_oauth1_la_LDFLAGS = -L${LIBOAUTH_LIB} -R${LIBOAUTH_LIB} -loauth -lxml2 -lcurl -ljansson libmod_tuscany_oauth1${libsuffix}: ln -s .libs/libmod_tuscany_oauth1${libsuffix} libmod_tuscany_oauth2_la_SOURCES = mod-oauth2.cpp -libmod_tuscany_oauth2_la_LDFLAGS = -lxml2 -lcurl -lmozjs +libmod_tuscany_oauth2_la_LDFLAGS = -lxml2 -lcurl -ljansson libmod_tuscany_oauth2${libsuffix}: ln -s .libs/libmod_tuscany_oauth2${libsuffix} diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp index d2c7cf7ddd..c9d8607144 100644 --- a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp +++ b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp @@ -56,18 +56,18 @@ namespace oauth1 { */ class ServerConf { public: - ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s) { + ServerConf(apr_pool_t* const p, server_rec* const s) : p(p), server(s) { } const gc_pool p; - server_rec* server; - string ca; - string cert; - string key; - list<list<value> > appkeys; - list<string> mcaddrs; - memcache::MemCached mc; - perthread_ptr<http::CURLSession> cs; + server_rec* const server; + gc_mutable_ref<string> ca; + gc_mutable_ref<string> cert; + gc_mutable_ref<string> key; + gc_mutable_ref<list<list<value> > > appkeys; + gc_mutable_ref<list<string> > mcaddrs; + gc_mutable_ref<memcache::MemCached> mc; + gc_mutable_ref<perthread_ptr<http::CURLSession> > cs; }; /** @@ -80,7 +80,7 @@ public: AuthnProviderConf(const string name, const authn_provider* provider) : name(name), provider(provider) { } - string name; + const string name; const authn_provider* provider; }; @@ -89,21 +89,21 @@ public: */ class DirConf { public: - DirConf(apr_pool_t* p, char* d) : p(p), dir(d), enabled(false), login("") { + DirConf(apr_pool_t* const p, const char* const d) : p(p), dir(d), enabled(false), login(emptyString) { } const gc_pool p; - const char* dir; + const char* const dir; bool enabled; - string login; - list<list<value> > scopeattrs; - list<AuthnProviderConf> apcs; + gc_mutable_ref<string> login; + gc_mutable_ref<list<list<value> > > scopeattrs; + gc_mutable_ref<list<AuthnProviderConf> > apcs; }; /** * Run the authnz hooks to authenticate a request. */ -const failable<int> checkAuthnzProviders(const string& user, request_rec* r, const list<AuthnProviderConf>& apcs) { +const failable<int> checkAuthnzProviders(const string& user, request_rec* const r, const list<AuthnProviderConf>& apcs) { if (isNil(apcs)) return mkfailure<int>("Authentication failure for: " + user, HTTP_UNAUTHORIZED); const AuthnProviderConf apc = car<AuthnProviderConf>(apcs); @@ -118,7 +118,7 @@ const failable<int> checkAuthnzProviders(const string& user, request_rec* r, con return OK; } -const failable<int> checkAuthnz(const string& user, request_rec* r, const list<AuthnProviderConf>& apcs) { +const failable<int> checkAuthnz(const string& user, request_rec* const r, const list<AuthnProviderConf>& apcs) { if (substr(user, 0, 1) == "/") return mkfailure<int>(string("Encountered FakeBasicAuth spoof: ") + user, HTTP_UNAUTHORIZED); @@ -139,7 +139,7 @@ const failable<value> userInfo(const value& sid, const memcache::MemCached& mc) /** * Handle an authenticated request. */ -const failable<int> authenticated(const list<list<value> >& userinfo, const bool check, request_rec* r, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs) { +const failable<int> authenticated(const list<list<value> >& userinfo, const bool check, request_rec* const r, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs) { debug(userinfo, "modoauth2::authenticated::userinfo"); if (isNil(scopeattrs)) { @@ -147,7 +147,7 @@ const failable<int> authenticated(const list<list<value> >& userinfo, const bool // Store user id in an environment variable const list<value> id = assoc<value>("id", userinfo); if (isNil(id) || isNil(cdr(id))) - return mkfailure<int>("Couldn't retrieve user id"); + return mkfailure<int>("Couldn't retrieve user id", HTTP_UNAUTHORIZED); apr_table_set(r->subprocess_env, "OAUTH2_ID", apr_pstrdup(r->pool, c_str(cadr(id)))); // If the request user field has not been mapped to another attribute, map the @@ -157,7 +157,7 @@ const failable<int> authenticated(const list<list<value> >& userinfo, const bool // Run the authnz hooks to check the authenticated user if (check) - return checkAuthnz(r->user == NULL? "" : r->user, r, apcs); + return checkAuthnz(r->user == NULL? emptyString : r->user, r, apcs); return OK; } @@ -210,7 +210,7 @@ const string header(const string& qs, const string& redir, const string& verif) */ const list<string> sign(const string& verb, const string& uri, const list<value> appkey, const string& tok, const string& sec) { char* qs = NULL; - char* suri = oauth_sign_url2(c_str(uri), &qs, OA_HMAC, c_str(verb), c_str(car(appkey)), c_str(cadr(appkey)), length(tok) != 0? c_str(tok) : NULL, length(sec) != 0? c_str(sec) : NULL); + char* const suri = oauth_sign_url2(c_str(uri), &qs, OA_HMAC, c_str(verb), c_str(car(appkey)), c_str(cadr(appkey)), length(tok) != 0? c_str(tok) : NULL, length(sec) != 0? c_str(sec) : NULL); const list<string> res = mklist<string>(suri, qs); free(suri); free(qs); @@ -220,7 +220,7 @@ const list<string> sign(const string& verb, const string& uri, const list<value> /** * Handle an authorize request. */ -const failable<int> authorize(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys, const memcache::MemCached& mc) { +const failable<int> authorize(const list<list<value> >& args, request_rec* const r, const list<list<value> >& appkeys, const memcache::MemCached& mc) { // Extract authorize, access_token, client ID and info URIs const list<value> ref = assoc<value>("openauth_referrer", args); if (isNil(ref) || isNil(cdr(ref))) @@ -249,19 +249,19 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co // Lookup client app configuration const list<value> app = assoc<value>(cadr(cid), appkeys); if (isNil(app) || isNil(cdr(app))) - return mkfailure<int>(string("client id not found: ") + cadr(cid)); + return mkfailure<int>(string("client id not found: ") + (string)cadr(cid)); list<value> appkey = cadr(app); // Build and sign the request token URI const string requri = httpd::unescape(cadr(req)) + string("&") + http::queryString(mklist<list<value> >(mklist<value>("oauth_callback", httpd::escape(redir)))); - const list<string> srequri = sign("POST", requri, appkey, "", ""); + const list<string> srequri = sign("POST", requri, appkey, emptyString, emptyString); debug(srequri, "modoauth1::authorize::srequri"); // Put the args into an oauth header - const string reqhdr = header(cadr(srequri), redir, ""); + const string reqhdr = header(cadr(srequri), redir, emptyString); // Send the request token request - char* pres = oauth_http_post2(c_str(car(srequri)), "", c_str(reqhdr)); + char* const pres = oauth_http_post2(c_str(car(srequri)), "", c_str(reqhdr)); if (pres == NULL) return mkfailure<int>("Couldn't send request token request"); const string res(pres); @@ -297,11 +297,10 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co * User profile parsing needs to be made configurable. */ const failable<list<value> > profileUserInfo(const value& cid, const string& info) { - string b = substr(info, 0, 1); + const string b = substr(info, 0, 1); if (b == "[") { // Twitter JSON profile - js::JSContext cx; - const list<value> infov(json::jsonValues(content(json::readJSON(mklist<string>(info), cx)))); + const list<value> infov(content(json::readValue(mklist<string>(info)))); if (isNil(infov)) return mkfailure<list<value> >("Couldn't retrieve user info"); debug(infov, "modoauth1::access_token::info"); @@ -314,8 +313,7 @@ const failable<list<value> > profileUserInfo(const value& cid, const string& inf } if (b == "{") { // Foursquare JSON profile - js::JSContext cx; - const list<value> infov(json::jsonValues(content(json::readJSON(mklist<string>(info), cx)))); + const list<value> infov(content(json::readValue(mklist<string>(info)))); if (isNil(infov)) return mkfailure<list<value> >("Couldn't retrieve user info"); debug(infov, "modoauth1::access_token::info"); @@ -328,7 +326,7 @@ const failable<list<value> > profileUserInfo(const value& cid, const string& inf } if (b == "<") { // XML profile - const list<value> infov = elementsToValues(readXML(mklist<string>(info))); + const list<value> infov = elementsToValues(content(xml::readElements(mklist<string>(info)))); if (isNil(infov)) return mkfailure<list<value> >("Couldn't retrieve user info"); debug(infov, "modoauth1::access_token::info"); @@ -370,8 +368,8 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, // Lookup client app configuration const list<value> app = assoc<value>(cadr(cid), appkeys); if (isNil(app) || isNil(cdr(app))) - return mkfailure<int>(string("client id not found: ") + cadr(cid)); - list<value> appkey = cadr(app); + return mkfailure<int>(string("client id not found: ") + (string)cadr(cid)); + const list<value> appkey = cadr(app); // Retrieve the request token from memcached const failable<value> sv = memcache::get(mklist<value>("tuscanyOAuth1Token", cadr(tv)), mc); @@ -384,10 +382,10 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, debug(stokuri, "modoauth1::access_token::stokuri"); // Put the args into an oauth header - string tokhdr = header(cadr(stokuri), "", cadr(vv)); + string tokhdr = header(cadr(stokuri), emptyString, cadr(vv)); // Send the access token request - char* ptokres = oauth_http_post2(c_str(car(stokuri)), "", c_str(tokhdr)); + char* const ptokres = oauth_http_post2(c_str(car(stokuri)), "", c_str(tokhdr)); if (ptokres == NULL) return mkfailure<int>("Couldn't post access_token request"); const string tokres(ptokres); @@ -410,10 +408,10 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, debug(sprofuri, "modoauth1::access_token::sprofuri"); // Put the args into an oauth header - string profhdr = header(cadr(sprofuri), "", ""); + const string profhdr = header(cadr(sprofuri), emptyString, emptyString); // Send the user profile request - char* pprofres = oauth_http_get2(c_str(car(sprofuri)), NULL, c_str(profhdr)); + char* const pprofres = oauth_http_get2(c_str(car(sprofuri)), NULL, c_str(profhdr)); if (pprofres == NULL) return mkfailure<int>("Couldn't get user info"); const string profres(pprofres); @@ -431,7 +429,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, return authrc; // Store user info in memcached keyed by session ID - const value sid = string("OAuth1_") + mkrand(); + const value sid = string("OAuth1_") + (string)mkrand(); const failable<bool> prc = memcache::put(mklist<value>("tuscanyOAuth1", sid), content(userinfo), mc); if (!hasContent(prc)) return mkfailure<int>(prc); @@ -446,17 +444,17 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, * Check user authentication. */ static int checkAuthn(request_rec *r) { - gc_scoped_pool pool(r->pool); + const gc_scoped_pool sp(r->pool); // Decline if we're not enabled or AuthType is not set to Open const DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_oauth1); if (!dc.enabled) return DECLINED; - const char* atype = ap_auth_type(r); + const char* const atype = ap_auth_type(r); if (atype == NULL || strcasecmp(atype, "Open")) return DECLINED; debug_httpdRequest(r, "modoauth1::checkAuthn::input"); - debug(atype, "modopenauth::checkAuthn::auth_type"); + debug(atype, "modoauth1::checkAuthn::auth_type"); // Get the server configuration const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_oauth1); @@ -471,9 +469,9 @@ static int checkAuthn(request_rec *r) { // Extract the user info from the auth session const failable<value> userinfo = userInfo(content(sid), sc.mc); if (!hasContent(userinfo)) - return httpd::reportStatus(mkfailure<int>(userinfo)); + return openauth::reportStatus(mkfailure<int>(reason(userinfo), HTTP_UNAUTHORIZED), dc.login, nilValue, r); r->ap_auth_type = const_cast<char*>(atype); - return httpd::reportStatus(authenticated(content(userinfo), false, r, dc.scopeattrs, dc.apcs)); + return openauth::reportStatus(authenticated(content(userinfo), false, r, dc.scopeattrs, dc.apcs), dc.login, nilValue, r); } // Get the request args @@ -482,19 +480,14 @@ static int checkAuthn(request_rec *r) { // Handle OAuth authorize request step if (string(r->uri) == "/oauth1/authorize/") { r->ap_auth_type = const_cast<char*>(atype); - return httpd::reportStatus(authorize(args, r, sc.appkeys, sc.mc)); + return openauth::reportStatus(authorize(args, r, sc.appkeys, sc.mc), dc.login, 1, r); } // Handle OAuth access_token request step if (string(r->uri) == "/oauth1/access_token/") { r->ap_auth_type = const_cast<char*>(atype); const failable<int> authrc = accessToken(args, r, sc.appkeys, dc.scopeattrs, dc.apcs, sc.mc); - - // Redirect to the login page if user is not authorized - if (!hasContent(authrc) && rcode(authrc) == HTTP_UNAUTHORIZED) - return httpd::reportStatus(openauth::login(dc.login, string("/"), 1, r)); - - return httpd::reportStatus(authrc); + return openauth::reportStatus(authrc, dc.login, 1, r); } // Redirect to the login page, unless we have a session id or an authorization @@ -509,22 +502,22 @@ static int checkAuthn(request_rec *r) { return DECLINED; r->ap_auth_type = const_cast<char*>(atype); - return httpd::reportStatus(openauth::login(dc.login, value(), value(), r)); + return httpd::reportStatus(openauth::login(dc.login, nilValue, nilValue, r)); } /** * Process the module configuration. */ -int postConfigMerge(ServerConf& mainsc, server_rec* s) { +int postConfigMerge(const ServerConf& mainsc, server_rec* const s) { if (s == NULL) return OK; ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth1); debug(httpd::serverName(s), "modoauth1::postConfigMerge::serverName"); // Merge configuration from main server - if (isNil(sc.appkeys)) + if (isNil((list<list<value> >)sc.appkeys)) sc.appkeys = mainsc.appkeys; - if (isNil(sc.mcaddrs)) + if (isNil((list<string>)sc.mcaddrs)) sc.mcaddrs = mainsc.mcaddrs; sc.mc = mainsc.mc; sc.cs = mainsc.cs; @@ -532,10 +525,10 @@ int postConfigMerge(ServerConf& mainsc, server_rec* s) { return postConfigMerge(mainsc, s->next); } -int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp, server_rec* s) { - gc_scoped_pool pool(p); +int postConfig(apr_pool_t* const p, unused apr_pool_t* const plog, unused apr_pool_t* const ptemp, server_rec* const s) { + const gc_scoped_pool sp(p); - ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth1); + const ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth1); debug(httpd::serverName(s), "modoauth1::postConfig::serverName"); // Merge server configurations @@ -543,30 +536,12 @@ int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp, } /** - * Lambda function that creates a new CURL session. - */ -class newsession { -public: - newsession(const string& ca, const string& cert, const string& key) : ca(ca), cert(cert), key(key) { - } - - const gc_ptr<http::CURLSession> operator()() const { - return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, key, "", 0); - } - -private: - const string ca; - const string cert; - const string key; -}; - -/** * Child process initialization. */ -void childInit(apr_pool_t* p, server_rec* s) { - gc_scoped_pool pool(p); +void childInit(apr_pool_t* const p, server_rec* const s) { + const gc_scoped_pool sp(p); - ServerConf* psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_oauth1); + ServerConf* const psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_oauth1); if(psc == NULL) { cfailure << "[Tuscany] Due to one or more errors mod_tuscany_oauth1 loading failed. Causing apache to stop loading." << endl; exit(APEXIT_CHILDFATAL); @@ -574,13 +549,21 @@ void childInit(apr_pool_t* p, server_rec* s) { ServerConf& sc = *psc; // Connect to Memcached - if (isNil(sc.mcaddrs)) + if (isNil((list<string>)sc.mcaddrs)) sc.mc = *(new (gc_new<memcache::MemCached>()) memcache::MemCached("localhost", 11211)); else sc.mc = *(new (gc_new<memcache::MemCached>()) memcache::MemCached(sc.mcaddrs)); // Setup a CURL session - sc.cs = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(sc.ca, sc.cert, sc.key))); + const string ca(sc.ca); + const string cert(sc.cert); + const string key(sc.key); + const gc_pool cp(gc_current_pool()); + const lambda<const gc_ptr<http::CURLSession>()> newsession = [ca, cert, key, cp]() -> const gc_ptr<http::CURLSession> { + const gc_scoped_pool sp(pool(cp)); + return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, key, emptyString, 0); + }; + sc.cs = *(new (gc_new<perthread_ptr<http::CURLSession> >()) perthread_ptr<http::CURLSession>(newsession)); // Merge the updated configuration into the virtual hosts postConfigMerge(sc, s->next); @@ -589,56 +572,56 @@ void childInit(apr_pool_t* p, server_rec* s) { /** * Configuration commands. */ -const char* confAppKey(cmd_parms *cmd, unused void *c, const char *arg1, const char* arg2, const char* arg3) { - gc_scoped_pool pool(cmd->pool); +char* const confAppKey(cmd_parms* cmd, unused void *c, char *arg1, char* arg2, char* arg3) { + const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth1); - sc.appkeys = cons<list<value> >(mklist<value>(arg1, mklist<value>(arg2, arg3)), sc.appkeys); + sc.appkeys = cons<list<value> >(mklist<value>(arg1, mklist<value>(arg2, arg3)), (list<list<value> >)sc.appkeys); return NULL; } -const char* confMemcached(cmd_parms *cmd, unused void *c, const char *arg) { - gc_scoped_pool pool(cmd->pool); +char* confMemcached(cmd_parms *cmd, unused void *c, char *arg) { + const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth1); - sc.mcaddrs = cons<string>(arg, sc.mcaddrs); + sc.mcaddrs = cons<string>(arg, (list<string>)sc.mcaddrs); return NULL; } -const char* confEnabled(cmd_parms *cmd, void *c, const int arg) { - gc_scoped_pool pool(cmd->pool); +char* confEnabled(cmd_parms *cmd, void *c, int arg) { + const gc_scoped_pool sp(cmd->pool); DirConf& dc = httpd::dirConf<DirConf>(c); dc.enabled = (bool)arg; return NULL; } -const char* confLogin(cmd_parms *cmd, void *c, const char* arg) { - gc_scoped_pool pool(cmd->pool); +char* confLogin(cmd_parms *cmd, void *c, char* arg) { + const gc_scoped_pool sp(cmd->pool); DirConf& dc = httpd::dirConf<DirConf>(c); dc.login = arg; return NULL; } -const char* confCAFile(cmd_parms *cmd, unused void *c, const char *arg) { - gc_scoped_pool pool(cmd->pool); +char* confCAFile(cmd_parms *cmd, unused void *c, char *arg) { + const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth1); sc.ca = arg; return NULL; } -const char* confCertFile(cmd_parms *cmd, unused void *c, const char *arg) { - gc_scoped_pool pool(cmd->pool); +char* confCertFile(cmd_parms *cmd, unused void *c, char *arg) { + const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth1); sc.cert = arg; return NULL; } -const char* confCertKeyFile(cmd_parms *cmd, unused void *c, const char *arg) { - gc_scoped_pool pool(cmd->pool); +char* confCertKeyFile(cmd_parms *cmd, unused void *c, char *arg) { + const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth1); sc.key = arg; return NULL; } -const char* confScopeAttr(cmd_parms *cmd, void* c, const char* arg1, const char* arg2) { - gc_scoped_pool pool(cmd->pool); +char* confScopeAttr(cmd_parms *cmd, void* c, char* arg1, char* arg2) { + const gc_scoped_pool sp(cmd->pool); DirConf& dc = httpd::dirConf<DirConf>(c); - dc.scopeattrs = cons<list<value> >(mklist<value>(arg1, arg2), dc.scopeattrs); + dc.scopeattrs = cons<list<value> >(mklist<value>(arg1, arg2), (list<list<value> >)dc.scopeattrs); return NULL; } -const char* confAuthnProvider(cmd_parms *cmd, void *c, const char* arg) { - gc_scoped_pool pool(cmd->pool); +char* confAuthnProvider(cmd_parms *cmd, void *c, char* arg) { + const gc_scoped_pool sp(cmd->pool); DirConf& dc = httpd::dirConf<DirConf>(c); // Lookup and cache the Authn provider diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp index e384a0e742..bedf83325f 100644 --- a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp +++ b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp @@ -50,18 +50,18 @@ namespace oauth2 { */ class ServerConf { public: - ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s) { + ServerConf(apr_pool_t* const p, server_rec* const s) : p(p), server(s) { } const gc_pool p; - server_rec* server; - string ca; - string cert; - string key; - list<list<value> > appkeys; - list<string> mcaddrs; - memcache::MemCached mc; - perthread_ptr<http::CURLSession> cs; + server_rec* const server; + gc_mutable_ref<string> ca; + gc_mutable_ref<string> cert; + gc_mutable_ref<string> key; + gc_mutable_ref<list<list<value> > > appkeys; + gc_mutable_ref<list<string> > mcaddrs; + gc_mutable_ref<memcache::MemCached> mc; + gc_mutable_ref<perthread_ptr<http::CURLSession> > cs; }; /** @@ -74,7 +74,7 @@ public: AuthnProviderConf(const string name, const authn_provider* provider) : name(name), provider(provider) { } - string name; + const string name; const authn_provider* provider; }; @@ -83,21 +83,21 @@ public: */ class DirConf { public: - DirConf(apr_pool_t* p, char* d) : p(p), dir(d), enabled(false), login("") { + DirConf(apr_pool_t* const p, const char* const d) : p(p), dir(d), enabled(false), login(emptyString) { } const gc_pool p; - const char* dir; + const char* const dir; bool enabled; - string login; - list<list<value> > scopeattrs; - list<AuthnProviderConf> apcs; + gc_mutable_ref<string> login; + gc_mutable_ref<list<list<value> > > scopeattrs; + gc_mutable_ref<list<AuthnProviderConf> > apcs; }; /** * Run the authnz hooks to authenticate a request. */ -const failable<int> checkAuthnzProviders(const string& user, request_rec* r, const list<AuthnProviderConf>& apcs) { +const failable<int> checkAuthnzProviders(const string& user, request_rec* const r, const list<AuthnProviderConf>& apcs) { if (isNil(apcs)) return mkfailure<int>("Authentication failure for: " + user, HTTP_UNAUTHORIZED); const AuthnProviderConf apc = car<AuthnProviderConf>(apcs); @@ -112,7 +112,7 @@ const failable<int> checkAuthnzProviders(const string& user, request_rec* r, con return OK; } -const failable<int> checkAuthnz(const string& user, request_rec* r, const list<AuthnProviderConf>& apcs) { +const failable<int> checkAuthnz(const string& user, request_rec* const r, const list<AuthnProviderConf>& apcs) { if (substr(user, 0, 1) == "/") return mkfailure<int>(string("Encountered FakeBasicAuth spoof: ") + user, HTTP_UNAUTHORIZED); @@ -133,7 +133,7 @@ const failable<value> userInfo(const value& sid, const memcache::MemCached& mc) /** * Handle an authenticated request. */ -const failable<int> authenticated(const list<list<value> >& userinfo, const bool check, request_rec* r, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs) { +const failable<int> authenticated(const list<list<value> >& userinfo, const bool check, request_rec* const r, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs) { debug(userinfo, "modoauth2::authenticated::userinfo"); if (isNil(scopeattrs)) { @@ -141,7 +141,7 @@ const failable<int> authenticated(const list<list<value> >& userinfo, const bool // Store user id in an environment variable const list<value> id = assoc<value>("id", userinfo); if (isNil(id) || isNil(cdr(id))) - return mkfailure<int>("Couldn't retrieve user id"); + return mkfailure<int>("Couldn't retrieve user id", HTTP_UNAUTHORIZED); apr_table_set(r->subprocess_env, "OAUTH2_ID", apr_pstrdup(r->pool, c_str(cadr(id)))); // If the request user field has not been mapped to another attribute, map the @@ -151,7 +151,7 @@ const failable<int> authenticated(const list<list<value> >& userinfo, const bool // Run the authnz hooks to check the authenticated user if (check) - return checkAuthnz(r->user == NULL? "" : r->user, r, apcs); + return checkAuthnz(r->user == NULL? emptyString : r->user, r, apcs); return OK; } @@ -172,7 +172,7 @@ const failable<int> authenticated(const list<list<value> >& userinfo, const bool /** * Handle an authorize request. */ -const failable<int> authorize(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys) { +const failable<int> authorize(const list<list<value> >& args, request_rec* const r, const list<list<value> >& appkeys) { // Extract authorize, access_token, client ID and info URIs const list<value> ref = assoc<value>("openauth_referrer", args); if (isNil(ref) || isNil(cdr(ref))) @@ -206,11 +206,11 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co // Lookup client app configuration const list<value> app = assoc<value>(cadr(cid), appkeys); if (isNil(app) || isNil(cdr(app))) - return mkfailure<int>(string("client id not found: ") + cadr(cid)); + return mkfailure<int>(string("client id not found: ") + (string)cadr(cid)); list<value> appkey = cadr(app); // Redirect to the authorize URI - const list<value> adisplay = (isNil(display) || isNil(cdr(display)))? list<value>() : mklist<value>("display", cadr(display)); + const list<value> adisplay = (isNil(display) || isNil(cdr(display)))? nilListValue : mklist<value>("display", cadr(display)); const list<list<value> > aargs = mklist<list<value> >(mklist<value>("response_type", "code"), mklist<value>("client_id", car(appkey)), mklist<value>("scope", cadr(scope)), adisplay, mklist<value>("redirect_uri", httpd::escape(redir)), mklist<value>("state", httpd::escape(state))); const string uri = httpd::unescape(cadr(auth)) + string("?") + http::queryString(aargs); debug(uri, "modoauth2::authorize::uri"); @@ -229,7 +229,7 @@ const failable<list<value> > profileUserInfo(const value& cid, const list<value> /** * Handle an access_token request. */ -const failable<int> accessToken(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys, const perthread_ptr<http::CURLSession>& cs, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs, const memcache::MemCached& mc) { +const failable<int> accessToken(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys, const http::CURLSession& cs, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs, const memcache::MemCached& mc) { // Extract access_token URI, client ID and authorization code parameters const list<value> state = assoc<value>("state", args); @@ -255,7 +255,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, // Lookup client app configuration const list<value> app = assoc<value>(cadr(cid), appkeys); if (isNil(app) || isNil(cdr(app))) - return mkfailure<int>(string("client id not found: ") + cadr(cid)); + return mkfailure<int>(string("client id not found: ") + (string)cadr(cid)); list<value> appkey = cadr(app); // Build the redirect URI @@ -269,7 +269,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, const string turi = httpd::unescape(cadr(tok)); debug(turi, "modoauth2::access_token::tokenuri"); const value tval = mklist<value>(string("application/x-www-form-urlencoded;charset=UTF-8"), mklist<value>(tqs)); - const failable<value> ftr = http::post(tval, turi, *(cs)); + const failable<value> ftr = http::post(tval, turi, cs); if (!hasContent(ftr)) return mkfailure<int>(ftr); const value tr = content(ftr); @@ -288,7 +288,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, const list<list<value> > iargs = mklist<list<value> >(tv); const string iuri = httpd::unescape(cadr(info)) + string("?") + http::queryString(iargs); debug(iuri, "modoauth2::access_token::infouri"); - const failable<value> profres = http::get(iuri, *(cs)); + const failable<value> profres = http::get(iuri, cs); if (!hasContent(profres)) return mkfailure<int>("Couldn't retrieve user info"); debug(content(profres), "modoauth2::access_token::info"); @@ -304,7 +304,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, return authrc; // Store user info in memcached keyed by a session ID - const value sid = string("OAuth2_") + mkrand(); + const value sid = string("OAuth2_") + (string)mkrand(); const failable<bool> prc = memcache::put(mklist<value>("tuscanyOAuth2", sid), content(userinfo), mc); if (!hasContent(prc)) return mkfailure<int>(prc); @@ -319,7 +319,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, * Check user authentication. */ static int checkAuthn(request_rec *r) { - gc_scoped_pool pool(r->pool); + const gc_scoped_pool sp(r->pool); // Decline if we're not enabled or AuthType is not set to Open const DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_oauth2); @@ -329,7 +329,7 @@ static int checkAuthn(request_rec *r) { if (atype == NULL || strcasecmp(atype, "Open")) return DECLINED; debug_httpdRequest(r, "modoauth2::checkAuthn::input"); - debug(atype, "modopenauth::checkAuthn::auth_type"); + debug(atype, "modoauth2::checkAuthn::auth_type"); // Get the server configuration const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_oauth2); @@ -344,9 +344,9 @@ static int checkAuthn(request_rec *r) { // Extract the user info from the auth session const failable<value> userinfo = userInfo(content(sid), sc.mc); if (!hasContent(userinfo)) - return httpd::reportStatus(mkfailure<int>(userinfo)); + return openauth::reportStatus(mkfailure<int>(reason(userinfo), HTTP_UNAUTHORIZED), dc.login, nilValue, r); r->ap_auth_type = const_cast<char*>(atype); - return httpd::reportStatus(authenticated(content(userinfo), false, r, dc.scopeattrs, dc.apcs)); + return openauth::reportStatus(authenticated(content(userinfo), false, r, dc.scopeattrs, dc.apcs), dc.login, nilValue, r); } // Get the request args @@ -355,19 +355,14 @@ static int checkAuthn(request_rec *r) { // Handle OAuth authorize request step if (string(r->uri) == "/oauth2/authorize/") { r->ap_auth_type = const_cast<char*>(atype); - return httpd::reportStatus(authorize(args, r, sc.appkeys)); + return openauth::reportStatus(authorize(args, r, sc.appkeys), dc.login, 1, r); } // Handle OAuth access_token request step if (string(r->uri) == "/oauth2/access_token/") { r->ap_auth_type = const_cast<char*>(atype); - const failable<int> authrc = accessToken(args, r, sc.appkeys, sc.cs, dc.scopeattrs, dc.apcs, sc.mc); - - // Redirect to the login page if user is not authorized - if (!hasContent(authrc) && rcode(authrc) == HTTP_UNAUTHORIZED) - return httpd::reportStatus(openauth::login(dc.login, string("/"), 1, r)); - - return httpd::reportStatus(authrc); + const failable<int> authrc = accessToken(args, r, sc.appkeys, *(*(perthread_ptr<http::CURLSession>*)sc.cs), dc.scopeattrs, dc.apcs, sc.mc); + return openauth::reportStatus(authrc, dc.login, 1, r); } // Redirect to the login page, unless we have a session id or an authorization @@ -382,22 +377,22 @@ static int checkAuthn(request_rec *r) { return DECLINED; r->ap_auth_type = const_cast<char*>(atype); - return httpd::reportStatus(openauth::login(dc.login, value(), value(), r)); + return httpd::reportStatus(openauth::login(dc.login, nilValue, nilValue, r)); } /** * Process the module configuration. */ -int postConfigMerge(ServerConf& mainsc, server_rec* s) { +int postConfigMerge(const ServerConf& mainsc, server_rec* const s) { if (s == NULL) return OK; ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth2); debug(httpd::serverName(s), "modoauth2::postConfigMerge::serverName"); // Merge configuration from main server - if (isNil(sc.appkeys)) + if (isNil((list<list<value> >)sc.appkeys)) sc.appkeys = mainsc.appkeys; - if (isNil(sc.mcaddrs)) + if (isNil((list<string>)sc.mcaddrs)) sc.mcaddrs = mainsc.mcaddrs; sc.mc = mainsc.mc; sc.cs = mainsc.cs; @@ -405,10 +400,10 @@ int postConfigMerge(ServerConf& mainsc, server_rec* s) { return postConfigMerge(mainsc, s->next); } -int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp, server_rec* s) { - gc_scoped_pool pool(p); +int postConfig(apr_pool_t* const p, unused apr_pool_t* const plog, unused apr_pool_t* const ptemp, server_rec* const s) { + const gc_scoped_pool sp(p); - ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth2); + const ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth2); debug(httpd::serverName(s), "modoauth2::postConfig::serverName"); // Merge server configurations @@ -416,30 +411,12 @@ int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp, } /** - * Lambda function that creates a new CURL session. - */ -class newsession { -public: - newsession(const string& ca, const string& cert, const string& key) : ca(ca), cert(cert), key(key) { - } - - const gc_ptr<http::CURLSession> operator()() const { - return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, key, "", 0); - } - -private: - const string ca; - const string cert; - const string key; -}; - -/** * Child process initialization. */ -void childInit(apr_pool_t* p, server_rec* s) { - gc_scoped_pool pool(p); +void childInit(apr_pool_t* const p, server_rec* const s) { + const gc_scoped_pool sp(p); - ServerConf* psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_oauth2); + ServerConf* const psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_oauth2); if(psc == NULL) { cfailure << "[Tuscany] Due to one or more errors mod_tuscany_oauth2 loading failed. Causing apache to stop loading." << endl; exit(APEXIT_CHILDFATAL); @@ -447,13 +424,21 @@ void childInit(apr_pool_t* p, server_rec* s) { ServerConf& sc = *psc; // Connect to Memcached - if (isNil(sc.mcaddrs)) + if (isNil((list<string>)sc.mcaddrs)) sc.mc = *(new (gc_new<memcache::MemCached>()) memcache::MemCached("localhost", 11211)); else sc.mc = *(new (gc_new<memcache::MemCached>()) memcache::MemCached(sc.mcaddrs)); // Setup a CURL session - sc.cs = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(sc.ca, sc.cert, sc.key))); + const string ca = sc.ca; + const string cert = sc.cert; + const string key = sc.key; + const gc_pool cp = gc_current_pool(); + const lambda<const gc_ptr<http::CURLSession>()> newsession = [ca, cert, key, cp]() -> const gc_ptr<http::CURLSession> { + const gc_scoped_pool sp(pool(cp)); + return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, key, emptyString, 0); + }; + sc.cs = *(new (gc_new<perthread_ptr<http::CURLSession> >()) perthread_ptr<http::CURLSession>(newsession)); // Merge the updated configuration into the virtual hosts postConfigMerge(sc, s->next); @@ -462,56 +447,56 @@ void childInit(apr_pool_t* p, server_rec* s) { /** * Configuration commands. */ -const char* confAppKey(cmd_parms *cmd, unused void *c, const char *arg1, const char* arg2, const char* arg3) { - gc_scoped_pool pool(cmd->pool); +char* confAppKey(cmd_parms *cmd, unused void *c, char *arg1, char* arg2, char* arg3) { + const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth2); - sc.appkeys = cons<list<value> >(mklist<value>(arg1, mklist<value>(arg2, arg3)), sc.appkeys); + sc.appkeys = cons<list<value> >(mklist<value>(arg1, mklist<value>(arg2, arg3)), (list<list<value> >)sc.appkeys); return NULL; } -const char* confMemcached(cmd_parms *cmd, unused void *c, const char *arg) { - gc_scoped_pool pool(cmd->pool); +char* confMemcached(cmd_parms *cmd, unused void *c, char *arg) { + const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth2); - sc.mcaddrs = cons<string>(arg, sc.mcaddrs); + sc.mcaddrs = cons<string>(arg, (list<string>)sc.mcaddrs); return NULL; } -const char* confEnabled(cmd_parms *cmd, void *c, const int arg) { - gc_scoped_pool pool(cmd->pool); +char* confEnabled(cmd_parms *cmd, void *c, int arg) { + const gc_scoped_pool sp(cmd->pool); DirConf& dc = httpd::dirConf<DirConf>(c); dc.enabled = (bool)arg; return NULL; } -const char* confLogin(cmd_parms *cmd, void *c, const char* arg) { - gc_scoped_pool pool(cmd->pool); +char* confLogin(cmd_parms *cmd, void *c, char* arg) { + const gc_scoped_pool sp(cmd->pool); DirConf& dc = httpd::dirConf<DirConf>(c); dc.login = arg; return NULL; } -const char* confCAFile(cmd_parms *cmd, unused void *c, const char *arg) { - gc_scoped_pool pool(cmd->pool); +char* confCAFile(cmd_parms *cmd, unused void *c, char *arg) { + const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth2); sc.ca = arg; return NULL; } -const char* confCertFile(cmd_parms *cmd, unused void *c, const char *arg) { - gc_scoped_pool pool(cmd->pool); +char* confCertFile(cmd_parms *cmd, unused void *c, char *arg) { + const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth2); sc.cert = arg; return NULL; } -const char* confCertKeyFile(cmd_parms *cmd, unused void *c, const char *arg) { - gc_scoped_pool pool(cmd->pool); +char* confCertKeyFile(cmd_parms *cmd, unused void *c, char *arg) { + const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth2); sc.key = arg; return NULL; } -const char* confScopeAttr(cmd_parms *cmd, void* c, const char* arg1, const char* arg2) { - gc_scoped_pool pool(cmd->pool); +char* confScopeAttr(cmd_parms *cmd, void* c, char* arg1, char* arg2) { + const gc_scoped_pool sp(cmd->pool); DirConf& dc = httpd::dirConf<DirConf>(c); - dc.scopeattrs = cons<list<value> >(mklist<value>(arg1, arg2), dc.scopeattrs); + dc.scopeattrs = cons<list<value> >(mklist<value>(arg1, arg2), (list<list<value> >)dc.scopeattrs); return NULL; } -const char* confAuthnProvider(cmd_parms *cmd, void *c, const char* arg) { - gc_scoped_pool pool(cmd->pool); +char* confAuthnProvider(cmd_parms *cmd, void *c, char* arg) { + const gc_scoped_pool sp(cmd->pool); DirConf& dc = httpd::dirConf<DirConf>(c); // Lookup and cache the Authn provider |