summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/trunk/modules/oauth/mod-oauth1.cpp')
-rw-r--r--sca-cpp/trunk/modules/oauth/mod-oauth1.cpp187
1 files changed, 85 insertions, 102 deletions
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