Skip to content

Commit

Permalink
Simplified and use service as Google login
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Niblett committed Oct 16, 2012
1 parent f939e5d commit 21deb2d
Show file tree
Hide file tree
Showing 32 changed files with 409 additions and 200 deletions.
19 changes: 1 addition & 18 deletions src/main/java/com/cilogi/shiro/gae/DatastoreRealm.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,8 @@ private AuthenticationInfo doGetAuthenticationInfo(String userName) throws Authe
LOG.info("Finding authentication info for " + userName + " in DB");
GaeUser user = dao().findUser(userName);

boolean isSocialUserFaking = false;
User googleUser = UserServiceFactory.getUserService().getCurrentUser();
if (user != null && googleUser != null && isSocialUserFaking(user)) {
LOG.warning("Google says " + googleUser.getEmail() + " and Shiro remembers " + user.getName());
isSocialUserFaking = true;
}

if (user == null || userIsNotQualified(user) || isSocialUserFaking) {
if (user == null || userIsNotQualified(user)) {
LOG.info("Rejecting " + user.getName());
return null;
}
Expand Down Expand Up @@ -108,15 +102,4 @@ private static CredentialsMatcher theCredentials() {
private static boolean userIsNotQualified(GaeUser user) {
return !user.isRegistered() || user.isSuspended();
}

private boolean isSocialUserFaking(GaeUser user) {
switch (user.getUserAuthType()) {
case CILOGI: return false; // not a social user, so can't fake
case GOOGLE:
User googleUser = UserServiceFactory.getUserService().getCurrentUser();
return !user.getName().equals(googleUser.getEmail());
default: return true; // we should never get here, as we're another type of social user who is handled by another realm

}
}
}
40 changes: 8 additions & 32 deletions src/main/java/com/cilogi/shiro/gae/GaeUser.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,28 +70,23 @@ public class GaeUser implements Serializable {

private boolean isSuspended;

private UserAuthType userAuthType;

private String accessToken;

/** For objectify to create instances on retrieval */
private GaeUser() {
this.roles = new HashSet<String>();
this.permissions = new HashSet<String>();
this.userAuthType = CILOGI;
}

GaeUser(String name) {
this(name, null, new HashSet<String>(), new HashSet<String>());
}


GaeUser(String name, String password) {
this(name, password, new HashSet<String>(), new HashSet<String>());
}

public GaeUser(String name, UserAuthType userAuthType, Set<String> roles, Set<String> permissions) {
this.name = name;
this.userAuthType = userAuthType;
this.roles = Collections.unmodifiableSet(roles);
this.permissions = Collections.unmodifiableSet(permissions);
this.dateRegistered = new Date();
this.isSuspended = false;
public GaeUser(String name, Set<String> roles, Set<String> permissions) {
this(name, null, roles, permissions);
}

public GaeUser(String name, String password, Set<String> roles, Set<String> permissions) {
Expand All @@ -100,7 +95,6 @@ public GaeUser(String name, String password, Set<String> roles, Set<String> perm

GaeUser(String name, String password, Set<String> roles, Set<String> permissions, boolean isRegistered) {
Preconditions.checkNotNull(name, "User name (email) can't be null");
Preconditions.checkNotNull(password, "User password can't be null");
Preconditions.checkNotNull(roles, "User roles can't be null");
Preconditions.checkNotNull(permissions, "User permissions can't be null");
this.name = name;
Expand All @@ -111,24 +105,6 @@ public GaeUser(String name, String password, Set<String> roles, Set<String> perm
this.permissions = Collections.unmodifiableSet(permissions);
this.dateRegistered = isRegistered ? new Date() : null;
this.isSuspended = false;
this.userAuthType = CILOGI;
}

public String getAccessToken() {
return accessToken;
}

public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}

public UserAuthType getUserAuthType() {
return userAuthType;
}

public void setUserAuthType(UserAuthType userAuthType) {
Preconditions.checkNotNull(userAuthType, "The auth type of a user cannot be null");
this.userAuthType = userAuthType;
}

public boolean isSuspended() {
Expand Down Expand Up @@ -183,7 +159,7 @@ private static ByteSource salt() {
}

private static String hash(String password, byte[] salt) {
return new Sha256Hash(password, new SimpleByteSource(salt), HASH_ITERATIONS).toHex();
return (password == null) ? null : new Sha256Hash(password, new SimpleByteSource(salt), HASH_ITERATIONS).toHex();
}

@Override
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/cilogi/shiro/gae/UserDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public UserDAO() {
userCache = new MemcacheManager().getCache("GaeUser");
}


/**
* Save user with authorization information
* @param user User
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2012 Tim Niblett. All Rights Reserved.
//
// File: GoogleGAEAuthenticationInfo.java (16-Oct-2012)
// Author: tim
//
// Copyright in the whole and every part of this source file belongs to
// Tim Niblett (the Author) and may not be used, sold, licenced,
// transferred, copied or reproduced in whole or in part in
// any manner or form or in or on any media to any person other than
// in accordance with the terms of The Author's agreement
// or otherwise without the prior written consent of The Author. All
// information contained in this source file is confidential information
// belonging to The Author and as such may not be disclosed other
// than in accordance with the terms of The Author's agreement, or
// otherwise, without the prior written consent of The Author. As
// confidential information this source file must be kept fully and
// effectively secure at all times.
//


package com.cilogi.shiro.googlegae;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;

import java.util.logging.Logger;


public class GoogleGAEAuthenticationInfo implements AuthenticationInfo {
static final Logger LOG = Logger.getLogger(GoogleGAEAuthenticationInfo.class.getName());

private final String principal;

public GoogleGAEAuthenticationInfo(String principal) {
this.principal = principal;
}

@Override
public Object getCredentials() {
return null;
}

@Override
public PrincipalCollection getPrincipals() {
return new SimplePrincipalCollection(principal, "GoogleGAE");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) 2012 Tim Niblett. All Rights Reserved.
//
// File: GoogleGAEAuthenticationToken.java (16-Oct-2012)
// Author: tim
//
// Copyright in the whole and every part of this source file belongs to
// Tim Niblett (the Author) and may not be used, sold, licenced,
// transferred, copied or reproduced in whole or in part in
// any manner or form or in or on any media to any person other than
// in accordance with the terms of The Author's agreement
// or otherwise without the prior written consent of The Author. All
// information contained in this source file is confidential information
// belonging to The Author and as such may not be disclosed other
// than in accordance with the terms of The Author's agreement, or
// otherwise, without the prior written consent of The Author. As
// confidential information this source file must be kept fully and
// effectively secure at all times.
//


package com.cilogi.shiro.googlegae;

import org.apache.shiro.authc.HostAuthenticationToken;
import org.apache.shiro.authc.RememberMeAuthenticationToken;

public class GoogleGAEAuthenticationToken implements HostAuthenticationToken, RememberMeAuthenticationToken {

private final String principal;
private final String host;

public GoogleGAEAuthenticationToken(String principal, String host) {
this.principal = principal;
this.host = host;
}

@Override
public Object getPrincipal() {
return principal;
}

@Override
public Object getCredentials() {
return null;
}

@Override
public boolean isRememberMe() {
return true;
}

@Override
public String getHost() {
return host;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2012 Tim Niblett. All Rights Reserved.
//
// File: GoogleGAECredentialsMatcher.java (16-Oct-2012)
// Author: tim
//
// Copyright in the whole and every part of this source file belongs to
// Tim Niblett (the Author) and may not be used, sold, licenced,
// transferred, copied or reproduced in whole or in part in
// any manner or form or in or on any media to any person other than
// in accordance with the terms of The Author's agreement
// or otherwise without the prior written consent of The Author. All
// information contained in this source file is confidential information
// belonging to The Author and as such may not be disclosed other
// than in accordance with the terms of The Author's agreement, or
// otherwise, without the prior written consent of The Author. As
// confidential information this source file must be kept fully and
// effectively secure at all times.
//


package com.cilogi.shiro.googlegae;

import com.google.common.base.Preconditions;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;

import java.util.logging.Logger;


public class GoogleGAECredentialsMatcher implements CredentialsMatcher {
static final Logger LOG = Logger.getLogger(GoogleGAECredentialsMatcher.class.getName());

public GoogleGAECredentialsMatcher() {}

@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
Preconditions.checkNotNull(info);
Preconditions.checkNotNull(token);

Object primary = info.getPrincipals().getPrimaryPrincipal();
return token instanceof GoogleGAEAuthenticationToken && token.getPrincipal().equals(primary);
}

}
49 changes: 49 additions & 0 deletions src/main/java/com/cilogi/shiro/googlegae/GoogleGAERealm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2012 Tim Niblett. All Rights Reserved.
//
// File: GoogleGAERealm.java (16-Oct-2012)
// Author: tim
//
// Copyright in the whole and every part of this source file belongs to
// Tim Niblett (the Author) and may not be used, sold, licenced,
// transferred, copied or reproduced in whole or in part in
// any manner or form or in or on any media to any person other than
// in accordance with the terms of The Author's agreement
// or otherwise without the prior written consent of The Author. All
// information contained in this source file is confidential information
// belonging to The Author and as such may not be disclosed other
// than in accordance with the terms of The Author's agreement, or
// otherwise, without the prior written consent of The Author. As
// confidential information this source file must be kept fully and
// effectively secure at all times.
//


package com.cilogi.shiro.googlegae;

import com.cilogi.shiro.gae.MemcacheManager;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.realm.AuthenticatingRealm;

import java.util.logging.Logger;


public class GoogleGAERealm extends AuthenticatingRealm {
static final Logger LOG = Logger.getLogger(GoogleGAERealm.class.getName());

public GoogleGAERealm() {
super(new MemcacheManager(), new GoogleGAECredentialsMatcher());
setAuthenticationTokenClass(GoogleGAEAuthenticationToken.class);
}

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
if (token != null && token instanceof GoogleGAEAuthenticationToken) {
GoogleGAEAuthenticationToken authToken = (GoogleGAEAuthenticationToken)token;
return new GoogleGAEAuthenticationInfo((String)authToken.getPrincipal());
} else {
return null;
}
}
}
3 changes: 1 addition & 2 deletions src/main/java/com/cilogi/shiro/guice/ServeModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ protected void configureServlets() {
serve(userBaseUrl + "/ajaxLogin").with(LoginServlet.class);
serve(userBaseUrl + "/socialLogin").with(OAuthLoginServlet.class);
serve(userBaseUrl + "/googleLogin").with(GoogleLoginServlet.class);
serve(userBaseUrl + "/googleLoginAuth").with(GoogleLoginServlet.class);
serve(userBaseUrl + "/register").with(RegisterServlet.class);
serve(userBaseUrl + "/registermail").with(MailQueueServlet.class);
serve(userBaseUrl + "/confirm").with(ConfirmServlet.class);
Expand All @@ -67,7 +66,7 @@ protected void configureServlets() {
serve(userBaseUrl + "/suspend").with(UserSuspendServlet.class);
serve(userBaseUrl + "/settings").with(SettingsServlet.class);
// this one is here so that the default login filter works
serve("/login.jsp").with(LoginJSPServlet.class);
serve("/login").with(LoginServlet.class);
// Lets check mail to see when stuff bounces
serve("/_ah/mail/*").with(MailReceiveServlet.class);
serve("/appstats/*").with(AppstatsServlet.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,8 @@ public Object getCredentials() {
return authToken;
}

@Override
public PrincipalCollection getPrincipals() {
return new SimplePrincipalCollection(principal, authType.name());
}

public UserAuthType getAuthType() {
return authType;
}
}
25 changes: 2 additions & 23 deletions src/main/java/com/cilogi/shiro/oauth/OAuthRealm.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.logging.Logger;


public class OAuthRealm extends AuthorizingRealm {
public class OAuthRealm extends AuthenticatingRealm {
static final Logger LOG = Logger.getLogger(OAuthRealm.class.getName());

public OAuthRealm() {
Expand All @@ -53,26 +54,4 @@ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
return null;
}
}

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Preconditions.checkNotNull(principals, "You can't have a null collection of principals");
String userName = (String) getAvailablePrincipal(principals);
if (userName == null) {
throw new NullPointerException("Can't find a principal in the collection");
}
LOG.fine("Finding authorization info for " + userName + " in DB");
GaeUser user = dao().findUser(userName);
if (user == null || user.isSuspended()) {
return null;
}
LOG.fine("Found " + userName + " in DB");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(user.getRoles());
info.setStringPermissions(user.getPermissions());
return info;
}

private static UserDAO dao() {
return UserDAOProvider.get();
}
}
Loading

0 comments on commit 21deb2d

Please sign in to comment.