/*
* UserGuard.java
*
* Created on July 1, 2007, 4:24 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package org.atomojo.auth.service.app;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import org.atomojo.auth.service.db.AuthDB;
import org.atomojo.auth.service.db.Group;
import org.atomojo.auth.service.db.Permission;
import org.atomojo.auth.service.db.Realm;
import org.atomojo.auth.service.db.RealmUser;
import org.atomojo.auth.service.db.User;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.ChallengeResponse;
import org.restlet.data.ChallengeScheme;
import org.restlet.routing.Filter;
import org.restlet.security.ChallengeAuthenticator;
import org.restlet.security.Verifier;
/**
*
* @author alex
*/
public class RealmUserGuard extends ChallengeAuthenticator
{
protected ChallengeScheme myScheme;
protected AuthDB db;
protected Realm realm;
protected Set<Permission> permissions;
protected Group group;
protected Permission adminPermission;
/** Creates a new instance of UserGuard */
public RealmUserGuard(Context context,AuthDB db,Realm realm,ChallengeScheme scheme,String realmName,Permission adminPermission)
{
super(context,scheme,realmName);
this.myScheme = scheme;
this.db = db;
this.realm = realm;
this.permissions = null;
this.group = null;
this.adminPermission = adminPermission;
setVerifier(new Verifier() {
public int verify(Request request,Response response) {
ChallengeResponse cr = request.getChallengeResponse();
if (cr==null) {
return Verifier.RESULT_MISSING;
}
String identifier = request.getChallengeResponse().getIdentifier();
char[] secret = request.getChallengeResponse().getSecret();
if ((identifier != null) && (secret != null)) {
getContext().getLogger().info("Authenticating " + identifier);
try {
Realm currentRealm = RealmUserGuard.this.realm == null ? (Realm) request.getAttributes().get(AuthApplication.REALM_ATTR) : RealmUserGuard.this.realm;
if (currentRealm != null) {
RealmUser user = AuthResource.findRealmUser(RealmUserGuard.this.db, currentRealm, identifier);
if (user != null && user.getUser().checkPassword(new String(secret))) {
getContext().getLogger().info("Authenticated: " + user.getAlias() + ", checking roles and groups");
if (permissions != null) {
for (Permission p : permissions) {
if (!user.hasPermission(p)) {
user = null;
break;
}
}
if (user != null && group != null) {
if (!user.isMemberOf(group)) {
user = null;
}
}
}
if (user != null && !hasRealmSpecific(request, user)) {
user = null;
}
if (user != null) {
getContext().getLogger().info("Accepted: " + user.getAlias());
}
if (user != null) {
if (user != null) {
request.getAttributes().put(AuthApplication.USER_ATTR, user);
}
return Verifier.RESULT_VALID;
}
}
}
// lookup for admin
User adminUser = AuthResource.findUser(RealmUserGuard.this.db, identifier);
if (adminUser != null && adminUser.hasPermission(RealmUserGuard.this.adminPermission) && adminUser.checkPassword(new String(secret))) {
// we have an admin user so shortcut and return 1
request.getAttributes().put(AuthApplication.USER_ATTR, adminUser);
return Verifier.RESULT_VALID;
}
} catch (SQLException ex) {
getContext().getLogger().log(Level.SEVERE, "Cannot check authentication.", ex);
} catch (NoSuchAlgorithmException ex) {
getContext().getLogger().log(Level.SEVERE, "Cannot check authentication.", ex);
}
}
return Verifier.RESULT_INVALID;
}
});
}
public void addPermission(Permission p)
{
if (this.permissions==null) {
this.permissions = new TreeSet<Permission>();
}
this.permissions.add(p);
}
public void setGroup(Group group)
{
this.group = group;
}
public int beforeHandle(Request request, Response response) {
if (request.getResourceRef().getRemainingPart().startsWith("/auth")) {
getContext().getLogger().fine("Passing auth request through...");
return Filter.CONTINUE;
} else {
return super.beforeHandle(request, response);
}
}
protected boolean hasRealmSpecific(Request request,RealmUser user) {
return true;
}
}