diff options
Diffstat (limited to '')
-rw-r--r-- | sca-cpp/trunk/modules/oauth/Makefile.am | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/oauth/htdocs/index.html | 9 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/oauth/htdocs/login/index.html | 8 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html | 8 | ||||
-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.cpp | 44 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/oauth/mod-oauth2.cpp | 20 | ||||
-rwxr-xr-x | sca-cpp/trunk/modules/oauth/oauth-conf | 7 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/oauth/oauth.composite | 1 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/oauth/oauth.hpp | 7 | ||||
-rwxr-xr-x | sca-cpp/trunk/modules/oauth/start-mixed-test | 8 | ||||
-rwxr-xr-x | sca-cpp/trunk/modules/oauth/start-test | 20 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/oauth/user-info.scm | 18 |
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)) |