summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/modules/oauth
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sca-cpp/trunk/modules/oauth/Makefile.am2
-rw-r--r--sca-cpp/trunk/modules/oauth/htdocs/index.html9
-rw-r--r--sca-cpp/trunk/modules/oauth/htdocs/login/index.html8
-rw-r--r--sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html8
-rw-r--r--sca-cpp/trunk/modules/oauth/htdocs/public/index.html (renamed from sca-cpp/trunk/modules/oauth/htdocs/unprotected/index.html)0
-rw-r--r--sca-cpp/trunk/modules/oauth/mod-oauth1.cpp44
-rw-r--r--sca-cpp/trunk/modules/oauth/mod-oauth2.cpp20
-rwxr-xr-xsca-cpp/trunk/modules/oauth/oauth-conf7
-rw-r--r--sca-cpp/trunk/modules/oauth/oauth.composite1
-rw-r--r--sca-cpp/trunk/modules/oauth/oauth.hpp7
-rwxr-xr-xsca-cpp/trunk/modules/oauth/start-mixed-test8
-rwxr-xr-xsca-cpp/trunk/modules/oauth/start-test20
-rw-r--r--sca-cpp/trunk/modules/oauth/user-info.scm18
13 files changed, 102 insertions, 50 deletions
diff --git a/sca-cpp/trunk/modules/oauth/Makefile.am b/sca-cpp/trunk/modules/oauth/Makefile.am
index 84bbe32eec..6c0cd2bc57 100644
--- a/sca-cpp/trunk/modules/oauth/Makefile.am
+++ b/sca-cpp/trunk/modules/oauth/Makefile.am
@@ -35,7 +35,7 @@ libmod_tuscany_oauth2_la_LDFLAGS = -lxml2 -lcurl -lmozjs
libmod_tuscany_oauth2.so:
ln -s .libs/libmod_tuscany_oauth2.so
-EXTRA_DIST = oauth.composite user-info.scm htdocs/index.html htdocs/login/index.html htdocs/logout/index.html htdocs/unprotected/index.html
+EXTRA_DIST = oauth.composite user-info.scm htdocs/index.html htdocs/login/index.html htdocs/logout/index.html htdocs/public/index.html
dist_noinst_SCRIPTS = start-test stop-test
diff --git a/sca-cpp/trunk/modules/oauth/htdocs/index.html b/sca-cpp/trunk/modules/oauth/htdocs/index.html
index 779ea74986..e8cdd2f26b 100644
--- a/sca-cpp/trunk/modules/oauth/htdocs/index.html
+++ b/sca-cpp/trunk/modules/oauth/htdocs/index.html
@@ -22,13 +22,14 @@
<script type="text/javascript" src="/js/ref.js"></script>
<script type="text/javascript">
var protected = component("Protected");
-var userInfo = reference(protected, "userInfo");
-var user = userInfo.apply("getuser");
+var userInfo = defun(reference(protected, "userInfo"), "getuser", "getemail", "getnickname", "getfullname", "getfirstname", "getlastname", "getrealm");
+var user = userInfo.getuser();
var email = userInfo.apply("getemail");
var nickname = userInfo.apply("getnickname");
var fullname = userInfo.apply("getfullname");
var firstname = userInfo.apply("getfirstname");
var lastname = userInfo.apply("getlastname");
+var realm = userInfo.apply("getrealm");
</script>
</head>
<body>
@@ -40,6 +41,7 @@ var lastname = userInfo.apply("getlastname");
<div>Fullname: <span id="fullname"></span></div>
<div>Firstname: <span id="firstname"></span></div>
<div>Lastname: <span id="lastname"></span></div>
+<div>Realm: <span id="realm"></span></div>
<script type="text/javascript">
document.getElementById('user').innerHTML=user;
document.getElementById('email').innerHTML=email;
@@ -47,9 +49,10 @@ document.getElementById('nickname').innerHTML=nickname;
document.getElementById('fullname').innerHTML=fullname;
document.getElementById('firstname').innerHTML=firstname;
document.getElementById('lastname').innerHTML=lastname;
+document.getElementById('realm').innerHTML=realm;
</script>
<p><a href="info">User info</a></p>
<p><a href="login">Sign in</a></p>
<p><a href="logout">Sign out</a></p>
-<p><a href="unprotected">Unprotected area</a></p>
+<p><a href="public">Public area</a></p>
</body></html>
diff --git a/sca-cpp/trunk/modules/oauth/htdocs/login/index.html b/sca-cpp/trunk/modules/oauth/htdocs/login/index.html
index 607c55ca18..8cdcb1cf64 100644
--- a/sca-cpp/trunk/modules/oauth/htdocs/login/index.html
+++ b/sca-cpp/trunk/modules/oauth/htdocs/login/index.html
@@ -56,12 +56,12 @@ function submitSignin2(w) {
}
function withFacebook() {
- var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'testfacebookapp', 'https://graph.facebook.com/me'];
+ var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'facebook.com', 'https://graph.facebook.com/me'];
return parms;
}
function withGithub() {
- var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'testgithubapp', 'https://github.com/api/v2/json/user/show'];
+ var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'github.com', 'https://github.com/api/v2/json/user/show'];
return parms;
}
@@ -77,12 +77,12 @@ function submitSignin1(w) {
}
function withLinkedin() {
- var parms = ['https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize', 'https://api.linkedin.com/uas/oauth/accessToken', 'testlinkedinapp', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,public-profile-url)'];
+ var parms = ['https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize', 'https://api.linkedin.com/uas/oauth/accessToken', 'linkedin.com', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,public-profile-url)'];
return parms;
}
function withTwitter() {
- var parms = ['https://api.twitter.com/oauth/request_token', 'https://api.twitter.com/oauth/authorize', 'https://api.twitter.com/oauth/access_token', 'testtwitterapp', 'https://api.twitter.com/1/statuses/user_timeline.json'];
+ var parms = ['https://api.twitter.com/oauth/request_token', 'https://api.twitter.com/oauth/authorize', 'https://api.twitter.com/oauth/access_token', 'twitter.com', 'https://api.twitter.com/1/statuses/user_timeline.json'];
return parms;
}
</script>
diff --git a/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html b/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html
index c187aa2a84..10773c4538 100644
--- a/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html
+++ b/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html
@@ -102,12 +102,12 @@ function submitOAuth2Signin(w) {
}
function withFacebook() {
- var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'testfacebookapp', 'https://graph.facebook.com/me'];
+ var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'facebook.com', 'https://graph.facebook.com/me'];
return parms;
}
function withGithub() {
- var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'testgithubapp', 'https://github.com/api/v2/json/user/show'];
+ var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'github.com', 'https://github.com/api/v2/json/user/show'];
return parms;
}
@@ -123,12 +123,12 @@ function submitOAuth1Signin(w) {
}
function withLinkedin() {
- var parms = ['https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize', 'https://api.linkedin.com/uas/oauth/accessToken', 'testlinkedinapp', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,public-profile-url)'];
+ var parms = ['https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize', 'https://api.linkedin.com/uas/oauth/accessToken', 'linkedin.com', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,public-profile-url)'];
return parms;
}
function withTwitter() {
- var parms = ['https://api.twitter.com/oauth/request_token', 'https://api.twitter.com/oauth/authorize', 'https://api.twitter.com/oauth/access_token', 'testtwitterapp', 'https://api.twitter.com/1/statuses/user_timeline.json'];
+ var parms = ['https://api.twitter.com/oauth/request_token', 'https://api.twitter.com/oauth/authorize', 'https://api.twitter.com/oauth/access_token', 'twitter.com', 'https://api.twitter.com/1/statuses/user_timeline.json'];
return parms;
}
</script>
diff --git a/sca-cpp/trunk/modules/oauth/htdocs/unprotected/index.html b/sca-cpp/trunk/modules/oauth/htdocs/public/index.html
index af2cd7ca19..af2cd7ca19 100644
--- a/sca-cpp/trunk/modules/oauth/htdocs/unprotected/index.html
+++ b/sca-cpp/trunk/modules/oauth/htdocs/public/index.html
diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
index 23ef90b0dd..22fdd0cce3 100644
--- a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
+++ b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
@@ -105,6 +105,12 @@ static int checkUserID(request_rec *r) {
const failable<int> authenticated(const list<list<value> >& info, request_rec* r) {
debug(info, "modoauth1::authenticated::info");
+ // Store user info in the request
+ const list<value> realm = assoc<value>("realm", info);
+ if (isNil(realm) || isNil(cdr(realm)))
+ return mkfailure<int>("Couldn't retrieve realm");
+ apr_table_set(r->subprocess_env, apr_pstrdup(r->pool, "REALM"), apr_pstrdup(r->pool, c_str(cadr(realm))));
+
const list<value> id = assoc<value>("id", info);
if (isNil(id) || isNil(cdr(id)))
return mkfailure<int>("Couldn't retrieve user id");
@@ -250,35 +256,53 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co
/**
* Extract user info from a profile/info response.
- * TODO This currently only works for twitter and linkedin profiles and
- * needs to be made configurable.
+ * TODO This currently only works for Twitter, Foursquare and LinkedIn.
+ * User profile parsing needs to be made configurable.
*/
-const failable<list<value> > profileUserInfo(const string& info) {
- if (substr(info, 0, 1) == "[") {
- // JSON profile
+const failable<list<value> > profileUserInfo(const value& cid, const string& info) {
+ string b = substr(info, 0, 1);
+ if (b == "[") {
+ // Twitter JSON profile
json::JSONContext cx;
const list<value> infov(json::jsonValues(content(json::readJSON(mklist<string>(info), cx))));
if (isNil(infov))
return mkfailure<list<value> >("Couldn't retrieve user info");
debug(infov, "modoauth1::access_token::info");
const list<value> uv = assoc<value>("user", car(infov));
+ debug(uv, "modoauth1::access_token::userInfo");
if (isNil(uv) || isNil(cdr(uv)))
return mkfailure<list<value> >("Couldn't retrieve user info");
const list<value> iv = cdr(uv);
- return iv;
-
- } else {
+ return cons<value>(mklist<value>("realm", cid), iv);
+ }
+ if (b == "{") {
+ // Foursquare JSON profile
+ json::JSONContext cx;
+ const list<value> infov(json::jsonValues(content(json::readJSON(mklist<string>(info), cx))));
+ if (isNil(infov))
+ return mkfailure<list<value> >("Couldn't retrieve user info");
+ debug(infov, "modoauth1::access_token::info");
+ const list<value> uv = assoc<value>("user", infov);
+ debug(uv, "modoauth1::access_token::userInfo");
+ if (isNil(uv) || isNil(cdr(uv)))
+ return mkfailure<list<value> >("Couldn't retrieve user info");
+ const list<value> iv = cdr(uv);
+ return cons<value>(mklist<value>("realm", cid), iv);
+ }
+ if (b == "<") {
// XML profile
const list<value> infov = elementsToValues(readXML(mklist<string>(info)));
if (isNil(infov))
return mkfailure<list<value> >("Couldn't retrieve user info");
debug(infov, "modoauth1::access_token::info");
const list<value> pv = car(infov);
+ debug(pv, "modoauth1::access_token::userInfo");
if (isNil(pv) || isNil(cdr(pv)))
return mkfailure<list<value> >("Couldn't retrieve user info");
const list<value> iv = cdr(pv);
- return iv;
+ return cons<value>(mklist<value>("realm", cid), iv);
}
+ return mkfailure<list<value> >("Couldn't retrieve user info");
}
/**
@@ -356,7 +380,7 @@ const failable<int> access_token(const list<list<value> >& args, request_rec* r,
debug(profres, "modoauth1::access_token::profres");
// Retrieve the user info from the profile
- const failable<list<value> > iv = profileUserInfo(profres);
+ const failable<list<value> > iv = profileUserInfo(cadr(cid), profres);
if (!hasContent(iv))
return mkfailure<int>(reason(iv));
diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
index 60eadc282c..bb96fcb916 100644
--- a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
+++ b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
@@ -164,6 +164,15 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co
}
/**
+ * Extract user info from a profile/info response.
+ * TODO This currently only works for Facebook and Gowalla.
+ * User profile parsing needs to be made configurable.
+ */
+const failable<list<value> > profileUserInfo(const value& cid, const list<value>& info) {
+ return cons<value>(mklist<value>("realm", cid), info);
+}
+
+/**
* Handle an access_token request.
*/
const failable<int> access_token(const list<list<value> >& args, request_rec* r, const ServerConf& sc) {
@@ -210,10 +219,15 @@ const failable<int> access_token(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("?") + httpd::queryString(iargs);
debug(iuri, "modoauth2::access_token::infouri");
- const failable<value> iv = http::get(iuri, sc.cs);
- if (!hasContent(iv))
+ const failable<value> profres = http::get(iuri, sc.cs);
+ if (!hasContent(profres))
return mkfailure<int>("Couldn't retrieve user info");
- debug(content(iv), "modoauth2::access_token::info");
+ debug(content(profres), "modoauth2::access_token::info");
+
+ // Retrieve the user info from the profile
+ const failable<list<value> > iv = profileUserInfo(cadr(cid), content(profres));
+ if (!hasContent(iv))
+ return mkfailure<int>(reason(iv));
// Store user info in memcached keyed by session ID
const value sid = string("OAuth2_") + mkrand();
diff --git a/sca-cpp/trunk/modules/oauth/oauth-conf b/sca-cpp/trunk/modules/oauth/oauth-conf
index 5c3fde2ccc..91ae1916c7 100755
--- a/sca-cpp/trunk/modules/oauth/oauth-conf
+++ b/sca-cpp/trunk/modules/oauth/oauth-conf
@@ -39,14 +39,17 @@ AuthOAuth On
AuthOAuthLoginPage /login
</Location>
-# Enable unauthenticated access to unprotected areas
+# Enable unauthenticated access to public areas
<Location /login>
AuthOAuth Off
</Location>
<Location /logout>
AuthOAuth Off
</Location>
-<Location /unprotected>
+<Location /public>
+AuthOAuth Off
+</Location>
+<Location /ui>
AuthOAuth Off
</Location>
diff --git a/sca-cpp/trunk/modules/oauth/oauth.composite b/sca-cpp/trunk/modules/oauth/oauth.composite
index 0119db22c9..c2025493c8 100644
--- a/sca-cpp/trunk/modules/oauth/oauth.composite
+++ b/sca-cpp/trunk/modules/oauth/oauth.composite
@@ -38,6 +38,7 @@
<property name="fullname">?</property>
<property name="firstname">?</property>
<property name="lastname">?</property>
+ <property name="realm">?</property>
</component>
</composite>
diff --git a/sca-cpp/trunk/modules/oauth/oauth.hpp b/sca-cpp/trunk/modules/oauth/oauth.hpp
index ab92cbd381..cea16e035f 100644
--- a/sca-cpp/trunk/modules/oauth/oauth.hpp
+++ b/sca-cpp/trunk/modules/oauth/oauth.hpp
@@ -43,10 +43,15 @@ namespace oauth {
/**
* Return the session id from a request.
*/
+const char* cookieName(const char* cs) {
+ if (*cs != ' ')
+ return cs;
+ return cookieName(cs + 1);
+}
const maybe<string> sessionID(const list<string> c) {
if (isNil(c))
return maybe<string>();
- const list<string> kv = tokenize("=", car(c));
+ const list<string> kv = tokenize("=", cookieName(c_str(car(c))));
if (!isNil(kv) && !isNil(cdr(kv))) {
if (car(kv) == "TuscanyOpenAuth")
return cadr(kv);
diff --git a/sca-cpp/trunk/modules/oauth/start-mixed-test b/sca-cpp/trunk/modules/oauth/start-mixed-test
index 468e6861d8..e838e9bb83 100755
--- a/sca-cpp/trunk/modules/oauth/start-mixed-test
+++ b/sca-cpp/trunk/modules/oauth/start-mixed-test
@@ -34,10 +34,10 @@ here=`readlink -f $0`; here=`dirname $here`
./oauth-memcached-conf tmp localhost 11213
# Configure your app keys here
-./oauth1-appkey-conf tmp testtwitterapp app2345 secret7890
-./oauth1-appkey-conf tmp testlinkedinapp app3456 secret4567
-./oauth2-appkey-conf tmp testfacebookapp app1234 secret6789
-./oauth2-appkey-conf tmp testgithubapp app5678 secret8901
+./oauth1-appkey-conf tmp twitter.com app2345 secret7890
+./oauth1-appkey-conf tmp linkedin.com app3456 secret4567
+./oauth2-appkey-conf tmp facebook.com app1234 secret6789
+./oauth2-appkey-conf tmp github.com app5678 secret8901
../openid/openid-conf tmp
../openid/openid-step2-conf tmp
diff --git a/sca-cpp/trunk/modules/oauth/start-test b/sca-cpp/trunk/modules/oauth/start-test
index 47171a91ae..8c59009102 100755
--- a/sca-cpp/trunk/modules/oauth/start-test
+++ b/sca-cpp/trunk/modules/oauth/start-test
@@ -21,20 +21,20 @@
../../components/cache/memcached-start 11212
../../components/cache/memcached-start 11213
-../../modules/http/ssl-ca-conf tmp localhost
-../../modules/http/ssl-cert-conf tmp localhost
-../../modules/http/httpd-conf tmp localhost 8090 htdocs
-../../modules/http/httpd-ssl-conf tmp 8453
+../../modules/http/ssl-ca-conf tmp jsdelfino.com
+../../modules/http/ssl-cert-conf tmp jsdelfino.com
+../../modules/http/httpd-conf tmp jsdelfino.com 8090/80 htdocs
+../../modules/http/httpd-ssl-conf tmp 8453/443
./oauth-conf tmp
-./oauth-memcached-conf tmp localhost 11212
-./oauth-memcached-conf tmp localhost 11213
+./oauth-memcached-conf tmp jsdelfino.com 11212
+./oauth-memcached-conf tmp jsdelfino.com 11213
# Configure your app keys here
-./oauth1-appkey-conf tmp testtwitterapp app2345 secret7890
-./oauth1-appkey-conf tmp testlinkedinapp app3456 secret4567
-./oauth2-appkey-conf tmp testfacebookapp app1234 secret6789
-./oauth2-appkey-conf tmp testgithubapp app5678 secret8901
+./oauth1-appkey-conf tmp twitter.com app2345 secret7890
+./oauth1-appkey-conf tmp linkedin.com app3456 secret4567
+./oauth2-appkey-conf tmp facebook.com app1234 secret6789
+./oauth2-appkey-conf tmp github.com app5678 secret8901
../../modules/server/server-conf tmp
../../modules/server/scheme-conf tmp
diff --git a/sca-cpp/trunk/modules/oauth/user-info.scm b/sca-cpp/trunk/modules/oauth/user-info.scm
index 58a84f86b0..4960a0a455 100644
--- a/sca-cpp/trunk/modules/oauth/user-info.scm
+++ b/sca-cpp/trunk/modules/oauth/user-info.scm
@@ -17,18 +17,20 @@
; OAuth support test case
-(define (get id user email nickname fullname firstname lastname) (list "text/html" (list
- "<html><body><p>The following info is generated on the server:</p><div>User: " (user) "</div><div>Email: " (email) "</div><div>Nickname: " (nickname) "</div><div>Fullname: " (fullname) "</div><div>Firstname: " (firstname) "</div><div>Lastname: " (lastname) "</div></body></html>")))
+(define (get id user email nickname fullname firstname lastname realm) (list "text/html" (list
+ "<html><body><p>The following info is generated on the server:</p><div>User: " (user) "</div><div>Email: " (email) "</div><div>Nickname: " (nickname) "</div><div>Fullname: " (fullname) "</div><div>Firstname: " (firstname) "</div><div>Lastname: " (lastname) "</div><div>Realm: " (realm) "</div></body></html>")))
-(define (getuser user email nickname fullname firstname lastname) (user))
+(define (getuser user email nickname fullname firstname lastname realm) (user))
-(define (getemail user email nickname fullname firstname lastname) (email))
+(define (getemail user email nickname fullname firstname lastname realm) (email))
-(define (getnickname user email nickname fullname firstname lastname) (nickname))
+(define (getnickname user email nickname fullname firstname lastname realm) (nickname))
-(define (getfullname user email nickname fullname firstname lastname) (fullname))
+(define (getfullname user email nickname fullname firstname lastname realm) (fullname))
-(define (getfirstname user email nickname fullname firstname lastname) (firstname))
+(define (getfirstname user email nickname fullname firstname lastname realm) (firstname))
-(define (getlastname user email nickname fullname firstname lastname) (lastname))
+(define (getlastname user email nickname fullname firstname lastname realm) (lastname))
+
+(define (getrealm user email nickname fullname firstname lastname realm) (realm))