You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by rb...@apache.org on 2012/04/16 23:30:49 UTC
svn commit: r1326805 - in /shindig/trunk: config/
content/samplecontainer/examples/oauth2/
java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/
java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/persistence/
java/gadgets/src/main/jav...
Author: rbaxter85
Date: Mon Apr 16 21:30:49 2012
New Revision: 1326805
URL: http://svn.apache.org/viewvc?rev=1326805&view=rev
Log:
SHINDIG-1731
Committed For Adam Clarke
Share OAuth2Token for a user across multiple gadgets
Added:
shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared1.xml (with props)
shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared2.xml (with props)
Modified:
shindig/trunk/config/oauth2.json
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/BasicOAuth2Store.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/OAuth2Message.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/persistence/OAuth2Client.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/persistence/sample/JSONOAuth2Persister.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/oauth2/persistence/OAuth2ClientTest.java
Modified: shindig/trunk/config/oauth2.json
URL: http://svn.apache.org/viewvc/shindig/trunk/config/oauth2.json?rev=1326805&r1=1326804&r2=1326805&view=diff
==============================================================================
--- shindig/trunk/config/oauth2.json (original)
+++ shindig/trunk/config/oauth2.json Mon Apr 16 21:30:49 2012
@@ -28,7 +28,7 @@
* to attain the information necessary to complete the OAuth 2.0 request *
* *
* *
- *******************************************************************************
+ *******************************************************************************
*/
{
"gadgetBindings" : {
@@ -38,6 +38,18 @@
"allowModuleOverride" : "true"
}
},
+ "%origin%%contextRoot%/samplecontainer/examples/oauth2/oauth2_google_shared1.xml" : {
+ "googleAPI" : {
+ "clientName" : "googleApi_shared_client",
+ "allowModuleOverride" : "true"
+ }
+ },
+ "%origin%%contextRoot%/samplecontainer/examples/oauth2/oauth2_google_shared2.xml" : {
+ "googleAPI" : {
+ "clientName" : "googleApi_shared_client",
+ "allowModuleOverride" : "true"
+ }
+ },
"%origin%%contextRoot%/samplecontainer/examples/oauth2/oauth2_facebook.xml" : {
"facebook" : {
"clientName" : "facebook_client1",
@@ -62,8 +74,7 @@
"allowModuleOverride" : "true"
}
}
- },
-
+ },
"clients" : {
"googleApi_client1" : {
"providerName" : "googleAPI",
@@ -71,9 +82,18 @@
"type" : "confidential",
"grant_type" : "code",
"client_id" : "YOUR_GOOGLE_APP_ID",
- "client_secret" : "YOUR_GOOGLE_APP_SECRET"
+ "client_secret" : "YOUR_GOOGLE_APP_SECRET",
+ "sharedToken" : "false"
+ },
+ "googleApi_shared_client" : {
+ "providerName" : "googleAPI",
+ "redirect_uri" : "%origin%%contextRoot%/gadgets/oauth2callback",
+ "type" : "confidential",
+ "grant_type" : "code",
+ "client_id" : "YOUR_GOOGLE_APP_ID",
+ "client_secret" : "YOUR_GOOGLE_APP_SECRET",
+ "sharedToken" : "true"
},
-
"facebook_client1" : {
"providerName" : "facebook",
"redirect_uri" : "%origin%%contextRoot%/gadgets/oauth2callback",
@@ -82,7 +102,6 @@
"client_id" : "YOUR_FACEBOOK_APP_ID",
"client_secret" : "YOUR_FACEBOOK_APP_SECRET"
},
-
"wl_client1" : {
"providerName" : "wlProvider",
"type" : "confidential",
@@ -104,31 +123,27 @@
"grant_type" : "code",
"client_id" : "testClientCredentialsClient",
"client_secret" : "clientCredentialsClient_secret"
- }
-
+ }
},
-
"providers" : {
"googleAPI" : {
- "client_authentication" : "STANDARD",
- "usesAuthorizationHeader" : "false",
+ "client_authentication" : "STANDARD",
+ "usesAuthorizationHeader" : "false",
"usesUrlParameter" : "true",
"endpoints" : {
"authorizationUrl" : "https://accounts.google.com/o/oauth2/auth",
"tokenUrl" : "https://accounts.google.com/o/oauth2/token"
}
},
-
"facebook" : {
"client_authentication" : "STANDARD",
"usesAuthorizationHeader" : "false",
- "usesUrlParameter" : "true",
+ "usesUrlParameter" : "true",
"endpoints" : {
"authorizationUrl" : "https://www.facebook.com/dialog/oauth",
"tokenUrl" : "https://graph.facebook.com/oauth/access_token"
}
},
-
"wlProvider" : {
"client_authentication" : "STANDARD",
"usesAuthorizationHeader" : "false",
@@ -138,7 +153,6 @@
"tokenUrl" : "https://oauth.live.com/token"
}
},
-
"shindigOAuth2Provider" : {
"client_authentication" : "Basic",
"usesAuthorizationHeader" : "true",
Added: shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared1.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared1.xml?rev=1326805&view=auto
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared1.xml (added)
+++ shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared1.xml Mon Apr 16 21:30:49 2012
@@ -0,0 +1,130 @@
+<?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.
+-->
+<Module>
+ <ModulePrefs title="Demo OAuth2 Authorization Code Gadget, uses sharedToken (1)">
+ <OAuth2>
+ <Service name="googleAPI" scope="https://www.google.com/m8/feeds/">
+ </Service>
+ </OAuth2>
+ <Require feature="oauthpopup" />
+ </ModulePrefs>
+ <Content type="html">
+ <![CDATA[
+
+ <style>
+ #main {
+ margin: 0px;
+ padding: 0px;
+ font-size: small;
+ }
+ </style>
+
+ <div id="main" style="display: none">
+ </div>
+
+ <div id="approval" style="display: none">
+ <a href="#" id="personalize">Personalize this gadget</a>
+ <ol>
+ <b><u>In order to use this Demo Gadget you must</u></b>
+ <li>Have or create a Google account and know your userid and password</li>
+ <li>Register a new application at <a href="https://code.google.com/apis/console">https://code.google.com/apis/console</a></li>
+ <li>Make sure your app's "Redirect URIs" applies to your shindig environment (e.g. http://localhost:8080/gadgets/oauth2callback)</li>
+ <li>Update the Google client "Client ID" and "Client Secret" in the OAuth2 persistence (default is <code>config/oauth2.json</code>)</li>
+ <li>Restart the server</li>
+ <li>Click the link above to initiate the authorization process</li>
+ </ol>
+ </div>
+
+ <div id="waiting" style="display: none">
+ Please click
+ <a href="#" id="approvaldone">I've approved access</a>
+ once you've approved access to your data.
+ </div>
+
+ <div id="error" style="display: none;background-color:yellow;font-size:xx-small;" title="An error occured processing your request">
+ <div id="error_code"><u>code:</u></div>
+ <div id="error_uri"><u>uri:</u></div>
+ <div id="error_description"><u>description:</u></div>
+ <div id="error_explanation"><u>explanation:</u></div>
+ <div id="error_trace"><u>trace:</u></div>
+ </div>
+
+ <script type="text/javascript">
+ function getElement(x) {
+ return document.getElementById(x);
+ }
+
+ function showOneSection(toshow) {
+ var sections = [ 'main', 'approval', 'waiting', 'error' ];
+ for (var i=0; i < sections.length; ++i) {
+ var s = sections[i];
+ var el = getElement(s);
+ if (s === toshow) {
+ el.style.display = "block";
+ } else {
+ el.style.display = "none";
+ }
+ }
+ }
+
+ function fetchData() {
+ url = "https://www.google.com/m8/feeds/contacts/default/full";
+ var params = {};
+ params[gadgets.io.RequestParameters.CONTENT_TYPE] =
+ gadgets.io.ContentType.TEXT;
+ params[gadgets.io.RequestParameters.AUTHORIZATION] =
+ gadgets.io.AuthorizationType.OAUTH2;
+ params[gadgets.io.RequestParameters.METHOD] =
+ gadgets.io.MethodType.GET;
+ params[gadgets.io.RequestParameters.OAUTH_SERVICE_NAME] = "googleAPI";
+ params[gadgets.io.RequestParameters.REFRESH_INTERVAL] = "0";
+
+ gadgets.io.makeRequest(url, function (response) {
+ if (response.oauthApprovalUrl) {
+ var onOpen = function() {
+ showOneSection('waiting');
+ };
+ var onClose = function() {
+ fetchData();
+ };
+ var popup = new gadgets.oauth.Popup(response.oauthApprovalUrl,
+ null, onOpen, onClose);
+ getElement('personalize').onclick = popup.createOpenerOnClick();
+ getElement('approvaldone').onclick = popup.createApprovedOnClick();
+ showOneSection('approval');
+ } else if (response.data) {
+ getElement('main').appendChild(document.createTextNode(response.data));
+ showOneSection('main');
+ } else {
+ getElement('error_code').appendChild(document.createTextNode(response.oauthError));
+ getElement('error_uri').appendChild(document.createTextNode(response.oauthErrorUri));
+ getElement('error_description').appendChild(document.createTextNode(response.oauthErrorText));
+ getElement('error_explanation').appendChild(document.createTextNode(response.oauthErrorExplanation));
+ getElement('error_trace').appendChild(document.createTextNode(response.oauthErrorTrace));
+ showOneSection('error');
+ }
+ }, params);
+ }
+
+ gadgets.util.registerOnLoadHandler(fetchData);
+ </script>
+ ]]>
+ </Content>
+</Module>
\ No newline at end of file
Propchange: shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared1.xml
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared2.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared2.xml?rev=1326805&view=auto
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared2.xml (added)
+++ shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared2.xml Mon Apr 16 21:30:49 2012
@@ -0,0 +1,130 @@
+<?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.
+-->
+<Module>
+ <ModulePrefs title="Demo OAuth2 Authorization Code Gadget, uses sharedToken (2)">
+ <OAuth2>
+ <Service name="googleAPI" scope="https://www.google.com/m8/feeds/">
+ </Service>
+ </OAuth2>
+ <Require feature="oauthpopup" />
+ </ModulePrefs>
+ <Content type="html">
+ <![CDATA[
+
+ <style>
+ #main {
+ margin: 0px;
+ padding: 0px;
+ font-size: small;
+ }
+ </style>
+
+ <div id="main" style="display: none">
+ </div>
+
+ <div id="approval" style="display: none">
+ <a href="#" id="personalize">Personalize this gadget</a>
+ <ol>
+ <b><u>In order to use this Demo Gadget you must</u></b>
+ <li>Have or create a Google account and know your userid and password</li>
+ <li>Register a new application at <a href="https://code.google.com/apis/console">https://code.google.com/apis/console</a></li>
+ <li>Make sure your app's "Redirect URIs" applies to your shindig environment (e.g. http://localhost:8080/gadgets/oauth2callback)</li>
+ <li>Update the Google client "Client ID" and "Client Secret" in the OAuth2 persistence (default is <code>config/oauth2.json</code>)</li>
+ <li>Restart the server</li>
+ <li>Click the link above to initiate the authorization process</li>
+ </ol>
+ </div>
+
+ <div id="waiting" style="display: none">
+ Please click
+ <a href="#" id="approvaldone">I've approved access</a>
+ once you've approved access to your data.
+ </div>
+
+ <div id="error" style="display: none;background-color:yellow;font-size:xx-small;" title="An error occured processing your request">
+ <div id="error_code"><u>code:</u></div>
+ <div id="error_uri"><u>uri:</u></div>
+ <div id="error_description"><u>description:</u></div>
+ <div id="error_explanation"><u>explanation:</u></div>
+ <div id="error_trace"><u>trace:</u></div>
+ </div>
+
+ <script type="text/javascript">
+ function getElement(x) {
+ return document.getElementById(x);
+ }
+
+ function showOneSection(toshow) {
+ var sections = [ 'main', 'approval', 'waiting', 'error' ];
+ for (var i=0; i < sections.length; ++i) {
+ var s = sections[i];
+ var el = getElement(s);
+ if (s === toshow) {
+ el.style.display = "block";
+ } else {
+ el.style.display = "none";
+ }
+ }
+ }
+
+ function fetchData() {
+ url = "https://www.google.com/m8/feeds/contacts/default/full";
+ var params = {};
+ params[gadgets.io.RequestParameters.CONTENT_TYPE] =
+ gadgets.io.ContentType.TEXT;
+ params[gadgets.io.RequestParameters.AUTHORIZATION] =
+ gadgets.io.AuthorizationType.OAUTH2;
+ params[gadgets.io.RequestParameters.METHOD] =
+ gadgets.io.MethodType.GET;
+ params[gadgets.io.RequestParameters.OAUTH_SERVICE_NAME] = "googleAPI";
+ params[gadgets.io.RequestParameters.REFRESH_INTERVAL] = "0";
+
+ gadgets.io.makeRequest(url, function (response) {
+ if (response.oauthApprovalUrl) {
+ var onOpen = function() {
+ showOneSection('waiting');
+ };
+ var onClose = function() {
+ fetchData();
+ };
+ var popup = new gadgets.oauth.Popup(response.oauthApprovalUrl,
+ null, onOpen, onClose);
+ getElement('personalize').onclick = popup.createOpenerOnClick();
+ getElement('approvaldone').onclick = popup.createApprovedOnClick();
+ showOneSection('approval');
+ } else if (response.data) {
+ getElement('main').appendChild(document.createTextNode(response.data));
+ showOneSection('main');
+ } else {
+ getElement('error_code').appendChild(document.createTextNode(response.oauthError));
+ getElement('error_uri').appendChild(document.createTextNode(response.oauthErrorUri));
+ getElement('error_description').appendChild(document.createTextNode(response.oauthErrorText));
+ getElement('error_explanation').appendChild(document.createTextNode(response.oauthErrorExplanation));
+ getElement('error_trace').appendChild(document.createTextNode(response.oauthErrorTrace));
+ showOneSection('error');
+ }
+ }, params);
+ }
+
+ gadgets.util.registerOnLoadHandler(fetchData);
+ </script>
+ ]]>
+ </Content>
+</Module>
\ No newline at end of file
Propchange: shindig/trunk/content/samplecontainer/examples/oauth2/oauth2_google_shared2.xml
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/BasicOAuth2Store.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/BasicOAuth2Store.java?rev=1326805&r1=1326804&r2=1326805&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/BasicOAuth2Store.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/BasicOAuth2Store.java Mon Apr 16 21:30:49 2012
@@ -1,22 +1,24 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package org.apache.shindig.gadgets.oauth2;
-import java.util.Set;
+import com.google.inject.Inject;
import org.apache.shindig.gadgets.GadgetException;
import org.apache.shindig.gadgets.GadgetException.Code;
@@ -24,11 +26,10 @@ import org.apache.shindig.gadgets.oauth2
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2Cache;
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2CacheException;
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2Client;
-import org.apache.shindig.gadgets.oauth2.persistence.OAuth2Encrypter;
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2PersistenceException;
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2Persister;
-import com.google.inject.Inject;
+import java.util.Set;
/**
* see {@link OAuth2Store}
@@ -43,7 +44,7 @@ import com.google.inject.Inject;
public class BasicOAuth2Store implements OAuth2Store {
private final static String LOG_CLASS = BasicOAuth2Store.class.getName();
private static final FilteredLogger LOG = FilteredLogger
- .getFilteredLogger(BasicOAuth2Store.LOG_CLASS);
+ .getFilteredLogger(BasicOAuth2Store.LOG_CLASS);
private final OAuth2Cache cache;
private final String globalRedirectUri;
@@ -51,7 +52,7 @@ public class BasicOAuth2Store implements
@Inject
public BasicOAuth2Store(final OAuth2Cache cache, final OAuth2Persister persister,
- final String globalRedirectUri) {
+ final String globalRedirectUri) {
this.cache = cache;
this.persister = persister;
this.globalRedirectUri = globalRedirectUri;
@@ -101,11 +102,11 @@ public class BasicOAuth2Store implements
}
public OAuth2Client getClient(final String gadgetUri, final String serviceName)
- throws GadgetException {
+ throws GadgetException {
final boolean isLogging = BasicOAuth2Store.LOG.isLoggable();
if (isLogging) {
BasicOAuth2Store.LOG.entering(BasicOAuth2Store.LOG_CLASS, "getClient", new Object[] {
- gadgetUri, serviceName });
+ gadgetUri, serviceName });
}
final Integer index = this.cache.getClientIndex(gadgetUri, serviceName);
@@ -131,7 +132,7 @@ public class BasicOAuth2Store implements
BasicOAuth2Store.LOG.log("Error loading OAuth2 client ", e);
}
throw new GadgetException(Code.OAUTH_STORAGE_ERROR, "Error loading OAuth2 client "
- + serviceName, e);
+ + serviceName, e);
}
}
@@ -158,11 +159,11 @@ public class BasicOAuth2Store implements
}
public OAuth2Accessor getOAuth2Accessor(final String gadgetUri, final String serviceName,
- final String user, final String scope) throws GadgetException {
+ final String user, final String scope) throws GadgetException {
final boolean isLogging = BasicOAuth2Store.LOG.isLoggable();
if (isLogging) {
BasicOAuth2Store.LOG.entering(BasicOAuth2Store.LOG_CLASS, "getOAuth2Accessor", new Object[] {
- gadgetUri, serviceName, user, scope });
+ gadgetUri, serviceName, user, scope });
}
final Integer index = this.cache.getOAuth2AccessorIndex(gadgetUri, serviceName, user, scope);
@@ -174,12 +175,12 @@ public class BasicOAuth2Store implements
if (client != null) {
final OAuth2Token accessToken = this.getToken(gadgetUri, serviceName, user, scope,
- OAuth2Token.Type.ACCESS);
+ OAuth2Token.Type.ACCESS);
final OAuth2Token refreshToken = this.getToken(gadgetUri, serviceName, user, scope,
- OAuth2Token.Type.REFRESH);
+ OAuth2Token.Type.REFRESH);
final BasicOAuth2Accessor newAccessor = new BasicOAuth2Accessor(gadgetUri, serviceName,
- user, scope, client.isAllowModuleOverride(), this, this.globalRedirectUri);
+ user, scope, client.isAllowModuleOverride(), this, this.globalRedirectUri);
newAccessor.setAccessToken(accessToken);
newAccessor.setAuthorizationUrl(client.getAuthorizationUrl());
newAccessor.setClientAuthenticationType(client.getClientAuthenticationType());
@@ -206,30 +207,33 @@ public class BasicOAuth2Store implements
}
public Integer getOAuth2AccessorIndex(final String gadgetUri, final String serviceName,
- final String user, final String scope) {
+ final String user, final String scope) {
return this.cache.getOAuth2AccessorIndex(gadgetUri, serviceName, user, scope);
}
public OAuth2Token getToken(final String gadgetUri, final String serviceName, final String user,
- final String scope, final OAuth2Token.Type type) throws GadgetException {
+ final String scope, final OAuth2Token.Type type) throws GadgetException {
final boolean isLogging = BasicOAuth2Store.LOG.isLoggable();
if (isLogging) {
BasicOAuth2Store.LOG.entering(BasicOAuth2Store.LOG_CLASS, "getToken", new Object[] {
- gadgetUri, serviceName, user, scope, type });
+ gadgetUri, serviceName, user, scope, type });
}
- final Integer index = this.cache.getTokenIndex(gadgetUri, serviceName, user, scope, type);
+ final String processedGadgetUri = this.getGadgetUri(gadgetUri, serviceName);
+
+ final Integer index = this.cache.getTokenIndex(processedGadgetUri, serviceName, user, scope,
+ type);
OAuth2Token token = this.cache.getToken(index);
if (token == null) {
try {
- token = this.persister.findToken(gadgetUri, serviceName, user, scope, type);
+ token = this.persister.findToken(processedGadgetUri, serviceName, user, scope, type);
if (token != null) {
this.cache.storeToken(token);
}
} catch (final OAuth2PersistenceException e) {
throw new GadgetException(Code.OAUTH_STORAGE_ERROR, "Error loading OAuth2 token " + index,
- e);
+ e);
}
}
@@ -285,7 +289,7 @@ public class BasicOAuth2Store implements
if (accessor != null) {
final Integer index = this.cache.getOAuth2AccessorIndex(accessor.getGadgetUri(),
- accessor.getServiceName(), accessor.getUser(), accessor.getScope());
+ accessor.getServiceName(), accessor.getUser(), accessor.getScope());
return this.cache.removeOAuth2Accessor(index);
}
@@ -308,7 +312,7 @@ public class BasicOAuth2Store implements
}
return this.removeToken(token.getGadgetUri(), token.getServiceName(), token.getUser(),
- token.getScope(), token.getType());
+ token.getScope(), token.getType());
}
if (isLogging) {
@@ -319,19 +323,23 @@ public class BasicOAuth2Store implements
}
public OAuth2Token removeToken(final String gadgetUri, final String serviceName,
- final String user, final String scope, final OAuth2Token.Type type) throws GadgetException {
+ final String user, final String scope, final OAuth2Token.Type type)
+ throws GadgetException {
final boolean isLogging = BasicOAuth2Store.LOG.isLoggable();
if (isLogging) {
BasicOAuth2Store.LOG.entering(BasicOAuth2Store.LOG_CLASS, "removeToken", new Object[] {
- gadgetUri, serviceName, user, scope, type });
+ gadgetUri, serviceName, user, scope, type });
}
- final Integer index = this.cache.getTokenIndex(gadgetUri, serviceName, user, scope, type);
+ final String processedGadgetUri = this.getGadgetUri(gadgetUri, serviceName);
+
+ final Integer index = this.cache.getTokenIndex(processedGadgetUri, serviceName, user, scope,
+ type);
try {
final OAuth2Token token = this.cache.removeToken(index);
if (token != null) {
- this.persister.removeToken(gadgetUri, serviceName, user, scope, type);
+ this.persister.removeToken(processedGadgetUri, serviceName, user, scope, type);
}
if (isLogging) {
@@ -344,15 +352,15 @@ public class BasicOAuth2Store implements
BasicOAuth2Store.LOG.log("Error loading OAuth2 token ", e);
}
throw new GadgetException(Code.OAUTH_STORAGE_ERROR, "Error loading OAuth2 token "
- + serviceName, e);
+ + serviceName, e);
}
}
public static boolean runImport(final OAuth2Persister source, final OAuth2Persister target,
- final boolean clean) {
+ final boolean clean) {
if (BasicOAuth2Store.LOG.isLoggable()) {
BasicOAuth2Store.LOG.entering(BasicOAuth2Store.LOG_CLASS, "runImport", new Object[] { source,
- target, clean });
+ target, clean });
}
// No import for default persistence
@@ -366,9 +374,16 @@ public class BasicOAuth2Store implements
}
if (token != null) {
+ final String gadgetUri = token.getGadgetUri();
+ final String serviceName = token.getServiceName();
+
+ final String processedGadgetUri = this.getGadgetUri(gadgetUri, serviceName);
+
+ token.setGadgetUri(processedGadgetUri);
+
final Integer index = this.cache.getTokenIndex(token);
- final OAuth2Token existingToken = this.getToken(token.getGadgetUri(), token.getServiceName(),
- token.getUser(), token.getScope(), token.getType());
+ final OAuth2Token existingToken = this.getToken(processedGadgetUri, token.getServiceName(),
+ token.getUser(), token.getScope(), token.getType());
try {
if (existingToken == null) {
this.persister.insertToken(token);
@@ -382,13 +397,13 @@ public class BasicOAuth2Store implements
BasicOAuth2Store.LOG.log("Error storing OAuth2 token " + index, e);
}
throw new GadgetException(Code.OAUTH_STORAGE_ERROR, "Error storing OAuth2 token " + index,
- e);
+ e);
} catch (final OAuth2PersistenceException e) {
if (isLogging) {
BasicOAuth2Store.LOG.log("Error storing OAuth2 token " + index, e);
}
throw new GadgetException(Code.OAUTH_STORAGE_ERROR, "Error storing OAuth2 token " + index,
- e);
+ e);
}
}
@@ -409,4 +424,17 @@ public class BasicOAuth2Store implements
BasicOAuth2Store.LOG.exiting(BasicOAuth2Store.LOG_CLASS, "storeOAuth2Accessor");
}
}
+
+ protected String getGadgetUri(final String gadgetUri, final String serviceName)
+ throws GadgetException {
+ String ret = gadgetUri;
+ final OAuth2Client client = this.getClient(ret, serviceName);
+ if (client != null) {
+ if (client.isSharedToken()) {
+ ret = client.getClientId() + ':' + client.getServiceName();
+ }
+ }
+
+ return ret;
+ }
}
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/OAuth2Message.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/OAuth2Message.java?rev=1326805&r1=1326804&r2=1326805&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/OAuth2Message.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/OAuth2Message.java Mon Apr 16 21:30:49 2012
@@ -71,6 +71,7 @@ public interface OAuth2Message {
public final static String RESPONSE_TYPE = "response_type";
public final static String SCOPE = "scope";
public final static String SERVER_ERROR = "server_error";
+ public final static String SHARED_TOKEN = "sharedToken";
public final static String STANDARD_AUTH_TYPE = "STANDARD";
public final static String STATE = "state";
public final static String TEMPORARILY_UNAVAILABLE = "temporarily_unavailable";
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/persistence/OAuth2Client.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/persistence/OAuth2Client.java?rev=1326805&r1=1326804&r2=1326805&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/persistence/OAuth2Client.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/persistence/OAuth2Client.java Mon Apr 16 21:30:49 2012
@@ -48,6 +48,7 @@ public class OAuth2Client implements Ser
private String tokenUrl;
private OAuth2Accessor.Type type = OAuth2Accessor.Type.UNKNOWN;
private boolean urlParameter;
+ private boolean sharedToken = false;
@Inject
public OAuth2Client(final OAuth2Encrypter encrypter) {
@@ -77,6 +78,9 @@ public class OAuth2Client implements Ser
} else if (!this.serviceName.equals(other.serviceName)) {
return false;
}
+ if (this.sharedToken != other.sharedToken) {
+ return false;
+ }
return true;
}
@@ -170,6 +174,10 @@ public class OAuth2Client implements Ser
return this.authorizationHeader;
}
+ public boolean isSharedToken() {
+ return this.sharedToken;
+ }
+
public boolean isUrlParameter() {
return this.urlParameter;
}
@@ -220,6 +228,10 @@ public class OAuth2Client implements Ser
this.serviceName = serviceName;
}
+ public void setSharedToken(final boolean sharedToken) {
+ this.sharedToken = sharedToken;
+ }
+
public void setTokenUrl(final String tokenUrl) {
this.tokenUrl = tokenUrl;
}
@@ -239,6 +251,31 @@ public class OAuth2Client implements Ser
+ this.gadgetUri + " , clientId = " + this.clientId + " , grantType = " + this.grantType
+ " , type = " + this.type.name() + " , grantType = " + this.grantType + " , tokenUrl = "
+ this.tokenUrl + " , authorizationUrl = " + this.authorizationUrl
- + " , this.clientAuthenticationType = " + this.clientAuthenticationType;
+ + " , this.clientAuthenticationType = " + this.clientAuthenticationType
+ + " , this.sharedToken = " + this.sharedToken;
+ }
+
+ @Override
+ public OAuth2Client clone() {
+ final OAuth2Client ret = new OAuth2Client(this.encrypter);
+ ret.setAllowModuleOverride(this.allowModuleOverride);
+ ret.setAuthorizationHeader(this.authorizationHeader);
+ ret.setAuthorizationUrl(authorizationUrl);
+ ret.setClientAuthenticationType(this.clientAuthenticationType);
+ ret.setClientId(this.clientId);
+ try {
+ ret.setClientSecret(this.clientSecret);
+ } catch (OAuth2EncryptionException e) {
+ }
+ ret.setGadgetUri(this.gadgetUri);
+ ret.setGrantType(this.grantType);
+ ret.setRedirectUri(this.redirectUri);
+ ret.setServiceName(this.serviceName);
+ ret.setSharedToken(this.sharedToken);
+ ret.setTokenUrl(this.tokenUrl);
+ ret.setType(this.type);
+ ret.setUrlParameter(this.urlParameter);
+
+ return ret;
}
}
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/persistence/sample/JSONOAuth2Persister.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/persistence/sample/JSONOAuth2Persister.java?rev=1326805&r1=1326804&r2=1326805&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/persistence/sample/JSONOAuth2Persister.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth2/persistence/sample/JSONOAuth2Persister.java Mon Apr 16 21:30:49 2012
@@ -1,27 +1,27 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package org.apache.shindig.gadgets.oauth2.persistence.sample;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
+import com.google.caja.util.Maps;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.google.inject.name.Named;
import org.apache.shindig.common.Nullable;
import org.apache.shindig.common.servlet.Authority;
@@ -37,17 +37,19 @@ import org.apache.shindig.gadgets.oauth2
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2PersistenceException;
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2Persister;
import org.apache.shindig.gadgets.oauth2.persistence.OAuth2TokenPersistence;
+
import org.json.JSONException;
import org.json.JSONObject;
-import com.google.caja.util.Maps;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import com.google.inject.name.Named;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
/**
- * Persistence implementation that reads <code>config/oauth2.json</code> on
- * startup
+ * Persistence implementation that reads <code>config/oauth2.json</code> on startup
*
*/
@Singleton
@@ -77,20 +79,20 @@ public class JSONOAuth2Persister impleme
private final static String LOG_CLASS = JSONOAuth2Persister.class.getName();
private static final FilteredLogger LOG = FilteredLogger
- .getFilteredLogger(JSONOAuth2Persister.LOG_CLASS);
+ .getFilteredLogger(JSONOAuth2Persister.LOG_CLASS);
@Inject
public JSONOAuth2Persister(final OAuth2Encrypter encrypter, final Authority authority,
- final String globalRedirectUri,
- @Nullable @Named("shindig.contextroot") final String contextRoot)
- throws OAuth2PersistenceException {
+ final String globalRedirectUri, @Nullable
+ @Named("shindig.contextroot")
+ final String contextRoot) throws OAuth2PersistenceException {
this.encrypter = encrypter;
this.authority = authority;
this.globalRedirectUri = globalRedirectUri;
this.contextRoot = contextRoot;
try {
this.configFile = new JSONObject(
- JSONOAuth2Persister.getJSONString(JSONOAuth2Persister.OAUTH2_CONFIG));
+ JSONOAuth2Persister.getJSONString(JSONOAuth2Persister.OAUTH2_CONFIG));
} catch (final Exception e) {
if (JSONOAuth2Persister.LOG.isLoggable()) {
JSONOAuth2Persister.LOG.log("OAuth2PersistenceException", e);
@@ -100,8 +102,9 @@ public class JSONOAuth2Persister impleme
}
public JSONOAuth2Persister(final OAuth2Encrypter encrypter, final Authority authority,
- final String globalRedirectUri,
- @Nullable @Named("shindig.contextroot") final String contextRoot, final JSONObject configFile) {
+ final String globalRedirectUri, @Nullable
+ @Named("shindig.contextroot")
+ final String contextRoot, final JSONObject configFile) {
this.encrypter = encrypter;
this.authority = authority;
this.globalRedirectUri = globalRedirectUri;
@@ -113,29 +116,34 @@ public class JSONOAuth2Persister impleme
return new OAuth2TokenPersistence(this.encrypter);
}
- public static OAuth2Client findClient(@SuppressWarnings("unused") final Integer index) {
+ public static OAuth2Client findClient(@SuppressWarnings("unused")
+ final Integer index) {
return null;
}
public OAuth2Client findClient(final String providerName, final String gadgetUri)
- throws OAuth2PersistenceException {
+ throws OAuth2PersistenceException {
return null;
}
- public static OAuth2Provider findProvider(@SuppressWarnings("unused") final Integer index) {
+ public static OAuth2Provider findProvider(@SuppressWarnings("unused")
+ final Integer index) {
return null;
}
- public static OAuth2Provider findProvider(@SuppressWarnings("unused") final String providerName) {
+ public static OAuth2Provider findProvider(@SuppressWarnings("unused")
+ final String providerName) {
return null;
}
- public static OAuth2Token findToken(@SuppressWarnings("unused") final Integer index) {
+ public static OAuth2Token findToken(@SuppressWarnings("unused")
+ final Integer index) {
return null;
}
public OAuth2Token findToken(final String providerName, final String gadgetUri,
- final String user, final String scope, final Type type) throws OAuth2PersistenceException {
+ final String user, final String scope, final Type type)
+ throws OAuth2PersistenceException {
return null;
}
@@ -173,6 +181,10 @@ public class JSONOAuth2Persister impleme
final String clientId = settings.getString(OAuth2Message.CLIENT_ID);
final String typeS = settings.optString(JSONOAuth2Persister.TYPE, null);
String grantType = settings.optString(OAuth2Message.GRANT_TYPE, null);
+ final String sharedToken = settings.optString(OAuth2Message.SHARED_TOKEN, "false");
+ if ("true".equalsIgnoreCase(sharedToken)) {
+ client.setSharedToken(true);
+ }
try {
client.setEncryptedSecret(secret.getBytes("UTF-8"));
@@ -216,7 +228,8 @@ public class JSONOAuth2Persister impleme
final Set<OAuth2Client> ret = new HashSet<OAuth2Client>(gadgetBindings.size());
for (final OAuth2GadgetBinding binding : gadgetBindings.values()) {
final String clientName = binding.getClientName();
- final OAuth2Client client = internalMap.get(clientName);
+ final OAuth2Client cachedClient = internalMap.get(clientName);
+ final OAuth2Client client = cachedClient.clone();
client.setGadgetUri(binding.getGadgetUri());
client.setServiceName(binding.getGadgetServiceName());
client.setAllowModuleOverride(binding.isAllowOverride());
@@ -231,7 +244,7 @@ public class JSONOAuth2Persister impleme
try {
final JSONObject bindings = this.configFile
- .getJSONObject(JSONOAuth2Persister.GADGET_BINDGINGS);
+ .getJSONObject(JSONOAuth2Persister.GADGET_BINDGINGS);
for (final Iterator<?> i = bindings.keys(); i.hasNext();) {
final String gadgetUriS = (String) i.next();
String gadgetUri = null;
@@ -247,12 +260,12 @@ public class JSONOAuth2Persister impleme
final JSONObject settings = binding.getJSONObject(gadgetServiceName);
final String clientName = settings.getString(JSONOAuth2Persister.CLIENT_NAME);
final boolean allowOverride = settings
- .getBoolean(JSONOAuth2Persister.ALLOW_MODULE_OVERRIDE);
+ .getBoolean(JSONOAuth2Persister.ALLOW_MODULE_OVERRIDE);
final OAuth2GadgetBinding gadgetBinding = new OAuth2GadgetBinding(gadgetUri,
- gadgetServiceName, clientName, allowOverride);
+ gadgetServiceName, clientName, allowOverride);
ret.put(gadgetBinding.getGadgetUri() + ':' + gadgetBinding.getGadgetServiceName(),
- gadgetBinding);
+ gadgetBinding);
}
}
@@ -276,12 +289,12 @@ public class JSONOAuth2Persister impleme
final JSONObject provider = providers.getJSONObject(providerName);
final JSONObject endpoints = provider.getJSONObject(JSONOAuth2Persister.ENDPOINTS);
- final String clientAuthenticationType = provider
- .optString(JSONOAuth2Persister.CLIENT_AUTHENTICATION,
+ final String clientAuthenticationType = provider.optString(
+ JSONOAuth2Persister.CLIENT_AUTHENTICATION,
JSONOAuth2Persister.NO_CLIENT_AUTHENTICATION);
final boolean authorizationHeader = provider.optBoolean(
- JSONOAuth2Persister.AUTHORIZATION_HEADER, false);
+ JSONOAuth2Persister.AUTHORIZATION_HEADER, false);
final boolean urlParameter = provider.optBoolean(JSONOAuth2Persister.URL_PARAMETER, false);
@@ -326,13 +339,14 @@ public class JSONOAuth2Persister impleme
return Collections.emptySet();
}
- public static boolean removeToken(@SuppressWarnings("unused") final Integer index) {
+ public static boolean removeToken(@SuppressWarnings("unused")
+ final Integer index) {
// does nothing
return false;
}
public boolean removeToken(final String providerName, final String gadgetUri, final String user,
- final String scope, final Type type) {
+ final String scope, final Type type) {
return false;
}
Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/oauth2/persistence/OAuth2ClientTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/oauth2/persistence/OAuth2ClientTest.java?rev=1326805&r1=1326804&r2=1326805&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/oauth2/persistence/OAuth2ClientTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/oauth2/persistence/OAuth2ClientTest.java Mon Apr 16 21:30:49 2012
@@ -54,9 +54,9 @@ public class OAuth2ClientTest extends Mo
Assert.assertEquals(false, result.isAuthorizationHeader());
Assert.assertEquals(false, result.isUrlParameter());
Assert
- .assertEquals(
- "org.apache.shindig.gadgets.oauth2.persistence.sample.OAuth2ClientImpl: serviceName = null , redirectUri = null , gadgetUri = null , clientId = null , grantType = NONE , type = UNKNOWN , grantType = NONE , tokenUrl = null , authorizationUrl = null , this.clientAuthenticationType = null",
- result.toString());
+ .assertEquals(
+ "org.apache.shindig.gadgets.oauth2.persistence.sample.OAuth2ClientImpl: serviceName = null , redirectUri = null , gadgetUri = null , clientId = null , grantType = NONE , type = UNKNOWN , grantType = NONE , tokenUrl = null , authorizationUrl = null , this.clientAuthenticationType = null , this.sharedToken = false",
+ result.toString());
}
@Test