Introduced OAuth

This commit is contained in:
Benjamin Ebling
2014-06-05 17:31:20 +02:00
parent 739d15e05d
commit f47c838ead
54 changed files with 4585 additions and 25 deletions
+1
View File
@@ -2,3 +2,4 @@ build.log
gwt-unitCache
bin/
log
**/*.orig
@@ -32,5 +32,5 @@
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
<stringAttribute key="workspace_bundles" value="com.google.gwt.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.mongodb.driver@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.deckmanadapter@4:true,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:default,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@4:true,com.sap.sailing.domain.swisstimingreplayadapter@4:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@4:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@5:true,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.mongodb@default:default,com.sap.sailing.nmeaconnector@default:default,com.sap.sailing.operationaltransformation@default:default,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@4:true,com.sap.sailing.server.gateway.serialization@default:default,com.sap.sailing.server.gateway@5:true,com.sap.sailing.server.replication@4:true,com.sap.sailing.server.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@4:true,com.sap.sailing.www@4:true,com.sap.sailing.xrr.resultimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.gwt@default:default,com.tractrac.clientmodule@default:default,net.sf.marineapi@default:default,org.json.simple@default:default,org.moxieapps.gwt.highcharts@default:default"/>
<stringAttribute key="workspace_bundles" value="com.google.gwt.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.mongodb.driver@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.deckmanadapter@4:true,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:default,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@4:true,com.sap.sailing.domain.swisstimingreplayadapter@4:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@4:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@5:true,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.mongodb@default:default,com.sap.sailing.nmeaconnector@default:default,com.sap.sailing.operationaltransformation@default:default,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@4:true,com.sap.sailing.server.gateway.serialization@default:default,com.sap.sailing.server.gateway@5:true,com.sap.sailing.server.replication@4:true,com.sap.sailing.server.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@4:true,com.sap.sailing.www@4:true,com.sap.sailing.xrr.resultimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.gwt@default:default,com.sap.sse.security.ui@6:true,com.sap.sse.security.userstore.mongodb@4:true,com.sap.sse.security.userstore@default:default,com.sap.sse.security@5:true,com.tractrac.clientmodule@default:default,net.sf.marineapi@default:default,org.json.simple@default:default,org.moxieapps.gwt.highcharts@default:default"/>
</launchConfiguration>
@@ -33,6 +33,6 @@
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
<stringAttribute key="workspace_bundles" value="com.google.gwt.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.mongodb.driver@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.deckmanadapter@4:true,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:true,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@4:true,com.sap.sailing.domain.swisstimingreplayadapter@4:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@4:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@5:true,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.mongodb@default:default,com.sap.sailing.nmeaconnector@default:default,com.sap.sailing.operationaltransformation@default:default,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@4:true,com.sap.sailing.server.gateway.serialization@default:default,com.sap.sailing.server.gateway@5:true,com.sap.sailing.server.replication@4:true,com.sap.sailing.server.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@4:true,com.sap.sailing.www@4:true,com.sap.sailing.xrr.resultimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.gwt@default:default,com.tractrac.clientmodule@default:default,net.sf.marineapi@default:default,org.json.simple@default:default,org.moxieapps.gwt.highcharts@default:default"/>
<stringAttribute key="workspace_bundles" value="com.google.gwt.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.mongodb.driver@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.deckmanadapter@4:true,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:true,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@4:true,com.sap.sailing.domain.swisstimingreplayadapter@4:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@4:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@5:true,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.mongodb@default:default,com.sap.sailing.nmeaconnector@default:default,com.sap.sailing.operationaltransformation@default:default,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@4:true,com.sap.sailing.server.gateway.serialization@default:default,com.sap.sailing.server.gateway@5:true,com.sap.sailing.server.replication@4:true,com.sap.sailing.server.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@4:true,com.sap.sailing.www@4:true,com.sap.sailing.xrr.resultimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.gwt@default:default,com.sap.sse.security.ui@6:true,com.sap.sse.security.userstore.mongodb@4:true,com.sap.sse.security.userstore@default:default,com.sap.sse.security@5:true,com.tractrac.clientmodule@default:default,net.sf.marineapi@default:default,org.json.simple@default:default,org.moxieapps.gwt.highcharts@default:default"/>
<stringAttribute key="yk-options" value="&#13;&#10;additional-options2=onexit\=snapshot&#13;&#10;"/>
</launchConfiguration>
@@ -14,7 +14,8 @@ Require-Bundle: javax.servlet;bundle-version="2.5.0",
com.sap.sse.security.userstore;bundle-version="1.0.0",
com.sap.sse.gwt;bundle-version="1.0.0",
com.google.gwt.osgi;bundle-version="2.6.0",
com.sap.sse.security;bundle-version="1.0.0"
com.sap.sse.security;bundle-version="1.0.0",
org.json.simple
Web-ContextPath: /security/ui
Export-Package: com.sap.sse.security.ui.loginpanel,
com.sap.sse.security.ui.server
@@ -0,0 +1,50 @@
<!doctype html>
<!-- The DOCTYPE declaration above will set the -->
<!-- browser's rendering engine into -->
<!-- "Standards Mode". Replacing this declaration -->
<!-- with a "Quirks Mode" doctype may lead to some -->
<!-- differences in layout. -->
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!-- -->
<!-- Consider inlining CSS to reduce the number of requested files -->
<!-- -->
<link rel="shortcut icon" type="image/x-icon" href="images/sap.ico" />
<!-- -->
<!-- Any title is fine -->
<!-- -->
<title>SAP Sailing Analytics Login</title>
<!-- -->
<!-- This script loads your compiled module. -->
<!-- If you add any GWT meta tags, they must -->
<!-- be added before this line. -->
<!-- -->
<script type="text/javascript" language="javascript" src="com.sap.sse.security.ui.OAuthLogin/com.sap.sse.security.ui.OAuthLogin.nocache.js"></script>
</head>
<!-- -->
<!-- The body can have arbitrary html, or -->
<!-- you can leave the body empty if you want -->
<!-- to create a completely dynamic UI. -->
<!-- -->
<body>
<!-- OPTIONAL: include this if you want history support -->
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
<!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
<noscript>
<div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
Your web browser must have JavaScript enabled
in order for this application to display correctly.
</div>
</noscript>
</body>
</html>
@@ -51,6 +51,7 @@ fieldset legend {
.settingsPanel-grid {
border: 1px solid black;
height: 95%;
}
/** Set ids using widget.getElement().setId("idOfElement") */
@@ -0,0 +1,2 @@
serviceClass: com.google.gwt.logging.shared.RemoteLoggingService
path: D8354F129B90BCD8991531844AB1022F.gwt.rpc
@@ -0,0 +1,2 @@
serviceClass: com.sap.sse.security.ui.oauth.shared.OAuthLoginService
path: 8B735C8E798B98733A7E8B145C0120A5.gwt.rpc
@@ -0,0 +1,2 @@
serviceClass: com.sap.sse.security.ui.oauth.shared.OAuthLoginService
path: EEC5843F25ABA077B61E75156C653DD9.gwt.rpc
@@ -0,0 +1,2 @@
serviceClass: com.sap.sse.security.ui.oauth.shared.OAuthLoginService
path: AD1ADB31EBB60B39D94A60549A394B28.gwt.rpc
+32 -9
View File
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- Apache Shiro -->
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener
@@ -27,15 +27,38 @@
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<servlet>
<display-name>User Management Service</display-name>
<servlet-name>UserManagementService</servlet-name>
<servlet-class>com.sap.sse.security.ui.server.UserManagementServiceImpl</servlet-class>
<servlet-name>UserManagementService</servlet-name>
<servlet-class>com.sap.sse.security.ui.server.UserManagementServiceImpl
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserManagementService</servlet-name>
<url-pattern>/service/usermanagement</url-pattern>
</servlet-mapping>
<servlet>
<display-name>OAuth Login Service</display-name>
<servlet-name>OAuthLogintService</servlet-name>
<servlet-class>com.sap.sse.security.ui.oauth.server.OAuthLoginServiceImpl
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OAuthLogintService</servlet-name>
<url-pattern>/service/oauthlogin</url-pattern>
</servlet-mapping>
<!-- remote logging -->
<servlet>
<servlet-name>remoteLogging</servlet-name>
<servlet-class>com.google.gwt.logging.server.RemoteLoggingServiceImpl
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>remoteLogging</servlet-name>
<url-pattern>/com.sap.sse.security.ui.OAuthLogin/remote_logging</url-pattern>
</servlet-mapping>
</web-app>
@@ -13,6 +13,7 @@ import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.IntegerBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.sap.sse.security.ui.shared.UserManagementServiceAsync;
@@ -62,8 +63,9 @@ public class SettingsPanel extends FlowPanel {
if (settings == null || settingTypes == null){
return;
}
Grid grid = new Grid(settings.size(), 2);
grid.addStyleName("settingsPanel-grid");
Grid grid = new Grid(settingTypes.size(), 2);
ScrollPanel scrollPanel = new ScrollPanel(grid);
scrollPanel.addStyleName("settingsPanel-grid");
int row = 0;
for (Entry<String, String> e : settingTypes.entrySet()){
final String key = e.getKey();
@@ -114,7 +116,7 @@ public class SettingsPanel extends FlowPanel {
}
else {
final TextBox value = new TextBox();
value.setText(settings.get(key).toString());
value.setText(settings.get(key));
value.addChangeHandler(new ChangeHandler() {
@Override
@@ -135,6 +137,6 @@ public class SettingsPanel extends FlowPanel {
}
row++;
}
add(grid);
add(scrollPanel);
}
}
@@ -0,0 +1,283 @@
package com.sap.sse.security.ui.oauth.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.RootPanel;
import com.sap.sse.security.ui.oauth.client.component.LoginScreen;
import com.sap.sse.security.ui.oauth.client.model.CredentialDTO;
import com.sap.sse.security.ui.oauth.client.model.SocialUserDTO;
import com.sap.sse.security.ui.oauth.client.util.ClientUtils;
import com.sap.sse.security.ui.oauth.shared.OAuthLoginService;
import com.sap.sse.security.ui.oauth.shared.OAuthLoginServiceAsync;
public class OAuthLoginEntryPoint implements EntryPoint {
// private static final Logger logger = Logger.getLogger(OAuthLoginEntryPoint.class.getName());
private final OAuthLoginServiceAsync oauthLoginService = GWT.create(OAuthLoginService.class);
LoginScreen loginScreen = new LoginScreen();
public void onModuleLoad() {
registerASyncService((ServiceDefTarget) oauthLoginService, "service/oauthlogin");
GWT.log("Loading app..");
setupLoginScreenHandlers();
RootPanel.get().add(loginScreen);
try {
handleRedirect();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
updateLoginStatus();
}
public void updateLoginStatus() {
// if there is a client side session show, Logout link
// if (ClientUtils.alreadyLoggedIn())
// {
// //log("Already logged in..showing Logout anchor");
// showLogoutAnchor();
// }
// else
// {
// //log("Showing Login anchor..");
// showLoginAchor();
// }
updateLoginLabel();
}
private void updateLoginLabel() {
String name = ClientUtils.getUsernameFromCookie();
// String authProviderName = ClientUtils.getAuthProviderNameFromCookie();
if (name != null) {
// String labelStr = "Welcome " + "<font color=\"#006600\">"+ authProviderName + "</font>" + " user " +
// "<font color=\"#006600\">" + name + "</font>";
// updateWelcomeLabel(labelStr);
} else {
// updateWelcomeLabel(WELCOME_STRING);
}
}
private void handleRedirect() throws Exception {
if (ClientUtils.redirected()) {
if (!ClientUtils.alreadyLoggedIn()) {
verifySocialUser();
}
} else {
// Window.alert("No redirection..");
}
updateLoginStatus();
}
private void verifySocialUser() throws Exception {
final String authProviderName = ClientUtils.getAuthProviderNameFromCookie();
final int authProvider = ClientUtils.getAuthProviderFromCookieAsInt();
log("Verifying " + authProviderName + " user ...");
oauthLoginService.verifySocialUser(ClientUtils.getCredential(), new AsyncCallback<SocialUserDTO>() {
@Override
public void onFailure(Throwable caught) {
Window.alert("Coult not verify" + authProvider + " user." + caught);
}
@Override
public void onSuccess(SocialUserDTO result) {
ClientUtils.saveSessionId(result.getSessionId());
String name = "";
if (result.getName() != null) {
name = result.getName();
} else if (result.getNickname() != null) // yahoo
{
name = result.getNickname();
} else if (result.getFirstName() != null) // linkedin
{
name = result.getFirstName();
String lastName = result.getLastName();
if (lastName != null) {
name = name + " " + lastName;
}
}
log(authProviderName + " user '" + name + "' is verified!\n" + result.getJson());
ClientUtils.saveUsername(name);
updateLoginStatus();
}
});
}
private void setupLoginScreenHandlers() {
loginScreen.getFacebookImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("Facebook");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getGoogleImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("Google");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getTwitterImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("Twitter");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getYahooImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("Yahoo!");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getLinkedinImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("Linkedin");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getInstagramImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("Instagram");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getVimeoImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("Vimeo");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getGithubImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("github");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getFlickrImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("flickr");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getLiveImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("Windows Live");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getTumblrImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("tumblr.");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getFoursquareImage().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final int authProvider = ClientUtils.getAuthProvider("foursquare");
getAuthorizationUrl(authProvider);
}
});
loginScreen.getBtnLogin().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
// clear all cookes first
ClientUtils.clearCookies();
// save the auth provider to cookie
ClientUtils.saveAuthProvider(ClientUtils.DEFAULT);
try {
verifySocialUser();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
private void getAuthorizationUrl(final int authProvider) {
String authProviderName = ClientUtils.getAuthProviderName(authProvider);
final String callbackUrl = ClientUtils.getCallbackUrl();
GWT.log("Getting authorization url");
final CredentialDTO credential = new CredentialDTO();
credential.setRedirectUrl(callbackUrl);
credential.setAuthProvider(authProvider);
oauthLoginService.getAuthorizationUrl(credential, new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
ClientUtils.handleException(caught);
}
@Override
public void onSuccess(String result) {
String authorizationUrl = result;
GWT.log("Authorization url: " + authorizationUrl);
// clear all cookes first
ClientUtils.clearCookies();
// save the auth provider to cookie
ClientUtils.saveAuthProvider(authProvider);
// save the redirect url to a cookie as well
// we need to redirect there after logout
ClientUtils.saveRediretUrl(callbackUrl);
// Window.alert("Redirecting to: " + authorizationUrl);
ClientUtils.redirect(authorizationUrl);
}
});
}
public void log(String msg) {
GWT.log(msg);
}
protected void registerASyncService(ServiceDefTarget serviceToRegister, String servicePath) {
String moduleBaseURL = GWT.getModuleBaseURL();
String baseURL = moduleBaseURL.substring(0, moduleBaseURL.lastIndexOf('/', moduleBaseURL.length()-2)+1);
serviceToRegister.setServiceEntryPoint(baseURL + servicePath);
}
}
@@ -0,0 +1,383 @@
package com.sap.sse.security.ui.oauth.client.component;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.sap.sse.security.ui.oauth.client.resources.ImageResources;
public class LoginScreen extends Composite
{
private VerticalPanel verticalPanel;
private Grid grid;
private FlexTable flexTableLeft;
private FlexTable flexTableRight;
private Image image;
private Image facebookImage;
private Image googleImage;
private Image twitterImage;
private Image linkedinImage;
private Image yahooImage;
private Image vimeoImage;
private Image githubImage;
private Image instagramImage;
private Image flickrImage;
private Image liveImage;
private Image tumblrImage;
private Image foursquareImage;
private TextBox usernameTextBox;
private PasswordTextBox passwordTextBox;
public static ImageResources images = ImageResources.INSTANCE;
private HorizontalPanel horizontalPanel;
private Button btnLogin;
public VerticalPanel getVerticalPanel()
{
return verticalPanel;
}
public Grid getGrid()
{
return grid;
}
public FlexTable getFlexTableLeft()
{
return flexTableLeft;
}
public FlexTable getFlexTableRight()
{
return flexTableRight;
}
public Image getImage()
{
return image;
}
public Image getFacebookImage()
{
return facebookImage;
}
public Image getGoogleImage()
{
return googleImage;
}
public Image getTwitterImage()
{
return twitterImage;
}
public Image getLinkedinImage()
{
return linkedinImage;
}
public Image getYahooImage()
{
return yahooImage;
}
public Image getVimeoImage()
{
return vimeoImage;
}
public Image getGithubImage()
{
return githubImage;
}
public HorizontalPanel getHorizontalPanel()
{
return horizontalPanel;
}
public Button getBtnLogin()
{
return btnLogin;
}
public Image getInstagramImage()
{
return instagramImage;
}
public Image getFlickrImage()
{
return flickrImage;
}
public TextBox getUsernameTextBox()
{
return usernameTextBox;
}
public PasswordTextBox getPasswordTextBox()
{
return passwordTextBox;
}
public void resetLoginParams()
{
getUsernameTextBox().setText("");
getPasswordTextBox().setText("");
}
public Image getLiveImage()
{
return liveImage;
}
public Image getTumblrImage()
{
return tumblrImage;
}
public Image getFoursquareImage()
{
return foursquareImage;
}
public LoginScreen()
{
verticalPanel = new VerticalPanel();
verticalPanel.setWidth("100%");
verticalPanel.setSpacing(4);
initWidget(verticalPanel);
HorizontalAlignmentConstant hal = HasHorizontalAlignment.ALIGN_LEFT;
HorizontalAlignmentConstant har = HasHorizontalAlignment.ALIGN_RIGHT;
grid = new Grid(1, 2);
verticalPanel.add(grid);
DecoratorPanel dp = new DecoratorPanel();
/* left side */
flexTableLeft = new FlexTable();
dp.add(flexTableLeft);
grid.setWidget(0, 0, dp);
Label loginWithLabel = new Label("Login With");
loginWithLabel.setWordWrap(false);
// loginWithLabel.setStyleName(labelStyle);
flexTableLeft.setWidget(0,0,loginWithLabel);
// row 1
int r; int c;
r = 1; c = 0;
facebookImage = new Image(images.facebookIconImageData().getSafeUri());
image = facebookImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with Facebook");
flexTableLeft.setWidget(r,c,image);
r = 1; c = 1;
googleImage = new Image(images.googleIconImageData().getSafeUri());
image = googleImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with Google");
flexTableLeft.setWidget(r,c,image);
flexTableLeft.getCellFormatter().setHorizontalAlignment(r,c,har);
r = 1; c = 2;
twitterImage = new Image(images.twitterIconImageData().getSafeUri());
image = twitterImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with Twitter");
flexTableLeft.setWidget(r,c,image);
flexTableLeft.getCellFormatter().setHorizontalAlignment(r,c,har);
r = 1; c = 3;
yahooImage = new Image(images.yahooIconImageData().getSafeUri());
image = yahooImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with Yahoo!");
flexTableLeft.setWidget(r,c,image);
flexTableLeft.getCellFormatter().setHorizontalAlignment(r,c,har);
// row 2
r = 2; c = 0;
linkedinImage = new Image(images.linkedinIconImageData().getSafeUri());
image = linkedinImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with LinkedIn");
flexTableLeft.setWidget(r,c,image);
flexTableLeft.getCellFormatter().setHorizontalAlignment(r,c,har);
r = 2; c = 1;
instagramImage = new Image(images.instagramIconImageData().getSafeUri());
image = instagramImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with Instagram");
flexTableLeft.setWidget(r,c,image);
flexTableLeft.getCellFormatter().setHorizontalAlignment(r,c,har);
r = 2; c = 2;
vimeoImage = new Image(images.vimeoIconImageData().getSafeUri());
image = vimeoImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with Vimeo");
flexTableLeft.setWidget(r,c,image);
flexTableLeft.getCellFormatter().setHorizontalAlignment(r,c,har);
r = 2; c = 3;
githubImage = new Image(images.githubIconImageData().getSafeUri());
image = githubImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with github");
flexTableLeft.setWidget(r,c,image);
flexTableLeft.getCellFormatter().setHorizontalAlignment(r,c,har);
// row 3
r = 3; c = 0;
flickrImage = new Image(images.flickrIconImageData().getSafeUri());
image = flickrImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with flickr");
flexTableLeft.setWidget(r,c,image);
flexTableLeft.getCellFormatter().setHorizontalAlignment(r,c,har);
r = 3; c = 1;
liveImage = new Image(images.liveIconImageData().getSafeUri());
image = liveImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with Microsoft Live Connect");
flexTableLeft.setWidget(r,c,image);
flexTableLeft.getCellFormatter().setHorizontalAlignment(r,c,har);
flexTableLeft.getCellFormatter().setHorizontalAlignment(1, 0, HasHorizontalAlignment.ALIGN_RIGHT);
flexTableLeft.getFlexCellFormatter().setColSpan(0, 0, 4);
flexTableLeft.getCellFormatter().setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_LEFT);
r = 3; c = 2;
tumblrImage = new Image(images.tumblrIconImageData().getSafeUri());
image = tumblrImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with tumblr.");
flexTableLeft.setWidget(r,c,image);
flexTableLeft.getCellFormatter().setHorizontalAlignment(r,c,har);
flexTableLeft.getCellFormatter().setHorizontalAlignment(1, 0, HasHorizontalAlignment.ALIGN_RIGHT);
flexTableLeft.getFlexCellFormatter().setColSpan(0, 0, 4);
flexTableLeft.getCellFormatter().setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_LEFT);
r = 3; c = 3;
foursquareImage = new Image(images.foursquareIconImageData().getSafeUri());
image = foursquareImage;
// image.setStyleName(imageStyle);
image.setTitle("Login with foursquare");
flexTableLeft.setWidget(r,c,image);
flexTableLeft.getCellFormatter().setHorizontalAlignment(r,c,har);
flexTableLeft.getCellFormatter().setHorizontalAlignment(1, 0, HasHorizontalAlignment.ALIGN_RIGHT);
flexTableLeft.getFlexCellFormatter().setColSpan(0, 0, 4);
flexTableLeft.getCellFormatter().setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_LEFT);
/********************** right side *******************/
dp = new DecoratorPanel();
flexTableRight = new FlexTable();
dp.add(flexTableRight);
grid.setWidget(0, 1, dp);
loginWithLabel = new Label("Login With Default Account");
loginWithLabel.setWordWrap(false);
// loginWithLabel.setStyleName(css.loginWithLabelStyle());
r = 0; c = 0;
flexTableRight.setWidget(r,c,loginWithLabel);
flexTableRight.getCellFormatter().setHorizontalAlignment(r,c,hal);
r = 1; c = 0;
Label userNameLabel = new Label("Username:");
userNameLabel.setWordWrap(false);
flexTableRight.setWidget(r,c,userNameLabel);
flexTableRight.getCellFormatter().setHorizontalAlignment(r,c,har);
r = 1; c = 1;
usernameTextBox = new TextBox();
flexTableRight.setWidget(r,c,usernameTextBox);
usernameTextBox.setWidth("175px");
flexTableRight.getCellFormatter().setHorizontalAlignment(r,c,hal);
r = 2; c = 0;
Label passwordLabel = new Label("Password:");
passwordLabel.setWordWrap(false);
flexTableRight.setWidget(r,c,passwordLabel);
flexTableRight.getCellFormatter().setHorizontalAlignment(r,c,har);
r = 2; c = 1;
passwordTextBox = new PasswordTextBox();
flexTableRight.setWidget(r,c,passwordTextBox);
passwordTextBox.setWidth("175px");
flexTableRight.getCellFormatter().setHorizontalAlignment(r,c,hal);
r = 3; c = 0;
flexTableRight.getCellFormatter().setVerticalAlignment(0, 0, HasVerticalAlignment.ALIGN_TOP);
flexTableRight.getFlexCellFormatter().setColSpan(0, 0, 2);
horizontalPanel = new HorizontalPanel();
flexTableRight.setWidget(3, 0, horizontalPanel);
horizontalPanel.setSpacing(8);
btnLogin = new Button("Login");
// btnLogin.setStyleName(css.buttonsStyle());
horizontalPanel.add(btnLogin);
HTML l = new HTML("&nbsp; <i>(Use \"test\" and \"secret\")</i>");
horizontalPanel.add(l);
flexTableRight.getFlexCellFormatter().setColSpan(3, 0, 2);
grid.getCellFormatter().setVerticalAlignment(0, 1, HasVerticalAlignment.ALIGN_TOP);
grid.getCellFormatter().setVerticalAlignment(0, 0, HasVerticalAlignment.ALIGN_TOP);
}
}
@@ -0,0 +1,82 @@
package com.sap.sse.security.ui.oauth.client.model;
import java.io.Serializable;
@SuppressWarnings("serial")
public class CredentialDTO implements Serializable
{
private String authProviderName;
private int authProvider;
private String redirectUrl;
private String state; // facebook
private String verifier; // code for facebook
private String loginName;
private String password;
private String email;
public String getAuthProviderName()
{
return authProviderName;
}
public void setAuthProviderName(String authProviderName)
{
this.authProviderName=authProviderName;
}
public int getAuthProvider()
{
return authProvider;
}
public void setAuthProvider(int authProvider)
{
this.authProvider=authProvider;
}
public String getRedirectUrl()
{
return redirectUrl;
}
public void setRedirectUrl(String redirectUrl)
{
this.redirectUrl=redirectUrl;
}
public String getState()
{
return state;
}
public void setState(String state)
{
this.state=state;
}
public String getVerifier()
{
return verifier;
}
public void setVerifier(String verifier)
{
this.verifier=verifier;
}
public String getLoginName()
{
return loginName;
}
public void setLoginName(String loginName)
{
this.loginName=loginName;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password=password;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email=email;
}
}
@@ -0,0 +1,283 @@
package com.sap.sse.security.ui.oauth.client.model;
import java.io.Serializable;
import com.sap.sse.security.SocialUser;
/**
* The object we send back and forth between client and server.
* Note: More information is stored in server side in ServersideSession
* object.
* @author muquit@muquit.com
*/
public class SocialUserDTO implements Serializable
{
private static final long serialVersionUID=1011L;
private String sessionId;
private String email;
private String json;
/* must be named exactly as JSON google returns -- starts */
private String id;
private String name; // full name
private String given_name; // first name
private String family_name; // last name
private String gender; // same on Yahoo
private String link;
private String locale;
/* must be named exactly as JSON google returns -- ends */
/* Yahoo --starts */
private String guid; // is it always the same for the user??
private String givenName;
private String familyName;
private String nickname;
private String location;
private String birthdate;
private String timeZone;
private String lang;
private String relationShipStatus;
private int displayAge;
/* Yahoo --ends */
/* Linkedin -starts */
private String firstName;
private String lastName;
private String headline;
/* Linkedin -starts */
/*
Google returns JSON like:
{
"id": "116397076041912827850",
"name": "Muhammad Muquit",
"given_name": "Muhammad",
"family_name": "Muquit",
"link": "https://plus.google.com/116397076041912827850",
"gender": "male",
"locale": "en-US"
}
*/
/*
* http://developer.yahoo.com/social/rest_api_guide/extended-profile-resource.html#
Yahoo returns JSON like:
{
"profile": {
"uri": "http:\/\/social.yahooapis.com\/v1\/user\/ECUFIYO7BLY5FOV54XAPEQDC3Y\/profile",
"guid": "ECUFIYO7BLY5FOAPEQDC3Y",
"birthYear": 1969,
"created": "2010-01-23T13:07:10Z",
"displayAge": 43,
"gender": "M",
"image": {
"height": 192,
"imageUrl": "http:\/\/l.yimg.com\/a\/i\/identity2\/profile_192c.png",
"size": "192x192",
"width": 192
},
"location": "Philadelphia, Pennsylvania",
"memberSince": "2006-08-04T13:27:58Z",
"nickname": "jdoe",
"profileUrl": "http:\/\/profile.yahoo.com\/ECUFIYO7BLY5FOV54XAPEQDC3Y",
"searchable": false,
"updated": "2011-04-16T07:28:00Z",
"isConnected": false
}
}
*/
public SocialUserDTO() {
}
public String getSessionId()
{
return sessionId;
}
public void setSessionId(String sessionId)
{
this.sessionId=sessionId;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email=email;
}
public String getJson()
{
return json;
}
public void setJson(String json)
{
this.json=json;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id=id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public String getGiven_name()
{
return given_name;
}
public void setGiven_name(String given_name)
{
this.given_name=given_name;
}
public String getFamily_name()
{
return family_name;
}
public void setFamily_name(String family_name)
{
this.family_name=family_name;
}
public String getGender()
{
return gender;
}
public void setGender(String gender)
{
this.gender=gender;
}
public String getLink()
{
return link;
}
public void setLink(String link)
{
this.link=link;
}
public String getLocale()
{
return locale;
}
public void setLocale(String locale)
{
this.locale=locale;
}
public String getGuid()
{
return guid;
}
public void setGuid(String guid)
{
this.guid=guid;
}
public String getGivenName()
{
return givenName;
}
public void setGivenName(String givenName)
{
this.givenName=givenName;
}
public String getFamilyName()
{
return familyName;
}
public void setFamilyName(String familyName)
{
this.familyName=familyName;
}
public String getNickname()
{
return nickname;
}
public void setNickname(String nickname)
{
this.nickname=nickname;
}
public String getLocation()
{
return location;
}
public void setLocation(String location)
{
this.location=location;
}
public String getBirthdate()
{
return birthdate;
}
public void setBirthdate(String birthdate)
{
this.birthdate=birthdate;
}
public String getTimeZone()
{
return timeZone;
}
public void setTimeZone(String timeZone)
{
this.timeZone=timeZone;
}
public String getLang()
{
return lang;
}
public void setLang(String lang)
{
this.lang=lang;
}
public String getRelationShipStatus()
{
return relationShipStatus;
}
public void setRelationShipStatus(String relationShipStatus)
{
this.relationShipStatus=relationShipStatus;
}
public int getDisplayAge()
{
return displayAge;
}
public void setDisplayAge(int displayAge)
{
this.displayAge=displayAge;
}
/* linkedin */
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName=firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName=lastName;
}
public String getHeadline()
{
return headline;
}
public void setHeadline(String headline)
{
this.headline=headline;
}
/* linkedin */
}
@@ -0,0 +1,52 @@
package com.sap.sse.security.ui.oauth.client.resources;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.DataResource;
public interface ImageResources extends ClientBundle {
public static final ImageResources INSTANCE = GWT.create(ImageResources.class);
@Source("../../images/facebook.png")
public DataResource facebookIconImageData();
@Source("../../images/flickr.png")
public DataResource flickrIconImageData();
@Source("../../images/github.png")
public DataResource githubIconImageData();
@Source("../../images/google.png")
public DataResource googleIconImageData();
@Source("../../images/linkedin.png")
public DataResource linkedinIconImageData();
@Source("../../images/twitter.png")
public DataResource twitterIconImageData();
@Source("../../images/vimeo.png")
public DataResource vimeoIconImageData();
@Source("../../images/wordpress.png")
public DataResource wordpressIconImageData();
@Source("../../images/yahoo.png")
public DataResource yahooIconImageData();
@Source("../../images/instagram.png")
public DataResource instagramIconImageData();
@Source("../../images/imgur.png")
public DataResource imgurIconImageData();
@Source("../../images/live32.png")
public DataResource liveIconImageData();
@Source("../../images/tumblr.png")
public DataResource tumblrIconImageData();
@Source("../../images/foursquare.png")
public DataResource foursquareIconImageData();
}
@@ -0,0 +1,505 @@
package com.sap.sse.security.ui.oauth.client.util;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sse.security.Credential;
import com.sap.sse.security.ui.oauth.client.model.CredentialDTO;
public class ClientUtils
{
private final static String SESSION_ID_COOKIE = "gwtgoogleoauthtest_session_id";
private final static String AUTH_PROVIDER_COOKIE = "gwtgoogleoauthtest_provider";
private final static String AUTH_PROVIDER_NAME_COOKIE = "gwtgoogleoauthtest_provider_name";
private final static String USERNAME_COOKIE = "gwtgoogleoauthtest_user";
private final static String REDIRECT_URL_COOKIE = "gwtgoogleoauthtest_redirect_url";
public final static int DIALOG_X_POSITION = 20;
public final static int DIALOG_Y_POSITION = 110;
// Callback URL is registered with each OAuth Provider
//private static final String APP_CALLBACK_URL = "http://oauthdemo2012.com:8888/GWTOAuthLoginDemo.html";
//http://127.0.0.1:8888/GWTOAuthLoginDemo.html?gwt.codesvr=127.0.0.1:9997&
private static final String APP_CALLBACK_URL = "http://localhost:8888/security/ui/OAuthLogin.html?gwt.codesvr=127.0.0.1:9997";
private static final String FACEBOOK_PROTECTED_RESOURCE_URL = "https://graph.facebook.com/me";
private static final String GOOGLE_PROTECTED_RESOURSE_URL = "https://www.googleapis.com/oauth2/v1/userinfo";
private static final String TWITTER_PROTECTED_RESOURCE_URL = "https://api.twitter.com/1/account/verify_credentials.json";
// %s is guid and the caller must replace
private static final String YAHOO_PROTECTED_RESOURCE_URL = "http://social.yahooapis.com/v1/user/%s/profile?format=json";
private static final String LINKEDIN_PROTECTED_RESOURCE_URL = "http://api.linkedin.com/v1/people/~?format=json";
// %s is userId and acess token and the caller must replace
private static final String INSTAGRAM_PROTECTED_RESOURCE_URL = "https://api.instagram.com/v1/users/%s/?access_token=%s";
private static final String IMGUR_PROTECTED_RESOURCE_URL = "http://api.imgur.com/2/account.json";
private static final String GITHUB_PROTECTED_RESOURCE_URL = "https://api.github.com/user?access_token=%s";
private static final String LIVE_PROTECTED_RESOURCE_URL = "https://apis.live.net/v5.0/me";
private static final String FLICKR_PROTECTED_RESOURCE_URL = "http://api.flickr.com/services/rest?format=json&nojsoncallback=1&method=flickr.test.login";
private static final String VIMEO_PROTECTED_RESOURCE_URL = "http://vimeo.com/api/rest/v2?format=json&method=vimeo.people.getInfo";
private static final String TUMBLR_PROTECTED_RESOURCE_URL = "https://api.tumblr.com/v2/user/info";
// caller must replace %s with access token
private static final String FOURSQUARE_PROTECTED_RESOURCE_URL = "https://api.foursquare.com/v2/users/self?oauth_token=%s";
public static final String SESSION_EXPIRED_MESSAGE = "Session has expired";
private static String[] authProviders =
{
"Facebook", "Google", "Twitter", "Yahoo!",
"Flickr", "ImaGur", "LinkedIn", "Windows Live",
"Instagram","github", "Vimeo", "Evernote",
"tumblr.", "foursquare",
};
public final static int UNKNOWN = -1;
public final static int DEFAULT = 0;
public final static int FACEBOOK = 1;
public final static int GOOGLE = 2;
public final static int TWITTER = 3;
public final static int YAHOO = 4;
public final static int FLICKR = 5;
public final static int IMGUR = 6;
public final static int LINKEDIN = 7;
public final static int WINDOWS_LIVE = 8;
public final static int INSTAGRAM = 9;
public final static int GITHUB = 10;
public final static int VIMEO = 11;
public final static int EVERNOTE = 12;
public final static int TUMBLR = 13;
public final static int FOURSQUARE = 14;
public static String[] getAuthProviders()
{
return authProviders;
}
public static int getAuthProvider(String authProviderName)
{
int authProvider = DEFAULT;
authProviderName = authProviderName.toLowerCase();
if (authProviderName.equals("facebook"))
return FACEBOOK;
else if (authProviderName.equals("google"))
return GOOGLE;
else if (authProviderName.equals("twitter"))
return TWITTER;
else if (authProviderName.equals("yahoo!"))
return YAHOO;
else if (authProviderName.equals("yahoo"))
return YAHOO;
else if (authProviderName.equals("flickr"))
return FLICKR;
else if (authProviderName.equals("imgur"))
return IMGUR;
else if (authProviderName.equals("linkedin"))
return LINKEDIN;
else if (authProviderName.equals("windows live"))
return WINDOWS_LIVE;
else if (authProviderName.equals("instagram"))
return INSTAGRAM;
else if (authProviderName.equals("github"))
return GITHUB;
else if (authProviderName.equals("vimeo"))
return VIMEO;
else if (authProviderName.equals("evernote"))
return EVERNOTE;
else if (authProviderName.equals("tumblr."))
return TUMBLR;
else if (authProviderName.equals("foursquare"))
return FOURSQUARE;
return authProvider;
}
public static String getAuthProviderName(int authProvider)
{
if (authProvider == FACEBOOK)
return "Facebook";
else if (authProvider == GOOGLE)
return "Google";
else if (authProvider == TWITTER)
return "Twitter";
else if (authProvider == YAHOO)
return "Yahoo!";
else if (authProvider == FLICKR)
return "Flicker";
else if (authProvider == IMGUR)
return "ImGur";
else if (authProvider == LINKEDIN)
return "LinkedIn";
else if (authProvider == WINDOWS_LIVE)
return "Windows Live";
else if (authProvider == INSTAGRAM)
return "Instagram";
else if (authProvider == GITHUB)
return "github";
else if (authProvider == VIMEO)
return "vimeo";
else if (authProvider == EVERNOTE)
return "Evernote";
else if (authProvider == TUMBLR)
return "tumblr.";
else if (authProvider == FOURSQUARE)
return "foursquare";
return "Default";
}
public static String getCallbackUrl()
{
return APP_CALLBACK_URL;
}
public static String getProctedResourceUrl(int authProvider)
{
switch(authProvider)
{
case FACEBOOK:
{
return FACEBOOK_PROTECTED_RESOURCE_URL;
}
case GOOGLE:
{
return GOOGLE_PROTECTED_RESOURSE_URL;
}
case TWITTER:
{
return TWITTER_PROTECTED_RESOURCE_URL;
}
case YAHOO:
{
return YAHOO_PROTECTED_RESOURCE_URL;
}
case LINKEDIN:
{
return LINKEDIN_PROTECTED_RESOURCE_URL;
}
case INSTAGRAM:
{
return INSTAGRAM_PROTECTED_RESOURCE_URL;
}
case IMGUR:
{
return IMGUR_PROTECTED_RESOURCE_URL;
}
case GITHUB:
{
return GITHUB_PROTECTED_RESOURCE_URL;
}
case FLICKR:
{
return FLICKR_PROTECTED_RESOURCE_URL;
}
case VIMEO:
{
return VIMEO_PROTECTED_RESOURCE_URL;
}
case WINDOWS_LIVE:
{
return LIVE_PROTECTED_RESOURCE_URL;
}
case TUMBLR:
{
return TUMBLR_PROTECTED_RESOURCE_URL;
}
case FOURSQUARE:
{
return FOURSQUARE_PROTECTED_RESOURCE_URL;
}
default:
{
return null;
}
}
}
public static void clearCookies()
{
Cookies.removeCookie(SESSION_ID_COOKIE);
Cookies.removeCookie(AUTH_PROVIDER_COOKIE);
Cookies.removeCookie(AUTH_PROVIDER_NAME_COOKIE);
Cookies.removeCookie(USERNAME_COOKIE);
Cookies.removeCookie(REDIRECT_URL_COOKIE);
}
public static String getSessionIdFromCookie()
{
return Cookies.getCookie(SESSION_ID_COOKIE);
}
public static String getAuthProviderFromCookie()
{
return Cookies.getCookie(AUTH_PROVIDER_COOKIE);
}
public static int getAuthProviderFromCookieAsInt()
{
String authProviderStr = getAuthProviderFromCookie();
int authProvider = UNKNOWN;
if (authProviderStr != null)
{
try
{
authProvider = Integer.parseInt(authProviderStr);
}
catch(NumberFormatException e)
{
return UNKNOWN;
}
}
return authProvider;
}
public static String getAuthProviderNameFromCookie()
{
return Cookies.getCookie(AUTH_PROVIDER_NAME_COOKIE);
}
public static String getUsernameFromCookie()
{
return Cookies.getCookie(USERNAME_COOKIE);
}
public static boolean alreadyLoggedIn()
{
if (getSessionIdFromCookie() != null)
return true;
return false;
}
public static void saveSessionId(String sessionId)
{
Cookies.setCookie(SESSION_ID_COOKIE,sessionId);
}
public static void saveAuthProvider(int authProvider)
{
Cookies.setCookie(AUTH_PROVIDER_COOKIE,Integer.toString(authProvider));
String authProviderName = getAuthProviderName(authProvider);
saveAuthProviderName(authProviderName);
}
public static void saveAuthProviderName(String authProviderName)
{
Cookies.setCookie(AUTH_PROVIDER_NAME_COOKIE,authProviderName);
}
public static void saveUsername(String username)
{
Cookies.setCookie(USERNAME_COOKIE,username);
}
public static void saveRediretUrl(String url)
{
Cookies.setCookie(REDIRECT_URL_COOKIE,url);
}
public static String getRedirectUrlFromCookie()
{
return Cookies.getCookie(REDIRECT_URL_COOKIE);
}
public static void redirect(String url)
{
Window.Location.assign(url);
}
public static boolean redirected()
{
String authProvider = getAuthProviderFromCookie();
if (authProvider == null)
{
return false;
}
if (Location.getParameter("code") != null) //facebook,google,github,windows live
return true;
if (Location.getParameter("oauth_token") != null) // twitter,yahoo,flickr
return true;
if (Location.getParameter("oauth_verifier") != null) // Flickr
return true;
String error = Location.getParameter("error");
if (error != null)
{
String errorMessage = Location.getParameter("error_description");
Window.alert("Error: " + error + ":" + errorMessage);
reload();
return false;
}
return false;
}
public static void reload()
{
String appUrl = getRedirectUrlFromCookie();
int savedAuthProvider = getAuthProviderFromCookieAsInt();
clearCookies();
// if (savedAuthProvider == DEFAULT || savedAuthProvider == UNKNOWN)
// {
// GWTOAuthLoginDemo.get().updateLoginStatus();
// }
if (appUrl != null)
{
redirect(appUrl);
}
}
public static CredentialDTO getCredential() throws Exception
{
String authProvider = getAuthProviderFromCookie();
if (authProvider == null)
return null;
int ap = DEFAULT;
try
{
ap = Integer.parseInt(authProvider);
}
catch(Exception e)
{
throw new Exception("Could not convert authProvider " + authProvider + " to Integer");
}
switch(ap)
{
case DEFAULT:
{
CredentialDTO credential = new CredentialDTO();
credential.setAuthProvider(ap);
return credential;
}
case FACEBOOK:
case INSTAGRAM:
case GITHUB:
{
CredentialDTO credential = new CredentialDTO();
credential.setAuthProvider(ap);
credential.setState(Location.getParameter("state"));
credential.setVerifier(Location.getParameter("code"));
return credential;
}
case GOOGLE:
case WINDOWS_LIVE:
case FOURSQUARE:
{
CredentialDTO credential = new CredentialDTO();
credential.setAuthProvider(ap);
credential.setVerifier(Location.getParameter("code"));
return credential;
}
case TWITTER:
case YAHOO:
case LINKEDIN:
case FLICKR:
case VIMEO:
case TUMBLR:
{
CredentialDTO credential = new CredentialDTO();
credential.setAuthProvider(ap);
credential.setVerifier(Location.getParameter("oauth_verifier"));
return credential;
}
default:
{
throw new Exception("ClientUtils.getCredential: Auth Provider " + authProvider + " Not implemented yet");
}
}
}
public static void handleException(Throwable caught)
{
if (caught.getMessage().equals(ClientUtils.SESSION_EXPIRED_MESSAGE))
{
showSessionExpires();
}
else
{
showGenericException(caught);
}
}
public static void showSessionExpires()
{
Window.alert("Your session seems to have expired!\n" + "You will be logged out");
ClientUtils.reload();
}
public static void showGenericException(Throwable caught)
{
String message = "Exception: " + caught;
caught.printStackTrace();
message += "\n";
message += "Please Logout/reload the application";
//String st = LogUtil.stackTraceToString(caught);
//message += "Stack Trace:\n" + st;
Window.alert(message);
}
public static void logout()
{
final String sessionId = ClientUtils.getSessionIdFromCookie();
new AsyncCallback<Void>()
{
@Override
public void onFailure(Throwable caught)
{
ClientUtils.reload(); // reload anyway otherwise we're toast! we will never be able to log out
}
@Override
public void onSuccess(Void result)
{
// GWTOAuthLoginDemo.get().log("Logged out.. clearing cookies");
// GWTOAuthLoginDemo.get().log("Redirecting to site url");
ClientUtils.reload();
}
// @Override
// protected void callService(AsyncCallback<Void> cb)
// {
// OAuthLoginService.Util.getInstance().logout(sessionId,cb);
// }
};
}
}
@@ -0,0 +1,763 @@
/*******************************************************************************
* Copyright 2011 Google Inc. All Rights Reserved.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* 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 com.sap.sse.security.ui.oauth.server;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpSession;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.FacebookApi;
import org.scribe.builder.api.FlickrApi;
import org.scribe.builder.api.Foursquare2Api;
import org.scribe.builder.api.GoogleApi;
import org.scribe.builder.api.ImgUrApi;
import org.scribe.builder.api.LinkedInApi;
import org.scribe.builder.api.LiveApi;
import org.scribe.builder.api.TumblrApi;
import org.scribe.builder.api.TwitterApi;
import org.scribe.builder.api.VimeoApi;
import org.scribe.builder.api.YahooApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.sap.sse.security.Credential;
import com.sap.sse.security.GithubApi;
import com.sap.sse.security.InstagramApi;
import com.sap.sse.security.OAuthToken;
import com.sap.sse.security.SecurityService;
import com.sap.sse.security.SessionUtils;
import com.sap.sse.security.SocialUser;
import com.sap.sse.security.ui.Activator;
import com.sap.sse.security.ui.oauth.client.model.CredentialDTO;
import com.sap.sse.security.ui.oauth.client.model.SocialUserDTO;
import com.sap.sse.security.ui.oauth.client.util.ClientUtils;
import com.sap.sse.security.ui.oauth.shared.OAuthException;
import com.sap.sse.security.ui.oauth.shared.OAuthLoginService;
import com.sap.sse.security.userstore.shared.SocialSettingsKeys;
// GWT has similar class.
@SuppressWarnings("serial")
public class OAuthLoginServiceImpl extends RemoteServiceServlet implements OAuthLoginService {
// private final String SESSION = "GWTOAuthLoginDemo_session";
private final BundleContext context;
private SecurityService securityService;
public OAuthLoginServiceImpl() {
context = Activator.getContext();
ServiceReference<?> serviceReference = context.getServiceReference(SecurityService.class.getName());
securityService = (SecurityService) context.getService(serviceReference);
SecurityUtils.setSecurityManager(securityService.getSecurityManager());
System.setProperty("java.net.useSystemProxies", "true");
}
private final static Logger logger = Logger.getLogger(OAuthLoginServiceImpl.class.getName());
private OAuthService getOAuthService(int authProvider) {
OAuthService service = null;
switch (authProvider) {
case ClientUtils.FACEBOOK: {
service = new ServiceBuilder().provider(FacebookApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.FACEBOOK_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.FACEBOOK_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.GOOGLE: {
service = new ServiceBuilder().provider(GoogleApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.GOOGLE_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.GOOGLE_APP_SECRET.name(), String.class)).scope(securityService.getSetting(SocialSettingsKeys.GOOGLE_SCOPE.name(), String.class))
.callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.TWITTER: {
service = new ServiceBuilder().provider(TwitterApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.TWITTER_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.TWITTER_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.YAHOO: {
service = new ServiceBuilder().provider(YahooApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.YAHOO_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.YAHOO_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.LINKEDIN: {
service = new ServiceBuilder().provider(LinkedInApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.LINKEDIN_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.LINKEDIN_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.INSTAGRAM: {
service = new ServiceBuilder().provider(InstagramApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.INSTAGRAM_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.INSTAGRAM_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.GITHUB: {
service = new ServiceBuilder().provider(GithubApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.GITHUB_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.GITHUB_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.IMGUR: {
service = new ServiceBuilder().provider(ImgUrApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.IMGUR_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.IMGUR_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.FLICKR: {
service = new ServiceBuilder().provider(FlickrApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.FLICKR_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.FLICKR_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.VIMEO: {
service = new ServiceBuilder().provider(VimeoApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.VIMEO_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.VIMEO_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.WINDOWS_LIVE: {
// a Scope must be specified
service = new ServiceBuilder().provider(LiveApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.WINDOWS_LIVE_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.WINDOWS_LIVE_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl())
.scope("wl.basic").build();
break;
}
case ClientUtils.TUMBLR: {
service = new ServiceBuilder().provider(TumblrApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.TUMBLR_LIVE_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.TUMBLR_LIVE_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.FOURSQUARE: {
service = new ServiceBuilder().provider(Foursquare2Api.class).apiKey(securityService.getSetting(SocialSettingsKeys.FOURSQUARE_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.FOURSQUARE_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
default: {
return null;
}
}
return service;
}
@Override
public String getAuthorizationUrl(CredentialDTO credential) throws OAuthException {
logger.info("callback url: " + credential.getRedirectUrl());
String authorizationUrl = null;
Token requestToken = null;
int authProvider = credential.getAuthProvider();
OAuthService service = getOAuthService(authProvider);
if (service == null) {
throw new OAuthException("Could not build OAuthService");
}
if (authProvider == ClientUtils.TWITTER || authProvider == ClientUtils.YAHOO
|| authProvider == ClientUtils.LINKEDIN || authProvider == ClientUtils.FLICKR
|| authProvider == ClientUtils.IMGUR || authProvider == ClientUtils.TUMBLR
|| authProvider == ClientUtils.VIMEO) {
String authProviderName = ClientUtils.getAuthProviderName(authProvider);
logger.info(authProviderName + " requires Request token first.. obtaining..");
try {
requestToken = service.getRequestToken();
logger.info("Got request token: " + requestToken);
// we must save in the session. It will be required to
// get the access token
SessionUtils.saveRequestTokenToSession(requestToken);
} catch (Exception e) {
String stackTrace = stackTraceToString(e);
throw new OAuthException("Could not get request token for " + authProvider + " " + stackTrace);
}
}
logger.info("Getting Authorization url...");
try {
authorizationUrl = service.getAuthorizationUrl(requestToken);
// Facebook has optional state var to protect against CSFR.
// We'll use it
if (authProvider == ClientUtils.FACEBOOK || authProvider == ClientUtils.GITHUB
|| authProvider == ClientUtils.INSTAGRAM) {
String state = makeRandomString();
authorizationUrl += "&state=" + state;
SessionUtils.saveStateToSession(state);
}
} catch (Exception e) {
// String st = LogUtil.stackTraceToString(e);
throw new OAuthException("Could not get Authorization url: ");
}
if (authProvider == ClientUtils.FLICKR) {
authorizationUrl += "&perms=read";
}
logger.info("Authorization url: " + authorizationUrl);
return authorizationUrl;
}
public static String stackTraceToString(Throwable caught) {
StringBuilder sb = new StringBuilder();
for (StackTraceElement e : caught.getStackTrace()) {
sb.append(e.toString()).append("\n");
}
return sb.toString();
}
private String makeRandomString() {
UUID uuid = UUID.randomUUID();
return uuid.toString();
}
private SocialUserDTO getSocialUser(Token accessToken, int authProvider) throws OAuthException {
logger.info("Token: " + accessToken + " Provider: " + authProvider);
OAuthService service = getOAuthService(authProvider);
String url = SessionUtils.getProtectedResourceUrlFromSession();
OAuthRequest request = new OAuthRequest(Verb.GET, url);
// sign the request
service.signRequest(accessToken, request);
Response response = request.send();
String json = response.getBody();
SocialUserDTO socialUser = getSocialUserFromJson(json, authProvider);
return socialUser;
}
@Override
public SocialUserDTO verifySocialUser(CredentialDTO credentialDTO) {
OAuthToken otoken = new OAuthToken(createCredentialFromDTO(credentialDTO), credentialDTO.getVerifier());
Subject subject = SecurityUtils.getSubject();
if (!subject.isAuthenticated()) {
subject.login(otoken);
try {
subject.login(otoken);
logger.info("User [" + subject.getPrincipal().toString() + "] logged in successfully.");
} catch (UnknownAccountException uae) {
logger.info("There is no user with username of " + subject.getPrincipal());
} catch (IncorrectCredentialsException ice) {
logger.info("Password for account " + subject.getPrincipal() + " was incorrect!");
} catch (LockedAccountException lae) {
logger.info("The account for username " + subject.getPrincipal() + " is locked. "
+ "Please contact your administrator to unlock it.");
} catch (AuthenticationException ae) {
logger.log(Level.SEVERE,ae.getLocalizedMessage());
}
}
return createSocialUserDTO(SessionUtils.loadSocialUser());
}
private SocialUserDTO getSocialUserFromJson(String json, int authProvider) throws OAuthException {
String authProviderName = ClientUtils.getAuthProviderName(authProvider);
logger.info("Auth provider: " + authProviderName);
JSONParser jsonParser = new JSONParser();
Object obj = null;
SocialUserDTO socialUser = new SocialUserDTO();
switch (authProvider) {
case ClientUtils.FACEBOOK: {
/*
* --Facebook-- { "id":"537157209", "name":"Muhammad Muquit", "first_name":"Muhammad", "last_name":"Muquit",
* "link":"http:\/\/www.facebook.com\/muhammad.muquit", "username":"muhammad.muquit", "gender":"male",
* "timezone":-5,"locale":"en_US", "verified":true, "updated_time":"2012-11-10T23:13:04+0000"} }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
socialUser.setName((String) jsonObj.get("name"));
socialUser.setFirstName((String) jsonObj.get("first_name"));
socialUser.setLastName((String) jsonObj.get("last_name"));
socialUser.setGender((String) jsonObj.get("gender"));
socialUser.setJson(json);
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
case ClientUtils.YAHOO: {
/*
* --YAHOO-- http://developer.yahoo.com/social/rest_api_guide/extended-profile-resource.html# { "profile": {
* "uri": "http:\/\/social.yahooapis.com\/v1\/user\/ECUFIYO7BLY5FOV54XAPEQDC3Y\/profile", "guid":
* "ECUFIYO7BLY5FOAPEQDC3Y", "birthYear": 1969, "created": "2010-01-23T13:07:10Z", "displayAge": 89,
* "gender": "M", "image": { "height": 192, "imageUrl":
* "http:\/\/l.yimg.com\/a\/i\/identity2\/profile_192c.png", "size": "192x192", "width": 192 }, "location":
* "Philadelphia, Pennsylvania", "memberSince": "2006-08-04T13:27:58Z", "nickname": "jdoe", "profileUrl":
* "http:\/\/profile.yahoo.com\/ECUFIYO7BLY5FOV54XAPEQDC3Y", "searchable": false, "updated":
* "2011-04-16T07:28:00Z", "isConnected": false } }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
// get profile object
JSONObject jsonObjPeople = (JSONObject) jsonObj.get("profile");
socialUser.setJson(json);
socialUser.setNickname((String) jsonObjPeople.get("nickname"));
socialUser.setGender((String) jsonObjPeople.get("gender"));
socialUser.setFirstName((String) jsonObjPeople.get("givenName"));
socialUser.setLastName((String) jsonObjPeople.get("familyName"));
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
case ClientUtils.GOOGLE: {
/*
* --Google-- { "id": "116397076041912827850", "name": "Muhammad Muquit", "given_name": "Muhammad",
* "family_name": "Muquit", "link": "https://plus.google.com/116397076041912827850", "gender": "male",
* "locale": "en-US" }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
socialUser.setJson(json);
socialUser.setName((String) jsonObj.get("name"));
socialUser.setFirstName((String) jsonObj.get("given_name"));
socialUser.setLastName((String) jsonObj.get("family_name"));
socialUser.setGender((String) jsonObj.get("gender"));
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
case ClientUtils.LINKEDIN: {
/*
* --Linkedin-- { "firstName": "Muhammad", "headline": "Sr. Software Engineer at British Telecom",
* "lastName": "Muquit", }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
socialUser.setJson(json);
socialUser.setFirstName((String) jsonObj.get("firstName"));
socialUser.setLastName((String) jsonObj.get("lastName"));
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
case ClientUtils.TWITTER: {
/*
* --Twitter -- { "id":955924206, "contributors_enabled":false, "profile_use_background_image":true,
* "time_zone":"Eastern Time (US & Canada)", "following":false, "friends_count":3, "profile_text_color":
* "333333", "geo_enabled":false, "created_at":"Sun Nov 18 17:54:22 +0000 2012", "utc_offset":-18000,
* "follow_request_sent":false, "name":"Muhammad Muquit", "id_str":"955924206",
* "default_profile_image":true, "verified":false, "profile_sidebar_border_color":"C0DEED", "url":null,
* "favourites_count":0, .. "lang":"en", "profile_background_color":"C0DEED", "screen_name":"mmqt2012", .. }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
socialUser.setJson(json);
socialUser.setName((String) jsonObj.get("name"));
socialUser.setGender((String) jsonObj.get("gender"));
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
case ClientUtils.INSTAGRAM: {
/*
* -- Instragram -- { "data": { "id": "1574083", "username": "snoopdogg", "full_name": "Snoop Dogg",
* "profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_1574083_75sq_1295469061.jpg",
* "bio": "This is my bio", "website": "http://snoopdogg.com", "counts": { "media": 1320, "follows": 420,
* "followed_by": 3410 } }
*/
try {
logger.info("Instragram JSON: " + json);
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
// get profile object
JSONObject jsonObjData = (JSONObject) jsonObj.get("data");
socialUser.setJson(json);
socialUser.setName((String) jsonObjData.get("username"));
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
case ClientUtils.GITHUB: {
/*
* -- github -- { "plan":{ "private_repos":0, "space":307200, "name":"free", "collaborators":0 },
* "followers":0, "type":"User", "events_url":"https://api.github.com/users/oauthdemo2012/events{/privacy}",
* "owned_private_repos":0, "public_gists":0, "avatar_url":
* "https://secure.gravatar.com/avatar/e0cb08c2b353cc1c3022dc65ebd060d1?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"
* , "received_events_url":"https://api.github.com/users/oauthdemo2012/received_events", "private_gists":0,
* "disk_usage":0, "url":"https://api.github.com/users/oauthdemo2012",
* "followers_url":"https://api.github.com/users/oauthdemo2012/followers", "login":"oauthdemo2012",
* "created_at":"2012-12-20T01:36:36Z",
* "following_url":"https://api.github.com/users/oauthdemo2012/following",
* "organizations_url":"https://api.github.com/users/oauthdemo2012/orgs", "following":0,
* "starred_url":"https://api.github.com/users/oauthdemo2012/starred{/owner}{/repo}", "collaborators":0,
* "public_repos":0, "repos_url":"https://api.github.com/users/oauthdemo2012/repos",
* "gists_url":"https://api.github.com/users/oauthdemo2012/gists{/gist_id}", "id":3085592,
* "total_private_repos":0, "html_url":"https://github.com/oauthdemo2012",
* "subscriptions_url":"https://api.github.com/users/oauthdemo2012/subscriptions",
* "gravatar_id":"e0cb08c2b353cc1c3022dc65ebd060d1" }
*/
logger.info("github JSON: " + json);
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
socialUser.setJson(json);
socialUser.setName((String) jsonObj.get("login"));
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
case ClientUtils.FLICKR: {
/*
* -- flickr -- { "user": { "id": "91390211@N06", "username": { "_content": "oauthdemo2012" } }, "stat":
* "ok" }
*/
logger.info("Flickr JSON: " + json);
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
JSONObject jsonObjUser = (JSONObject) jsonObj.get("user");
JSONObject jsonObjUsername = (JSONObject) jsonObjUser.get("username");
socialUser.setName((String) jsonObjUsername.get("_content"));
socialUser.setJson(json);
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
case ClientUtils.VIMEO: {
/*
* --Vimeo starts -- { "generated_in": "0.0698", "stat": "ok", "person": { "created_on":
* "2012-12-22 23:37:55", "id": "15432968", "is_contact": "0", "is_plus": "0", "is_pro": "0", "is_staff":
* "0", "is_subscribed_to": "0", "username": "user15432968", "display_name": "oauthdemo2012", "location":
* "", "url": [ "" ], ..... } }
*/
logger.info("Vimeo JSON: " + json);
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
JSONObject jsonObjPerson = (JSONObject) jsonObj.get("person");
String userName = (String) jsonObjPerson.get("username");
String displayName = (String) jsonObjPerson.get("display_name");
if (displayName != null) {
socialUser.setName(displayName);
} else if (userName != null) {
socialUser.setName(userName);
} else {
socialUser.setName("Unknown");
}
socialUser.setJson(json);
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
case ClientUtils.WINDOWS_LIVE: {
/*
* Windows Live --starts -- { "id" : "contact.c1678ab4000000000000000000000000", "first_name" : "Roberto",
* "last_name" : "Tamburello", "name" : "Roberto Tamburello", "gender" : "male", "locale" : "en_US" }
*/
logger.info("Windows Live JSON: " + json);
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
JSONObject jsonErrorObj = (JSONObject) jsonObj.get("error");
if (jsonErrorObj != null) {
/*
* { "error": { "code": "request_token_too_many", "message":
* "The request includes more than one access token. Only one access token is allowed." } }
*/
String message = (String) jsonErrorObj.get("message");
throw new OAuthException("Error: " + message);
}
socialUser.setName((String) jsonObj.get("name"));
socialUser.setLastName((String) jsonObj.get("last_name"));
socialUser.setFirstName((String) jsonObj.get("first_name"));
socialUser.setJson(json);
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
case ClientUtils.TUMBLR: {
/*
* tumblr. -- { "meta": { "status": 200, "msg": "OK" }, "response": { "user": { "name": "oauthdemo2012",
* "likes": 0, "following": 1, "default_post_format": "html", "blogs": [ { "name": "oauthdemo2012", "url":
* "http:\/\/oauthdemo2012.tumblr.com\/", "followers": 0, "primary": true, "title": "Untitled",
* "description": "", "admin": true, "updated": 0, "posts": 0, "messages": 0, "queue": 0, "drafts": 0,
* "share_likes": true, "ask": false, "tweet": "N", "facebook": "N", "facebook_opengraph_enabled": "N",
* "type": "public" } ] } } }
*/
logger.info("tumblr JSON: " + json);
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
JSONObject jsonObjResponse = (JSONObject) jsonObj.get("response");
JSONObject jsonObjUser = (JSONObject) jsonObjResponse.get("user");
String userName = (String) jsonObjUser.get("name");
socialUser.setName(userName);
socialUser.setJson(json);
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
case ClientUtils.FOURSQUARE: {
/*
* foursquare -- { "meta": { "code": 200, "errorType": "deprecated", "errorDetail":
* "Please provide an API version to avoid future errors.See http://bit.ly/vywCav" }, "notifications": [ {
* "type": "notificationTray", "item": { "unreadCount": 0 } } ], "response": { "user": { "id": "43999331",
* "firstName": "OAuth", "lastName": "Demo", "gender": "none", "relationship": "self", "photo":
* "https://foursquare.com/img/blank_boy.png", "friends": { "count": 0, "groups": [ { "type": "friends",
* "name": "Mutual friends", "count": 0, "items": [] }, { "type": "others", "name": "Other friends",
* "count": 0, "items": [] } ] }, ...... } } }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
JSONObject jsonObjResponse = (JSONObject) jsonObj.get("response");
JSONObject jsonObjUser = (JSONObject) jsonObjResponse.get("user");
String firstName = (String) jsonObjUser.get("firstName");
String lastName = (String) jsonObjUser.get("lastName");
if (firstName != null && lastName != null) {
socialUser.setName(firstName + " " + lastName);
} else {
socialUser.setName("UNKNOWN");
}
socialUser.setJson(json);
return socialUser;
} catch (ParseException e) {
throw new OAuthException("Could not parse JSON data from " + authProviderName + ":" + e.getMessage());
}
}
default: {
throw new OAuthException("Unknown Auth Provider: " + authProviderName);
}
}
/*
* We don't use Gson() anymore as it choked on nested Facebook JSON data Dec-03-2012
*/
/*
* // map json to SocialUser try { Gson gson = new Gson(); SocialUser user =
* gson.fromJson(json,SocialUser.class); // pretty print json //gson = new
* GsonBuilder().setPrettyPrinting().create(); //String jsonPretty = gson.toJson(json); user.setJson(json);
* return user; } catch (Exception e) { e.printStackTrace(); throw new
* OurException("Could not map userinfo JSON to SocialUser class: " + e); }
*/
}
private HttpSession getHttpSession() {
return getThreadLocalRequest().getSession();
}
private HttpSession validateSession(String sessionId) throws OAuthException {
if (sessionId == null)
throw new OAuthException("Session Id can not be empty");
HttpSession session = getHttpSession();
if (session == null) {
throw new OAuthException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
* ServersideSession ssSession=getServersideSession(); if (ssSession == null) { throw new
* OurException(ClientUtils.SESSION_EXPIRED_MESSAGE); } if (sessionId.equals(ssSession.getSessionId())) { return
* session; }
*/
String savedSessionId = SessionUtils.getSessionIdFromSession();
if (sessionId.equals(savedSessionId)) {
return session;
}
throw new OAuthException("Session Id mismatch: expected " + "'" + sessionId + "'" + " Found: " + "'"
+ savedSessionId + "'");
}
/*
* private ServersideSession getServersideSession() { HttpSession session = getHttpSession(); if (session != null) {
* ServersideSession ssSession = (ServersideSession) session.getAttribute(SESSION); return ssSession; } return null;
* }
*/
@Override
public void logout(String sessionId) throws OAuthException {
validateSession(sessionId);
getHttpSession().invalidate();
logger.info("Invalidated HTTP session");
}
@Override
public SocialUserDTO fetchMe(String sessionId) throws OAuthException {
validateSession(sessionId);
int authProvider = SessionUtils.getAuthProviderFromSession();
Token accessToken = SessionUtils.getAccessTokenFromSession();
SocialUserDTO user = getSocialUser(accessToken, authProvider);
return user;
}
private static Map<String, String> parseQueryString(String qs) {
String[] ps = qs.split("&");
Map<String, String> map = new HashMap<String, String>();
for (String p : ps) {
String k = p.split("=")[0];
String v = p.split("=")[1];
map.put(k, v);
}
return map;
}
private String getQueryStringValue(String qs, String name) {
Map<String, String> map = parseQueryString(qs);
return map.get(name);
}
@Override
public String getAccessToken(String sessionId) throws OAuthException {
validateSession(sessionId);
Token accessToken = SessionUtils.getAccessTokenFromSession();
if (accessToken == null) {
throw new OAuthException("Could not find Access Token in HTTP Session");
}
return accessToken.getRawResponse();
}
private Credential createCredentialFromDTO(CredentialDTO credentialDTO){
Credential credential = new Credential();
credential.setAuthProvider(credentialDTO.getAuthProvider());
credential.setAuthProviderName(credentialDTO.getAuthProviderName());
credential.setEmail(credentialDTO.getEmail());
credential.setLoginName(credentialDTO.getLoginName());
credential.setPassword(credentialDTO.getPassword());
credential.setRedirectUrl(credentialDTO.getRedirectUrl());
credential.setState(credentialDTO.getState());
credential.setVerifier(credentialDTO.getVerifier());
return credential;
}
private SocialUserDTO createSocialUserDTO(SocialUser socialUser){
SocialUserDTO socialUserDTO = new SocialUserDTO();
socialUserDTO.setSessionId(socialUser.getSessionId());
socialUserDTO.setEmail(socialUser.getEmail());
socialUserDTO.setJson(socialUser.getJson());
/* must be named exactly as JSON google returns -- starts */
socialUserDTO.setId(socialUser.getId());
socialUserDTO.setName(socialUser.getName());
socialUserDTO.setGiven_name(socialUser.getGiven_name());
socialUserDTO.setFamily_name(socialUser.getFamily_name());
socialUserDTO.setGender(socialUser.getGender());
socialUserDTO.setLink(socialUser.getLink());
socialUserDTO.setLocale(socialUser.getLocale());
/* must be named exactly as JSON google returns -- ends */
/* Yahoo --starts */
socialUserDTO.setGuid(socialUser.getGuid()); // is it always the same for the user??
socialUserDTO.setGivenName(socialUser.getGivenName());
socialUserDTO.setFamilyName(socialUser.getFamilyName());
socialUserDTO.setNickname(socialUser.getNickname());
socialUserDTO.setLocation(socialUser.getLocation());
socialUserDTO.setBirthdate(socialUser.getBirthdate());
socialUserDTO.setTimeZone(socialUser.getTimeZone());
socialUserDTO.setLang(socialUser.getLang());
socialUserDTO.setRelationShipStatus(socialUser.getRelationShipStatus());
socialUserDTO.setDisplayAge(socialUser.getDisplayAge());
/* Yahoo --ends */
/* Linkedin -starts */
socialUserDTO.setFirstName(socialUser.getFirstName());
socialUserDTO.setLastName(socialUser.getLastName());
socialUserDTO.setHeadline(socialUser.getHeadline());
return socialUserDTO;
}
}
@@ -0,0 +1,21 @@
package com.sap.sse.security.ui.oauth.shared;
public class OAuthException extends Exception {
/**
*
*/
private static final long serialVersionUID = 7014475448354180158L;
public OAuthException() {
super("OAuthException!");
}
public OAuthException(String message) {
super("OAuthException: "+ message);
// TODO Auto-generated constructor stub
}
}
@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright 2011 Google Inc. All Rights Reserved.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* 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 com.sap.sse.security.ui.oauth.shared;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.sap.sse.security.ui.oauth.client.model.CredentialDTO;
import com.sap.sse.security.ui.oauth.client.model.SocialUserDTO;
@RemoteServiceRelativePath("OAuthLoginService")
public interface OAuthLoginService extends RemoteService
{
public String getAuthorizationUrl(CredentialDTO credential) throws OAuthException;
public SocialUserDTO verifySocialUser(CredentialDTO credential) throws OAuthException;
public SocialUserDTO fetchMe(String sessionId) throws OAuthException;
public String getAccessToken(String sessionId) throws OAuthException;
public void logout(String sessionId) throws OAuthException;
/**
* Utility class for simplifying access to the instance of async service.
*/
public static class Util
{
private static OAuthLoginServiceAsync instance;
public static OAuthLoginServiceAsync getInstance()
{
if (instance == null)
{
instance=GWT.create(OAuthLoginService.class);
}
return instance;
}
}
}
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright 2011 Google Inc. All Rights Reserved.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* 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 com.sap.sse.security.ui.oauth.shared;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sse.security.ui.oauth.client.model.CredentialDTO;
import com.sap.sse.security.ui.oauth.client.model.SocialUserDTO;
public interface OAuthLoginServiceAsync
{
public void getAuthorizationUrl(CredentialDTO credential, AsyncCallback<String> callback);
public void verifySocialUser(CredentialDTO credential, AsyncCallback<SocialUserDTO> callback);
public void fetchMe(String sessionId, AsyncCallback<SocialUserDTO> callback);
public void getAccessToken(String sessionId, AsyncCallback<String> callback);
public void logout(String sessionId, AsyncCallback<Void> callback);
}
@@ -8,6 +8,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
@@ -174,7 +175,7 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
@Override
public Map<String, String> getSettings() {
Map<String, String> settings = new HashMap<String, String>();
Map<String, String> settings = new TreeMap<String, String>();
for (Entry<String, Object> e : securityService.getAllSettings().entrySet()){
settings.put(e.getKey(), e.getValue().toString());
}
@@ -196,7 +197,7 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
@Override
public Map<String, String> getSettingTypes() {
Map<String, String> settingTypes = new HashMap<String, String>();
Map<String, String> settingTypes = new TreeMap<String, String>();
for (Entry<String, Class<?>> e : securityService.getAllSettingTypes().entrySet()){
settingTypes.put(e.getKey(), e.getValue().getName());
}
@@ -20,8 +20,10 @@ public class UserDTO implements IsSerializable {
}
public UserDTO(String name, AccountDTO... accounts) {
super();
this.name = name;
// for (AccountDTO account : accounts){
// this.accounts.put(account.getAccountType(), account);
// }
}
public String getName() {
@@ -43,6 +45,10 @@ public class UserDTO implements IsSerializable {
public Map<String, AccountDTO> getAccounts() {
return accounts;
}
public void setAccounts(Map<String, AccountDTO> accounts) {
this.accounts = accounts;
}
}
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Could not determine the version of your GWT SDK; using the module DTD from GWT 1.6.4. You may want to change this. -->
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.4.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.4.0/distro-source/core/src/gwt-module.dtd">
<module>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Inherit the default GWT style sheet. You can change -->
<!-- the theme of your GWT application by uncommenting -->
<!-- any one of the following lines. -->
<inherits name='com.google.gwt.user.theme.clean.Clean'/>
<inherits name='com.google.gwt.debug.Debug'/>
<!-- <inherits name='com.google.gwt.user.theme.standard.Standard'/> -->
<!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
<!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/> -->
<stylesheet src="../Login.css" />
<inherits name="com.google.gwt.resources.Resources" />
<inherits name="com.google.gwt.logging.Logging"/>
<inherits name="com.sap.sse.security.ui.LoginPanel"/>
<super-source path="jre" />
<!-- Specify the app entry point class. -->
<entry-point class='com.sap.sse.security.ui.oauth.client.OAuthLoginEntryPoint'/>
<set-property name="gwt.logging.enabled" value="TRUE"/>
<set-property name="gwt.logging.logLevel" value="FINE"/>
<set-property name="gwt.logging.firebugHandler" value="ENABLED" />
<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />
<set-property name="gwt.logging.consoleHandler" value="ENABLED" />
<set-property name="gwt.logging.developmentModeHandler" value="DISABLED" />
<set-property name="gwt.logging.popupHandler" value="DISABLED" />
<set-property name="gwt.logging.systemHandler" value="ENABLED" />
<!-- Specify the paths for translatable code -->
<extend-property name="locale" values="de"/>
<source path='client'/>
<source path='login'/>
<source path='shared'/>
<source path='oauth'/>
</module>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -11,6 +11,7 @@ import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.Sha256Hash;
import com.sap.sse.security.userstore.shared.SocialSettingsKeys;
import com.sap.sse.security.userstore.shared.User;
import com.sap.sse.security.userstore.shared.UserManagementException;
import com.sap.sse.security.userstore.shared.UserStore;
@@ -28,6 +29,7 @@ public class UserStoreImpl implements UserStore {
users = new ConcurrentHashMap<>();
settings = new ConcurrentHashMap<>();
settingTypes = new ConcurrentHashMap<String, Class<?>>();
initSocialSettingsIfEmpty();
addSetting("email_required", Boolean.class);
for (User u : PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory().loadAllUsers()){
users.put(u.getName(), u);
@@ -49,6 +51,15 @@ public class UserStoreImpl implements UserStore {
}
}
private void initSocialSettingsIfEmpty() {
for (SocialSettingsKeys ssk : SocialSettingsKeys.values()){
if (settingTypes.get(ssk.name()) == null || settings.get(ssk.name()) == null){
addSetting(ssk.name(), String.class);
setSetting(ssk.name(), ssk.getValue());
}
}
}
@Override
public String getName() {
return "MongoDB user store";
@@ -0,0 +1,31 @@
package com.sap.sse.security.userstore.shared;
public enum SocialSettingsKeys {
FACEBOOK_APP_NAME("Sailing"),FACEBOOK_APP_ID("351552528316184"),FACEBOOK_APP_SECRET("d1a0ac61c5fb36cbd6fda3c32a4af227"),
GOOGLE_APP_NAME(null), GOOGLE_APP_ID(null) , GOOGLE_APP_SECRET(null) , GOOGLE_SCOPE("https://www.googleapis.com/auth/userinfo.profile"),
TWITTER_APP_NAME(null) , TWITTER_APP_ID(null) , TWITTER_APP_SECRET(null) ,
YAHOO_APP_NAME(null) , YAHOO_APP_ID(null) , YAHOO_APP_SECRET(null) ,
INSTAGRAM_APP_NAME(null) , INSTAGRAM_APP_ID(null) , INSTAGRAM_APP_SECRET(null) ,
LINKEDIN_APP_NAME(null) , LINKEDIN_APP_ID(null) , LINKEDIN_APP_SECRET(null) , LINKEDIN_USER_TOKEN(null) , LINKEDIN_USER_SECRET(null) ,
GITHUB_APP_NAME(null) , GITHUB_APP_ID(null) , GITHUB_APP_SECRET(null) ,
FLICKR_APP_NAME(null) , FLICKR_APP_ID(null) , FLICKR_APP_SECRET(null) ,
IMGUR_APP_NAME(null) , IMGUR_APP_ID(null) , IMGUR_APP_SECRET(null) ,
VIMEO_APP_NAME(null) , VIMEO_APP_ID(null) , VIMEO_APP_SECRET(null) ,
EVERNOTE_APP_NAME(null) , EVERNOTE_APP_ID(null) , EVERNOTE_APP_SECRET(null) ,
WINDOWS_LIVE_APP_NAME(null) , WINDOWS_LIVE_APP_ID(null) , WINDOWS_LIVE_APP_SECRET(null) ,
TUMBLR_LIVE_APP_NAME(null) , TUMBLR_LIVE_APP_ID(null) , TUMBLR_LIVE_APP_SECRET(null) ,
FOURSQUARE_APP_NAME(null) , FOURSQUARE_APP_ID(null) , FOURSQUARE_APP_SECRET(null) ;
private String value;
private SocialSettingsKeys(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
+12 -2
View File
@@ -18,15 +18,25 @@ Bundle-ClassPath: lib/shiro-core-1.2.2.jar,
Require-Bundle: javax.servlet;bundle-version="2.5.0",
com.sap.sse.security.userstore;bundle-version="1.0.0",
com.google.gwt.osgi,
slf4j.api;bundle-version="1.6.4"
slf4j.api;bundle-version="1.6.4",
org.json.simple
Web-ContextPath: /security
Export-Package: com.sap.sse.security,
org.apache.shiro,
org.apache.shiro.authc,
org.apache.shiro.authz,
org.apache.shiro.authz.annotation,
org.apache.shiro.crypto,
org.apache.shiro.crypto.hash,
org.apache.shiro.realm,
org.apache.shiro.session,
org.apache.shiro.subject,
org.apache.shiro.util,
org.apache.shiro.web.env,
org.apache.shiro.web.servlet
org.apache.shiro.web.servlet,
org.scribe.builder,
org.scribe.builder.api,
org.scribe.extractors,
org.scribe.model,
org.scribe.oauth,
org.scribe.utils
+5 -2
View File
@@ -11,9 +11,12 @@ credentialsMatcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
credentialsMatcher.storedCredentialsHexEncoded = false
credentialsMatcher.hashIterations = 1024
myRealm = com.sap.sse.security.UsernamePasswordRealm
myRealm.credentialsMatcher = $credentialsMatcher
upRealm = com.sap.sse.security.UsernamePasswordRealm
upRealm.credentialsMatcher = $credentialsMatcher
oauthRealm = com.sap.sse.security.OAuthRealm
securityManager.realms = $upRealm, $oauthRealm
authc = org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter
authc.loginUrl = /Login.html?gwt.codesvr=127.0.0.1:9997
@@ -9,11 +9,16 @@ import org.osgi.framework.ServiceRegistration;
public class Activator implements BundleActivator {
private static BundleContext context;
private static SecurityService securityService;
private ServiceRegistration<?> registration;
static BundleContext getContext() {
return context;
}
static SecurityService getSecurityService(){
return securityService;
}
/*
* (non-Javadoc)
@@ -23,8 +28,9 @@ public class Activator implements BundleActivator {
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
securityService = new SecurityServiceImpl();
registration = context.registerService(SecurityService.class.getName(),
new SecurityServiceImpl(), null);
securityService, null);
Logger.getLogger(Activator.class.getName()).info("Security Service registered.");
}
@@ -0,0 +1,440 @@
package com.sap.sse.security;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.rpc.AsyncCallback;
public class ClientUtils
{
private final static String SESSION_ID_COOKIE = "gwtgoogleoauthtest_session_id";
private final static String AUTH_PROVIDER_COOKIE = "gwtgoogleoauthtest_provider";
private final static String AUTH_PROVIDER_NAME_COOKIE = "gwtgoogleoauthtest_provider_name";
private final static String USERNAME_COOKIE = "gwtgoogleoauthtest_user";
private final static String REDIRECT_URL_COOKIE = "gwtgoogleoauthtest_redirect_url";
public final static int DIALOG_X_POSITION = 20;
public final static int DIALOG_Y_POSITION = 110;
// Callback URL is registered with each OAuth Provider
//private static final String APP_CALLBACK_URL = "http://oauthdemo2012.com:8888/GWTOAuthLoginDemo.html";
//http://127.0.0.1:8888/GWTOAuthLoginDemo.html?gwt.codesvr=127.0.0.1:9997&
private static final String APP_CALLBACK_URL = "http://localhost:8888/security/ui/OAuthLogin.html?gwt.codesvr=127.0.0.1:9997";
private static final String FACEBOOK_PROTECTED_RESOURCE_URL = "https://graph.facebook.com/me";
private static final String GOOGLE_PROTECTED_RESOURSE_URL = "https://www.googleapis.com/oauth2/v1/userinfo";
private static final String TWITTER_PROTECTED_RESOURCE_URL = "https://api.twitter.com/1/account/verify_credentials.json";
// %s is guid and the caller must replace
private static final String YAHOO_PROTECTED_RESOURCE_URL = "http://social.yahooapis.com/v1/user/%s/profile?format=json";
private static final String LINKEDIN_PROTECTED_RESOURCE_URL = "http://api.linkedin.com/v1/people/~?format=json";
// %s is userId and acess token and the caller must replace
private static final String INSTAGRAM_PROTECTED_RESOURCE_URL = "https://api.instagram.com/v1/users/%s/?access_token=%s";
private static final String IMGUR_PROTECTED_RESOURCE_URL = "http://api.imgur.com/2/account.json";
private static final String GITHUB_PROTECTED_RESOURCE_URL = "https://api.github.com/user?access_token=%s";
private static final String LIVE_PROTECTED_RESOURCE_URL = "https://apis.live.net/v5.0/me";
private static final String FLICKR_PROTECTED_RESOURCE_URL = "http://api.flickr.com/services/rest?format=json&nojsoncallback=1&method=flickr.test.login";
private static final String VIMEO_PROTECTED_RESOURCE_URL = "http://vimeo.com/api/rest/v2?format=json&method=vimeo.people.getInfo";
private static final String TUMBLR_PROTECTED_RESOURCE_URL = "https://api.tumblr.com/v2/user/info";
// caller must replace %s with access token
private static final String FOURSQUARE_PROTECTED_RESOURCE_URL = "https://api.foursquare.com/v2/users/self?oauth_token=%s";
public static final String SESSION_EXPIRED_MESSAGE = "Session has expired";
private static String[] authProviders =
{
"Facebook", "Google", "Twitter", "Yahoo!",
"Flickr", "ImaGur", "LinkedIn", "Windows Live",
"Instagram","github", "Vimeo", "Evernote",
"tumblr.", "foursquare",
};
public final static int UNKNOWN = -1;
public final static int DEFAULT = 0;
public final static int FACEBOOK = 1;
public final static int GOOGLE = 2;
public final static int TWITTER = 3;
public final static int YAHOO = 4;
public final static int FLICKR = 5;
public final static int IMGUR = 6;
public final static int LINKEDIN = 7;
public final static int WINDOWS_LIVE = 8;
public final static int INSTAGRAM = 9;
public final static int GITHUB = 10;
public final static int VIMEO = 11;
public final static int EVERNOTE = 12;
public final static int TUMBLR = 13;
public final static int FOURSQUARE = 14;
public static String[] getAuthProviders()
{
return authProviders;
}
public static int getAuthProvider(String authProviderName)
{
int authProvider = DEFAULT;
authProviderName = authProviderName.toLowerCase();
if (authProviderName.equals("facebook"))
return FACEBOOK;
else if (authProviderName.equals("google"))
return GOOGLE;
else if (authProviderName.equals("twitter"))
return TWITTER;
else if (authProviderName.equals("yahoo!"))
return YAHOO;
else if (authProviderName.equals("yahoo"))
return YAHOO;
else if (authProviderName.equals("flickr"))
return FLICKR;
else if (authProviderName.equals("imgur"))
return IMGUR;
else if (authProviderName.equals("linkedin"))
return LINKEDIN;
else if (authProviderName.equals("windows live"))
return WINDOWS_LIVE;
else if (authProviderName.equals("instagram"))
return INSTAGRAM;
else if (authProviderName.equals("github"))
return GITHUB;
else if (authProviderName.equals("vimeo"))
return VIMEO;
else if (authProviderName.equals("evernote"))
return EVERNOTE;
else if (authProviderName.equals("tumblr."))
return TUMBLR;
else if (authProviderName.equals("foursquare"))
return FOURSQUARE;
return authProvider;
}
public static String getAuthProviderName(int authProvider)
{
if (authProvider == FACEBOOK)
return "Facebook";
else if (authProvider == GOOGLE)
return "Google";
else if (authProvider == TWITTER)
return "Twitter";
else if (authProvider == YAHOO)
return "Yahoo!";
else if (authProvider == FLICKR)
return "Flicker";
else if (authProvider == IMGUR)
return "ImGur";
else if (authProvider == LINKEDIN)
return "LinkedIn";
else if (authProvider == WINDOWS_LIVE)
return "Windows Live";
else if (authProvider == INSTAGRAM)
return "Instagram";
else if (authProvider == GITHUB)
return "github";
else if (authProvider == VIMEO)
return "vimeo";
else if (authProvider == EVERNOTE)
return "Evernote";
else if (authProvider == TUMBLR)
return "tumblr.";
else if (authProvider == FOURSQUARE)
return "foursquare";
return "Default";
}
public static String getCallbackUrl()
{
return APP_CALLBACK_URL;
}
public static String getProctedResourceUrl(int authProvider)
{
switch(authProvider)
{
case FACEBOOK:
{
return FACEBOOK_PROTECTED_RESOURCE_URL;
}
case GOOGLE:
{
return GOOGLE_PROTECTED_RESOURSE_URL;
}
case TWITTER:
{
return TWITTER_PROTECTED_RESOURCE_URL;
}
case YAHOO:
{
return YAHOO_PROTECTED_RESOURCE_URL;
}
case LINKEDIN:
{
return LINKEDIN_PROTECTED_RESOURCE_URL;
}
case INSTAGRAM:
{
return INSTAGRAM_PROTECTED_RESOURCE_URL;
}
case IMGUR:
{
return IMGUR_PROTECTED_RESOURCE_URL;
}
case GITHUB:
{
return GITHUB_PROTECTED_RESOURCE_URL;
}
case FLICKR:
{
return FLICKR_PROTECTED_RESOURCE_URL;
}
case VIMEO:
{
return VIMEO_PROTECTED_RESOURCE_URL;
}
case WINDOWS_LIVE:
{
return LIVE_PROTECTED_RESOURCE_URL;
}
case TUMBLR:
{
return TUMBLR_PROTECTED_RESOURCE_URL;
}
case FOURSQUARE:
{
return FOURSQUARE_PROTECTED_RESOURCE_URL;
}
default:
{
return null;
}
}
}
public static void clearCookies()
{
Cookies.removeCookie(SESSION_ID_COOKIE);
Cookies.removeCookie(AUTH_PROVIDER_COOKIE);
Cookies.removeCookie(AUTH_PROVIDER_NAME_COOKIE);
Cookies.removeCookie(USERNAME_COOKIE);
Cookies.removeCookie(REDIRECT_URL_COOKIE);
}
public static String getSessionIdFromCookie()
{
return Cookies.getCookie(SESSION_ID_COOKIE);
}
public static String getAuthProviderFromCookie()
{
return Cookies.getCookie(AUTH_PROVIDER_COOKIE);
}
public static int getAuthProviderFromCookieAsInt()
{
String authProviderStr = getAuthProviderFromCookie();
int authProvider = UNKNOWN;
if (authProviderStr != null)
{
try
{
authProvider = Integer.parseInt(authProviderStr);
}
catch(NumberFormatException e)
{
return UNKNOWN;
}
}
return authProvider;
}
public static String getAuthProviderNameFromCookie()
{
return Cookies.getCookie(AUTH_PROVIDER_NAME_COOKIE);
}
public static String getUsernameFromCookie()
{
return Cookies.getCookie(USERNAME_COOKIE);
}
public static boolean alreadyLoggedIn()
{
if (getSessionIdFromCookie() != null)
return true;
return false;
}
public static void saveSessionId(String sessionId)
{
Cookies.setCookie(SESSION_ID_COOKIE,sessionId);
}
public static void saveAuthProvider(int authProvider)
{
Cookies.setCookie(AUTH_PROVIDER_COOKIE,Integer.toString(authProvider));
String authProviderName = getAuthProviderName(authProvider);
saveAuthProviderName(authProviderName);
}
public static void saveAuthProviderName(String authProviderName)
{
Cookies.setCookie(AUTH_PROVIDER_NAME_COOKIE,authProviderName);
}
public static void saveUsername(String username)
{
Cookies.setCookie(USERNAME_COOKIE,username);
}
public static void saveRediretUrl(String url)
{
Cookies.setCookie(REDIRECT_URL_COOKIE,url);
}
public static String getRedirectUrlFromCookie()
{
return Cookies.getCookie(REDIRECT_URL_COOKIE);
}
public static void redirect(String url)
{
Window.Location.assign(url);
}
public static boolean redirected()
{
String authProvider = getAuthProviderFromCookie();
if (authProvider == null)
{
return false;
}
if (Location.getParameter("code") != null) //facebook,google,github,windows live
return true;
if (Location.getParameter("oauth_token") != null) // twitter,yahoo,flickr
return true;
if (Location.getParameter("oauth_verifier") != null) // Flickr
return true;
String error = Location.getParameter("error");
if (error != null)
{
String errorMessage = Location.getParameter("error_description");
Window.alert("Error: " + error + ":" + errorMessage);
reload();
return false;
}
return false;
}
public static void reload()
{
String appUrl = getRedirectUrlFromCookie();
int savedAuthProvider = getAuthProviderFromCookieAsInt();
clearCookies();
// if (savedAuthProvider == DEFAULT || savedAuthProvider == UNKNOWN)
// {
// GWTOAuthLoginDemo.get().updateLoginStatus();
// }
if (appUrl != null)
{
redirect(appUrl);
}
}
public static void handleException(Throwable caught)
{
if (caught.getMessage().equals(ClientUtils.SESSION_EXPIRED_MESSAGE))
{
showSessionExpires();
}
else
{
showGenericException(caught);
}
}
public static void showSessionExpires()
{
Window.alert("Your session seems to have expired!\n" + "You will be logged out");
ClientUtils.reload();
}
public static void showGenericException(Throwable caught)
{
String message = "Exception: " + caught;
caught.printStackTrace();
message += "\n";
message += "Please Logout/reload the application";
//String st = LogUtil.stackTraceToString(caught);
//message += "Stack Trace:\n" + st;
Window.alert(message);
}
public static void logout()
{
final String sessionId = ClientUtils.getSessionIdFromCookie();
new AsyncCallback<Void>()
{
@Override
public void onFailure(Throwable caught)
{
ClientUtils.reload(); // reload anyway otherwise we're toast! we will never be able to log out
}
@Override
public void onSuccess(Void result)
{
// GWTOAuthLoginDemo.get().log("Logged out.. clearing cookies");
// GWTOAuthLoginDemo.get().log("Redirecting to site url");
ClientUtils.reload();
}
// @Override
// protected void callService(AsyncCallback<Void> cb)
// {
// OAuthLoginService.Util.getInstance().logout(sessionId,cb);
// }
};
}
}
@@ -0,0 +1,82 @@
package com.sap.sse.security;
import java.io.Serializable;
@SuppressWarnings("serial")
public class Credential implements Serializable
{
private String authProviderName;
private int authProvider;
private String redirectUrl;
private String state; // facebook
private String verifier; // code for facebook
private String loginName;
private String password;
private String email;
public String getAuthProviderName()
{
return authProviderName;
}
public void setAuthProviderName(String authProviderName)
{
this.authProviderName=authProviderName;
}
public int getAuthProvider()
{
return authProvider;
}
public void setAuthProvider(int authProvider)
{
this.authProvider=authProvider;
}
public String getRedirectUrl()
{
return redirectUrl;
}
public void setRedirectUrl(String redirectUrl)
{
this.redirectUrl=redirectUrl;
}
public String getState()
{
return state;
}
public void setState(String state)
{
this.state=state;
}
public String getVerifier()
{
return verifier;
}
public void setVerifier(String verifier)
{
this.verifier=verifier;
}
public String getLoginName()
{
return loginName;
}
public void setLoginName(String loginName)
{
this.loginName=loginName;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password=password;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email=email;
}
}
@@ -0,0 +1,45 @@
package com.sap.sse.security;
import java.util.UUID;
import org.scribe.builder.api.DefaultApi20;
import org.scribe.model.OAuthConfig;
import org.scribe.model.Verb;
import org.scribe.utils.Preconditions;
/**
*
* @author muquit@muquit.com Dec 19, 2012 8:56:46 PM
*/
public class GithubApi extends DefaultApi20
{
private static final String AUTHORIZATION_URL = "https://github.com/login/oauth/authorize?client_id=%s&redirect_uri=%s&scope=user&state=%s";
@Override
public String getAccessTokenEndpoint()
{
return "https://github.com/login/oauth/access_token";
}
@Override
public Verb getAccessTokenVerb()
{
return Verb.POST;
}
/*
@Override
public AccessTokenExtractor getAccessTokenExtractor()
{
return new JsonTokenExtractor();
}
*/
@Override
public String getAuthorizationUrl(OAuthConfig config)
{
Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback for Instagram");
String uuid = UUID.randomUUID().toString();
return String.format(AUTHORIZATION_URL,config.getApiKey(),config.getCallback(),uuid);
}
}
@@ -0,0 +1,43 @@
package com.sap.sse.security;
import java.util.UUID;
import org.scribe.builder.api.DefaultApi20;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.extractors.JsonTokenExtractor;
import org.scribe.model.OAuthConfig;
import org.scribe.model.Verb;
import org.scribe.utils.Preconditions;
/**
* @author muquit@muquit.com
*/
public class InstagramApi extends DefaultApi20
{
private static final String AUTHORIZATION_URL = "https://api.instagram.com/oauth/authorize?client_id=%s&redirect_uri=%s&state=%s&response_type=code";
@Override
public String getAccessTokenEndpoint()
{
return "https://api.instagram.com/oauth/access_token";
}
@Override
public Verb getAccessTokenVerb()
{
return Verb.POST;
}
@Override
public AccessTokenExtractor getAccessTokenExtractor()
{
return new JsonTokenExtractor();
}
@Override
public String getAuthorizationUrl(OAuthConfig config)
{
Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback for Instagram");
String uuid = UUID.randomUUID().toString();
return String.format(AUTHORIZATION_URL, config.getApiKey(), config.getCallback(),uuid);
}
}
@@ -0,0 +1,708 @@
package com.sap.sse.security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.FacebookApi;
import org.scribe.builder.api.FlickrApi;
import org.scribe.builder.api.Foursquare2Api;
import org.scribe.builder.api.GoogleApi;
import org.scribe.builder.api.ImgUrApi;
import org.scribe.builder.api.LinkedInApi;
import org.scribe.builder.api.LiveApi;
import org.scribe.builder.api.TumblrApi;
import org.scribe.builder.api.TwitterApi;
import org.scribe.builder.api.VimeoApi;
import org.scribe.builder.api.YahooApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;
// GWT has similar class.
import com.sap.sse.security.userstore.shared.SocialSettingsKeys;
public class OAuthRealm extends AuthorizingRealm {
private final static Log logger = LogFactory.getLog(OAuthRealm.class);
private SecurityService securityService;
public OAuthRealm() {
securityService = Activator.getSecurityService();
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection token) {
System.out.println("authorization");
AuthorizationInfo info = new AuthorizationInfo() {
private static final long serialVersionUID = 1L;
@Override
public Collection<String> getStringPermissions() {
// TODO Auto-generated method stub
return new ArrayList<String>();
}
@Override
public Collection<String> getRoles() {
ArrayList<String> roles = new ArrayList<>();
roles.add("admin");
return roles;
}
@Override
public Collection<Permission> getObjectPermissions() {
ArrayList<Permission> permissions = new ArrayList<>();
permissions.add(new Permission() {
@Override
public boolean implies(Permission arg0) {
return false;
}
});
return permissions;
}
};
return info;
}
@Override
public boolean supports(AuthenticationToken token) {
if (token == null)
return false;
if (!(token instanceof OAuthToken))
return false;
return true;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
OAuthToken otoken = (OAuthToken) token;
Credential credential = (Credential) otoken.getCredentials();
System.out.println("Checking authentication!");
int authProvider = credential.getAuthProvider();
logger.info("authProvider: " + authProvider);
String authProviderName = ClientUtils.getAuthProviderName(authProvider);
logger.info("Verifying social usr from " + authProviderName);
Token requestToken = null;
String yahooGuid = null;
String protectedResourceUrl = ClientUtils.getProctedResourceUrl(authProvider);
if (authProvider == ClientUtils.FACEBOOK || authProvider == ClientUtils.INSTAGRAM) {
logger.info("Verifying state: " + credential.getState());
// verifyState(credential.getState());
}
/* if there is any request token in session, get it */
requestToken = SessionUtils.getRequestTokenFromSession();
OAuthService service = null;
Verifier verifier = null;
Token accessToken = null;
/* Get Access Token */
if (authProvider != ClientUtils.DEFAULT) {
service = getOAuthService(authProvider);
verifier = new Verifier(credential.getVerifier());
logger.info("Requesting access token with requestToken: " + requestToken);
logger.info("verifier=" + verifier);
try {
accessToken = service.getAccessToken(requestToken, verifier);
} catch (Exception e) {
System.out.println("Error receiving request token:");
e.printStackTrace();
}
if (accessToken == null) {
logger.error("Could not get Access Token for " + authProviderName);
throw new AuthenticationException("Could not get Access Token");
}
logger.info("Got the access token: " + accessToken);
logger.info(" Token: " + accessToken.getToken());
logger.info(" Secret: " + accessToken.getSecret());
logger.info(" Raw: " + accessToken.getRawResponse());
}
// if (authProvider == ClientUtils.INSTAGRAM)
// {
// try
// {
// instragramToken = InstragramToken.parse(accessToken.getRawResponse());
// } catch (ParseException e)
// {
// throw new RuntimeException("Could not parse " + authProviderName + " Json AccessToken");
// }
// logger.info("Getting Instragram Access Token");
// logger.info(" access token" + instragramToken.getAcessToken());
// logger.info(" userId: " + instragramToken.getUserId());
// logger.info(" full name: " + instragramToken.getFullName());
// logger.info(" username: " + instragramToken.getFullName());
// logger.info(" raw: " + instragramToken.getRawResponse());
//
// // replace userId and access token in protected resource url
// protectedResourceUrl = ClientUtils.getProctedResourceUrl(authProvider);
// logger.info("Instragram protected resource url: " + protectedResourceUrl);
// protectedResourceUrl = String.format(protectedResourceUrl,
// instragramToken.getUserId(),instragramToken.getAcessToken());
// logger.info("Instragram protected resource url: " + protectedResourceUrl);
// }
if (authProvider == ClientUtils.GITHUB || authProvider == ClientUtils.FOURSQUARE) {
protectedResourceUrl = String.format(protectedResourceUrl, accessToken.getToken());
}
if (authProvider == ClientUtils.YAHOO) {
// throw new OurException("Not implemented for yahoo yet!)");
/* we need to replace <GUID> */
yahooGuid = getQueryStringValue(accessToken.getRawResponse(), "xoauth_yahoo_guid");
if (yahooGuid == null) {
throw new RuntimeException("Could not get Yahoo GUID from Query String");
}
// must save it to session. we'll use to get the user profile
SessionUtils.saveYahooGuidToSession(yahooGuid);
protectedResourceUrl = ClientUtils.getProctedResourceUrl(authProvider);
protectedResourceUrl = String.format(protectedResourceUrl, yahooGuid);
logger.info("Yahoo protected resource url: " + protectedResourceUrl);
}
// make session id
String sessionId = makeRandomString();
// must save session id to session
SessionUtils.saveSessionIdToSession(sessionId);
// must save authProvider to session
SessionUtils.saveAuthProviderToSession(authProvider);
SocialUser socialUser = null;
if (authProvider != ClientUtils.DEFAULT) {
// must save acess token to session
SessionUtils.saveAccessTokenToSession(accessToken);
// must save the protected resource url to session
SessionUtils.saveProtectedResourceUrlToSession(protectedResourceUrl);
// now request protected resource
logger.info("Getting protected resource");
logger.info("Protected resource url: " + protectedResourceUrl);
try {
OAuthRequest request = new OAuthRequest(Verb.GET, protectedResourceUrl);
service.signRequest(accessToken, request);
Response response = request.send();
logger.info("Status code: " + response.getCode());
logger.info("Body: " + response.getBody());
String json = response.getBody();
socialUser = getSocialUserFromJson(json, authProvider);
} catch (Exception e) {
logger.error("Could not retrieve protected resource: " + e);
throw new RuntimeException("Could not retrieve protected resource: " + e);
}
} else {
throw new AuthenticationException("Not a valid SocialUser!");
}
socialUser.setSessionId(sessionId);
SessionUtils.safeSocialUser(socialUser);
SimpleAuthenticationInfo sai = new SimpleAuthenticationInfo();
SimplePrincipalCollection spc = new SimplePrincipalCollection();
spc.add(otoken.getPrincipal(), otoken.getPrincipal().toString());
sai.setCredentials(otoken.getCredentials());
sai.setPrincipals(spc);
return sai;
}
private OAuthService getOAuthService(int authProvider) throws AuthenticationException {
OAuthService service = null;
switch (authProvider) {
case ClientUtils.FACEBOOK: {
service = new ServiceBuilder().provider(FacebookApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.FACEBOOK_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.FACEBOOK_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.GOOGLE: {
service = new ServiceBuilder().provider(GoogleApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.GOOGLE_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.GOOGLE_APP_SECRET.name(), String.class)).scope(securityService.getSetting(SocialSettingsKeys.GOOGLE_SCOPE.name(), String.class))
.callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.TWITTER: {
service = new ServiceBuilder().provider(TwitterApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.TWITTER_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.TWITTER_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.YAHOO: {
service = new ServiceBuilder().provider(YahooApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.YAHOO_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.YAHOO_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.LINKEDIN: {
service = new ServiceBuilder().provider(LinkedInApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.LINKEDIN_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.LINKEDIN_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.INSTAGRAM: {
service = new ServiceBuilder().provider(InstagramApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.INSTAGRAM_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.INSTAGRAM_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.GITHUB: {
service = new ServiceBuilder().provider(GithubApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.GITHUB_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.GITHUB_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.IMGUR: {
service = new ServiceBuilder().provider(ImgUrApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.IMGUR_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.IMGUR_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.FLICKR: {
service = new ServiceBuilder().provider(FlickrApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.FLICKR_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.FLICKR_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.VIMEO: {
service = new ServiceBuilder().provider(VimeoApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.VIMEO_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.VIMEO_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.WINDOWS_LIVE: {
// a Scope must be specified
service = new ServiceBuilder().provider(LiveApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.WINDOWS_LIVE_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.WINDOWS_LIVE_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl())
.scope("wl.basic").build();
break;
}
case ClientUtils.TUMBLR: {
service = new ServiceBuilder().provider(TumblrApi.class).apiKey(securityService.getSetting(SocialSettingsKeys.TUMBLR_LIVE_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.TUMBLR_LIVE_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
case ClientUtils.FOURSQUARE: {
service = new ServiceBuilder().provider(Foursquare2Api.class).apiKey(securityService.getSetting(SocialSettingsKeys.FOURSQUARE_APP_ID.name(), String.class))
.apiSecret(securityService.getSetting(SocialSettingsKeys.FOURSQUARE_APP_SECRET.name(), String.class)).callback(ClientUtils.getCallbackUrl()).build();
break;
}
default: {
return null;
}
}
return service;
}
public static String stackTraceToString(Throwable caught) {
StringBuilder sb = new StringBuilder();
for (StackTraceElement e : caught.getStackTrace()) {
sb.append(e.toString()).append("\n");
}
return sb.toString();
}
private String makeRandomString() {
UUID uuid = UUID.randomUUID();
return uuid.toString();
}
private String getQueryStringValue(String qs, String name) {
Map<String, String> map = parseQueryString(qs);
return map.get(name);
}
private static Map<String, String> parseQueryString(String qs) {
String[] ps = qs.split("&");
Map<String, String> map = new HashMap<String, String>();
for (String p : ps) {
String k = p.split("=")[0];
String v = p.split("=")[1];
map.put(k, v);
}
return map;
}
private SocialUser getSocialUserFromJson(String json, int authProvider) throws AuthenticationException {
String authProviderName = ClientUtils.getAuthProviderName(authProvider);
Object obj = null;
JSONParser jsonParser = new JSONParser();
SocialUser socialUser = new SocialUser();
switch (authProvider) {
case ClientUtils.FACEBOOK: {
/*
* --Facebook-- { "id":"537157209", "name":"Muhammad Muquit", "first_name":"Muhammad", "last_name":"Muquit",
* "link":"http:\/\/www.facebook.com\/muhammad.muquit", "username":"muhammad.muquit", "gender":"male",
* "timezone":-5,"locale":"en_US", "verified":true, "updated_time":"2012-11-10T23:13:04+0000"} }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
socialUser.setName((String) jsonObj.get("name"));
socialUser.setFirstName((String) jsonObj.get("first_name"));
socialUser.setLastName((String) jsonObj.get("last_name"));
socialUser.setGender((String) jsonObj.get("gender"));
socialUser.setJson(json);
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
case ClientUtils.YAHOO: {
/*
* --YAHOO-- http://developer.yahoo.com/social/rest_api_guide/extended-profile-resource.html# { "profile": {
* "uri": "http:\/\/social.yahooapis.com\/v1\/user\/ECUFIYO7BLY5FOV54XAPEQDC3Y\/profile", "guid":
* "ECUFIYO7BLY5FOAPEQDC3Y", "birthYear": 1969, "created": "2010-01-23T13:07:10Z", "displayAge": 89,
* "gender": "M", "image": { "height": 192, "imageUrl":
* "http:\/\/l.yimg.com\/a\/i\/identity2\/profile_192c.png", "size": "192x192", "width": 192 }, "location":
* "Philadelphia, Pennsylvania", "memberSince": "2006-08-04T13:27:58Z", "nickname": "jdoe", "profileUrl":
* "http:\/\/profile.yahoo.com\/ECUFIYO7BLY5FOV54XAPEQDC3Y", "searchable": false, "updated":
* "2011-04-16T07:28:00Z", "isConnected": false } }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
// get profile object
JSONObject jsonObjPeople = (JSONObject) jsonObj.get("profile");
socialUser.setJson(json);
socialUser.setNickname((String) jsonObjPeople.get("nickname"));
socialUser.setGender((String) jsonObjPeople.get("gender"));
socialUser.setFirstName((String) jsonObjPeople.get("givenName"));
socialUser.setLastName((String) jsonObjPeople.get("familyName"));
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
case ClientUtils.GOOGLE: {
/*
* --Google-- { "id": "116397076041912827850", "name": "Muhammad Muquit", "given_name": "Muhammad",
* "family_name": "Muquit", "link": "https://plus.google.com/116397076041912827850", "gender": "male",
* "locale": "en-US" }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
socialUser.setJson(json);
socialUser.setName((String) jsonObj.get("name"));
socialUser.setFirstName((String) jsonObj.get("given_name"));
socialUser.setLastName((String) jsonObj.get("family_name"));
socialUser.setGender((String) jsonObj.get("gender"));
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
case ClientUtils.LINKEDIN: {
/*
* --Linkedin-- { "firstName": "Muhammad", "headline": "Sr. Software Engineer at British Telecom",
* "lastName": "Muquit", }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
socialUser.setJson(json);
socialUser.setFirstName((String) jsonObj.get("firstName"));
socialUser.setLastName((String) jsonObj.get("lastName"));
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
case ClientUtils.TWITTER: {
/*
* --Twitter -- { "id":955924206, "contributors_enabled":false, "profile_use_background_image":true,
* "time_zone":"Eastern Time (US & Canada)", "following":false, "friends_count":3, "profile_text_color":
* "333333", "geo_enabled":false, "created_at":"Sun Nov 18 17:54:22 +0000 2012", "utc_offset":-18000,
* "follow_request_sent":false, "name":"Muhammad Muquit", "id_str":"955924206",
* "default_profile_image":true, "verified":false, "profile_sidebar_border_color":"C0DEED", "url":null,
* "favourites_count":0, .. "lang":"en", "profile_background_color":"C0DEED", "screen_name":"mmqt2012", .. }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
socialUser.setJson(json);
socialUser.setName((String) jsonObj.get("name"));
socialUser.setGender((String) jsonObj.get("gender"));
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
case ClientUtils.INSTAGRAM: {
/*
* -- Instragram -- { "data": { "id": "1574083", "username": "snoopdogg", "full_name": "Snoop Dogg",
* "profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_1574083_75sq_1295469061.jpg",
* "bio": "This is my bio", "website": "http://snoopdogg.com", "counts": { "media": 1320, "follows": 420,
* "followed_by": 3410 } }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
// get profile object
JSONObject jsonObjData = (JSONObject) jsonObj.get("data");
socialUser.setJson(json);
socialUser.setName((String) jsonObjData.get("username"));
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
case ClientUtils.GITHUB: {
/*
* -- github -- { "plan":{ "private_repos":0, "space":307200, "name":"free", "collaborators":0 },
* "followers":0, "type":"User", "events_url":"https://api.github.com/users/oauthdemo2012/events{/privacy}",
* "owned_private_repos":0, "public_gists":0, "avatar_url":
* "https://secure.gravatar.com/avatar/e0cb08c2b353cc1c3022dc65ebd060d1?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"
* , "received_events_url":"https://api.github.com/users/oauthdemo2012/received_events", "private_gists":0,
* "disk_usage":0, "url":"https://api.github.com/users/oauthdemo2012",
* "followers_url":"https://api.github.com/users/oauthdemo2012/followers", "login":"oauthdemo2012",
* "created_at":"2012-12-20T01:36:36Z",
* "following_url":"https://api.github.com/users/oauthdemo2012/following",
* "organizations_url":"https://api.github.com/users/oauthdemo2012/orgs", "following":0,
* "starred_url":"https://api.github.com/users/oauthdemo2012/starred{/owner}{/repo}", "collaborators":0,
* "public_repos":0, "repos_url":"https://api.github.com/users/oauthdemo2012/repos",
* "gists_url":"https://api.github.com/users/oauthdemo2012/gists{/gist_id}", "id":3085592,
* "total_private_repos":0, "html_url":"https://github.com/oauthdemo2012",
* "subscriptions_url":"https://api.github.com/users/oauthdemo2012/subscriptions",
* "gravatar_id":"e0cb08c2b353cc1c3022dc65ebd060d1" }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
socialUser.setJson(json);
socialUser.setName((String) jsonObj.get("login"));
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
case ClientUtils.FLICKR: {
/*
* -- flickr -- { "user": { "id": "91390211@N06", "username": { "_content": "oauthdemo2012" } }, "stat":
* "ok" }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
JSONObject jsonObjUser = (JSONObject) jsonObj.get("user");
JSONObject jsonObjUsername = (JSONObject) jsonObjUser.get("username");
socialUser.setName((String) jsonObjUsername.get("_content"));
socialUser.setJson(json);
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
case ClientUtils.VIMEO: {
/*
* --Vimeo starts -- { "generated_in": "0.0698", "stat": "ok", "person": { "created_on":
* "2012-12-22 23:37:55", "id": "15432968", "is_contact": "0", "is_plus": "0", "is_pro": "0", "is_staff":
* "0", "is_subscribed_to": "0", "username": "user15432968", "display_name": "oauthdemo2012", "location":
* "", "url": [ "" ], ..... } }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
JSONObject jsonObjPerson = (JSONObject) jsonObj.get("person");
String userName = (String) jsonObjPerson.get("username");
String displayName = (String) jsonObjPerson.get("display_name");
if (displayName != null) {
socialUser.setName(displayName);
} else if (userName != null) {
socialUser.setName(userName);
} else {
socialUser.setName("Unknown");
}
socialUser.setJson(json);
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
case ClientUtils.WINDOWS_LIVE: {
/*
* Windows Live --starts -- { "id" : "contact.c1678ab4000000000000000000000000", "first_name" : "Roberto",
* "last_name" : "Tamburello", "name" : "Roberto Tamburello", "gender" : "male", "locale" : "en_US" }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
JSONObject jsonErrorObj = (JSONObject) jsonObj.get("error");
if (jsonErrorObj != null) {
/*
* { "error": { "code": "request_token_too_many", "message":
* "The request includes more than one access token. Only one access token is allowed." } }
*/
String message = (String) jsonErrorObj.get("message");
throw new AuthenticationException("Error: " + message);
}
socialUser.setName((String) jsonObj.get("name"));
socialUser.setLastName((String) jsonObj.get("last_name"));
socialUser.setFirstName((String) jsonObj.get("first_name"));
socialUser.setJson(json);
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
case ClientUtils.TUMBLR: {
/*
* tumblr. -- { "meta": { "status": 200, "msg": "OK" }, "response": { "user": { "name": "oauthdemo2012",
* "likes": 0, "following": 1, "default_post_format": "html", "blogs": [ { "name": "oauthdemo2012", "url":
* "http:\/\/oauthdemo2012.tumblr.com\/", "followers": 0, "primary": true, "title": "Untitled",
* "description": "", "admin": true, "updated": 0, "posts": 0, "messages": 0, "queue": 0, "drafts": 0,
* "share_likes": true, "ask": false, "tweet": "N", "facebook": "N", "facebook_opengraph_enabled": "N",
* "type": "public" } ] } } }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
JSONObject jsonObjResponse = (JSONObject) jsonObj.get("response");
JSONObject jsonObjUser = (JSONObject) jsonObjResponse.get("user");
String userName = (String) jsonObjUser.get("name");
socialUser.setName(userName);
socialUser.setJson(json);
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
case ClientUtils.FOURSQUARE: {
/*
* foursquare -- { "meta": { "code": 200, "errorType": "deprecated", "errorDetail":
* "Please provide an API version to avoid future errors.See http://bit.ly/vywCav" }, "notifications": [ {
* "type": "notificationTray", "item": { "unreadCount": 0 } } ], "response": { "user": { "id": "43999331",
* "firstName": "OAuth", "lastName": "Demo", "gender": "none", "relationship": "self", "photo":
* "https://foursquare.com/img/blank_boy.png", "friends": { "count": 0, "groups": [ { "type": "friends",
* "name": "Mutual friends", "count": 0, "items": [] }, { "type": "others", "name": "Other friends",
* "count": 0, "items": [] } ] }, ...... } } }
*/
try {
obj = jsonParser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
JSONObject jsonObjResponse = (JSONObject) jsonObj.get("response");
JSONObject jsonObjUser = (JSONObject) jsonObjResponse.get("user");
String firstName = (String) jsonObjUser.get("firstName");
String lastName = (String) jsonObjUser.get("lastName");
if (firstName != null && lastName != null) {
socialUser.setName(firstName + " " + lastName);
} else {
socialUser.setName("UNKNOWN");
}
socialUser.setJson(json);
return socialUser;
} catch (Exception e) {
throw new AuthenticationException("Could not parse JSON data from " + authProviderName + ":"
+ e.getMessage());
}
}
default: {
throw new AuthenticationException("Unknown Auth Provider: " + authProviderName);
}
}
/*
* We don't use Gson() anymore as it choked on nested Facebook JSON data Dec-03-2012
*/
/*
* // map json to SocialUser try { Gson gson = new Gson(); SocialUser user =
* gson.fromJson(json,SocialUser.class); // pretty print json //gson = new
* GsonBuilder().setPrettyPrinting().create(); //String jsonPretty = gson.toJson(json); user.setJson(json);
* return user; } catch (Exception e) { e.printStackTrace(); throw new
* AuthenticationException("Could not map userinfo JSON to SocialUser class: " + e); }
*/
}
}
@@ -0,0 +1,27 @@
package com.sap.sse.security;
import org.apache.shiro.authc.AuthenticationToken;
public class OAuthToken implements AuthenticationToken {
private Credential credential;
private String principal;
public OAuthToken(Credential credential, String principal) {
this.credential = credential;
this.principal = principal;
}
@Override
public Object getCredentials() {
// TODO Auto-generated method stub
return credential;
}
@Override
public Object getPrincipal() {
// TODO Auto-generated method stub
return principal;
}
}
@@ -119,7 +119,7 @@ public class SecurityServiceImpl extends RemoteServiceServlet implements Securi
@Override
public <T> T getSetting(String key, Class<T> clazz) {
return store.getSetting("", clazz);
return store.getSetting(key, clazz);
}
@Override
@@ -0,0 +1,279 @@
package com.sap.sse.security;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.session.Session;
import org.scribe.exceptions.OAuthException;
import org.scribe.model.Token;
public class SessionUtils {
public static final String SESSION_ID = "GWTOAuthLoginDemo_sessionid";
public static final String SESSION_REQUEST_TOKEN = "GWTOAuthLoginDemo_request_token";
public static final String SESSION_NONCE = "GWTOAuthLoginDemo_nonce";
public static final String SESSION_PROTECTED_URL = "GWTOAuthLoginDemo_protected_url";
public static final String SESSION_ACCESS_TOKEN = "GWTOAuthLoginDemo_access_token";
public static final String SESSION_YAHOO_GUID = "GWTOAuthLoginDemo_yahoo_guid";
public static final String SESSION_AUTH_PROVIDER = "GWTOAuthLoginDemo_auth_provider";
public static final String SOCIAL_USER = "Social_User";
public static void saveRequestTokenToSession(Token requestToken) throws Exception {
Session session = SecurityUtils.getSubject().getSession();
if (session == null) {
throw new Exception(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
* ServersideSession sss = getServersideSession(); if (sss == null) { sss = new ServersideSession();
* sss.setRequestToken(requestToken); session.setAttribute(SESSION,sss); } else {
* sss.setRequestToken(requestToken); }
*/
session.setAttribute(SESSION_REQUEST_TOKEN, requestToken);
}
public static void saveStateToSession(String state) throws Exception {
Session session = SecurityUtils.getSubject().getSession();
if (session == null) {
throw new Exception(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
* ServersideSession sss = getServersideSession(); if (sss == null) { sss = new ServersideSession();
* sss.setState(state); session.setAttribute(SESSION,sss); } else { sss.setState(state); }
*/
session.setAttribute(SESSION_NONCE, state);
}
public static String getProtectedResourceUrlFromSession() throws OAuthException {
Session session = SecurityUtils.getSubject().getSession();
if (session == null) {
throw new OAuthException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
* ServersideSession sss = getServersideSession(); if (sss != null) return sss.getProtectedResourceUrl();
*
* return null;
*/
return (String) session.getAttribute(SESSION_PROTECTED_URL);
}
public static String getStateFromSession() throws Exception {
Session session = SecurityUtils.getSubject().getSession();
if (session == null) {
throw new Exception(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
* ServersideSession sss = getServersideSession(); if (sss != null) return sss.getState();
*
* return null;
*/
return (String) session.getAttribute(SESSION_NONCE);
}
public static String getSessionIdFromSession() throws OAuthException {
Session session = SecurityUtils.getSubject().getSession();
if (session == null) {
throw new OAuthException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
* ServersideSession sss = getServersideSession(); if (sss != null) return sss.getSessionId();
*/
String sessionId = (String) session.getAttribute(SESSION_ID);
return sessionId;
}
public static Token getAccessTokenFromSession() throws OAuthException {
Session session = SecurityUtils.getSubject().getSession();
if (session == null) {
throw new OAuthException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
* ServersideSession sss = getServersideSession(); if (sss != null) { return sss.getAccessToken(); } return
* null;
*/
return (Token) session.getAttribute(SESSION_ACCESS_TOKEN);
}
public static int getAuthProviderFromSession() throws OAuthException {
Session session = SecurityUtils.getSubject().getSession();
if (session == null) {
throw new OAuthException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
* ServersideSession sss = getServersideSession(); if (sss != null) return sss.getAuthProvider();
*/
return (Integer) session.getAttribute(SESSION_AUTH_PROVIDER);
}
public static void safeSocialUser(SocialUser user) {
Session session = SecurityUtils.getSubject().getSession();
if (session == null) {
return;
}
session.setAttribute(SOCIAL_USER, user);
}
public static SocialUser loadSocialUser() {
Session session = SecurityUtils.getSubject().getSession();
if (session == null) {
return null;
}
SocialUser user = (SocialUser) session.getAttribute(SOCIAL_USER);
if (user == null) {
user = new SocialUser();
safeSocialUser(user);
}
return user;
}
public static void saveSessionIdToSession(String sessionId) throws AuthenticationException
{
Session session = SecurityUtils.getSubject().getSession();
if (session == null)
{
throw new AuthenticationException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
session.setAttribute(SESSION_ID,sessionId);
/*
ServersideSession sss = getServersideSession();
if (sss == null)
{
sss = new ServersideSession();
sss.setSessionId(sessionId);
session.setAttribute(SESSION,sss);
}
else
{
sss.setSessionId(sessionId);
}
*/
}
public static void saveProtectedResourceUrlToSession(String url) throws AuthenticationException
{
Session session = SecurityUtils.getSubject().getSession();
if (session == null)
{
throw new AuthenticationException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
ServersideSession sss = getServersideSession();
if (sss == null)
{
sss = new ServersideSession();
sss.setProtectedResourceUrl(url);
session.setAttribute(SESSION,sss);
}
else
{
sss.setProtectedResourceUrl(url);
}
*/
session.setAttribute(SESSION_PROTECTED_URL,url);
}
public static void saveAuthProviderToSession(int authProvider) throws AuthenticationException
{
Session session = SecurityUtils.getSubject().getSession();
if (session == null)
{
throw new AuthenticationException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
ServersideSession sss = getServersideSession();
if (sss == null)
{
sss = new ServersideSession();
sss.setAuthProvider(authProvider);
session.setAttribute(SESSION,sss);
}
else
{
sss.setAuthProvider(authProvider);
}
*/
session.setAttribute(SESSION_AUTH_PROVIDER,authProvider);
}
public static void saveAccessTokenToSession(Token accessToken) throws AuthenticationException
{
Session session = SecurityUtils.getSubject().getSession();
if (session == null)
{
throw new AuthenticationException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
ServersideSession sss = getServersideSession();
if (sss == null)
{
sss = new ServersideSession();
sss.setAccessToken(accessToken);
session.setAttribute(SESSION,sss);
}
else
{
sss.setAccessToken(accessToken);
}
*/
session.setAttribute(SESSION_ACCESS_TOKEN,accessToken);
}
public static void saveYahooGuidToSession(String guid) throws AuthenticationException
{
Session session = SecurityUtils.getSubject().getSession();
if (session == null)
{
throw new AuthenticationException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
ServersideSession sss = getServersideSession();
if (sss == null)
{
sss = new ServersideSession();
sss.setYahooGuid(guid);
session.setAttribute(SESSION,sss);
}
else
{
sss.setYahooGuid(guid);
}
*/
session.setAttribute(SESSION_YAHOO_GUID,guid);
}
public static String getYahooGuidFromSession() throws AuthenticationException
{
Session session = SecurityUtils.getSubject().getSession();
if (session == null)
{
throw new AuthenticationException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
ServersideSession sss = getServersideSession();
if (sss != null)
{
return sss.getYahooGuid();
}
return null;
*/
return (String) session.getAttribute(SESSION_YAHOO_GUID);
}
public static Token getRequestTokenFromSession() throws AuthenticationException
{
Session session = SecurityUtils.getSubject().getSession();
if (session == null)
{
throw new AuthenticationException(ClientUtils.SESSION_EXPIRED_MESSAGE);
}
/*
ServersideSession sss = getServersideSession();
if (sss != null)
return sss.getRequestToken();
return null;
*/
return (Token) session.getAttribute(SESSION_REQUEST_TOKEN);
}
}
@@ -0,0 +1,280 @@
package com.sap.sse.security;
import java.io.Serializable;
/**
* The object we send back and forth between client and server.
* Note: More information is stored in server side in ServersideSession
* object.
* @author muquit@muquit.com
*/
public class SocialUser implements Serializable
{
private static final long serialVersionUID=1011L;
private String sessionId;
private String email;
private String json;
/* must be named exactly as JSON google returns -- starts */
private String id;
private String name; // full name
private String given_name; // first name
private String family_name; // last name
private String gender; // same on Yahoo
private String link;
private String locale;
/* must be named exactly as JSON google returns -- ends */
/* Yahoo --starts */
private String guid; // is it always the same for the user??
private String givenName;
private String familyName;
private String nickname;
private String location;
private String birthdate;
private String timeZone;
private String lang;
private String relationShipStatus;
private int displayAge;
/* Yahoo --ends */
/* Linkedin -starts */
private String firstName;
private String lastName;
private String headline;
/* Linkedin -starts */
/*
Google returns JSON like:
{
"id": "116397076041912827850",
"name": "Muhammad Muquit",
"given_name": "Muhammad",
"family_name": "Muquit",
"link": "https://plus.google.com/116397076041912827850",
"gender": "male",
"locale": "en-US"
}
*/
/*
* http://developer.yahoo.com/social/rest_api_guide/extended-profile-resource.html#
Yahoo returns JSON like:
{
"profile": {
"uri": "http:\/\/social.yahooapis.com\/v1\/user\/ECUFIYO7BLY5FOV54XAPEQDC3Y\/profile",
"guid": "ECUFIYO7BLY5FOAPEQDC3Y",
"birthYear": 1969,
"created": "2010-01-23T13:07:10Z",
"displayAge": 43,
"gender": "M",
"image": {
"height": 192,
"imageUrl": "http:\/\/l.yimg.com\/a\/i\/identity2\/profile_192c.png",
"size": "192x192",
"width": 192
},
"location": "Philadelphia, Pennsylvania",
"memberSince": "2006-08-04T13:27:58Z",
"nickname": "jdoe",
"profileUrl": "http:\/\/profile.yahoo.com\/ECUFIYO7BLY5FOV54XAPEQDC3Y",
"searchable": false,
"updated": "2011-04-16T07:28:00Z",
"isConnected": false
}
}
*/
public String getSessionId()
{
return sessionId;
}
public void setSessionId(String sessionId)
{
this.sessionId=sessionId;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email=email;
}
public String getJson()
{
return json;
}
public void setJson(String json)
{
this.json=json;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id=id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public String getGiven_name()
{
return given_name;
}
public void setGiven_name(String given_name)
{
this.given_name=given_name;
}
public String getFamily_name()
{
return family_name;
}
public void setFamily_name(String family_name)
{
this.family_name=family_name;
}
public String getGender()
{
return gender;
}
public void setGender(String gender)
{
this.gender=gender;
}
public String getLink()
{
return link;
}
public void setLink(String link)
{
this.link=link;
}
public String getLocale()
{
return locale;
}
public void setLocale(String locale)
{
this.locale=locale;
}
public String getGuid()
{
return guid;
}
public void setGuid(String guid)
{
this.guid=guid;
}
public String getGivenName()
{
return givenName;
}
public void setGivenName(String givenName)
{
this.givenName=givenName;
}
public String getFamilyName()
{
return familyName;
}
public void setFamilyName(String familyName)
{
this.familyName=familyName;
}
public String getNickname()
{
return nickname;
}
public void setNickname(String nickname)
{
this.nickname=nickname;
}
public String getLocation()
{
return location;
}
public void setLocation(String location)
{
this.location=location;
}
public String getBirthdate()
{
return birthdate;
}
public void setBirthdate(String birthdate)
{
this.birthdate=birthdate;
}
public String getTimeZone()
{
return timeZone;
}
public void setTimeZone(String timeZone)
{
this.timeZone=timeZone;
}
public String getLang()
{
return lang;
}
public void setLang(String lang)
{
this.lang=lang;
}
public String getRelationShipStatus()
{
return relationShipStatus;
}
public void setRelationShipStatus(String relationShipStatus)
{
this.relationShipStatus=relationShipStatus;
}
public int getDisplayAge()
{
return displayAge;
}
public void setDisplayAge(int displayAge)
{
this.displayAge=displayAge;
}
/* linkedin */
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName=firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName=lastName;
}
public String getHeadline()
{
return headline;
}
public void setHeadline(String headline)
{
this.headline=headline;
}
/* linkedin */
}
@@ -34,6 +34,15 @@ public class UsernamePasswordRealm extends AuthorizingRealm {
store = (UserStore) context.
getService(serviceReference);
}
@Override
public boolean supports(AuthenticationToken token) {
if (token == null)
return false;
if (! (token instanceof UsernamePasswordToken))
return false;
return true;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {