in modules/oauth/mod-oauth1.cpp [352:447]
const failable<int> accessToken(const list<value>& args, request_rec* r, const list<value>& appkeys, const list<value>& scopeattrs, const list<AuthnProviderConf>& apcs, const memcache::MemCached& mc) {
// Extract access_token URI, client ID and verification code
const list<value> ref = assoc<value>("openauth_referrer", args);
if (isNull(ref) || isNull(cdr(ref)))
return mkfailure<int>("Missing openauth_referrer parameter");
const list<value> tok = assoc<value>("oauth1_access_token", args);
if (isNull(tok) || isNull(cdr(tok)))
return mkfailure<int>("Missing oauth1_access_token parameter");
const list<value> cid = assoc<value>("oauth1_client_id", args);
if (isNull(cid) || isNull(cdr(cid)))
return mkfailure<int>("Missing oauth1_client_id parameter");
const list<value> info = assoc<value>("oauth1_info", args);
if (isNull(info) || isNull(cdr(info)))
return mkfailure<int>("Missing oauth1_info parameter");
const list<value> tv = assoc<value>("oauth_token", args);
if (isNull(tv) || isNull(cdr(tv)))
return mkfailure<int>("Missing oauth_token parameter");
const list<value> vv = assoc<value>("oauth_verifier", args);
if (isNull(vv) || isNull(cdr(vv)))
return mkfailure<int>("Missing oauth_verifier parameter");
// Lookup client app configuration
const list<value> app = assoc<value>(cadr(cid), appkeys);
if (isNull(app) || isNull(cdr(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);
if (!hasContent(sv))
return mkfailure<int>(sv);
// Build and sign access token request URI
const string tokuri = httpd::unescape(cadr(tok)) + string("?") + http::queryString(mklist<value>(vv));
const list<string> stokuri = sign("POST", tokuri, appkey, cadr(tv), content(sv));
debug(stokuri, "modoauth1::access_token::stokuri");
// Put the args into an oauth header
string tokhdr = header(cadr(stokuri), emptyString, cadr(vv));
// Send the access token request
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);
free(ptokres);
debug(tokres, "modoauth1::access_token::res");
const list<value> tokresargs = httpd::queryArgs(tokres);
// Retrieve the access token
const list<value> atv = assoc<value>("oauth_token", tokresargs);
if (isNull(atv) || isNull(cdr(atv)))
return mkfailure<int>("Couldn't retrieve oauth_token");
const list<value> asv = assoc<value>("oauth_token_secret", tokresargs);
if (isNull(asv) || isNull(cdr(asv)))
return mkfailure<int>("Couldn't retrieve oauth_token_secret");
debug(atv, "modoauth1::access_token::token");
// Build and sign user profile request URI
const string profuri = httpd::unescape(cadr(info));
const list<string> sprofuri = sign("GET", profuri, appkey, cadr(atv), cadr(asv));
debug(sprofuri, "modoauth1::access_token::sprofuri");
// Put the args into an oauth header
const string profhdr = header(cadr(sprofuri), emptyString, emptyString);
// Send the user profile request
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);
free(pprofres);
debug(profres, "modoauth1::access_token::profres");
// Retrieve the user info from the profile
const failable<list<value> > userinfo = profileUserInfo(cadr(cid), profres);
if (!hasContent(userinfo))
return mkfailure<int>(userinfo);
// Validate the authenticated user
const failable<int> authrc = authenticated(content(userinfo), r, scopeattrs, apcs);
if (!hasContent(authrc))
return authrc;
// Store user info in memcached keyed by session ID
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);
// Send session ID to the client in a cookie
debug(c_str(openauth::cookie("TuscanyOAuth1", sid, httpd::hostName(r))), "modoauth1::access_token::setcookie");
apr_table_set(r->err_headers_out, "Set-Cookie", c_str(openauth::cookie("TuscanyOAuth1", sid, httpd::hostName(r))));
return httpd::externalRedirect(httpd::url(httpd::unescape(cadr(ref)), r), r);
}