/*
* SyncResource.java
*
* Created on April 12, 2007, 1:39 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package org.atomojo.auth.service.app;
import java.sql.SQLException;
import java.util.UUID;
import java.util.logging.Level;
import org.atomojo.app.client.XMLRepresentationParser;
import org.atomojo.auth.service.db.AuthDB;
import org.atomojo.auth.service.db.Realm;
import org.atomojo.auth.service.db.RealmUser;
import org.atomojo.auth.service.db.User;
import org.atomojo.auth.service.db.XML;
import org.infoset.xml.Document;
import org.infoset.xml.Element;
import org.infoset.xml.XMLException;
import org.infoset.xml.util.DocumentDestination;
import org.restlet.Request;
import org.restlet.data.CharacterSet;
import org.restlet.data.MediaType;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.ServerResource;
/**
*
* @author alex
*/
public class RealmUsersResource extends ServerResource
{
AuthDB db;
XMLRepresentationParser parser = XML.createParser();
/** Creates a new instance of SyncResource */
public RealmUsersResource() {
setNegotiated(false);
}
protected void doInit() {
db = (AuthDB)getRequest().getAttributes().get(AuthApplication.DB_ATTR);
parser.addAllowedElement(XML.USER_NAME);
}
public Representation get()
{
try {
Realm realm = fetch();
if (realm!=null) {
Representation entity = new DBIteratorRepresentation(MediaType.APPLICATION_XML,XML.USERS_NAME,db.getRealmUsers(realm));
entity.setCharacterSet(CharacterSet.UTF_8);
return entity;
} else {
getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND);
return new StringRepresentation("Realm not found.");
}
} catch (IllegalArgumentException ex) {
getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
return new StringRepresentation("Invalid UUID value for realm id.");
} catch (SQLException ex) {
getContext().getLogger().log(Level.SEVERE,"Cannot get users from database.",ex);
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
return new StringRepresentation("Database error, see logs.");
}
}
public Representation post(Representation entity)
{
if (!XMLRepresentationParser.isXML(entity.getMediaType())) {
getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
return new StringRepresentation("Non-XML media type for entity body: "+entity.getMediaType().getName());
}
Document doc = null;
try {
DocumentDestination dest = new DocumentDestination();
parser.parse(entity,dest);
doc = dest.getDocument();
Element top = doc.getDocumentElement();
String sid = top.getAttributeValue("id");
String alias = top.getAttributeValue("alias");
if (sid==null && alias==null) {
getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
return new StringRepresentation("One of the 'id' or 'alias' attributes must be specified.");
}
UUID id = null;
if (sid!=null) {
try {
id = UUID.fromString(sid);
} catch (IllegalArgumentException ex) {
getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
return new StringRepresentation("Invalid UUID value for user id.");
}
}
String password = top.getAttributeValue("password");
Element name = top.getFirstElementNamed(XML.NAME_NAME);
Element email = top.getFirstElementNamed(XML.EMAIL_NAME);
if (alias!=null && !User.isAlias(alias)) {
getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
return new StringRepresentation("The alias '"+alias+"' does not contain all letters or digits.");
}
try {
Realm realm = null;
try {
realm = fetch();
} catch (IllegalArgumentException ex) {
getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
return new StringRepresentation("Invalid UUID value for realm id.");
}
if (realm==null) {
getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND);
return new StringRepresentation("Realm not found.");
}
User user = null;
if (id!=null) {
user = db.getUser(id);
if (user==null) {
getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND);
return new StringRepresentation("User with id "+id+" not found.");
} else if (alias==null && user.getAlias()==null) {
getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
return new StringRepresentation("The global user "+id+" does not have an alias and the alias was not specified on the request.");
}
}
if (user==null) {
// we have a request to create a realm user not tied to an existing user.
// create a new user and then the realm user
user = db.createUser(UUID.randomUUID(),null,null,null);
if (user==null) {
// this really shouldn't happen because we don't have an alias
getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND);
return new StringRepresentation("User creation is not available.");
}
// set the password if they specified it
if (password!=null) {
user.setPassword(password);
}
}
if (alias!=null && alias.equals(user.getAlias())) {
// inherit the alias as it is the same
alias = null;
}
if (db.isRealmUserAliasAvailable(realm,user,alias)) {
RealmUser realmUser = db.createRealmUser(realm,user,alias,name==null ? null : name.getText(),email==null ? null : email.getText());
if (realmUser==null) {
getResponse().setStatus(Status.CLIENT_ERROR_EXPECTATION_FAILED);
return new StringRepresentation("The realm user could not be created.");
} else {
Representation responseEntity = new DBObjectRepresentation(MediaType.APPLICATION_XML,realmUser);
responseEntity.setCharacterSet(CharacterSet.UTF_8);
getResponse().setStatus(Status.SUCCESS_CREATED);
return responseEntity;
}
} else {
getResponse().setStatus(Status.CLIENT_ERROR_CONFLICT);
return new StringRepresentation("The alias "+alias+" is not available.");
}
} catch (SQLException ex) {
getContext().getLogger().log(Level.SEVERE,"Realm user creation failed.",ex);
getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
return new StringRepresentation("User creation refused.");
}
} catch (XMLException ex) {
getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
return new StringRepresentation("XML parse error: "+ex.getMessage());
} catch (Exception ex) {
getLogger().log(Level.SEVERE,"Exception during processing.",ex);
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
return new StringRepresentation("Exception during processing.");
}
}
protected Realm fetch()
throws SQLException
{
/*
Realm realm = null;
if (name!=null) {
realm = db.getRealm(name);
}
if (suuid!=null) {
UUID id = UUID.fromString(suuid);
realm = db.getRealm(id);
}
return realm;
*/
Realm realm = (Realm)getRequest().getAttributes().get(AuthApplication.REALM_ATTR);
return realm;
}
}