summaryrefslogtreecommitdiffstats
path: root/sca-cpp
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-11-03 16:39:53 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-11-03 16:39:53 +0000
commit034b527d25626a4812fc696c3878744695c23a0b (patch)
tree5d7d9c3dfadba189d359f5ef4e12e135ad3a7317 /sca-cpp
parentd63c8ad1885acb086a2947502a3beeded8f5dd05 (diff)
Improvements to OAuth and OpenID modules. Store client app in an environment variable. Add support for more OAuth providers. Fix a cookie parsing bug.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1030524 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-cpp')
-rwxr-xr-xsca-cpp/trunk/modules/http/httpd-ssl-conf4
-rw-r--r--sca-cpp/trunk/modules/oauth/Makefile.am2
-rw-r--r--sca-cpp/trunk/modules/oauth/htdocs/index.html9
-rw-r--r--sca-cpp/trunk/modules/oauth/htdocs/login/index.html8
-rw-r--r--sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html8
-rw-r--r--sca-cpp/trunk/modules/oauth/htdocs/public/index.html (renamed from sca-cpp/trunk/modules/oauth/htdocs/unprotected/index.html)0
-rw-r--r--sca-cpp/trunk/modules/oauth/mod-oauth1.cpp44
-rw-r--r--sca-cpp/trunk/modules/oauth/mod-oauth2.cpp20
-rwxr-xr-xsca-cpp/trunk/modules/oauth/oauth-conf7
-rw-r--r--sca-cpp/trunk/modules/oauth/oauth.composite1
-rw-r--r--sca-cpp/trunk/modules/oauth/oauth.hpp7
-rwxr-xr-xsca-cpp/trunk/modules/oauth/start-mixed-test8
-rwxr-xr-xsca-cpp/trunk/modules/oauth/start-test20
-rw-r--r--sca-cpp/trunk/modules/oauth/user-info.scm18
-rw-r--r--sca-cpp/trunk/modules/openid/Makefile.am2
-rw-r--r--sca-cpp/trunk/modules/openid/htdocs/index.html11
-rw-r--r--sca-cpp/trunk/modules/openid/htdocs/public/index.html (renamed from sca-cpp/trunk/modules/openid/htdocs/unprotected/index.html)0
-rwxr-xr-xsca-cpp/trunk/modules/openid/openid-conf7
-rw-r--r--sca-cpp/trunk/modules/openid/openid.composite1
-rw-r--r--sca-cpp/trunk/modules/openid/user-info.scm10
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.hpp2
-rw-r--r--sca-cpp/trunk/modules/wsgi/scdl.py6
-rw-r--r--sca-cpp/trunk/samples/loan-python/Makefile.am28
-rw-r--r--sca-cpp/trunk/samples/loan-python/htdocs/index.html156
-rw-r--r--sca-cpp/trunk/samples/loan-python/loan-approval.py77
-rw-r--r--sca-cpp/trunk/samples/loan-python/loan.composite46
-rw-r--r--sca-cpp/trunk/samples/loan-python/loan.py45
-rwxr-xr-xsca-cpp/trunk/samples/loan-python/server-test58
-rwxr-xr-xsca-cpp/trunk/samples/loan-python/start31
-rwxr-xr-xsca-cpp/trunk/samples/loan-python/stop21
-rw-r--r--sca-cpp/trunk/samples/loan-python/util.py145
-rw-r--r--sca-cpp/trunk/samples/store-cluster/htdocs/domains/jane/login/index.html69
-rw-r--r--sca-cpp/trunk/samples/store-cluster/htdocs/domains/joe/login/index.html69
-rw-r--r--sca-cpp/trunk/samples/store-cluster/htdocs/login/index.html69
-rwxr-xr-xsca-cpp/trunk/samples/store-cluster/server-ssl-conf1
35 files changed, 890 insertions, 120 deletions
diff --git a/sca-cpp/trunk/modules/http/httpd-ssl-conf b/sca-cpp/trunk/modules/http/httpd-ssl-conf
index e48902fd82..5f1058ea75 100755
--- a/sca-cpp/trunk/modules/http/httpd-ssl-conf
+++ b/sca-cpp/trunk/modules/http/httpd-ssl-conf
@@ -117,7 +117,7 @@ BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-res
SSLOptions -StrictRequire +OptRenegotiate
# Verify client certificates
-SSLVerifyClient optional
+SSLVerifyClient none
SSLVerifyDepth 1
# Enable SSL proxy engine
@@ -195,7 +195,7 @@ SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128 and ( \
( %{SSL_CLIENT_I_DN_O} == "$org" and %{SSL_CLIENT_S_DN_OU} == "tunnel" ) or \
( %{SSL_CLIENT_I_DN_O} == "$org" and %{SSL_CLIENT_S_DN_OU} == "proxy" and \
%{HTTP:X-Forwarded-SSL-Issuer-DN-O} == "$org" and %{HTTP:X-Forwarded-SSL-Client-DN-OU} == "server" ) or \
-%{REQUEST_URI} =~ m/^.(login|logout|openid|unprotected).*$/ )
+%{REQUEST_URI} =~ m/^.(login|logout|openid|public|ui).*$/ )
# Record received SSL client certificate info in environment vars
RewriteEngine on
diff --git a/sca-cpp/trunk/modules/oauth/Makefile.am b/sca-cpp/trunk/modules/oauth/Makefile.am
index 84bbe32eec..6c0cd2bc57 100644
--- a/sca-cpp/trunk/modules/oauth/Makefile.am
+++ b/sca-cpp/trunk/modules/oauth/Makefile.am
@@ -35,7 +35,7 @@ libmod_tuscany_oauth2_la_LDFLAGS = -lxml2 -lcurl -lmozjs
libmod_tuscany_oauth2.so:
ln -s .libs/libmod_tuscany_oauth2.so
-EXTRA_DIST = oauth.composite user-info.scm htdocs/index.html htdocs/login/index.html htdocs/logout/index.html htdocs/unprotected/index.html
+EXTRA_DIST = oauth.composite user-info.scm htdocs/index.html htdocs/login/index.html htdocs/logout/index.html htdocs/public/index.html
dist_noinst_SCRIPTS = start-test stop-test
diff --git a/sca-cpp/trunk/modules/oauth/htdocs/index.html b/sca-cpp/trunk/modules/oauth/htdocs/index.html
index 779ea74986..e8cdd2f26b 100644
--- a/sca-cpp/trunk/modules/oauth/htdocs/index.html
+++ b/sca-cpp/trunk/modules/oauth/htdocs/index.html
@@ -22,13 +22,14 @@
<script type="text/javascript" src="/js/ref.js"></script>
<script type="text/javascript">
var protected = component("Protected");
-var userInfo = reference(protected, "userInfo");
-var user = userInfo.apply("getuser");
+var userInfo = defun(reference(protected, "userInfo"), "getuser", "getemail", "getnickname", "getfullname", "getfirstname", "getlastname", "getrealm");
+var user = userInfo.getuser();
var email = userInfo.apply("getemail");
var nickname = userInfo.apply("getnickname");
var fullname = userInfo.apply("getfullname");
var firstname = userInfo.apply("getfirstname");
var lastname = userInfo.apply("getlastname");
+var realm = userInfo.apply("getrealm");
</script>
</head>
<body>
@@ -40,6 +41,7 @@ var lastname = userInfo.apply("getlastname");
<div>Fullname: <span id="fullname"></span></div>
<div>Firstname: <span id="firstname"></span></div>
<div>Lastname: <span id="lastname"></span></div>
+<div>Realm: <span id="realm"></span></div>
<script type="text/javascript">
document.getElementById('user').innerHTML=user;
document.getElementById('email').innerHTML=email;
@@ -47,9 +49,10 @@ document.getElementById('nickname').innerHTML=nickname;
document.getElementById('fullname').innerHTML=fullname;
document.getElementById('firstname').innerHTML=firstname;
document.getElementById('lastname').innerHTML=lastname;
+document.getElementById('realm').innerHTML=realm;
</script>
<p><a href="info">User info</a></p>
<p><a href="login">Sign in</a></p>
<p><a href="logout">Sign out</a></p>
-<p><a href="unprotected">Unprotected area</a></p>
+<p><a href="public">Public area</a></p>
</body></html>
diff --git a/sca-cpp/trunk/modules/oauth/htdocs/login/index.html b/sca-cpp/trunk/modules/oauth/htdocs/login/index.html
index 607c55ca18..8cdcb1cf64 100644
--- a/sca-cpp/trunk/modules/oauth/htdocs/login/index.html
+++ b/sca-cpp/trunk/modules/oauth/htdocs/login/index.html
@@ -56,12 +56,12 @@ function submitSignin2(w) {
}
function withFacebook() {
- var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'testfacebookapp', 'https://graph.facebook.com/me'];
+ var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'facebook.com', 'https://graph.facebook.com/me'];
return parms;
}
function withGithub() {
- var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'testgithubapp', 'https://github.com/api/v2/json/user/show'];
+ var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'github.com', 'https://github.com/api/v2/json/user/show'];
return parms;
}
@@ -77,12 +77,12 @@ function submitSignin1(w) {
}
function withLinkedin() {
- var parms = ['https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize', 'https://api.linkedin.com/uas/oauth/accessToken', 'testlinkedinapp', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,public-profile-url)'];
+ var parms = ['https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize', 'https://api.linkedin.com/uas/oauth/accessToken', 'linkedin.com', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,public-profile-url)'];
return parms;
}
function withTwitter() {
- var parms = ['https://api.twitter.com/oauth/request_token', 'https://api.twitter.com/oauth/authorize', 'https://api.twitter.com/oauth/access_token', 'testtwitterapp', 'https://api.twitter.com/1/statuses/user_timeline.json'];
+ var parms = ['https://api.twitter.com/oauth/request_token', 'https://api.twitter.com/oauth/authorize', 'https://api.twitter.com/oauth/access_token', 'twitter.com', 'https://api.twitter.com/1/statuses/user_timeline.json'];
return parms;
}
</script>
diff --git a/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html b/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html
index c187aa2a84..10773c4538 100644
--- a/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html
+++ b/sca-cpp/trunk/modules/oauth/htdocs/login/mixed.html
@@ -102,12 +102,12 @@ function submitOAuth2Signin(w) {
}
function withFacebook() {
- var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'testfacebookapp', 'https://graph.facebook.com/me'];
+ var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'facebook.com', 'https://graph.facebook.com/me'];
return parms;
}
function withGithub() {
- var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'testgithubapp', 'https://github.com/api/v2/json/user/show'];
+ var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'github.com', 'https://github.com/api/v2/json/user/show'];
return parms;
}
@@ -123,12 +123,12 @@ function submitOAuth1Signin(w) {
}
function withLinkedin() {
- var parms = ['https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize', 'https://api.linkedin.com/uas/oauth/accessToken', 'testlinkedinapp', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,public-profile-url)'];
+ var parms = ['https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize', 'https://api.linkedin.com/uas/oauth/accessToken', 'linkedin.com', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,public-profile-url)'];
return parms;
}
function withTwitter() {
- var parms = ['https://api.twitter.com/oauth/request_token', 'https://api.twitter.com/oauth/authorize', 'https://api.twitter.com/oauth/access_token', 'testtwitterapp', 'https://api.twitter.com/1/statuses/user_timeline.json'];
+ var parms = ['https://api.twitter.com/oauth/request_token', 'https://api.twitter.com/oauth/authorize', 'https://api.twitter.com/oauth/access_token', 'twitter.com', 'https://api.twitter.com/1/statuses/user_timeline.json'];
return parms;
}
</script>
diff --git a/sca-cpp/trunk/modules/oauth/htdocs/unprotected/index.html b/sca-cpp/trunk/modules/oauth/htdocs/public/index.html
index af2cd7ca19..af2cd7ca19 100644
--- a/sca-cpp/trunk/modules/oauth/htdocs/unprotected/index.html
+++ b/sca-cpp/trunk/modules/oauth/htdocs/public/index.html
diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
index 23ef90b0dd..22fdd0cce3 100644
--- a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
+++ b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
@@ -105,6 +105,12 @@ static int checkUserID(request_rec *r) {
const failable<int> authenticated(const list<list<value> >& info, request_rec* r) {
debug(info, "modoauth1::authenticated::info");
+ // Store user info in the request
+ const list<value> realm = assoc<value>("realm", info);
+ if (isNil(realm) || isNil(cdr(realm)))
+ return mkfailure<int>("Couldn't retrieve realm");
+ apr_table_set(r->subprocess_env, apr_pstrdup(r->pool, "REALM"), apr_pstrdup(r->pool, c_str(cadr(realm))));
+
const list<value> id = assoc<value>("id", info);
if (isNil(id) || isNil(cdr(id)))
return mkfailure<int>("Couldn't retrieve user id");
@@ -250,35 +256,53 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co
/**
* Extract user info from a profile/info response.
- * TODO This currently only works for twitter and linkedin profiles and
- * needs to be made configurable.
+ * TODO This currently only works for Twitter, Foursquare and LinkedIn.
+ * User profile parsing needs to be made configurable.
*/
-const failable<list<value> > profileUserInfo(const string& info) {
- if (substr(info, 0, 1) == "[") {
- // JSON profile
+const failable<list<value> > profileUserInfo(const value& cid, const string& info) {
+ string b = substr(info, 0, 1);
+ if (b == "[") {
+ // Twitter JSON profile
json::JSONContext cx;
const list<value> infov(json::jsonValues(content(json::readJSON(mklist<string>(info), cx))));
if (isNil(infov))
return mkfailure<list<value> >("Couldn't retrieve user info");
debug(infov, "modoauth1::access_token::info");
const list<value> uv = assoc<value>("user", car(infov));
+ debug(uv, "modoauth1::access_token::userInfo");
if (isNil(uv) || isNil(cdr(uv)))
return mkfailure<list<value> >("Couldn't retrieve user info");
const list<value> iv = cdr(uv);
- return iv;
-
- } else {
+ return cons<value>(mklist<value>("realm", cid), iv);
+ }
+ if (b == "{") {
+ // Foursquare JSON profile
+ json::JSONContext cx;
+ const list<value> infov(json::jsonValues(content(json::readJSON(mklist<string>(info), cx))));
+ if (isNil(infov))
+ return mkfailure<list<value> >("Couldn't retrieve user info");
+ debug(infov, "modoauth1::access_token::info");
+ const list<value> uv = assoc<value>("user", infov);
+ debug(uv, "modoauth1::access_token::userInfo");
+ if (isNil(uv) || isNil(cdr(uv)))
+ return mkfailure<list<value> >("Couldn't retrieve user info");
+ const list<value> iv = cdr(uv);
+ return cons<value>(mklist<value>("realm", cid), iv);
+ }
+ if (b == "<") {
// XML profile
const list<value> infov = elementsToValues(readXML(mklist<string>(info)));
if (isNil(infov))
return mkfailure<list<value> >("Couldn't retrieve user info");
debug(infov, "modoauth1::access_token::info");
const list<value> pv = car(infov);
+ debug(pv, "modoauth1::access_token::userInfo");
if (isNil(pv) || isNil(cdr(pv)))
return mkfailure<list<value> >("Couldn't retrieve user info");
const list<value> iv = cdr(pv);
- return iv;
+ return cons<value>(mklist<value>("realm", cid), iv);
}
+ return mkfailure<list<value> >("Couldn't retrieve user info");
}
/**
@@ -356,7 +380,7 @@ const failable<int> access_token(const list<list<value> >& args, request_rec* r,
debug(profres, "modoauth1::access_token::profres");
// Retrieve the user info from the profile
- const failable<list<value> > iv = profileUserInfo(profres);
+ const failable<list<value> > iv = profileUserInfo(cadr(cid), profres);
if (!hasContent(iv))
return mkfailure<int>(reason(iv));
diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
index 60eadc282c..bb96fcb916 100644
--- a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
+++ b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
@@ -164,6 +164,15 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co
}
/**
+ * Extract user info from a profile/info response.
+ * TODO This currently only works for Facebook and Gowalla.
+ * User profile parsing needs to be made configurable.
+ */
+const failable<list<value> > profileUserInfo(const value& cid, const list<value>& info) {
+ return cons<value>(mklist<value>("realm", cid), info);
+}
+
+/**
* Handle an access_token request.
*/
const failable<int> access_token(const list<list<value> >& args, request_rec* r, const ServerConf& sc) {
@@ -210,10 +219,15 @@ const failable<int> access_token(const list<list<value> >& args, request_rec* r,
const list<list<value> > iargs = mklist<list<value> >(tv);
const string iuri = httpd::unescape(cadr(info)) + string("?") + httpd::queryString(iargs);
debug(iuri, "modoauth2::access_token::infouri");
- const failable<value> iv = http::get(iuri, sc.cs);
- if (!hasContent(iv))
+ const failable<value> profres = http::get(iuri, sc.cs);
+ if (!hasContent(profres))
return mkfailure<int>("Couldn't retrieve user info");
- debug(content(iv), "modoauth2::access_token::info");
+ debug(content(profres), "modoauth2::access_token::info");
+
+ // Retrieve the user info from the profile
+ const failable<list<value> > iv = profileUserInfo(cadr(cid), content(profres));
+ if (!hasContent(iv))
+ return mkfailure<int>(reason(iv));
// Store user info in memcached keyed by session ID
const value sid = string("OAuth2_") + mkrand();
diff --git a/sca-cpp/trunk/modules/oauth/oauth-conf b/sca-cpp/trunk/modules/oauth/oauth-conf
index 5c3fde2ccc..91ae1916c7 100755
--- a/sca-cpp/trunk/modules/oauth/oauth-conf
+++ b/sca-cpp/trunk/modules/oauth/oauth-conf
@@ -39,14 +39,17 @@ AuthOAuth On
AuthOAuthLoginPage /login
</Location>
-# Enable unauthenticated access to unprotected areas
+# Enable unauthenticated access to public areas
<Location /login>
AuthOAuth Off
</Location>
<Location /logout>
AuthOAuth Off
</Location>
-<Location /unprotected>
+<Location /public>
+AuthOAuth Off
+</Location>
+<Location /ui>
AuthOAuth Off
</Location>
diff --git a/sca-cpp/trunk/modules/oauth/oauth.composite b/sca-cpp/trunk/modules/oauth/oauth.composite
index 0119db22c9..c2025493c8 100644
--- a/sca-cpp/trunk/modules/oauth/oauth.composite
+++ b/sca-cpp/trunk/modules/oauth/oauth.composite
@@ -38,6 +38,7 @@
<property name="fullname">?</property>
<property name="firstname">?</property>
<property name="lastname">?</property>
+ <property name="realm">?</property>
</component>
</composite>
diff --git a/sca-cpp/trunk/modules/oauth/oauth.hpp b/sca-cpp/trunk/modules/oauth/oauth.hpp
index ab92cbd381..cea16e035f 100644
--- a/sca-cpp/trunk/modules/oauth/oauth.hpp
+++ b/sca-cpp/trunk/modules/oauth/oauth.hpp
@@ -43,10 +43,15 @@ namespace oauth {
/**
* Return the session id from a request.
*/
+const char* cookieName(const char* cs) {
+ if (*cs != ' ')
+ return cs;
+ return cookieName(cs + 1);
+}
const maybe<string> sessionID(const list<string> c) {
if (isNil(c))
return maybe<string>();
- const list<string> kv = tokenize("=", car(c));
+ const list<string> kv = tokenize("=", cookieName(c_str(car(c))));
if (!isNil(kv) && !isNil(cdr(kv))) {
if (car(kv) == "TuscanyOpenAuth")
return cadr(kv);
diff --git a/sca-cpp/trunk/modules/oauth/start-mixed-test b/sca-cpp/trunk/modules/oauth/start-mixed-test
index 468e6861d8..e838e9bb83 100755
--- a/sca-cpp/trunk/modules/oauth/start-mixed-test
+++ b/sca-cpp/trunk/modules/oauth/start-mixed-test
@@ -34,10 +34,10 @@ here=`readlink -f $0`; here=`dirname $here`
./oauth-memcached-conf tmp localhost 11213
# Configure your app keys here
-./oauth1-appkey-conf tmp testtwitterapp app2345 secret7890
-./oauth1-appkey-conf tmp testlinkedinapp app3456 secret4567
-./oauth2-appkey-conf tmp testfacebookapp app1234 secret6789
-./oauth2-appkey-conf tmp testgithubapp app5678 secret8901
+./oauth1-appkey-conf tmp twitter.com app2345 secret7890
+./oauth1-appkey-conf tmp linkedin.com app3456 secret4567
+./oauth2-appkey-conf tmp facebook.com app1234 secret6789
+./oauth2-appkey-conf tmp github.com app5678 secret8901
../openid/openid-conf tmp
../openid/openid-step2-conf tmp
diff --git a/sca-cpp/trunk/modules/oauth/start-test b/sca-cpp/trunk/modules/oauth/start-test
index 47171a91ae..8c59009102 100755
--- a/sca-cpp/trunk/modules/oauth/start-test
+++ b/sca-cpp/trunk/modules/oauth/start-test
@@ -21,20 +21,20 @@
../../components/cache/memcached-start 11212
../../components/cache/memcached-start 11213
-../../modules/http/ssl-ca-conf tmp localhost
-../../modules/http/ssl-cert-conf tmp localhost
-../../modules/http/httpd-conf tmp localhost 8090 htdocs
-../../modules/http/httpd-ssl-conf tmp 8453
+../../modules/http/ssl-ca-conf tmp jsdelfino.com
+../../modules/http/ssl-cert-conf tmp jsdelfino.com
+../../modules/http/httpd-conf tmp jsdelfino.com 8090/80 htdocs
+../../modules/http/httpd-ssl-conf tmp 8453/443
./oauth-conf tmp
-./oauth-memcached-conf tmp localhost 11212
-./oauth-memcached-conf tmp localhost 11213
+./oauth-memcached-conf tmp jsdelfino.com 11212
+./oauth-memcached-conf tmp jsdelfino.com 11213
# Configure your app keys here
-./oauth1-appkey-conf tmp testtwitterapp app2345 secret7890
-./oauth1-appkey-conf tmp testlinkedinapp app3456 secret4567
-./oauth2-appkey-conf tmp testfacebookapp app1234 secret6789
-./oauth2-appkey-conf tmp testgithubapp app5678 secret8901
+./oauth1-appkey-conf tmp twitter.com app2345 secret7890
+./oauth1-appkey-conf tmp linkedin.com app3456 secret4567
+./oauth2-appkey-conf tmp facebook.com app1234 secret6789
+./oauth2-appkey-conf tmp github.com app5678 secret8901
../../modules/server/server-conf tmp
../../modules/server/scheme-conf tmp
diff --git a/sca-cpp/trunk/modules/oauth/user-info.scm b/sca-cpp/trunk/modules/oauth/user-info.scm
index 58a84f86b0..4960a0a455 100644
--- a/sca-cpp/trunk/modules/oauth/user-info.scm
+++ b/sca-cpp/trunk/modules/oauth/user-info.scm
@@ -17,18 +17,20 @@
; OAuth support test case
-(define (get id user email nickname fullname firstname lastname) (list "text/html" (list
- "<html><body><p>The following info is generated on the server:</p><div>User: " (user) "</div><div>Email: " (email) "</div><div>Nickname: " (nickname) "</div><div>Fullname: " (fullname) "</div><div>Firstname: " (firstname) "</div><div>Lastname: " (lastname) "</div></body></html>")))
+(define (get id user email nickname fullname firstname lastname realm) (list "text/html" (list
+ "<html><body><p>The following info is generated on the server:</p><div>User: " (user) "</div><div>Email: " (email) "</div><div>Nickname: " (nickname) "</div><div>Fullname: " (fullname) "</div><div>Firstname: " (firstname) "</div><div>Lastname: " (lastname) "</div><div>Realm: " (realm) "</div></body></html>")))
-(define (getuser user email nickname fullname firstname lastname) (user))
+(define (getuser user email nickname fullname firstname lastname realm) (user))
-(define (getemail user email nickname fullname firstname lastname) (email))
+(define (getemail user email nickname fullname firstname lastname realm) (email))
-(define (getnickname user email nickname fullname firstname lastname) (nickname))
+(define (getnickname user email nickname fullname firstname lastname realm) (nickname))
-(define (getfullname user email nickname fullname firstname lastname) (fullname))
+(define (getfullname user email nickname fullname firstname lastname realm) (fullname))
-(define (getfirstname user email nickname fullname firstname lastname) (firstname))
+(define (getfirstname user email nickname fullname firstname lastname realm) (firstname))
-(define (getlastname user email nickname fullname firstname lastname) (lastname))
+(define (getlastname user email nickname fullname firstname lastname realm) (lastname))
+
+(define (getrealm user email nickname fullname firstname lastname realm) (realm))
diff --git a/sca-cpp/trunk/modules/openid/Makefile.am b/sca-cpp/trunk/modules/openid/Makefile.am
index ba6e523ad2..a46dd56743 100644
--- a/sca-cpp/trunk/modules/openid/Makefile.am
+++ b/sca-cpp/trunk/modules/openid/Makefile.am
@@ -25,7 +25,7 @@ mod_DATA = openid.prefix
openid.prefix: $(top_builddir)/config.status
echo ${MODAUTHOPENID_PREFIX} >openid.prefix
-EXTRA_DIST = openid.composite user-info.scm htdocs/index.html htdocs/login/index.html htdocs/logout/index.html htdocs/unprotected/index.html
+EXTRA_DIST = openid.composite user-info.scm htdocs/index.html htdocs/login/index.html htdocs/logout/index.html htdocs/public/index.html
dist_noinst_SCRIPTS = start-test stop-test
diff --git a/sca-cpp/trunk/modules/openid/htdocs/index.html b/sca-cpp/trunk/modules/openid/htdocs/index.html
index c2dfc791e6..cdc65a4e37 100644
--- a/sca-cpp/trunk/modules/openid/htdocs/index.html
+++ b/sca-cpp/trunk/modules/openid/htdocs/index.html
@@ -22,9 +22,10 @@
<script type="text/javascript" src="/js/ref.js"></script>
<script type="text/javascript">
var protected = component("Protected");
-var userInfo = reference(protected, "userInfo");
-var user = userInfo.apply("getuser");
-var email = userInfo.apply("getemail");
+var userInfo = defun(reference(protected, "userInfo"), "getuser", "getemail", "getrealm");
+var user = userInfo.getuser();
+var email = userInfo.getemail();
+var realm = userInfo.getrealm();
</script>
</head>
<body>
@@ -32,12 +33,14 @@ var email = userInfo.apply("getemail");
<p>The following info is returned by a JSONRPC service:</p>
<div id="user"></div>
<div id="email"></div>
+<div id="realm"></div>
<script type="text/javascript">
document.getElementById('user').innerHTML="User: " + user;
document.getElementById('email').innerHTML="Email: " + email;
+document.getElementById('realm').innerHTML="Realm: " + realm;
</script>
<p><a href="info">User info</a></p>
<p><a href="login">Sign in</a></p>
<p><a href="logout">Sign out</a></p>
-<p><a href="unprotected">Unprotected area</a></p>
+<p><a href="public">Public area</a></p>
</body></html>
diff --git a/sca-cpp/trunk/modules/openid/htdocs/unprotected/index.html b/sca-cpp/trunk/modules/openid/htdocs/public/index.html
index af2cd7ca19..af2cd7ca19 100644
--- a/sca-cpp/trunk/modules/openid/htdocs/unprotected/index.html
+++ b/sca-cpp/trunk/modules/openid/htdocs/public/index.html
diff --git a/sca-cpp/trunk/modules/openid/openid-conf b/sca-cpp/trunk/modules/openid/openid-conf
index 95cdb1945c..839b58b554 100755
--- a/sca-cpp/trunk/modules/openid/openid-conf
+++ b/sca-cpp/trunk/modules/openid/openid-conf
@@ -47,14 +47,17 @@ AuthOpenIDAXAdd FIRSTNAME http://axschema.org/namePerson/first
AuthOpenIDAXAdd LASTNAME http://axschema.org/namePerson/last
</Location>
-# Enable unauthenticated access to unprotected areas
+# Enable unauthenticated access to public areas
<Location /login>
AuthOpenIDEnabled Off
</Location>
<Location /logout>
AuthOpenIDEnabled Off
</Location>
-<Location /unprotected>
+<Location /public>
+AuthOpenIDEnabled Off
+</Location>
+<Location /ui>
AuthOpenIDEnabled Off
</Location>
diff --git a/sca-cpp/trunk/modules/openid/openid.composite b/sca-cpp/trunk/modules/openid/openid.composite
index 016139a9a7..08bb74b7c7 100644
--- a/sca-cpp/trunk/modules/openid/openid.composite
+++ b/sca-cpp/trunk/modules/openid/openid.composite
@@ -34,6 +34,7 @@
</service>
<property name="user">anonymous</property>
<property name="email">anonymous@example.com</property>
+ <property name="realm">example.com</property>
</component>
</composite>
diff --git a/sca-cpp/trunk/modules/openid/user-info.scm b/sca-cpp/trunk/modules/openid/user-info.scm
index 69eb207be9..b1ef74c6bd 100644
--- a/sca-cpp/trunk/modules/openid/user-info.scm
+++ b/sca-cpp/trunk/modules/openid/user-info.scm
@@ -17,10 +17,12 @@
; OpenID support test case
-(define (get id user email) (list "text/html" (list
- "<html><body><p>The following info is generated on the server:</p><div>User: " (user) "</div><div>Email: " (email) "</div></body></html>")))
+(define (get id user email realm) (list "text/html" (list
+ "<html><body><p>The following info is generated on the server:</p><div>User: " (user) "</div><div>Email: " (email) "</div><div>Realm: " (realm) "</div></body></html>")))
-(define (getuser user email) (user))
+(define (getuser user email realm) (user))
-(define (getemail user email) (email))
+(define (getemail user email realm) (email))
+
+(define (getrealm user email realm) (realm))
diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp
index 2fe4bd76e0..c2705b0538 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.hpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.hpp
@@ -395,6 +395,8 @@ const value mkpropProxy(const value& prop) {
return lambda<value(const list<value>&)>(hostPropProxy(elementValue(prop)));
if (scdl::name(prop) == "user")
return lambda<value(const list<value>&)>(userPropProxy(elementValue(prop)));
+ if (scdl::name(prop) == "realm")
+ return lambda<value(const list<value>&)>(envPropProxy("REALM", elementValue(prop)));
if (scdl::name(prop) == "email")
return lambda<value(const list<value>&)>(envPropProxy("EMAIL", elementValue(prop)));
if (scdl::name(prop) == "nickname")
diff --git a/sca-cpp/trunk/modules/wsgi/scdl.py b/sca-cpp/trunk/modules/wsgi/scdl.py
index 447dd985c2..97c2f7dd69 100644
--- a/sca-cpp/trunk/modules/wsgi/scdl.py
+++ b/sca-cpp/trunk/modules/wsgi/scdl.py
@@ -216,13 +216,15 @@ def mkproperty(name, l):
return property(name, l)
# Evaluate a property, return a lambda function returning the property
-# value. The host, user and email properties are configured with the
-# values from the HTTP request, if any
+# value. The host, user, realm, nickname and email properties are configured
+# with the values from the HTTP request, if any.
def evalProperty(p):
if car(p) == "host":
return mkproperty(car(p), lambda: hostProperty(cadr(p), environ))
if car(p) == "user":
return mkproperty(car(p), lambda: userProperty(cadr(p)))
+ if car(p) == "realm":
+ return mkproperty(car(p), lambda: hostProperty(cadr(p), environ))
if car(p) == "nickname":
return mkproperty(car(p), lambda: nicknameProperty(cadr(p)))
if car(p) == "email":
diff --git a/sca-cpp/trunk/samples/loan-python/Makefile.am b/sca-cpp/trunk/samples/loan-python/Makefile.am
new file mode 100644
index 0000000000..0d0027ce6b
--- /dev/null
+++ b/sca-cpp/trunk/samples/loan-python/Makefile.am
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+if WANT_PYTHON
+
+dist_sample_SCRIPTS = start stop
+sampledir = $(prefix)/samples/loan-python
+
+nobase_dist_sample_DATA = loan.py loan-approval.py util.py loan.composite htdocs/*.html
+
+dist_noinst_SCRIPTS = server-test
+TESTS = server-test
+
+endif
diff --git a/sca-cpp/trunk/samples/loan-python/htdocs/index.html b/sca-cpp/trunk/samples/loan-python/htdocs/index.html
new file mode 100644
index 0000000000..bb05427a37
--- /dev/null
+++ b/sca-cpp/trunk/samples/loan-python/htdocs/index.html
@@ -0,0 +1,156 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/js/ref.js"></script>
+
+<script type="text/javascript">
+var component = new tuscany.sca.Component("Store");
+
+//@Reference
+var catalog = new tuscany.sca.Reference("catalog");
+
+//@Reference
+var shoppingCart = new tuscany.sca.Reference("shoppingCart");
+
+//@Reference
+var shoppingTotal = new tuscany.sca.Reference("shoppingTotal");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.apply("total", shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.apply("items", catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sca-cpp/trunk/samples/loan-python/loan-approval.py b/sca-cpp/trunk/samples/loan-python/loan-approval.py
new file mode 100644
index 0000000000..3951f16eeb
--- /dev/null
+++ b/sca-cpp/trunk/samples/loan-python/loan-approval.py
@@ -0,0 +1,77 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Loan approval service implementation
+import uuid
+import sys
+from util import *
+from loan import *
+
+loansId = ("loans", "1234")
+
+# Return the list of loans
+def loans(cache):
+ l = cache("get", loansId)
+ if l is None:
+ return ()
+ return l
+
+# Post a new loan request
+def post(collection, item, cache):
+ id = str(uuid.uuid1())
+ loans = cons(cons(id, cdr(item)), loans(cache))
+ cache("put", loansId, loans)
+ return (id,)
+
+# Return the person currently processing a loan request
+def processor(l):
+ if approver(l) is not None:
+ return approver(l)
+ return assessor(l)
+
+# Return a list of loans that match a given criteria
+def get(r, cache):
+ # All the loans
+ if r == ():
+ return loans(cache)
+ # Loans that need approval
+ if car(r) == "needApproval":
+ return filter(lambda l: (amount(l) >= 10000 or risk(l) == "high") and approval(l) is None, loans(cache))
+ # Loans that need a risk assessment
+ if car(r) == "needAssessment":
+ return filter(lambda : amount(l) < 10000 and risk(l) is None, loans(cache))
+ # Loans currently under approval
+ if car(r) == "underApproval":
+ return filter(lambda l: approver(l) is not None, loans(cache))
+ # Loans currently under assessment
+ if car(r) == "underAssessment":
+ return filter(lambda l: assessor(l) is not None, loans(cache))
+ # Loan requests that are unassigned
+ if car(r) == "unassigned":
+ return filter(lambda l: processor(l) is None, loans(cache))
+ # Loan requests that are assigned and getting processed
+ if car(r) == "assigned":
+ return filter(lambda l: processor(l) == cadr(r), loans(cache))
+ # Approved loans
+ if car(r) == "approved":
+ return filter(lambda l: approval(l) == true, loans(cache))
+ # Denied loans
+ if car(r) == "denied":
+ return filter(lambda l: approval(l) == false, loans(cache))
+ # A particular loan
+ return filter(lambda l: id(l) == r, loans(cache))
+
diff --git a/sca-cpp/trunk/samples/loan-python/loan.composite b/sca-cpp/trunk/samples/loan-python/loan.composite
new file mode 100644
index 0000000000..0e64b5bf44
--- /dev/null
+++ b/sca-cpp/trunk/samples/loan-python/loan.composite
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="LoanApprovalUI">
+ <t:implementation.widget/>
+ <reference name="loanApproval" target="LoanApproval"/>
+ </component>
+
+ <component name="LoanApproval">
+ <t:implementation.python script="loan-approval.py"/>
+ <service name="LoanApproval">
+ <t:binding.atom uri="loan-approval"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache" library="libmemcache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ <property name="servers">localhost:11211</property>
+ </component>
+
+</composite>
diff --git a/sca-cpp/trunk/samples/loan-python/loan.py b/sca-cpp/trunk/samples/loan-python/loan.py
new file mode 100644
index 0000000000..9e345cd1f6
--- /dev/null
+++ b/sca-cpp/trunk/samples/loan-python/loan.py
@@ -0,0 +1,45 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from util import *
+
+# Loan data type
+
+def firstName(loan):
+ return assoc("'firstName", loan)
+
+def lastName(loan):
+ return assoc("'lastName", loan)
+
+def ssn(loan):
+ return assoc("'ssn", loan)
+
+def amount(loan):
+ return assoc("'amount", loan)
+
+def approver(loan):
+ return assoc("'approver", loan)
+
+def approval(loan):
+ return assoc("'approval", loan)
+
+def assessor(loan):
+ return assoc("'assessor", loan)
+
+def risk(loan):
+ return assoc("'risk", loan)
+
diff --git a/sca-cpp/trunk/samples/loan-python/server-test b/sca-cpp/trunk/samples/loan-python/server-test
new file mode 100755
index 0000000000..1612bc59e2
--- /dev/null
+++ b/sca-cpp/trunk/samples/loan-python/server-test
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/ 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test Catalog
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/catalog -X POST -H "Content-type: application/json-rpc" --data @../store-cpp/htdocs/test/items-request.txt >tmp/items-result.txt 2>/dev/null
+ diff tmp/items-result.txt ../store-cpp/htdocs/test/items-result.txt
+ rc=$?
+fi
+
+# Test Shopping Cart
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart -X POST -H "Content-type: application/atom+xml" --data @../store-cpp/htdocs/test/shopping-cart-entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart >tmp/shopping-cart-feed.xml 2>/dev/null
+ grep "3.55" tmp/shopping-cart-feed.xml >/dev/null
+ rc=$?
+fi
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sca-cpp/trunk/samples/loan-python/start b/sca-cpp/trunk/samples/loan-python/start
new file mode 100755
index 0000000000..e7aa7d86ca
--- /dev/null
+++ b/sca-cpp/trunk/samples/loan-python/start
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite loan.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sca-cpp/trunk/samples/loan-python/stop b/sca-cpp/trunk/samples/loan-python/stop
new file mode 100755
index 0000000000..a59273b8ed
--- /dev/null
+++ b/sca-cpp/trunk/samples/loan-python/stop
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+../../modules/http/httpd-stop tmp
+../../components/cache/memcached-stop
diff --git a/sca-cpp/trunk/samples/loan-python/util.py b/sca-cpp/trunk/samples/loan-python/util.py
new file mode 100644
index 0000000000..560101e32d
--- /dev/null
+++ b/sca-cpp/trunk/samples/loan-python/util.py
@@ -0,0 +1,145 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Simple utility functions
+from sys import maxint
+
+# Scheme-like lists
+def cons(a, b):
+ return (a,) + b
+
+def car(l):
+ return l[0]
+
+def first(l):
+ return car(l)
+
+def cdr(l):
+ return l[1:]
+
+def rest(l):
+ return cdr(l)
+
+def cadr(l):
+ return car(cdr(l))
+
+def cddr(l):
+ return cdr(cdr(l))
+
+def caddr(l):
+ return car(cddr(l))
+
+def append(a, b):
+ return a + b
+
+def reverse(l):
+ r = list(l)
+ r.reverse()
+ return tuple(r)
+
+def isNil(l):
+ if isinstance(l, streampair):
+ return l.isNil()
+ return l == ()
+
+def isSymbol(v):
+ return isinstance(v, basestring) and v[0:1] == "'"
+
+def isList(v):
+ if getattr(v, '__iter__', False) == False:
+ return False
+ if isinstance(v, basestring) or isinstance(v, dict):
+ return False
+ return True
+
+def isTaggedList(v, t):
+ return isList(v) and not isNil(v) and car(v) == t
+
+
+# Scheme-like streams
+class streampair(object):
+ def __init__(self, car, cdr):
+ self.car = car
+ self.cdr = cdr
+
+ def __repr__(self):
+ return repr(self[0:len(self)])
+
+ def isNil(self):
+ return self.cdr == ()
+
+ def __len__(self):
+ if self.cdr == ():
+ return 0
+ return 1 + len(self.cdr())
+
+ def __getitem__(self, i):
+ if i == 0:
+ return self.car
+ return self.cdr()[i - 1]
+
+ def __getslice__(self, i, j):
+ if isNil(self):
+ return ()
+ if i > 0:
+ if j == maxint:
+ return self.cdr()[i - 1: j]
+ return self.cdr()[i - 1: j - 1]
+ if j == maxint:
+ return self
+ if j == 0:
+ return (self.car,)
+ return (self.car,) + self.cdr()[: j - 1]
+
+ def __eq__(self, other):
+ sl = len(self)
+ ol = len(other)
+ if sl != ol:
+ return False
+ return self[0: sl] == other[0: ol]
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+def cons_stream(car, cdr):
+ return streampair(car, cdr)
+
+
+# Scheme-like associations
+def assoc(k, l):
+ if l == ():
+ return None
+
+ if k == car(car(l)):
+ return car(l)
+ return assoc(k, cdr(l))
+
+# Currying / partial function application
+def curry(f, *args):
+ return lambda *a: f(*(args + a))
+
+# Split a path into a list of segments
+def tokens(path):
+ return tuple(filter(lambda s: len(s) != 0, path.split("/")))
+
+# Write a list of strings to a stream
+def writeStrings(l, os):
+ if l == ():
+ return os
+ os.write(car(l))
+ return writeStrings(cdr(l), os)
+
diff --git a/sca-cpp/trunk/samples/store-cluster/htdocs/domains/jane/login/index.html b/sca-cpp/trunk/samples/store-cluster/htdocs/domains/jane/login/index.html
index 16246cc621..c187aa2a84 100644
--- a/sca-cpp/trunk/samples/store-cluster/htdocs/domains/jane/login/index.html
+++ b/sca-cpp/trunk/samples/store-cluster/htdocs/domains/jane/login/index.html
@@ -17,7 +17,7 @@
under the License.
-->
-<html><body><h1>Sign in with an OpenID or OAuth 2.0 provider</h1>
+<html><body><h1>Sign in with an OpenID or OAuth provider</h1>
<script type="text/javascript">
function queryParams() {
@@ -91,23 +91,44 @@ function withXRDSEndpoint() {
return document.fields.endpoint.value;
}
-function submitOAuthSignin(w) {
+function submitOAuth2Signin(w) {
parms = w();
- document.oauthSignin.mod_oauth_authorize.value = parms[0];
- document.oauthSignin.mod_oauth_access_token.value = parms[1];
- document.oauthSignin.mod_oauth_client_id.value = parms[2];
- document.oauthSignin.mod_oauth_info.value = parms[3];
- document.oauthSignin.action = openauthReferrer();
- document.oauthSignin.submit();
+ 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();
+ document.oauth2Signin.submit();
}
function withFacebook() {
- var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'app1234', 'https://graph.facebook.com/me'];
+ var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'testfacebookapp', 'https://graph.facebook.com/me'];
return parms;
}
function withGithub() {
- var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'app2345', 'https://github.com/api/v2/json/user/show'];
+ var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'testgithubapp', 'https://github.com/api/v2/json/user/show'];
+ return parms;
+}
+
+function submitOAuth1Signin(w) {
+ parms = w();
+ 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();
+ 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)'];
+ 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'];
return parms;
}
</script>
@@ -139,20 +160,32 @@ function withGithub() {
<input type="text" size="50" name="endpoint" value="https://www.google.com/accounts/o8/id"/><br/>
<input type="button" onclick="submitOpenIDSignin(withXRDSEndpoint)" value="Sign in"/></p>
-<p>Sign in with your Facebook account<br/><input type="button" onclick="submitOAuthSignin(withFacebook)" value="Sign in"/></p>
-<p>Sign in with your Github account<br/><input type="button" onclick="submitOAuthSignin(withGithub)" value="Sign in"/></p>
+<p>Sign in with your Facebook account<br/><input type="button" onclick="submitOAuth2Signin(withFacebook)" value="Sign in"/></p>
+<p>Sign in with your Github account<br/><input type="button" onclick="submitOAuth2Signin(withGithub)" value="Sign in"/></p>
+
+<p>Sign in with your Linkedin account<br/><input type="button" onclick="submitOAuth1Signin(withLinkedin)" value="Sign in"/></p>
+<p>Sign in with your Twitter account<br/><input type="button" onclick="submitOAuth1Signin(withTwitter)" value="Sign in"/></p>
</form>
<form name="openIDSignin" action="/" method="GET">
<input type="hidden" name="openid_identifier" value=""/>
</form>
-<form name="oauthSignin" action="/" method="GET">
-<input type="hidden" name="mod_oauth_authorize" value=""/>
-<input type="hidden" name="mod_oauth_access_token" value=""/>
-<input type="hidden" name="mod_oauth_client_id" value=""/>
-<input type="hidden" name="mod_oauth_info" value=""/>
-<input type="hidden" name="mod_oauth_step" value="authorize"/>
+<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"/>
+</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"/>
</form>
</body></html>
diff --git a/sca-cpp/trunk/samples/store-cluster/htdocs/domains/joe/login/index.html b/sca-cpp/trunk/samples/store-cluster/htdocs/domains/joe/login/index.html
index 16246cc621..c187aa2a84 100644
--- a/sca-cpp/trunk/samples/store-cluster/htdocs/domains/joe/login/index.html
+++ b/sca-cpp/trunk/samples/store-cluster/htdocs/domains/joe/login/index.html
@@ -17,7 +17,7 @@
under the License.
-->
-<html><body><h1>Sign in with an OpenID or OAuth 2.0 provider</h1>
+<html><body><h1>Sign in with an OpenID or OAuth provider</h1>
<script type="text/javascript">
function queryParams() {
@@ -91,23 +91,44 @@ function withXRDSEndpoint() {
return document.fields.endpoint.value;
}
-function submitOAuthSignin(w) {
+function submitOAuth2Signin(w) {
parms = w();
- document.oauthSignin.mod_oauth_authorize.value = parms[0];
- document.oauthSignin.mod_oauth_access_token.value = parms[1];
- document.oauthSignin.mod_oauth_client_id.value = parms[2];
- document.oauthSignin.mod_oauth_info.value = parms[3];
- document.oauthSignin.action = openauthReferrer();
- document.oauthSignin.submit();
+ 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();
+ document.oauth2Signin.submit();
}
function withFacebook() {
- var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'app1234', 'https://graph.facebook.com/me'];
+ var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'testfacebookapp', 'https://graph.facebook.com/me'];
return parms;
}
function withGithub() {
- var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'app2345', 'https://github.com/api/v2/json/user/show'];
+ var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'testgithubapp', 'https://github.com/api/v2/json/user/show'];
+ return parms;
+}
+
+function submitOAuth1Signin(w) {
+ parms = w();
+ 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();
+ 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)'];
+ 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'];
return parms;
}
</script>
@@ -139,20 +160,32 @@ function withGithub() {
<input type="text" size="50" name="endpoint" value="https://www.google.com/accounts/o8/id"/><br/>
<input type="button" onclick="submitOpenIDSignin(withXRDSEndpoint)" value="Sign in"/></p>
-<p>Sign in with your Facebook account<br/><input type="button" onclick="submitOAuthSignin(withFacebook)" value="Sign in"/></p>
-<p>Sign in with your Github account<br/><input type="button" onclick="submitOAuthSignin(withGithub)" value="Sign in"/></p>
+<p>Sign in with your Facebook account<br/><input type="button" onclick="submitOAuth2Signin(withFacebook)" value="Sign in"/></p>
+<p>Sign in with your Github account<br/><input type="button" onclick="submitOAuth2Signin(withGithub)" value="Sign in"/></p>
+
+<p>Sign in with your Linkedin account<br/><input type="button" onclick="submitOAuth1Signin(withLinkedin)" value="Sign in"/></p>
+<p>Sign in with your Twitter account<br/><input type="button" onclick="submitOAuth1Signin(withTwitter)" value="Sign in"/></p>
</form>
<form name="openIDSignin" action="/" method="GET">
<input type="hidden" name="openid_identifier" value=""/>
</form>
-<form name="oauthSignin" action="/" method="GET">
-<input type="hidden" name="mod_oauth_authorize" value=""/>
-<input type="hidden" name="mod_oauth_access_token" value=""/>
-<input type="hidden" name="mod_oauth_client_id" value=""/>
-<input type="hidden" name="mod_oauth_info" value=""/>
-<input type="hidden" name="mod_oauth_step" value="authorize"/>
+<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"/>
+</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"/>
</form>
</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 16246cc621..c187aa2a84 100644
--- a/sca-cpp/trunk/samples/store-cluster/htdocs/login/index.html
+++ b/sca-cpp/trunk/samples/store-cluster/htdocs/login/index.html
@@ -17,7 +17,7 @@
under the License.
-->
-<html><body><h1>Sign in with an OpenID or OAuth 2.0 provider</h1>
+<html><body><h1>Sign in with an OpenID or OAuth provider</h1>
<script type="text/javascript">
function queryParams() {
@@ -91,23 +91,44 @@ function withXRDSEndpoint() {
return document.fields.endpoint.value;
}
-function submitOAuthSignin(w) {
+function submitOAuth2Signin(w) {
parms = w();
- document.oauthSignin.mod_oauth_authorize.value = parms[0];
- document.oauthSignin.mod_oauth_access_token.value = parms[1];
- document.oauthSignin.mod_oauth_client_id.value = parms[2];
- document.oauthSignin.mod_oauth_info.value = parms[3];
- document.oauthSignin.action = openauthReferrer();
- document.oauthSignin.submit();
+ 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();
+ document.oauth2Signin.submit();
}
function withFacebook() {
- var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'app1234', 'https://graph.facebook.com/me'];
+ var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'testfacebookapp', 'https://graph.facebook.com/me'];
return parms;
}
function withGithub() {
- var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'app2345', 'https://github.com/api/v2/json/user/show'];
+ var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'testgithubapp', 'https://github.com/api/v2/json/user/show'];
+ return parms;
+}
+
+function submitOAuth1Signin(w) {
+ parms = w();
+ 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();
+ 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)'];
+ 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'];
return parms;
}
</script>
@@ -139,20 +160,32 @@ function withGithub() {
<input type="text" size="50" name="endpoint" value="https://www.google.com/accounts/o8/id"/><br/>
<input type="button" onclick="submitOpenIDSignin(withXRDSEndpoint)" value="Sign in"/></p>
-<p>Sign in with your Facebook account<br/><input type="button" onclick="submitOAuthSignin(withFacebook)" value="Sign in"/></p>
-<p>Sign in with your Github account<br/><input type="button" onclick="submitOAuthSignin(withGithub)" value="Sign in"/></p>
+<p>Sign in with your Facebook account<br/><input type="button" onclick="submitOAuth2Signin(withFacebook)" value="Sign in"/></p>
+<p>Sign in with your Github account<br/><input type="button" onclick="submitOAuth2Signin(withGithub)" value="Sign in"/></p>
+
+<p>Sign in with your Linkedin account<br/><input type="button" onclick="submitOAuth1Signin(withLinkedin)" value="Sign in"/></p>
+<p>Sign in with your Twitter account<br/><input type="button" onclick="submitOAuth1Signin(withTwitter)" value="Sign in"/></p>
</form>
<form name="openIDSignin" action="/" method="GET">
<input type="hidden" name="openid_identifier" value=""/>
</form>
-<form name="oauthSignin" action="/" method="GET">
-<input type="hidden" name="mod_oauth_authorize" value=""/>
-<input type="hidden" name="mod_oauth_access_token" value=""/>
-<input type="hidden" name="mod_oauth_client_id" value=""/>
-<input type="hidden" name="mod_oauth_info" value=""/>
-<input type="hidden" name="mod_oauth_step" value="authorize"/>
+<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"/>
+</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"/>
</form>
</body></html>
diff --git a/sca-cpp/trunk/samples/store-cluster/server-ssl-conf b/sca-cpp/trunk/samples/store-cluster/server-ssl-conf
index 0b54b5cbf3..06ca590efb 100755
--- a/sca-cpp/trunk/samples/store-cluster/server-ssl-conf
+++ b/sca-cpp/trunk/samples/store-cluster/server-ssl-conf
@@ -36,7 +36,6 @@ tar -C tmp/ssl -c `../../modules/http/ssl-cert-find tmp/ssl` | tar -C $root -x
../../modules/oauth/oauth-memcached-conf $root localhost 11211
../../modules/oauth/oauth-memcached-conf $root localhost 11212
../../modules/oauth/oauth-memcached-conf $root localhost 11213
-../../modules/oauth/oauth-app-conf $root app1234 secret6789
../../modules/openid/openid-conf $root
../../modules/openid/openid-step2-conf $root
../../modules/openid/openid-memcached-conf $root localhost 11211