diff options
42 files changed, 670 insertions, 453 deletions
diff --git a/sca-cpp/trunk/hosting/server/htdocs/app/index.html b/sca-cpp/trunk/hosting/server/htdocs/app/index.html index 0b01c1d3bd..19fa7488a5 100644 --- a/sca-cpp/trunk/hosting/server/htdocs/app/index.html +++ b/sca-cpp/trunk/hosting/server/htdocs/app/index.html @@ -74,8 +74,12 @@ appcache.get = function(uri) { document.head.appendChild(ui.declareCSS(appcache.get('/ui-min.css'))); })(); +</script> + +<script type="text/javascript"> + // Redirect to login page if not signed in -if (document.location.protocol == 'https:' && !ui.signedin()) +if (document.location.protocol == 'https:' && !hasauthcookie()) document.location = '/login/'; </script> diff --git a/sca-cpp/trunk/hosting/server/htdocs/index.html b/sca-cpp/trunk/hosting/server/htdocs/index.html index 3bc1529dbb..468461cedc 100644 --- a/sca-cpp/trunk/hosting/server/htdocs/index.html +++ b/sca-cpp/trunk/hosting/server/htdocs/index.html @@ -74,8 +74,11 @@ appcache.get = function(uri) { document.head.appendChild(ui.declareCSS(appcache.get('/ui-min.css'))); })(); +</script> +<script type="text/javascript"> + // Redirect to login page if not signed in -if (document.location.protocol == 'https:' && !ui.signedin()) +if (document.location.protocol == 'https:' && !hasauthcookie()) document.location = '/login/'; </script> @@ -260,7 +263,7 @@ function showmenu(mdiv, view, appname) { ui.menu(isNil(config.compose)? 'Composition' : config.compose, '/#view=graph&app=' + appname, '_view', view == 'graph'))), mklist( ui.menu('Account', '/#view=account', '_view', view == 'account'), - ui.signedin()? ui.menufunc('Sign out', 'logout();', false) : ui.menu('Sign in', '/login/', '_self', false))); + hasauthcookie()? ui.menufunc('Sign out', 'logout();', false) : ui.menu('Sign in', '/login/', '_self', false))); } /** @@ -434,8 +437,7 @@ window.onloginredirect = function(e) { */ function logout() { // Clear session cookie and user-specific local storage entries - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; - document.cookie = reset; + clearauthcookie(); localStorage.removeItem('/r/EditWidget/accounts'); localStorage.removeItem('/r/EditWidget/dashboards'); //localStorage.clear(); diff --git a/sca-cpp/trunk/hosting/server/htdocs/login/index.html b/sca-cpp/trunk/hosting/server/htdocs/login/index.html index 9052abe8d3..359afc1807 100644 --- a/sca-cpp/trunk/hosting/server/htdocs/login/index.html +++ b/sca-cpp/trunk/hosting/server/htdocs/login/index.html @@ -32,31 +32,50 @@ <h1>Sign in</h1> -<form name="openIDForm"> +<form name="googleOpenIDForm"> <table border="0"> -<tr><td><b>Sign in with your Google account</b></td></tr> -<tr><td><input type="button" value="Sign in" class="graybutton" style="font-weight: bold;" onclick="submitOpenIDSignin(withGoogle)"/></td></tr> +<tr><td><b>Sign in with your Google account (using OpenID)</b></td></tr> +<tr><td><input type="button" value="Sign in" class="graybutton" style="font-weight: bold;" onclick="submitOpenIDSignin(withGoogleOpenID)"/></td></tr> </table> </form> -<form name="oauth2Form"> +<form name="facebookOAuth2Form"> <table border="0"> -<tr><td><b>Sign in with your Facebook account</b></td></tr> -<tr><td><input type="button" value="Sign in" class="graybutton" style="font-weight: bold;" onclick="submitOAuth2Signin(withFacebook)"/></td></tr> +<tr><td><b>Sign in with your Facebook account (using OAuth)</b></td></tr> +<tr><td><input type="button" value="Sign in" class="graybutton" style="font-weight: bold;" onclick="submitOAuth2Signin(withFacebook)"/></td></tr> </table> </form> +<form name="googleOAuth2Form"> +<table border="0"> +<tr><td><b>Sign in with your Google account (using OAuth)</b></td></tr> +<tr><td><input type="button" value="Sign in" class="graybutton" style="font-weight: bold;" onclick="submitOAuth2Signin(withGoogleOAuth)"/></td></tr> +</table> +</form> + +<form name="formSignin" method="POST" action="/login/dologin"> +<table border="0"> +<tr><td colspan="2"><b>Sign in with your user id and password</b></td></tr> +<tr><td>User id:</td><td><input type="text" name="httpd_username" value=""/></td></tr> +<tr><td>Password:</td><td><input type="password" name="httpd_password" value=""/></td></tr> +<tr><td><input type="button" class="graybutton" style="font-weight: bold;" onclick="submitFormSignin()" value="Sign in"/></td><td></td></tr> +</table> +</p> +<input type="hidden" name="httpd_location" value="/"/> +</form> + <form name="openIDSignin" action="/" method="GET"> <input type="hidden" name="openid_identifier" value=""/> </form> -<form name="oauth2Signin" action="/" method="GET"> -<input type="hidden" name="mod_oauth2_authorize" value=""/> -<input type="hidden" name="mod_oauth2_access_token" value=""/> -<input type="hidden" name="mod_oauth2_client_id" value=""/> -<input type="hidden" name="mod_oauth2_info" value=""/> -<input type="hidden" name="mod_oauth2_display" value=""/> -<input type="hidden" name="mod_oauth2_step" value="authorize"/> +<form name="oauth2Signin" action="/oauth2/authorize/" method="GET"> +<input type="hidden" name="oauth2_authorize" value=""/> +<input type="hidden" name="oauth2_access_token" value=""/> +<input type="hidden" name="oauth2_client_id" value=""/> +<input type="hidden" name="oauth2_info" value=""/> +<input type="hidden" name="oauth2_display" value=""/> +<input type="hidden" name="oauth2_scope" value=""/> +<input type="hidden" name="openauth_referrer" value=""/> </form> <script type="text/javascript"> @@ -85,8 +104,7 @@ function openauthReferrer() { * Signin with OpenID. */ function submitOpenIDSignin(w) { - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; - document.cookie = reset; + clearauthcookie(); localStorage.removeItem('/r/EditWidget/accounts'); localStorage.removeItem('/r/EditWidget/dashboards'); //localStorage.clear(); @@ -95,7 +113,7 @@ function submitOpenIDSignin(w) { document.openIDSignin.submit(); } -function withGoogle() { +function withGoogleOpenID() { return 'https://www.google.com/accounts/o8/id'; } @@ -104,25 +122,40 @@ function withGoogle() { */ function submitOAuth2Signin(w) { parms = w(); - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; - document.cookie = reset; + clearauthcookie(); localStorage.removeItem('/r/EditWidget/accounts'); localStorage.removeItem('/r/EditWidget/dashboards'); //localStorage.clear(); - document.oauth2Signin.mod_oauth2_authorize.value = parms[0]; - document.oauth2Signin.mod_oauth2_access_token.value = parms[1]; - document.oauth2Signin.mod_oauth2_client_id.value = parms[2]; - document.oauth2Signin.mod_oauth2_info.value = parms[3]; - document.oauth2Signin.mod_oauth2_display.value = parms[4]; - document.oauth2Signin.action = openauthReferrer(); + document.oauth2Signin.oauth2_authorize.value = parms[0]; + document.oauth2Signin.oauth2_access_token.value = parms[1]; + document.oauth2Signin.oauth2_client_id.value = parms[2]; + document.oauth2Signin.oauth2_info.value = parms[3]; + document.oauth2Signin.oauth2_scope.value = parms[4]; + document.oauth2Signin.oauth2_display.value = parms[5]; + document.oauth2Signin.openauth_referrer.value = openauthReferrer(); + document.oauth2Signin.action = '/oauth2/authorize/'; document.oauth2Signin.submit(); } function withFacebook() { - var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'facebook.com', 'https://graph.facebook.com/me', ui.isMobile()? 'touch' : 'page']; + var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'facebook.com', 'https://graph.facebook.com/me', 'email', ui.isMobile()? 'touch' : 'page']; return parms; } +function withGoogleOAuth() { + var parms = ['https://accounts.google.com/o/oauth2/auth', 'https://accounts.google.com/o/oauth2/token', 'google.com', 'https://www.googleapis.com/oauth2/v1/userinfo', 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile', '']; + return parms; +} + +/** + * Signin with a userid and password. + */ +function submitFormSignin() { + clearauthcookie(); + document.formSignin.httpd_location.value = '/'; + document.formSignin.submit(); +} + /** * Handle orientation change. */ diff --git a/sca-cpp/trunk/hosting/server/htdocs/public/notauth/index.html b/sca-cpp/trunk/hosting/server/htdocs/public/notauth/index.html index 21f70f8a65..0c0435d8a7 100644 --- a/sca-cpp/trunk/hosting/server/htdocs/public/notauth/index.html +++ b/sca-cpp/trunk/hosting/server/htdocs/public/notauth/index.html @@ -110,7 +110,7 @@ var cdiv = $('content'); function showmenu(mdiv) { mdiv.innerHTML = ui.menubar( mklist(ui.menu('Home', '/', '_view', false)), - mklist(ui.signedin()? ui.menufunc('Sign out', 'logout();', false) : ui.menu('Sign in', '/login/', '_self', false))); + mklist(hasauthcookie()? ui.menufunc('Sign out', 'logout();', false) : ui.menu('Sign in', '/login/', '_self', false))); } showmenu(mdiv); @@ -121,8 +121,7 @@ cdiv.style.top = ui.pixpos(mdiv.offsetTop + mdiv.offsetHeight); */ function logout() { // Clear session cookie and user-specific local storage entries - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; - document.cookie = reset; + clearauthcookie(); localStorage.removeItem('/r/EditWidget/accounts'); localStorage.removeItem('/r/EditWidget/dashboards'); //localStorage.clear(); diff --git a/sca-cpp/trunk/hosting/server/htdocs/public/notfound/index.html b/sca-cpp/trunk/hosting/server/htdocs/public/notfound/index.html index 839cc3395b..0b364b1753 100644 --- a/sca-cpp/trunk/hosting/server/htdocs/public/notfound/index.html +++ b/sca-cpp/trunk/hosting/server/htdocs/public/notfound/index.html @@ -111,7 +111,7 @@ var cdiv = $('content'); function showmenu(mdiv) { mdiv.innerHTML = ui.menubar( mklist(ui.menu('Home', '/', '_view', false)), - mklist(ui.signedin()? ui.menufunc('Sign out', 'logout();', false) : ui.menu('Sign in', '/login/', '_self', false))); + mklist(hasauthcookie()? ui.menufunc('Sign out', 'logout();', false) : ui.menu('Sign in', '/login/', '_self', false))); } showmenu(mdiv); @@ -122,8 +122,7 @@ cdiv.style.top = ui.pixpos(mdiv.offsetTop + mdiv.offsetHeight); */ function logout() { // Clear session cookie and user-specific local storage entries - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; - document.cookie = reset; + clearauthcookie(); localStorage.removeItem('/r/EditWidget/accounts'); localStorage.removeItem('/r/EditWidget/dashboards'); //localStorage.clear(); diff --git a/sca-cpp/trunk/hosting/server/htdocs/public/notyet/index.html b/sca-cpp/trunk/hosting/server/htdocs/public/notyet/index.html index c014c7266e..11d25eedef 100644 --- a/sca-cpp/trunk/hosting/server/htdocs/public/notyet/index.html +++ b/sca-cpp/trunk/hosting/server/htdocs/public/notyet/index.html @@ -111,7 +111,7 @@ var cdiv = $('content'); function showmenu(mdiv) { mdiv.innerHTML = ui.menubar( mklist(ui.menu('Home', '/', '_view', false)), - mklist(ui.signedin()? ui.menufunc('Sign out', 'logout();', false) : ui.menu('Sign in', '/login/', '_self', false))); + mklist(hasauthcookie()? ui.menufunc('Sign out', 'logout();', false) : ui.menu('Sign in', '/login/', '_self', false))); } showmenu(mdiv); @@ -122,8 +122,7 @@ cdiv.style.top = ui.pixpos(mdiv.offsetTop + mdiv.offsetHeight); */ function logout() { // Clear session cookie and user-specific local storage entries - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; - document.cookie = reset; + clearauthcookie(); localStorage.removeItem('/r/EditWidget/accounts'); localStorage.removeItem('/r/EditWidget/dashboards'); //localStorage.clear(); diff --git a/sca-cpp/trunk/hosting/server/htdocs/public/oops/index.html b/sca-cpp/trunk/hosting/server/htdocs/public/oops/index.html index 2ef7754919..8d27c498d2 100644 --- a/sca-cpp/trunk/hosting/server/htdocs/public/oops/index.html +++ b/sca-cpp/trunk/hosting/server/htdocs/public/oops/index.html @@ -110,7 +110,7 @@ var cdiv = $('content'); function showmenu(mdiv) { mdiv.innerHTML = ui.menubar( mklist(ui.menu('Home', '/', '_view', false)), - mklist(ui.signedin()? ui.menufunc('Sign out', 'logout();', false) : ui.menu('Sign in', '/login/', '_self', false))); + mklist(hasauthcookie()? ui.menufunc('Sign out', 'logout();', false) : ui.menu('Sign in', '/login/', '_self', false))); } showmenu(mdiv); @@ -121,8 +121,7 @@ cdiv.style.top = ui.pixpos(mdiv.offsetTop + mdiv.offsetHeight); */ function logout() { // Clear session cookie and user-specific local storage entries - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; - document.cookie = reset; + clearauthcookie(); localStorage.removeItem('/r/EditWidget/accounts'); localStorage.removeItem('/r/EditWidget/dashboards'); //localStorage.clear(); diff --git a/sca-cpp/trunk/hosting/server/ssl-start b/sca-cpp/trunk/hosting/server/ssl-start index 4689566176..49d2b424b9 100755 --- a/sca-cpp/trunk/hosting/server/ssl-start +++ b/sca-cpp/trunk/hosting/server/ssl-start @@ -17,15 +17,15 @@ # specific language governing permissions and limitations # under the License. -# For this module to work, add the example.com domain to your /etc/hosts as follows: -# 127.0.0.1 example.com +# For this module to work, add the www.example.com domain to your /etc/hosts as follows: +# 127.0.0.1 www.example.com here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here` jsprefix=`echo "import os; print os.path.realpath('$here/../../modules/js')" | python` # Create SSL certificates -../../modules/http/ssl-ca-conf tmp example.com -../../modules/http/ssl-cert-conf tmp example.com server +../../modules/http/ssl-ca-conf tmp www.example.com +../../modules/http/ssl-cert-conf tmp www.example.com server # Configure and start logging if [ -x ../../components/log/scribe-cat ]; then @@ -40,31 +40,32 @@ fi ../../components/cache/memcached-start tmp 11212 # Configure server -../../modules/http/httpd-conf tmp example.com 8090 htdocs +../../modules/http/httpd-conf tmp www.example.com 8090 htdocs ../../modules/http/httpd-event-conf tmp ../../modules/http/httpd-ssl-conf tmp 8453 -# Configure password authentication -#../../modules/http/open-auth-conf tmp -#../../modules/http/passwd-auth-conf tmp john john -#../../modules/http/passwd-auth-conf tmp jane jane -#../../modules/http/passwd-auth-conf tmp admin admin +# Configure OpenID step2 authentication +../../modules/openid/openid-conf tmp +../../modules/openid/openid-step2-conf tmp +../../modules/openid/openid-memcached-conf tmp localhost 11212 # Configure OAuth authentication # Configure your OAuth app keys here ../../modules/oauth/oauth-conf tmp ../../modules/oauth/oauth-memcached-conf tmp localhost 11212 ../../modules/oauth/oauth2-appkey-conf tmp facebook.com 12345 67890 +../../modules/oauth/oauth2-appkey-conf tmp google.com 12345 67890 -# Configure OpenID step2 authentication -../../modules/openid/openid-conf tmp -../../modules/openid/openid-step2-conf tmp -../../modules/openid/openid-memcached-conf tmp localhost 11212 +# Configure password authentication +../../modules/http/open-auth-conf tmp +../../modules/http/passwd-auth-conf tmp john john +../../modules/http/passwd-auth-conf tmp jane jane +../../modules/http/passwd-auth-conf tmp admin admin # Configure authorized users -#../../modules/http/group-auth-conf tmp john -#../../modules/http/group-auth-conf tmp jane -#../../modules/http/group-auth-conf tmp admin +../../modules/http/group-auth-conf tmp john +../../modules/http/group-auth-conf tmp jane +../../modules/http/group-auth-conf tmp admin # Configure the email addresses associated with your OpenID and OAuth ids here ../../modules/http/group-auth-conf tmp john@example.com ../../modules/http/group-auth-conf tmp jane@example.com @@ -91,11 +92,11 @@ CustomLog "|$here/../../components/log/scribe-cat server" sslcombined EOF - cat >tmp/conf/mod-security-log.conf <<EOF +# cat >tmp/conf/mod-security-log.conf <<EOF # Generated by: ssl-start $* -SecAuditLog "|$here/../../components/log/scribe-cat secaudit" - -EOF +#SecAuditLog "|$here/../../components/log/scribe-cat secaudit" +# +#EOF else cat >tmp/conf/log.conf <<EOF @@ -111,11 +112,11 @@ CustomLog $here/tmp/logs/ssl_access_log sslcombined EOF - cat >tmp/conf/mod-security-log.conf <<EOF +# cat >tmp/conf/mod-security-log.conf <<EOF # Generated by: ssl-start $* -SecAuditLog $here/tmp/logs/secaudit_log secaudit - -EOF +#SecAuditLog $here/tmp/logs/secaudit_log +# +#EOF fi @@ -180,5 +181,6 @@ AliasMatch /v/([^/]+)(.*)$ $here/htdocs/app\$2 EOF # Start server +#../../modules/http/httpd-loglevel-conf tmp debug ../../modules/http/httpd-start tmp diff --git a/sca-cpp/trunk/modules/http/basic-auth-conf b/sca-cpp/trunk/modules/http/basic-auth-conf index 77ca054f1c..39dde90b50 100755 --- a/sca-cpp/trunk/modules/http/basic-auth-conf +++ b/sca-cpp/trunk/modules/http/basic-auth-conf @@ -25,6 +25,11 @@ root=`echo "import os; print os.path.realpath('$1')" | python` conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"` host=`echo $conf | awk '{ print $6 }'` +loc=$2 +if [ "$loc" = "" ]; then + loc="/" +fi + sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"` if [ "$sslconf" = "" ]; then sslsuffix="" @@ -44,7 +49,7 @@ cat >>$root/conf/locauth$sslsuffix.conf <<EOF # Generated by: basic-auth-conf $* # Require clients to present a userid + password for HTTP # basic authentication -<Location /> +<Location $loc> AuthType Basic AuthName "$host" AuthBasicProvider file diff --git a/sca-cpp/trunk/modules/http/form-auth-conf b/sca-cpp/trunk/modules/http/form-auth-conf index 4ba3bec23a..2898d9b7ed 100755 --- a/sca-cpp/trunk/modules/http/form-auth-conf +++ b/sca-cpp/trunk/modules/http/form-auth-conf @@ -25,7 +25,11 @@ root=`echo "import os; print os.path.realpath('$1')" | python` conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"` host=`echo $conf | awk '{ print $6 }'` -pw=`cat $root/cert/ca.key | head -2 | tail -1` +if [ "$2" = "" ]; then + pw=`cat $root/cert/ca.key | head -2 | tail -1` +else + pw="$2" +fi sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"` if [ "$sslconf" = "" ]; then diff --git a/sca-cpp/trunk/modules/http/htdocs/login/index.html b/sca-cpp/trunk/modules/http/htdocs/login/index.html index 99aeb31d1b..5c5286f7c4 100644 --- a/sca-cpp/trunk/modules/http/htdocs/login/index.html +++ b/sca-cpp/trunk/modules/http/htdocs/login/index.html @@ -32,8 +32,7 @@ <script type="text/javascript"> function submitFormSignin() { - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; + clearauthcookie(); document.formSignin.httpd_location.value = '/'; document.formSignin.submit(); } diff --git a/sca-cpp/trunk/modules/http/htdocs/logout/index.html b/sca-cpp/trunk/modules/http/htdocs/logout/index.html index 4e7df1bcf3..795f8f32a2 100644 --- a/sca-cpp/trunk/modules/http/htdocs/logout/index.html +++ b/sca-cpp/trunk/modules/http/htdocs/logout/index.html @@ -33,8 +33,7 @@ <form name="signout" action="/login" method="GET"> <script type="text/javascript"> function submitSignout() { - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; + clearauthcookie(); document.signout.submit(); return true; } diff --git a/sca-cpp/trunk/modules/http/http.hpp b/sca-cpp/trunk/modules/http/http.hpp index 2334c1c525..eb7a8d506f 100644 --- a/sca-cpp/trunk/modules/http/http.hpp +++ b/sca-cpp/trunk/modules/http/http.hpp @@ -52,6 +52,11 @@ namespace tuscany { namespace http { /** + * Enable CURL verbose debug log. + */ +//#define WANT_MAINTAINER_CURL_VERBOSE + +/** * CURL library runtime, one per process. */ class CURLRuntime { @@ -243,7 +248,7 @@ const failable<CURL*> setup(const string& url, const CURLSession& cs) { CURL* ch = handle(cs); curl_easy_reset(ch); curl_easy_setopt(ch, CURLOPT_USERAGENT, "libcurl/1.0"); -#ifdef WANT_MAINTAINER_MODE +#ifdef WANT_MAINTAINER_CURL_VERBOSE curl_easy_setopt(ch, CURLOPT_VERBOSE, true); #endif @@ -454,9 +459,9 @@ const failable<value> evalExpr(const value& expr, const string& url, const CURLS /** * Find and return a header. */ -const failable<string> header(const char* prefix, const list<string>& h) { +const maybe<string> header(const char* prefix, const list<string>& h) { if (isNil(h)) - return mkfailure<string>(string("Couldn't find header: ") + prefix); + return maybe<string>(); const string s = car(h); if (find(s, prefix) != 0) return header(prefix, cdr(h)); @@ -467,8 +472,9 @@ const failable<string> header(const char* prefix, const list<string>& h) { /** * Find and return a location header. */ -const failable<string> location(const list<string>& h) { - return header("Location: ", h); +const string location(const list<string>& h) { + const maybe<string> l = header("Location: ", h); + return hasContent(l)? content(l) : ""; } /** @@ -484,8 +490,9 @@ const value entryId(const failable<string> l) { /** * Find and return a content-type header. */ -const failable<string> contentType(const list<string>& h) { - return header("Content-Type: ", h); +const string contentType(const list<string>& h) { + const maybe<string> ct = header("Content-Type: ", h); + return hasContent(ct)? content(ct) : ""; } /** @@ -516,44 +523,40 @@ const failable<value> getcontent(const string& url, const CURLSession& cs) { } /** - * HTTP GET, return a list of values representing the resource at the given URL. + * Convert an HTTP content response to a value. */ -const failable<value> get(const string& url, const CURLSession& cs) { - debug(url, "http::get::url"); +const failable<value> responseValue(const list<list<string> > res) { - // Get the contents of the resource at the given URL - const failable<list<list<string> > > res = get<list<string> >(rcons<string>, list<string>(), url, cs); - if (!hasContent(res)) - return mkfailure<value>(reason(res)); - const string ct(content(contentType(car(content(res))))); - debug(ct, "http::get::contentType"); + // Parse the returned content + const string ct = contentType(car(res)); + debug(ct, "http::responseValue::contentType"); - const list<string> ls(reverse(cadr(content(res)))); - debug(ls, "http::get::content"); + const list<string> ls(reverse(cadr(res))); + debug(ls, "http::responseValue::content"); if (atom::isATOMEntry(ls)) { // Read an ATOM entry const value val(elementsToValues(content(atom::readATOMEntry(ls)))); - debug(val, "http::get::result"); + debug(val, "http::responseValue::result"); return val; } if (contains(ct, "application/atom+xml") || atom::isATOMFeed(ls)) { // Read an ATOM feed const value val(elementsToValues(content(atom::readATOMFeed(ls)))); - debug(val, "http::get::result"); + debug(val, "http::responseValue::result"); return val; } if (contains(ct, "application/rss+xml") || rss::isRSSFeed(ls)) { // Read an RSS feed const value val(elementsToValues(content(rss::readRSSFeed(ls)))); - debug(val, "http::get::result"); + debug(val, "http::responseValue::result"); return val; } if (contains(ct, "text/javascript") || contains(ct, "application/json") || json::isJSON(ls)) { // Read a JSON document js::JSContext cx; const value val(json::jsonValues(content(json::readJSON(ls, cx)))); - debug(val, "http::get::result"); + debug(val, "http::responseValue::result"); return val; } if (contains(ct, "application/x-javascript")) { @@ -565,27 +568,42 @@ const failable<value> get(const string& url, const CURLSession& cs) { const size_t fp = find(s, '('); const size_t lp = find_last(s, ')'); const list<string> jls = mklist<string>(substr(s, fp + 1, lp - (fp + 1))); - debug(jls, "http::get::javascript::content"); + debug(jls, "http::responseValue::javascript::content"); js::JSContext cx; const value val(json::jsonValues(content(json::readJSON(jls, cx)))); - debug(val, "http::get::result"); + debug(val, "http::responseValue::result"); return val; } if (contains(ct, "text/xml") || contains(ct, "application/xml") || isXML(ls)) { // Read an XML document const value val(elementsToValues(readXML(ls))); - debug(val, "http::get::result"); + debug(val, "http::responseValue::result"); return val; } // Return the content type and a content list const value val(mklist<value>(ct, mkvalues(ls))); - debug(val, "http::get::result"); + debug(val, "http::responseValue::result"); return val; } /** + * HTTP GET, return a list of values representing the resource at the given URL. + */ +const failable<value> get(const string& url, const CURLSession& cs) { + debug(url, "http::get::url"); + + // Get the contents of the resource at the given URL + const failable<list<list<string> > > res = get<list<string> >(rcons<string>, list<string>(), url, cs); + if (!hasContent(res)) + return mkfailure<value>(reason(res)); + + // Parse the returned content + return responseValue(content(res)); +} + +/** * Form an HTTP content request. */ const failable<list<list<string> > > writeRequest(const failable<list<string> >& ls, const string& ct) { @@ -686,9 +704,15 @@ const failable<value> post(const value& val, const string& url, const CURLSessio return mkfailure<value>(reason(res)); // Return the new entry id from the HTTP location header, if any - const value eid(entryId(location(car(content(res))))); - debug(eid, "http::post::result"); - return eid; + const string loc = location(car(content(res))); + if (length(loc) != 0) { + const value eid(entryId(location(car(content(res))))); + debug(eid, "http::post::result"); + return eid; + } + + // Return the returned content + return responseValue(content(res)); } /** diff --git a/sca-cpp/trunk/modules/http/httpd-conf b/sca-cpp/trunk/modules/http/httpd-conf index e5e7f27287..f940073a91 100755 --- a/sca-cpp/trunk/modules/http/httpd-conf +++ b/sca-cpp/trunk/modules/http/httpd-conf @@ -35,6 +35,8 @@ else pportsuffix=":$pport" fi +dothost=`echo $host | grep "\."` + mkdir -p $4 htdocs=`echo "import os; print os.path.realpath('$4')" | python` @@ -85,10 +87,7 @@ LogFormat "[%{%a %b %d %H:%M:%S %Y}t] [access] %h %l %u \"%r\" %>s %b \"%{Refere Include conf/log.conf # Configure tracking -CookieTracking on -CookieName TuscanyVisitorId -CookieStyle Cookie -CookieExpires 31556926 +Include conf/tracking.conf # Configure Mime types and default charsets TypesConfig $here/conf/mime.types @@ -96,12 +95,12 @@ AddDefaultCharset utf-8 AddCharset utf-8 .html .js .css # Configure cache control -SetEnvIf Request_URI "^/app.html$" must-revalidate -Header onsuccess set Cache-Control "max-age=604800" env=!must-revalidate -Header set Cache-Control "must-revalidate, max-age=0" env=must-revalidate -Header set Expires "Tue, 01 Jan 1980 00:00:00 GMT" env=must-revalidate +<Directory /> +ExpiresActive On +ExpiresDefault M604800 +</Directory> -# Configuration auth modules +# Configure auth modules Include conf/auth.conf # Set default document root @@ -138,6 +137,7 @@ ServerName http://$host$pportsuffix <Location /> RewriteEngine on RewriteCond %{HTTP_HOST} !^$host [NC] +RewriteCond %{HTTP:X-Forwarded-Server} ^$ [NC] RewriteRule .* http://$host$pportsuffix%{REQUEST_URI} [R] </Location> @@ -152,6 +152,26 @@ Include conf/pubauth.conf EOF +# Generate tracking configuration +cat >$root/conf/tracking.conf <<EOF +# Generated by: httpd-conf $* +# Configure tracking +CookieTracking on +CookieName TuscanyVisitorId +CookieStyle Cookie +CookieExpires 31556926 + +EOF + +if [ "$dothost" != "" ]; then + cat >>$root/conf/tracking.conf <<EOF +# Generated by: httpd-conf $* +CookieDomain .$dothost + +EOF + +fi + # Configure logging cat >$root/conf/log.conf <<EOF # Generated by: httpd-conf $* @@ -206,6 +226,7 @@ LoadModule negotiation_module ${modules_prefix}/modules/mod_negotiation.so LoadModule dir_module ${modules_prefix}/modules/mod_dir.so LoadModule setenvif_module ${modules_prefix}/modules/mod_setenvif.so LoadModule env_module ${modules_prefix}/modules/mod_env.so +LoadModule expires_module ${modules_prefix}/modules/mod_expires.so <IfModule !log_config_module> LoadModule log_config_module ${modules_prefix}/modules/mod_log_config.so </IfModule> @@ -223,7 +244,6 @@ LoadModule ratelimit_module ${modules_prefix}/modules/mod_ratelimit.so LoadModule reqtimeout_module ${modules_prefix}/modules/mod_reqtimeout.so LoadModule mod_tuscany_ssltunnel $here/libmod_tuscany_ssltunnel$libsuffix -LoadModule mod_tuscany_openauth $here/libmod_tuscany_openauth$libsuffix EOF diff --git a/sca-cpp/trunk/modules/http/httpd-ssl-conf b/sca-cpp/trunk/modules/http/httpd-ssl-conf index 9bf98162ce..cb5ccfb8db 100755 --- a/sca-cpp/trunk/modules/http/httpd-ssl-conf +++ b/sca-cpp/trunk/modules/http/httpd-ssl-conf @@ -68,6 +68,7 @@ ServerName https://$host$sslpportsuffix <Location /> RewriteEngine on RewriteCond %{HTTP_HOST} !^$host [NC] +RewriteCond %{HTTP:X-Forwarded-Server} ^$ [NC] RewriteRule .* https://$host$sslpportsuffix%{REQUEST_URI} [R] </Location> diff --git a/sca-cpp/trunk/modules/http/httpd.hpp b/sca-cpp/trunk/modules/http/httpd.hpp index af075a04e8..718ed6e52b 100644 --- a/sca-cpp/trunk/modules/http/httpd.hpp +++ b/sca-cpp/trunk/modules/http/httpd.hpp @@ -44,14 +44,14 @@ #include <http_connection.h> #include <http_request.h> // Ignore conversion warnings in HTTPD 2.3.15 header -#ifdef WANT_MAINTAINER_MODE +#ifdef WANT_MAINTAINER_WARNINGS #ifndef IS_DARWIN #pragma GCC diagnostic ignored "-Wconversion" #endif #endif #include <http_protocol.h> // Re-enable conversion warnings -#ifdef WANT_MAINTAINER_MODE +#ifdef WANT_MAINTAINER_WARNINGS #ifndef IS_DARWIN #pragma GCC diagnostic warning "-Wconversion" #endif @@ -259,6 +259,8 @@ const list<value> pathInfo(const list<value>& uri, const list<value>& path) { * Convert a URI to an absolute URL. */ const string url(const string& uri, request_rec* r) { + if (contains(uri, "://")) + return uri; ostringstream n; const string s = scheme(r); const string h = hostName(r, "localhost"); @@ -406,8 +408,8 @@ const failable<int> writeResult(const failable<list<string> >& ls, const string& const string ob(str(os)); // Make sure browsers come back and check for updated dynamic content - // The actual header setup is configured in httpd-conf, based on the must-revalidate env variable - apr_table_set(r->subprocess_env, apr_pstrdup(r->pool, "must-revalidate"), apr_pstrdup(r->pool, "true")); + apr_table_set(r->headers_out, "Cache-Control", "must-revalidate, max-age=0"); + apr_table_set(r->headers_out, "Expires", "Tue, 01 Jan 1980 00:00:00 GMT"); // Compute and return an Etag for the returned content const string etag(ap_md5_binary(r->pool, (const unsigned char*)c_str(ob), (int)length(ob))); @@ -658,7 +660,7 @@ const void* userData(const string& k, const server_rec* s) { return v; } -#ifdef WANT_MAINTAINER_MODE +#ifdef WANT_MAINTAINER_LOG /** * Debug log. @@ -701,8 +703,6 @@ int debugNote(unused void* r, const char* key, const char* value) { * Log a request. */ const bool debugRequest(request_rec* r, const string& msg) { - if (!isDebugLog()) - return true; gc_scoped_pool(); cdebug << msg << ":" << endl; cdebug << " unparsed uri: " << debugOptional(r->unparsed_uri) << endl; @@ -725,11 +725,11 @@ const bool debugRequest(request_rec* r, const string& msg) { return true; } -#define httpdDebugRequest(r, msg) httpd::debugRequest(r, msg) +#define debug_httpdRequest(r, msg) if (debug_islogging()) httpd::debugRequest(r, msg) #else -#define httpdDebugRequest(r, msg) +#define debug_httpdRequest(r, msg) #endif diff --git a/sca-cpp/trunk/modules/http/mod-openauth.cpp b/sca-cpp/trunk/modules/http/mod-openauth.cpp index 09d62bf5f7..b1aabd73fe 100644 --- a/sca-cpp/trunk/modules/http/mod-openauth.cpp +++ b/sca-cpp/trunk/modules/http/mod-openauth.cpp @@ -77,7 +77,7 @@ public: string login; }; -#ifdef WANT_MAINTAINER_MODE +#ifdef WANT_MAINTAINER_LOG /** * Log session entries. @@ -88,12 +88,16 @@ int debugSessionEntry(unused void* r, const char* key, const char* value) { } const bool debugSession(request_rec* r, session_rec* z) { - if (!isDebugLog()) - return true; apr_table_do(debugSessionEntry, r, z->entries, NULL); return true; } +#define debug_authSession(r, z) if (debug_islogging()) openauth::debugSession(r, z) + +#else + +#define debug_authSession(r, z) + #endif /** @@ -110,9 +114,7 @@ const failable<value> userInfoFromSession(const string& realm, request_rec* r) { ap_session_load_fn(r, &z); if (z == NULL) return mkfailure<value>("Couldn't retrieve user session"); -#ifdef WANT_MAINTAINER_MODE - debugSession(r, z); -#endif + debug_authSession(r, z); if (ap_session_get_fn == NULL) ap_session_get_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_get); @@ -213,10 +215,10 @@ static int checkAuthn(request_rec *r) { // Create a scoped memory pool gc_scoped_pool pool(r->pool); - httpdDebugRequest(r, "modopenauth::checkAuthn::input"); + debug_httpdRequest(r, "modopenauth::checkAuthn::input"); // Get session id from the request - const maybe<string> sid = sessionID(r); + const maybe<string> sid = sessionID(r, "TuscanyOpenAuth"); if (hasContent(sid)) { // Decline if the session id was not created by this module const string stype = substr(content(sid), 0, 7); @@ -283,12 +285,12 @@ static int checkAuthn(request_rec *r) { // Decline if the request is for another authentication provider if (!isNil(assoc<value>("openid_identifier", args))) return DECLINED; - if (!isNil(assoc<value>("mod_oauth1_step", args))) - return DECLINED; - if (!isNil(assoc<value>("mod_oauth2_step", args))) - return DECLINED; - // Redirect to the login page + // Redirect to the login page, unless we have a session id from another module + if (hasContent(sessionID(r, "TuscanyOpenIDAuth")) || + hasContent(sessionID(r, "TuscanyOAuth1")) || + hasContent(sessionID(r, "TuscanyOAuth2"))) + return DECLINED; r->ap_auth_type = const_cast<char*>(atype); return httpd::reportStatus(login(dc.login, r)); } diff --git a/sca-cpp/trunk/modules/http/open-auth-conf b/sca-cpp/trunk/modules/http/open-auth-conf index 9c209b8685..5226622058 100755 --- a/sca-cpp/trunk/modules/http/open-auth-conf +++ b/sca-cpp/trunk/modules/http/open-auth-conf @@ -22,6 +22,13 @@ here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $h mkdir -p $1 root=`echo "import os; print os.path.realpath('$1')" | python` +uname=`uname -s` +if [ $uname = "Darwin" ]; then + libsuffix=".dylib" +else + libsuffix=".so" +fi + conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"` host=`echo $conf | awk '{ print $6 }'` @@ -32,7 +39,19 @@ else sslsuffix="-ssl" fi -pw=`cat $root/cert/ca.key | head -2 | tail -1` +if [ "$2" = "" ]; then + pw=`cat $root/cert/ca.key | head -2 | tail -1` +else + pw="$2" +fi + +# Configure HTTPD mod_tuscany_openauth module +cat >>$root/conf/modules.conf <<EOF +# Generated by: openauth-conf $* +# Load support for Open authentication +LoadModule mod_tuscany_openauth $here/libmod_tuscany_openauth$libsuffix + +EOF # Disallow public access to server resources cat >$root/conf/noauth$sslsuffix.conf <<EOF diff --git a/sca-cpp/trunk/modules/http/openauth.hpp b/sca-cpp/trunk/modules/http/openauth.hpp index e044a74fe2..5d887885aa 100644 --- a/sca-cpp/trunk/modules/http/openauth.hpp +++ b/sca-cpp/trunk/modules/http/openauth.hpp @@ -47,7 +47,7 @@ const char* cookieName(const char* cs) { return cs; return cookieName(cs + 1); } -const maybe<string> sessionID(const list<string> c) { +const maybe<string> sessionID(const list<string>& c, const string& key) { if (isNil(c)) return maybe<string>(); const string cn = cookieName(c_str(car(c))); @@ -55,29 +55,29 @@ const maybe<string> sessionID(const list<string> c) { if (i < length(cn)) { const list<string> kv = mklist<string>(substr(cn, 0, i), substr(cn, i+1)); if (!isNil(kv) && !isNil(cdr(kv))) { - if (car(kv) == "TuscanyOpenAuth") + if (car(kv) == key) return cadr(kv); } } - return sessionID(cdr(c)); + return sessionID(cdr(c), key); } -const maybe<string> sessionID(const request_rec* r) { +const maybe<string> sessionID(const request_rec* r, const string& key) { const string c = httpd::cookie(r); debug(c, "openauth::sessionid::cookies"); if (length(c) == 0) return maybe<string>(); - return sessionID(tokenize(";", c)); + return sessionID(tokenize(";", c), key); } /** * Convert a session id to a cookie string. */ -const string cookie(const string& sid, const string& domain) { +const string cookie(const string& key, const string& sid, const string& domain) { const time_t t = time(NULL) + 86400; char exp[32]; strftime(exp, 32, "%a, %d-%b-%Y %H:%M:%S GMT", gmtime(&t)); - const string c = string("TuscanyOpenAuth=") + sid + "; expires=" + string(exp) + "; domain=." + domain + "; path=/"; + const string c = key + string("=") + sid + "; expires=" + string(exp) + "; domain=." + domain + "; path=/"; debug(c, "openauth::cookie"); return c; } diff --git a/sca-cpp/trunk/modules/http/proxy-conf b/sca-cpp/trunk/modules/http/proxy-conf index 76e5b2f3dd..4c445db9fa 100755 --- a/sca-cpp/trunk/modules/http/proxy-conf +++ b/sca-cpp/trunk/modules/http/proxy-conf @@ -25,6 +25,9 @@ root=`echo "import os; print os.path.realpath('$1')" | python` cat >>$root/conf/vhost.conf <<EOF # Generated by: proxy-conf $* # Enable load balancing +ProxyPass /balancer-manager ! +ProxyPass /server-status ! +ProxyPass /server-info ! ProxyPass / balancer://cluster/ <Proxy balancer://cluster> @@ -37,5 +40,22 @@ RequestHeader set X-Forwarded-HTTPS %{HTTPS}s RequestHeader set X-Forwarded-Port %{SERVER_PORT}s </Location> +# Enable balancer manager +<Location /balancer-manager> +SetHandler balancer-manager +HostnameLookups on +Require user admin +</Location> + +EOF + +cat >>$root/conf/pubauth.conf <<EOF +# Generated by: proxy-conf $* +# Allow the server admin to manage the load balancer +<Location /balancer-manager> +HostnameLookups on +Require user admin +</Location> + EOF diff --git a/sca-cpp/trunk/modules/http/proxy-ssl-conf b/sca-cpp/trunk/modules/http/proxy-ssl-conf index 7e8003d283..d87aea6670 100755 --- a/sca-cpp/trunk/modules/http/proxy-ssl-conf +++ b/sca-cpp/trunk/modules/http/proxy-ssl-conf @@ -26,6 +26,8 @@ cat >>$root/conf/vhost-ssl.conf <<EOF # Generated by: proxy-ssl-conf $* # Enable load balancing ProxyPass /balancer-manager ! +ProxyPass /server-status ! +ProxyPass /server-info ! ProxyPass / balancer://sslcluster/ <Proxy balancer://sslcluster> @@ -33,6 +35,11 @@ Require all granted ProxySet lbmethod=byrequests </Proxy> +<Location /> +RequestHeader set X-Forwarded-HTTPS %{HTTPS}s +RequestHeader set X-Forwarded-Port %{SERVER_PORT}s +</Location> + # Enable balancer manager <Location /balancer-manager> SetHandler balancer-manager @@ -40,11 +47,6 @@ HostnameLookups on Require user admin </Location> -<Location /> -RequestHeader set X-Forwarded-HTTPS %{HTTPS}s -RequestHeader set X-Forwarded-Port %{SERVER_PORT}s -</Location> - EOF cat >>$root/conf/svhost-ssl.conf <<EOF diff --git a/sca-cpp/trunk/modules/js/htdocs/ui.js b/sca-cpp/trunk/modules/js/htdocs/ui.js index eabf851b55..dcc1462084 100644 --- a/sca-cpp/trunk/modules/js/htdocs/ui.js +++ b/sca-cpp/trunk/modules/js/htdocs/ui.js @@ -193,13 +193,6 @@ ui.windowtitle = function(host) { }; /** - * Return true if the session cookie contains signin information. - */ -ui.signedin = function() { - return !isNil(document.cookie) && document.cookie.indexOf('TuscanyOpenAuth=') != -1; -}; - -/** * Convert a CSS position to a numeric position. */ ui.numpos = function(p) { diff --git a/sca-cpp/trunk/modules/js/htdocs/util.js b/sca-cpp/trunk/modules/js/htdocs/util.js index 60c8a0c8e6..677132d2a8 100644 --- a/sca-cpp/trunk/modules/js/htdocs/util.js +++ b/sca-cpp/trunk/modules/js/htdocs/util.js @@ -334,6 +334,28 @@ function issubdomain(host) { } /** + * Return true if the document cookie contains auth information. + */ +function hasauthcookie() { + return !isNil(document.cookie) && + (document.cookie.indexOf('TuscanyOpenAuth=') != -1 || + document.cookie.indexOf('TuscanyOAuth1=') != -1 || + document.cookie.indexOf('TuscanyOAuth2=') != -1 || + document.cookie.indexOf('TuscanyOpenIDAuth=') != -1); +} + +/** + * Clear auth information from the document cookie. + */ +function clearauthcookie() { + document.cookie = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth1=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth2=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOpenIDAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + return true; +} + +/** * Format a string like Python format. */ function format() { diff --git a/sca-cpp/trunk/modules/oauth/htdocs/login/index.html b/sca-cpp/trunk/modules/oauth/htdocs/login/index.html index d1002f79ec..02439154e7 100644 --- a/sca-cpp/trunk/modules/oauth/htdocs/login/index.html +++ b/sca-cpp/trunk/modules/oauth/htdocs/login/index.html @@ -44,7 +44,7 @@ function queryParams() { function oauthReferrer() { r = queryParams()['openauth_referrer']; if (typeof(r) == 'undefined') - return r; + return '/'; q = r.indexOf('?'); if (q > 0) return r.substring(0, q); @@ -55,38 +55,48 @@ if (typeof(oauthReferrer()) == 'undefined') { document.location = '/'; } +function clearauthcookie() { + document.cookie = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth1=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth2=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOpenIDAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + return true; +} + function submitSignin2(w) { parms = w(); - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + window.location.hostname + '; path=/'; - document.cookie = reset; - document.signin2.mod_oauth2_authorize.value = parms[0]; - document.signin2.mod_oauth2_access_token.value = parms[1]; - document.signin2.mod_oauth2_client_id.value = parms[2]; - document.signin2.mod_oauth2_info.value = parms[3]; - document.signin2.action = oauthReferrer(); + clearauthcookie(); + document.signin2.oauth2_authorize.value = parms[0]; + document.signin2.oauth2_access_token.value = parms[1]; + document.signin2.oauth2_client_id.value = parms[2]; + document.signin2.oauth2_info.value = parms[3]; + document.signin2.oauth2_scope.value = parms[4]; + document.signin2.oauth2_display.value = parms[5]; + document.signin2.openauth_referrer.value = oauthReferrer(); + document.signin2.action = '/oauth2/authorize/'; document.signin2.submit(); } function withFacebook() { - var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'facebook.com', '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', 'email', 'page']; return parms; } function withGithub() { - 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']; + 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', 'email', '']; return parms; } function submitSignin1(w) { parms = w(); - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + window.location.hostname + '; path=/'; - document.cookie = reset; - document.signin1.mod_oauth1_request_token.value = parms[0]; - document.signin1.mod_oauth1_authorize.value = parms[1]; - document.signin1.mod_oauth1_access_token.value = parms[2]; - document.signin1.mod_oauth1_client_id.value = parms[3]; - document.signin1.mod_oauth1_info.value = parms[4]; - document.signin1.action = oauthReferrer(); + clearauthcookie(); + document.signin1.oauth1_request_token.value = parms[0]; + document.signin1.oauth1_authorize.value = parms[1]; + document.signin1.oauth1_access_token.value = parms[2]; + document.signin1.oauth1_client_id.value = parms[3]; + document.signin1.oauth1_info.value = parms[4]; + document.signin1.openauth_referrer.value = oauthReferrer(); + document.signin1.action = '/oauth1/authorize/'; document.signin1.submit(); } @@ -109,20 +119,22 @@ function withTwitter() { </form> <form name="signin2" action="/" method="GET"> -<input type="hidden" name="mod_oauth2_authorize" value=""/> -<input type="hidden" name="mod_oauth2_access_token" value=""/> -<input type="hidden" name="mod_oauth2_client_id" value=""/> -<input type="hidden" name="mod_oauth2_info" value=""/> -<input type="hidden" name="mod_oauth2_step" value="authorize"/> +<input type="hidden" name="oauth2_authorize" value=""/> +<input type="hidden" name="oauth2_access_token" value=""/> +<input type="hidden" name="oauth2_client_id" value=""/> +<input type="hidden" name="oauth2_info" value=""/> +<input type="hidden" name="oauth2_scope" value=""/> +<input type="hidden" name="oauth2_display" value=""/> +<input type="hidden" name="openauth_referrer" value=""/> </form> <form name="signin1" action="/" method="GET"> -<input type="hidden" name="mod_oauth1_request_token" value=""/> -<input type="hidden" name="mod_oauth1_authorize" value=""/> -<input type="hidden" name="mod_oauth1_access_token" value=""/> -<input type="hidden" name="mod_oauth1_client_id" value=""/> -<input type="hidden" name="mod_oauth1_info" value=""/> -<input type="hidden" name="mod_oauth1_step" value="authorize"/> +<input type="hidden" name="oauth1_request_token" value=""/> +<input type="hidden" name="oauth1_authorize" value=""/> +<input type="hidden" name="oauth1_access_token" value=""/> +<input type="hidden" name="oauth1_client_id" value=""/> +<input type="hidden" name="oauth1_info" value=""/> +<input type="hidden" name="openauth_referrer" value=""/> </form> </body> diff --git a/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html b/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html index 57484dc479..50d70f04e4 100644 --- a/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html +++ b/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html @@ -29,9 +29,16 @@ <h1>Sign in with a Form, an OpenID provider or an OAuth provider</h1> <script type="text/javascript"> +function clearauthcookie() { + document.cookie = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth1=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth2=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOpenIDAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + return true; +} + function submitFormSignin() { - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + window.location.hostname + '; path=/'; - document.cookie = reset; + clearauthcookie(); document.formSignin.httpd_location.value = '/'; document.formSignin.submit(); } @@ -50,7 +57,7 @@ function queryParams() { function openauthReferrer() { r = queryParams()['openauth_referrer']; if (typeof(r) == 'undefined') - return r; + return '/'; q = r.indexOf('?'); if (q > 0) return r.substring(0, q); @@ -62,8 +69,7 @@ if (typeof(openauthReferrer()) == 'undefined') { } function submitOpenIDSignin(w) { - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + window.location.hostname + '; path=/'; - document.cookie = reset; + clearauthcookie(); document.openIDSignin.openid_identifier.value = w(); document.openIDSignin.action = openauthReferrer(); document.openIDSignin.submit(); @@ -111,36 +117,38 @@ function withXRDSEndpoint() { function submitOAuth2Signin(w) { parms = w(); - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + window.location.hostname + '; path=/'; - document.cookie = reset; - document.oauth2Signin.mod_oauth2_authorize.value = parms[0]; - document.oauth2Signin.mod_oauth2_access_token.value = parms[1]; - document.oauth2Signin.mod_oauth2_client_id.value = parms[2]; - document.oauth2Signin.mod_oauth2_info.value = parms[3]; - document.oauth2Signin.action = openauthReferrer(); + clearauthcookie(); + document.oauth2Signin.oauth2_authorize.value = parms[0]; + document.oauth2Signin.oauth2_access_token.value = parms[1]; + document.oauth2Signin.oauth2_client_id.value = parms[2]; + document.oauth2Signin.oauth2_info.value = parms[3]; + document.oauth2Signin.oauth2_scope.value = parms[4]; + document.oauth2Signin.oauth2_display.value = parms[5]; + document.oauth2Signin.openauth_referrer.value = openauthReferrer(); + document.oauth2Signin.action = '/oauth2/authorize/'; document.oauth2Signin.submit(); } function withFacebook() { - var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'facebook.com', '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', 'email', 'page']; return parms; } function withGithub() { - 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']; + 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', 'email', '']; return parms; } function submitOAuth1Signin(w) { parms = w(); - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + window.location.hostname + '; path=/'; - document.cookie = reset; - document.oauth1Signin.mod_oauth1_request_token.value = parms[0]; - document.oauth1Signin.mod_oauth1_authorize.value = parms[1]; - document.oauth1Signin.mod_oauth1_access_token.value = parms[2]; - document.oauth1Signin.mod_oauth1_client_id.value = parms[3]; - document.oauth1Signin.mod_oauth1_info.value = parms[4]; - document.oauth1Signin.action = openauthReferrer(); + clearauthcookie(); + document.oauth1Signin.oauth1_request_token.value = parms[0]; + document.oauth1Signin.oauth1_authorize.value = parms[1]; + document.oauth1Signin.oauth1_access_token.value = parms[2]; + document.oauth1Signin.oauth1_client_id.value = parms[3]; + document.oauth1Signin.oauth1_info.value = parms[4]; + document.oauth1Signin.openauth_referrer.value = openauthReferrer(); + document.oauth1Signin.action = '/oauth1/authorize/'; document.oauth1Signin.submit(); } @@ -205,20 +213,22 @@ function withTwitter() { </form> <form name="oauth2Signin" action="/" method="GET"> -<input type="hidden" name="mod_oauth2_authorize" value=""/> -<input type="hidden" name="mod_oauth2_access_token" value=""/> -<input type="hidden" name="mod_oauth2_client_id" value=""/> -<input type="hidden" name="mod_oauth2_info" value=""/> -<input type="hidden" name="mod_oauth2_step" value="authorize"/> +<input type="hidden" name="oauth2_authorize" value=""/> +<input type="hidden" name="oauth2_access_token" value=""/> +<input type="hidden" name="oauth2_client_id" value=""/> +<input type="hidden" name="oauth2_info" value=""/> +<input type="hidden" name="oauth2_scope" value=""/> +<input type="hidden" name="oauth2_display" value=""/> +<input type="hidden" name="openauth_referrer" value=""/> </form> <form name="oauth1Signin" action="/" method="GET"> -<input type="hidden" name="mod_oauth1_request_token" value=""/> -<input type="hidden" name="mod_oauth1_authorize" value=""/> -<input type="hidden" name="mod_oauth1_access_token" value=""/> -<input type="hidden" name="mod_oauth1_client_id" value=""/> -<input type="hidden" name="mod_oauth1_info" value=""/> -<input type="hidden" name="mod_oauth1_step" value="authorize"/> +<input type="hidden" name="oauth1_request_token" value=""/> +<input type="hidden" name="oauth1_authorize" value=""/> +<input type="hidden" name="oauth1_access_token" value=""/> +<input type="hidden" name="oauth1_client_id" value=""/> +<input type="hidden" name="oauth1_info" value=""/> +<input type="hidden" name="openauth_referrer" value=""/> </form> </body> diff --git a/sca-cpp/trunk/modules/oauth/htdocs/logout/index.html b/sca-cpp/trunk/modules/oauth/htdocs/logout/index.html index 35172da07f..a9d2e628d7 100644 --- a/sca-cpp/trunk/modules/oauth/htdocs/logout/index.html +++ b/sca-cpp/trunk/modules/oauth/htdocs/logout/index.html @@ -31,9 +31,16 @@ <form name="signout" action="/login" method="GET"> <script type="text/javascript"> +function clearauthcookie() { + document.cookie = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth1=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth2=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOpenIDAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + return true; +} + function submitSignout() { - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + window.location.hostname + '; path=/'; - document.cookie = reset; + clearauthcookie(); document.signout.submit(); return true; } diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp index 1276ea4855..29fe756178 100644 --- a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp +++ b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp @@ -89,7 +89,7 @@ public: * Return the user info for a session. */ const failable<value> userInfo(const value& sid, const memcache::MemCached& mc) { - return memcache::get(mklist<value>("tuscanyOpenAuth", sid), mc); + return memcache::get(mklist<value>("tuscanyOAuth1", sid), mc); } /** @@ -174,25 +174,28 @@ const list<string> sign(const string& verb, const string& uri, const list<value> */ const failable<int> authorize(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys, const memcache::MemCached& mc) { // Extract authorize, access_token, client ID and info URIs - const list<value> req = assoc<value>("mod_oauth1_request_token", args); + const list<value> ref = assoc<value>("openauth_referrer", args); + if (isNil(ref) || isNil(cdr(ref))) + return mkfailure<int>("Missing openauth_referrer parameter"); + const list<value> req = assoc<value>("oauth1_request_token", args); if (isNil(req) || isNil(cdr(req))) - return mkfailure<int>("Missing mod_oauth1_request_token parameter"); - const list<value> auth = assoc<value>("mod_oauth1_authorize", args); + return mkfailure<int>("Missing oauth1_request_token parameter"); + const list<value> auth = assoc<value>("oauth1_authorize", args); if (isNil(auth) || isNil(cdr(auth))) - return mkfailure<int>("Missing mod_oauth1_authorize parameter"); - const list<value> tok = assoc<value>("mod_oauth1_access_token", args); + return mkfailure<int>("Missing oauth1_authorize parameter"); + const list<value> tok = assoc<value>("oauth1_access_token", args); if (isNil(tok) || isNil(cdr(tok))) - return mkfailure<int>("Missing mod_oauth1_access_token parameter"); - const list<value> cid = assoc<value>("mod_oauth1_client_id", args); + return mkfailure<int>("Missing oauth1_access_token parameter"); + const list<value> cid = assoc<value>("oauth1_client_id", args); if (isNil(cid) || isNil(cdr(cid))) - return mkfailure<int>("Missing mod_oauth1_client_id parameter"); - const list<value> info = assoc<value>("mod_oauth1_info", args); + return mkfailure<int>("Missing oauth1_client_id parameter"); + const list<value> info = assoc<value>("oauth1_info", args); if (isNil(info) || isNil(cdr(info))) - return mkfailure<int>("Missing mod_oauth1_info parameter"); + return mkfailure<int>("Missing oauth1_info parameter"); // Build the redirect URI - const list<list<value> > redirargs = mklist<list<value> >(mklist<value>("mod_oauth1_step", "access_token"), tok, cid, info); - const string redir = httpd::url(r->uri, r) + string("?") + http::queryString(redirargs); + const list<list<value> > redirargs = mklist<list<value> >(tok, cid, info, ref); + const string redir = httpd::url("/oauth1/access_token/", r) + string("?") + http::queryString(redirargs); debug(redir, "modoauth1::authorize::redir"); // Lookup client app configuration @@ -296,15 +299,18 @@ const failable<list<value> > profileUserInfo(const value& cid, const string& inf */ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys, const memcache::MemCached& mc) { // Extract access_token URI, client ID and verification code - const list<value> tok = assoc<value>("mod_oauth1_access_token", args); + const list<value> ref = assoc<value>("openauth_referrer", args); + if (isNil(ref) || isNil(cdr(ref))) + return mkfailure<int>("Missing openauth_referrer parameter"); + const list<value> tok = assoc<value>("oauth1_access_token", args); if (isNil(tok) || isNil(cdr(tok))) - return mkfailure<int>("Missing mod_oauth1_access_token parameter"); - const list<value> cid = assoc<value>("mod_oauth1_client_id", args); + return mkfailure<int>("Missing oauth1_access_token parameter"); + const list<value> cid = assoc<value>("oauth1_client_id", args); if (isNil(cid) || isNil(cdr(cid))) - return mkfailure<int>("Missing mod_oauth1_client_id parameter"); - const list<value> info = assoc<value>("mod_oauth1_info", args); + return mkfailure<int>("Missing oauth1_client_id parameter"); + const list<value> info = assoc<value>("oauth1_info", args); if (isNil(info) || isNil(cdr(info))) - return mkfailure<int>("Missing mod_oauth1_info parameter"); + return mkfailure<int>("Missing oauth1_info parameter"); const list<value> tv = assoc<value>("oauth_token", args); if (isNil(tv) || isNil(cdr(tv))) return mkfailure<int>("Missing oauth_token parameter"); @@ -372,14 +378,14 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, // Store user info in memcached keyed by session ID const value sid = string("OAuth1_") + mkrand(); - const failable<bool> prc = memcache::put(mklist<value>("tuscanyOpenAuth", sid), content(iv), mc); + const failable<bool> prc = memcache::put(mklist<value>("tuscanyOAuth1", sid), content(iv), mc); if (!hasContent(prc)) return mkfailure<int>(reason(prc)); // Send session ID to the client in a cookie - debug(c_str(openauth::cookie(sid, httpd::hostName(r))), "modoauth1::access_token::setcookie"); - apr_table_set(r->err_headers_out, "Set-Cookie", c_str(openauth::cookie(sid, httpd::hostName(r)))); - return httpd::externalRedirect(httpd::url(r->uri, r), r); + 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); } /** @@ -391,6 +397,7 @@ static int checkAuthn(request_rec *r) { if (!dc.enabled) return DECLINED; const char* atype = ap_auth_type(r); + debug(atype, "modopenauth::checkAuthn::auth_type"); if (atype == NULL || strcasecmp(atype, "Open")) return DECLINED; @@ -398,11 +405,11 @@ static int checkAuthn(request_rec *r) { gc_scoped_pool pool(r->pool); // Get the server configuration - httpdDebugRequest(r, "modoauth1::checkAuthn::input"); + debug_httpdRequest(r, "modoauth1::checkAuthn::input"); const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_oauth1); // Get session id from the request - const maybe<string> sid = openauth::sessionID(r); + const maybe<string> sid = openauth::sessionID(r, "TuscanyOAuth1"); if (hasContent(sid)) { // Decline if the session id was not created by this module if (substr(content(sid), 0, 7) != "OAuth1_") @@ -416,33 +423,25 @@ static int checkAuthn(request_rec *r) { } } - // Get the request args - const list<list<value> > args = httpd::queryArgs(r); - - // Decline if the request is for another authentication provider - if (!isNil(assoc<value>("openid_identifier", args))) - return DECLINED; - if (!isNil(assoc<value>("mod_oauth2_step", args))) - return DECLINED; - - // Determine the OAuth protocol flow step, conveniently passed - // around in a request arg - const list<value> sl = assoc<value>("mod_oauth1_step", args); - const value step = !isNil(sl) && !isNil(cdr(sl))? cadr(sl) : ""; - // Handle OAuth authorize request step - if (step == "authorize") { + 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 httpd::reportStatus(authorize(httpd::queryArgs(r), r, sc.appkeys, sc.mc)); } // Handle OAuth access_token request step - if (step == "access_token") { + if (string(r->uri) == "/oauth1/access_token/") { r->ap_auth_type = const_cast<char*>(atype); - return httpd::reportStatus(accessToken(args, r, sc.appkeys, sc.mc)); + return httpd::reportStatus(accessToken(httpd::queryArgs(r), r, sc.appkeys, sc.mc)); } - // Redirect to the login page + // Redirect to the login page, unless we have a session id from another module + if (hasContent(openauth::sessionID(r, "TuscanyOpenIDAuth")) || + hasContent(openauth::sessionID(r, "TuscanyOpenAuth")) || + hasContent(openauth::sessionID(r, "TuscanyOAuth2"))) + return DECLINED; + if ((substr(string(r->uri), 0, 8) == "/oauth2/") || !isNil(assoc<value>("openid_identifier", httpd::queryArgs(r)))) + return DECLINED; r->ap_auth_type = const_cast<char*>(atype); return httpd::reportStatus(openauth::login(dc.login, r)); } diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp index ace611d3dc..dbede7ed8b 100644 --- a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp +++ b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp @@ -83,7 +83,7 @@ public: * Return the user info for a session. */ const failable<value> userInfo(const value& sid, const memcache::MemCached& mc) { - return memcache::get(mklist<value>("tuscanyOpenAuth", sid), mc); + return memcache::get(mklist<value>("tuscanyOAuth2", sid), mc); } /** @@ -126,25 +126,35 @@ const failable<int> authenticated(const list<list<value> >& attrs, const list<li */ const failable<int> authorize(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys) { // Extract authorize, access_token, client ID and info URIs - const list<value> auth = assoc<value>("mod_oauth2_authorize", args); + const list<value> ref = assoc<value>("openauth_referrer", args); + if (isNil(ref) || isNil(cdr(ref))) + return mkfailure<int>("Missing openauth_referrer parameter"); + const list<value> auth = assoc<value>("oauth2_authorize", args); if (isNil(auth) || isNil(cdr(auth))) - return mkfailure<int>("Missing mod_oauth2_authorize parameter"); - const list<value> tok = assoc<value>("mod_oauth2_access_token", args); + return mkfailure<int>("Missing oauth2_authorize parameter"); + const list<value> tok = assoc<value>("oauth2_access_token", args); if (isNil(tok) || isNil(cdr(tok))) - return mkfailure<int>("Missing mod_oauth2_access_token parameter"); - const list<value> cid = assoc<value>("mod_oauth2_client_id", args); + return mkfailure<int>("Missing oauth2_access_token parameter"); + const list<value> cid = assoc<value>("oauth2_client_id", args); if (isNil(cid) || isNil(cdr(cid))) - return mkfailure<int>("Missing mod_oauth2_client_id parameter"); - const list<value> info = assoc<value>("mod_oauth2_info", args); + return mkfailure<int>("Missing oauth2_client_id parameter"); + const list<value> info = assoc<value>("oauth2_info", args); if (isNil(info) || isNil(cdr(info))) - return mkfailure<int>("Missing mod_oauth2_info parameter"); - const list<value> display = assoc<value>("mod_oauth2_display", args); + return mkfailure<int>("Missing oauth2_info parameter"); + const list<value> scope = assoc<value>("oauth2_scope", args); + if (isNil(scope) || isNil(cdr(scope))) + return mkfailure<int>("Missing oauth2_scope parameter"); + const list<value> display = assoc<value>("oauth2_display", args); // Build the redirect URI - const list<list<value> > rargs = mklist<list<value> >(mklist<value>("mod_oauth2_step", "access_token"), tok, cid, info); - const string redir = httpd::url(r->uri, r) + string("?") + http::queryString(rargs); + const string redir = httpd::url("/oauth2/access_token/", r); debug(redir, "modoauth2::authorize::redir"); + // Build the state URI + const list<list<value> > stargs = mklist<list<value> >(tok, cid, info, ref); + const string state = http::queryString(stargs); + debug(state, "modoauth2::authorize::state"); + // Lookup client app configuration const list<value> app = assoc<value>(cadr(cid), appkeys); if (isNil(app) || isNil(cdr(app))) @@ -153,7 +163,7 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co // Redirect to the authorize URI const list<value> adisplay = (isNil(display) || isNil(cdr(display)))? list<value>() : mklist<value>("display", cadr(display)); - const list<list<value> > aargs = mklist<list<value> >(mklist<value>("client_id", car(appkey)), mklist<value>("scope", "email"), adisplay, mklist<value>("redirect_uri", httpd::escape(redir))); + 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"); return httpd::externalRedirect(uri, r); @@ -172,16 +182,23 @@ 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 memcache::MemCached& mc) { - // Extract access_token URI, client ID and authorization code - const list<value> tok = assoc<value>("mod_oauth2_access_token", args); + // Extract access_token URI, client ID and authorization code parameters + const list<value> state = assoc<value>("state", args); + if (isNil(state) || isNil(cdr(state))) + return mkfailure<int>("Missing state parameter"); + const list<list<value> >& stargs = httpd::queryArgs(httpd::unescape(cadr(state))); + const list<value> ref = assoc<value>("openauth_referrer", stargs); + if (isNil(ref) || isNil(cdr(ref))) + return mkfailure<int>("Missing openauth_referrer parameter"); + const list<value> tok = assoc<value>("oauth2_access_token", stargs); if (isNil(tok) || isNil(cdr(tok))) - return mkfailure<int>("Missing mod_oauth2_access_token parameter"); - const list<value> cid = assoc<value>("mod_oauth2_client_id", args); + return mkfailure<int>("Missing oauth2_access_token parameter"); + const list<value> cid = assoc<value>("oauth2_client_id", stargs); if (isNil(cid) || isNil(cdr(cid))) - return mkfailure<int>("Missing mod_oauth2_client_id parameter"); - const list<value> info = assoc<value>("mod_oauth2_info", args); + return mkfailure<int>("Missing oauth2_client_id parameter"); + const list<value> info = assoc<value>("oauth2_info", stargs); if (isNil(info) || isNil(cdr(info))) - return mkfailure<int>("Missing mod_oauth2_info parameter"); + return mkfailure<int>("Missing oauth2_info parameter"); const list<value> code = assoc<value>("code", args); if (isNil(code) || isNil(cdr(code))) return mkfailure<int>("Missing code parameter"); @@ -193,19 +210,26 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, list<value> appkey = cadr(app); // Build the redirect URI - const list<list<value> > rargs = mklist<list<value> >(mklist<value>("mod_oauth2_step", "access_token"), tok, cid, info); - const string redir = httpd::url(r->uri, r) + string("?") + http::queryString(rargs); + const string redir = httpd::url("/oauth2/access_token/", r); debug(redir, "modoauth2::access_token::redir"); // Request access token - const list<list<value> > targs = mklist<list<value> >(mklist<value>("client_id", car(appkey)), mklist<value>("redirect_uri", httpd::escape(redir)), mklist<value>("client_secret", cadr(appkey)), code); - const string turi = httpd::unescape(cadr(tok)) + string("?") + http::queryString(targs); + const list<list<value> > targs = mklist<list<value> >(mklist<value>("client_id", car(appkey)), mklist<value>("redirect_uri", httpd::escape(redir)), mklist<value>("client_secret", cadr(appkey)), code, mklist<value>("grant_type", "authorization_code")); + const string tqs = http::queryString(targs); + debug(tqs, "modoauth2::access_token::tokenqs"); + const string turi = httpd::unescape(cadr(tok)); debug(turi, "modoauth2::access_token::tokenuri"); - const failable<value> tr = http::get(turi, *(cs)); - if (!hasContent(tr)) - return mkfailure<int>(reason(tr)); + 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)); + if (!hasContent(ftr)) + return mkfailure<int>(reason(ftr)); + const value tr = content(ftr); debug(tr, "modoauth2::access_token::response"); - const list<value> tv = assoc<value>("access_token", httpd::queryArgs(join("", convertValues<string>(cadr<value>(content(tr)))))); + if (!isList(tr) || isNil(tr)) + return mkfailure<int>("Empty access token"); + const list<value> tv = isString(car<value>(tr)) ? + assoc<value>("access_token", httpd::queryArgs(join("", convertValues<string>(cadr<value>(tr))))) : + assoc<value>("access_token", tr); if (isNil(tv) || isNil(cdr(tv))) return mkfailure<int>("Couldn't retrieve access_token"); debug(tv, "modoauth2::access_token::token"); @@ -227,14 +251,14 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r, // Store user info in memcached keyed by session ID const value sid = string("OAuth2_") + mkrand(); - const failable<bool> prc = memcache::put(mklist<value>("tuscanyOpenAuth", sid), content(iv), mc); + const failable<bool> prc = memcache::put(mklist<value>("tuscanyOAuth2", sid), content(iv), mc); if (!hasContent(prc)) return mkfailure<int>(reason(prc)); // Send session ID to the client in a cookie - debug(c_str(openauth::cookie(sid, httpd::hostName(r))), "modoauth2::access_token::setcookie"); - apr_table_set(r->err_headers_out, "Set-Cookie", c_str(openauth::cookie(sid, httpd::hostName(r)))); - return httpd::externalRedirect(httpd::url(r->uri, r), r); + debug(c_str(openauth::cookie("TuscanyOAuth2", sid, httpd::hostName(r))), "modoauth2::access_token::setcookie"); + apr_table_set(r->err_headers_out, "Set-Cookie", c_str(openauth::cookie("TuscanyOAuth2", sid, httpd::hostName(r)))); + return httpd::externalRedirect(httpd::url(httpd::unescape(cadr(ref)), r), r); } /** @@ -246,6 +270,7 @@ static int checkAuthn(request_rec *r) { if (!dc.enabled) return DECLINED; const char* atype = ap_auth_type(r); + debug(atype, "modopenauth::checkAuthn::auth_type"); if (atype == NULL || strcasecmp(atype, "Open")) return DECLINED; @@ -253,11 +278,11 @@ static int checkAuthn(request_rec *r) { gc_scoped_pool pool(r->pool); // Get the server configuration - httpdDebugRequest(r, "modoauth2::checkAuthn::input"); + debug_httpdRequest(r, "modoauth2::checkAuthn::input"); const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_oauth2); // Get session id from the request - const maybe<string> sid = openauth::sessionID(r); + const maybe<string> sid = openauth::sessionID(r, "TuscanyOAuth2"); if (hasContent(sid)) { // Decline if the session id was not created by this module if (substr(content(sid), 0, 7) != "OAuth2_") @@ -271,33 +296,25 @@ static int checkAuthn(request_rec *r) { } } - // Get the request args - const list<list<value> > args = httpd::queryArgs(r); - - // Decline if the request is for another authentication provider - if (!isNil(assoc<value>("openid_identifier", args))) - return DECLINED; - if (!isNil(assoc<value>("mod_oauth1_step", args))) - return DECLINED; - - // Determine the OAuth protocol flow step, conveniently passed - // around in a request arg - const list<value> sl = assoc<value>("mod_oauth2_step", args); - const value step = !isNil(sl) && !isNil(cdr(sl))? cadr(sl) : ""; - // Handle OAuth authorize request step - if (step == "authorize") { + if (string(r->uri) == "/oauth2/authorize/") { r->ap_auth_type = const_cast<char*>(atype); - return httpd::reportStatus(authorize(args, r, sc.appkeys)); + return httpd::reportStatus(authorize(httpd::queryArgs(r), r, sc.appkeys)); } // Handle OAuth access_token request step - if (step == "access_token") { + if (string(r->uri) == "/oauth2/access_token/") { r->ap_auth_type = const_cast<char*>(atype); - return httpd::reportStatus(accessToken(args, r, sc.appkeys, sc.cs, sc.mc)); + return httpd::reportStatus(accessToken(httpd::queryArgs(r), r, sc.appkeys, sc.cs, sc.mc)); } - // Redirect to the login page + // Redirect to the login page, unless we have a session id from another module + if (hasContent(openauth::sessionID(r, "TuscanyOpenIDAuth")) || + hasContent(openauth::sessionID(r, "TuscanyOpenAuth")) || + hasContent(openauth::sessionID(r, "TuscanyOAuth1"))) + return DECLINED; + if ((substr(string(r->uri), 0, 8) == "/oauth1/") || !isNil(assoc<value>("openid_identifier", httpd::queryArgs(r)))) + return DECLINED; r->ap_auth_type = const_cast<char*>(atype); return httpd::reportStatus(openauth::login(dc.login, r)); } diff --git a/sca-cpp/trunk/modules/oauth/start-mixed-test b/sca-cpp/trunk/modules/oauth/start-mixed-test index d0c184144b..11bba42ef0 100755 --- a/sca-cpp/trunk/modules/oauth/start-mixed-test +++ b/sca-cpp/trunk/modules/oauth/start-mixed-test @@ -17,6 +17,9 @@ # specific language governing permissions and limitations # under the License. +# For this module to work, add the www.example.com domain to your /etc/hosts as follows: +# 127.0.0.1 www.example.com + # Test supporting both OpenID and OAuth in the same app here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here` @@ -24,14 +27,19 @@ here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $h ../../components/cache/memcached-start tmp 11212 ../../components/cache/memcached-start tmp 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/ssl-ca-conf tmp www.example.com +../../modules/http/ssl-cert-conf tmp www.example.com +../../modules/http/httpd-conf tmp www.example.com 8090 htdocs ../../modules/http/httpd-ssl-conf tmp 8453 +../openid/openid-conf tmp +../openid/openid-step2-conf tmp +../openid/openid-memcached-conf tmp www.example.com 11212 +../openid/openid-memcached-conf tmp www.example.com 11213 + ./oauth-conf tmp -./oauth-memcached-conf tmp localhost 11212 -./oauth-memcached-conf tmp localhost 11213 +./oauth-memcached-conf tmp www.example.com 11212 +./oauth-memcached-conf tmp www.example.com 11213 # Configure your app keys here ./oauth1-appkey-conf tmp twitter.com app2345 secret7890 @@ -39,11 +47,6 @@ here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $h ./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 -../openid/openid-memcached-conf tmp localhost 11212 -../openid/openid-memcached-conf tmp localhost 11213 - ../http/open-auth-conf tmp ../http/passwd-auth-conf tmp foo foo @@ -51,7 +54,7 @@ here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $h # to the authorized user group ../../modules/http/group-auth-conf tmp foo ../../modules/http/group-auth-conf tmp 123456 -../../modules/http/group-auth-conf tmp https://www.google.com/accounts/o8/id?id=12345678 +../../modules/http/group-auth-conf tmp jane@example.com ../../modules/server/server-conf tmp ../../modules/server/scheme-conf tmp diff --git a/sca-cpp/trunk/modules/oauth/start-test b/sca-cpp/trunk/modules/oauth/start-test index d38f8d3d1a..21e1e005bd 100755 --- a/sca-cpp/trunk/modules/oauth/start-test +++ b/sca-cpp/trunk/modules/oauth/start-test @@ -17,21 +17,24 @@ # specific language governing permissions and limitations # under the License. +# For this module to work, add the www.example.com domain to your /etc/hosts as follows: +# 127.0.0.1 www.example.com + # Setup -../../ubuntu/ip-redirect-all 80 8090 -../../ubuntu/ip-redirect-all 443 8453 +#../../ubuntu/ip-redirect-all 80 8090 +#../../ubuntu/ip-redirect-all 443 8453 ../../components/cache/memcached-start tmp 11212 ../../components/cache/memcached-start tmp 11213 -../../modules/http/ssl-ca-conf tmp localhost -../../modules/http/ssl-cert-conf tmp localhost -../../modules/http/httpd-conf tmp localhost 8090/80 htdocs -../../modules/http/httpd-ssl-conf tmp 8453/443 +../../modules/http/ssl-ca-conf tmp www.example.com +../../modules/http/ssl-cert-conf tmp www.example.com +../../modules/http/httpd-conf tmp www.example.com 8090 htdocs +../../modules/http/httpd-ssl-conf tmp 8453 ./oauth-conf tmp -./oauth-memcached-conf tmp localhost 11212 -./oauth-memcached-conf tmp localhost 11213 +./oauth-memcached-conf tmp www.example.com 11212 +./oauth-memcached-conf tmp www.example.com 11213 # Configure your app keys here ./oauth1-appkey-conf tmp twitter.com app2345 secret7890 @@ -41,7 +44,7 @@ # For this test to work you need to add your oauth user id to the # authorized user group -../../modules/http/group-auth-conf tmp 123456 +../../modules/http/group-auth-conf tmp jane@example.com ../../modules/server/server-conf tmp ../../modules/server/scheme-conf tmp diff --git a/sca-cpp/trunk/modules/openid/htdocs/login/index.html b/sca-cpp/trunk/modules/openid/htdocs/login/index.html index dcb10e111f..47fbb73204 100644 --- a/sca-cpp/trunk/modules/openid/htdocs/login/index.html +++ b/sca-cpp/trunk/modules/openid/htdocs/login/index.html @@ -55,9 +55,16 @@ if (typeof(openidReferrer()) == 'undefined') { document.location = '/'; } +function clearauthcookie() { + document.cookie = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth1=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth2=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOpenIDAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + return true; +} + function submitSignin(w) { - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + window.location.hostname + '; path=/'; - document.cookie = reset; + clearauthcookie(); document.signin.openid_identifier.value = w(); document.signin.action = openidReferrer(); document.signin.submit(); diff --git a/sca-cpp/trunk/modules/openid/htdocs/logout/index.html b/sca-cpp/trunk/modules/openid/htdocs/logout/index.html index 35172da07f..a9d2e628d7 100644 --- a/sca-cpp/trunk/modules/openid/htdocs/logout/index.html +++ b/sca-cpp/trunk/modules/openid/htdocs/logout/index.html @@ -31,9 +31,16 @@ <form name="signout" action="/login" method="GET"> <script type="text/javascript"> +function clearauthcookie() { + document.cookie = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth1=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOAuth2=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + document.cookie = 'TuscanyOpenIDAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/'; + return true; +} + function submitSignout() { - var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + window.location.hostname + '; path=/'; - document.cookie = reset; + clearauthcookie(); document.signout.submit(); return true; } diff --git a/sca-cpp/trunk/modules/openid/openid-conf b/sca-cpp/trunk/modules/openid/openid-conf index f4f715ce99..d07e4b7cad 100755 --- a/sca-cpp/trunk/modules/openid/openid-conf +++ b/sca-cpp/trunk/modules/openid/openid-conf @@ -58,7 +58,7 @@ AuthName "$host" Require valid-user AuthOpenIDEnabled On AuthOpenIDCookiePath / -AuthOpenIDCookieName TuscanyOpenAuth +AuthOpenIDCookieName TuscanyOpenIDAuth AuthOpenIDLoginPage /login/ AuthOpenIDAXAdd REMOTE_USER http://axschema.org/contact/email AuthOpenIDAXAdd EMAIL http://axschema.org/contact/email diff --git a/sca-cpp/trunk/modules/openid/start-test b/sca-cpp/trunk/modules/openid/start-test index 195e1c3c98..5cac1dbe14 100755 --- a/sca-cpp/trunk/modules/openid/start-test +++ b/sca-cpp/trunk/modules/openid/start-test @@ -31,9 +31,9 @@ ./openid-memcached-conf tmp localhost 11213 ./openid-step2-conf tmp -# For this test to work you need to add your openid to the -# the authorized user group -../../modules/http/group-auth-conf tmp https://www.google.com/accounts/o8/id?id=1234567 +# For this test to work you need to add your openid (or email address if +# available from your openid attributes to the the authorized user group +../../modules/http/group-auth-conf tmp jane@example.com ../../modules/server/server-conf tmp ../../modules/server/scheme-conf tmp diff --git a/sca-cpp/trunk/samples/store-cluster/domains/jane/htdocs/login/index.html b/sca-cpp/trunk/samples/store-cluster/domains/jane/htdocs/login/index.html index 5bdd1132be..fcad40bf8a 100644 --- a/sca-cpp/trunk/samples/store-cluster/domains/jane/htdocs/login/index.html +++ b/sca-cpp/trunk/samples/store-cluster/domains/jane/htdocs/login/index.html @@ -45,7 +45,7 @@ function queryParams() { function openauthReferrer() { r = queryParams()['openauth_referrer']; if (typeof(r) == 'undefined') - return r; + return '/'; q = r.indexOf('?'); if (q > 0) return r.substring(0, q); @@ -57,8 +57,7 @@ if (typeof(openauthReferrer()) == 'undefined') { } function submitOpenIDSignin(w) { - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; + clearauthcookie(); document.openIDSignin.openid_identifier.value = w(); document.openIDSignin.action = openauthReferrer(); document.openIDSignin.submit(); @@ -106,46 +105,48 @@ function withXRDSEndpoint() { function submitOAuth2Signin(w) { parms = w(); - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; - document.oauth2Signin.mod_oauth2_authorize.value = parms[0]; - document.oauth2Signin.mod_oauth2_access_token.value = parms[1]; - document.oauth2Signin.mod_oauth2_client_id.value = parms[2]; - document.oauth2Signin.mod_oauth2_info.value = parms[3]; - document.oauth2Signin.action = openauthReferrer(); + clearauthcookie(); + document.oauth2Signin.oauth2_authorize.value = parms[0]; + document.oauth2Signin.oauth2_access_token.value = parms[1]; + document.oauth2Signin.oauth2_client_id.value = parms[2]; + document.oauth2Signin.oauth2_info.value = parms[3]; + document.oauth2Signin.oauth2_scope.value = parms[4]; + document.oauth2Signin.oauth2_display.value = parms[5]; + document.oauth2Signin.openauth_referrer.value = openauthReferrer(); + document.oauth2Signin.action = '/oauth2/authorize/'; document.oauth2Signin.submit(); } 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', 'email', 'page']; 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', 'email', '']; return parms; } function submitOAuth1Signin(w) { parms = w(); - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; - document.oauth1Signin.mod_oauth1_request_token.value = parms[0]; - document.oauth1Signin.mod_oauth1_authorize.value = parms[1]; - document.oauth1Signin.mod_oauth1_access_token.value = parms[2]; - document.oauth1Signin.mod_oauth1_client_id.value = parms[3]; - document.oauth1Signin.mod_oauth1_info.value = parms[4]; - document.oauth1Signin.action = openauthReferrer(); + clearauthcookie(); + document.oauth1Signin.oauth1_request_token.value = parms[0]; + document.oauth1Signin.oauth1_authorize.value = parms[1]; + document.oauth1Signin.oauth1_access_token.value = parms[2]; + document.oauth1Signin.oauth1_client_id.value = parms[3]; + document.oauth1Signin.oauth1_info.value = parms[4]; + document.oauth1Signin.openauth_referrer.value = openauthReferrer(); + document.oauth1Signin.action = '/oauth1/authorize/'; document.oauth1Signin.submit(); } 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> @@ -189,20 +190,22 @@ function withTwitter() { </form> <form name="oauth2Signin" action="/" method="GET"> -<input type="hidden" name="mod_oauth2_authorize" value=""/> -<input type="hidden" name="mod_oauth2_access_token" value=""/> -<input type="hidden" name="mod_oauth2_client_id" value=""/> -<input type="hidden" name="mod_oauth2_info" value=""/> -<input type="hidden" name="mod_oauth2_step" value="authorize"/> +<input type="hidden" name="oauth2_authorize" value=""/> +<input type="hidden" name="oauth2_access_token" value=""/> +<input type="hidden" name="oauth2_client_id" value=""/> +<input type="hidden" name="oauth2_info" value=""/> +<input type="hidden" name="oauth2_scope" value=""/> +<input type="hidden" name="oauth2_display" value=""/> +<input type="hidden" name="openauth_referrer" value=""/> </form> <form name="oauth1Signin" action="/" method="GET"> -<input type="hidden" name="mod_oauth1_request_token" value=""/> -<input type="hidden" name="mod_oauth1_authorize" value=""/> -<input type="hidden" name="mod_oauth1_access_token" value=""/> -<input type="hidden" name="mod_oauth1_client_id" value=""/> -<input type="hidden" name="mod_oauth1_info" value=""/> -<input type="hidden" name="mod_oauth1_step" value="authorize"/> +<input type="hidden" name="oauth1_request_token" value=""/> +<input type="hidden" name="oauth1_authorize" value=""/> +<input type="hidden" name="oauth1_access_token" value=""/> +<input type="hidden" name="oauth1_client_id" value=""/> +<input type="hidden" name="oauth1_info" value=""/> +<input type="hidden" name="openauth_referrer" value=""/> </form> </body> diff --git a/sca-cpp/trunk/samples/store-cluster/domains/jane/htdocs/logout/index.html b/sca-cpp/trunk/samples/store-cluster/domains/jane/htdocs/logout/index.html index 56dfa71962..91608a6523 100644 --- a/sca-cpp/trunk/samples/store-cluster/domains/jane/htdocs/logout/index.html +++ b/sca-cpp/trunk/samples/store-cluster/domains/jane/htdocs/logout/index.html @@ -33,8 +33,7 @@ <form name="signout" action="/login" method="GET"> <script type="text/javascript"> function submitSignout() { - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; + clearauthcookie(); document.signout.submit(); return true; } diff --git a/sca-cpp/trunk/samples/store-cluster/domains/joe/htdocs/login/index.html b/sca-cpp/trunk/samples/store-cluster/domains/joe/htdocs/login/index.html index 5bdd1132be..fcad40bf8a 100644 --- a/sca-cpp/trunk/samples/store-cluster/domains/joe/htdocs/login/index.html +++ b/sca-cpp/trunk/samples/store-cluster/domains/joe/htdocs/login/index.html @@ -45,7 +45,7 @@ function queryParams() { function openauthReferrer() { r = queryParams()['openauth_referrer']; if (typeof(r) == 'undefined') - return r; + return '/'; q = r.indexOf('?'); if (q > 0) return r.substring(0, q); @@ -57,8 +57,7 @@ if (typeof(openauthReferrer()) == 'undefined') { } function submitOpenIDSignin(w) { - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; + clearauthcookie(); document.openIDSignin.openid_identifier.value = w(); document.openIDSignin.action = openauthReferrer(); document.openIDSignin.submit(); @@ -106,46 +105,48 @@ function withXRDSEndpoint() { function submitOAuth2Signin(w) { parms = w(); - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; - document.oauth2Signin.mod_oauth2_authorize.value = parms[0]; - document.oauth2Signin.mod_oauth2_access_token.value = parms[1]; - document.oauth2Signin.mod_oauth2_client_id.value = parms[2]; - document.oauth2Signin.mod_oauth2_info.value = parms[3]; - document.oauth2Signin.action = openauthReferrer(); + clearauthcookie(); + document.oauth2Signin.oauth2_authorize.value = parms[0]; + document.oauth2Signin.oauth2_access_token.value = parms[1]; + document.oauth2Signin.oauth2_client_id.value = parms[2]; + document.oauth2Signin.oauth2_info.value = parms[3]; + document.oauth2Signin.oauth2_scope.value = parms[4]; + document.oauth2Signin.oauth2_display.value = parms[5]; + document.oauth2Signin.openauth_referrer.value = openauthReferrer(); + document.oauth2Signin.action = '/oauth2/authorize/'; document.oauth2Signin.submit(); } 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', 'email', 'page']; 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', 'email', '']; return parms; } function submitOAuth1Signin(w) { parms = w(); - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; - document.oauth1Signin.mod_oauth1_request_token.value = parms[0]; - document.oauth1Signin.mod_oauth1_authorize.value = parms[1]; - document.oauth1Signin.mod_oauth1_access_token.value = parms[2]; - document.oauth1Signin.mod_oauth1_client_id.value = parms[3]; - document.oauth1Signin.mod_oauth1_info.value = parms[4]; - document.oauth1Signin.action = openauthReferrer(); + clearauthcookie(); + document.oauth1Signin.oauth1_request_token.value = parms[0]; + document.oauth1Signin.oauth1_authorize.value = parms[1]; + document.oauth1Signin.oauth1_access_token.value = parms[2]; + document.oauth1Signin.oauth1_client_id.value = parms[3]; + document.oauth1Signin.oauth1_info.value = parms[4]; + document.oauth1Signin.openauth_referrer.value = openauthReferrer(); + document.oauth1Signin.action = '/oauth1/authorize/'; document.oauth1Signin.submit(); } 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> @@ -189,20 +190,22 @@ function withTwitter() { </form> <form name="oauth2Signin" action="/" method="GET"> -<input type="hidden" name="mod_oauth2_authorize" value=""/> -<input type="hidden" name="mod_oauth2_access_token" value=""/> -<input type="hidden" name="mod_oauth2_client_id" value=""/> -<input type="hidden" name="mod_oauth2_info" value=""/> -<input type="hidden" name="mod_oauth2_step" value="authorize"/> +<input type="hidden" name="oauth2_authorize" value=""/> +<input type="hidden" name="oauth2_access_token" value=""/> +<input type="hidden" name="oauth2_client_id" value=""/> +<input type="hidden" name="oauth2_info" value=""/> +<input type="hidden" name="oauth2_scope" value=""/> +<input type="hidden" name="oauth2_display" value=""/> +<input type="hidden" name="openauth_referrer" value=""/> </form> <form name="oauth1Signin" action="/" method="GET"> -<input type="hidden" name="mod_oauth1_request_token" value=""/> -<input type="hidden" name="mod_oauth1_authorize" value=""/> -<input type="hidden" name="mod_oauth1_access_token" value=""/> -<input type="hidden" name="mod_oauth1_client_id" value=""/> -<input type="hidden" name="mod_oauth1_info" value=""/> -<input type="hidden" name="mod_oauth1_step" value="authorize"/> +<input type="hidden" name="oauth1_request_token" value=""/> +<input type="hidden" name="oauth1_authorize" value=""/> +<input type="hidden" name="oauth1_access_token" value=""/> +<input type="hidden" name="oauth1_client_id" value=""/> +<input type="hidden" name="oauth1_info" value=""/> +<input type="hidden" name="openauth_referrer" value=""/> </form> </body> diff --git a/sca-cpp/trunk/samples/store-cluster/domains/joe/htdocs/logout/index.html b/sca-cpp/trunk/samples/store-cluster/domains/joe/htdocs/logout/index.html index 5f7880d626..91608a6523 100644 --- a/sca-cpp/trunk/samples/store-cluster/domains/joe/htdocs/logout/index.html +++ b/sca-cpp/trunk/samples/store-cluster/domains/joe/htdocs/logout/index.html @@ -33,12 +33,12 @@ <form name="signout" action="/login" method="GET"> <script type="text/javascript"> function submitSignout() { - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; + clearauthcookie(); document.signout.submit(); return true; } </script> <input type="button" onclick="submitSignout()" value="Sign out"/> </form> -</body></html> +</body> +</html> diff --git a/sca-cpp/trunk/samples/store-cluster/htdocs/login/index.html b/sca-cpp/trunk/samples/store-cluster/htdocs/login/index.html index 5bdd1132be..fcad40bf8a 100644 --- a/sca-cpp/trunk/samples/store-cluster/htdocs/login/index.html +++ b/sca-cpp/trunk/samples/store-cluster/htdocs/login/index.html @@ -45,7 +45,7 @@ function queryParams() { function openauthReferrer() { r = queryParams()['openauth_referrer']; if (typeof(r) == 'undefined') - return r; + return '/'; q = r.indexOf('?'); if (q > 0) return r.substring(0, q); @@ -57,8 +57,7 @@ if (typeof(openauthReferrer()) == 'undefined') { } function submitOpenIDSignin(w) { - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; + clearauthcookie(); document.openIDSignin.openid_identifier.value = w(); document.openIDSignin.action = openauthReferrer(); document.openIDSignin.submit(); @@ -106,46 +105,48 @@ function withXRDSEndpoint() { function submitOAuth2Signin(w) { parms = w(); - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; - document.oauth2Signin.mod_oauth2_authorize.value = parms[0]; - document.oauth2Signin.mod_oauth2_access_token.value = parms[1]; - document.oauth2Signin.mod_oauth2_client_id.value = parms[2]; - document.oauth2Signin.mod_oauth2_info.value = parms[3]; - document.oauth2Signin.action = openauthReferrer(); + clearauthcookie(); + document.oauth2Signin.oauth2_authorize.value = parms[0]; + document.oauth2Signin.oauth2_access_token.value = parms[1]; + document.oauth2Signin.oauth2_client_id.value = parms[2]; + document.oauth2Signin.oauth2_info.value = parms[3]; + document.oauth2Signin.oauth2_scope.value = parms[4]; + document.oauth2Signin.oauth2_display.value = parms[5]; + document.oauth2Signin.openauth_referrer.value = openauthReferrer(); + document.oauth2Signin.action = '/oauth2/authorize/'; document.oauth2Signin.submit(); } 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', 'email', 'page']; 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', 'email', '']; return parms; } function submitOAuth1Signin(w) { parms = w(); - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; - document.oauth1Signin.mod_oauth1_request_token.value = parms[0]; - document.oauth1Signin.mod_oauth1_authorize.value = parms[1]; - document.oauth1Signin.mod_oauth1_access_token.value = parms[2]; - document.oauth1Signin.mod_oauth1_client_id.value = parms[3]; - document.oauth1Signin.mod_oauth1_info.value = parms[4]; - document.oauth1Signin.action = openauthReferrer(); + clearauthcookie(); + document.oauth1Signin.oauth1_request_token.value = parms[0]; + document.oauth1Signin.oauth1_authorize.value = parms[1]; + document.oauth1Signin.oauth1_access_token.value = parms[2]; + document.oauth1Signin.oauth1_client_id.value = parms[3]; + document.oauth1Signin.oauth1_info.value = parms[4]; + document.oauth1Signin.openauth_referrer.value = openauthReferrer(); + document.oauth1Signin.action = '/oauth1/authorize/'; document.oauth1Signin.submit(); } 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> @@ -189,20 +190,22 @@ function withTwitter() { </form> <form name="oauth2Signin" action="/" method="GET"> -<input type="hidden" name="mod_oauth2_authorize" value=""/> -<input type="hidden" name="mod_oauth2_access_token" value=""/> -<input type="hidden" name="mod_oauth2_client_id" value=""/> -<input type="hidden" name="mod_oauth2_info" value=""/> -<input type="hidden" name="mod_oauth2_step" value="authorize"/> +<input type="hidden" name="oauth2_authorize" value=""/> +<input type="hidden" name="oauth2_access_token" value=""/> +<input type="hidden" name="oauth2_client_id" value=""/> +<input type="hidden" name="oauth2_info" value=""/> +<input type="hidden" name="oauth2_scope" value=""/> +<input type="hidden" name="oauth2_display" value=""/> +<input type="hidden" name="openauth_referrer" value=""/> </form> <form name="oauth1Signin" action="/" method="GET"> -<input type="hidden" name="mod_oauth1_request_token" value=""/> -<input type="hidden" name="mod_oauth1_authorize" value=""/> -<input type="hidden" name="mod_oauth1_access_token" value=""/> -<input type="hidden" name="mod_oauth1_client_id" value=""/> -<input type="hidden" name="mod_oauth1_info" value=""/> -<input type="hidden" name="mod_oauth1_step" value="authorize"/> +<input type="hidden" name="oauth1_request_token" value=""/> +<input type="hidden" name="oauth1_authorize" value=""/> +<input type="hidden" name="oauth1_access_token" value=""/> +<input type="hidden" name="oauth1_client_id" value=""/> +<input type="hidden" name="oauth1_info" value=""/> +<input type="hidden" name="openauth_referrer" value=""/> </form> </body> diff --git a/sca-cpp/trunk/samples/store-cluster/htdocs/logout/index.html b/sca-cpp/trunk/samples/store-cluster/htdocs/logout/index.html index 56dfa71962..91608a6523 100644 --- a/sca-cpp/trunk/samples/store-cluster/htdocs/logout/index.html +++ b/sca-cpp/trunk/samples/store-cluster/htdocs/logout/index.html @@ -33,8 +33,7 @@ <form name="signout" action="/login" method="GET"> <script type="text/javascript"> function submitSignout() { - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; + clearauthcookie(); document.signout.submit(); return true; } diff --git a/sca-cpp/trunk/samples/store-python/htdocs/login/index.html b/sca-cpp/trunk/samples/store-python/htdocs/login/index.html index 99aeb31d1b..5c5286f7c4 100644 --- a/sca-cpp/trunk/samples/store-python/htdocs/login/index.html +++ b/sca-cpp/trunk/samples/store-python/htdocs/login/index.html @@ -32,8 +32,7 @@ <script type="text/javascript"> function submitFormSignin() { - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; + clearauthcookie(); document.formSignin.httpd_location.value = '/'; document.formSignin.submit(); } diff --git a/sca-cpp/trunk/samples/store-python/htdocs/logout/index.html b/sca-cpp/trunk/samples/store-python/htdocs/logout/index.html index 5f7880d626..452fa7399d 100644 --- a/sca-cpp/trunk/samples/store-python/htdocs/logout/index.html +++ b/sca-cpp/trunk/samples/store-python/htdocs/logout/index.html @@ -33,8 +33,7 @@ <form name="signout" action="/login" method="GET"> <script type="text/javascript"> function submitSignout() { - var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE'; - document.cookie = reset; + clearauthcookie(); document.signout.submit(); return true; } |