/** * PODD is an OWL ontology database used for scientific project management * * Copyright (C) 2009-2013 The University Of Queensland * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see <http://www.gnu.org/licenses/>. */ package com.github.podd.resources; import java.io.ByteArrayOutputStream; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; import org.openrdf.OpenRDFException; import org.openrdf.model.Model; import org.openrdf.model.URI; import org.openrdf.model.impl.LinkedHashModel; import org.openrdf.model.vocabulary.RDF; import org.openrdf.rio.RDFFormat; import org.openrdf.rio.Rio; import org.restlet.data.MediaType; import org.restlet.data.Status; import org.restlet.representation.ByteArrayRepresentation; import org.restlet.representation.Representation; import org.restlet.representation.Variant; import org.restlet.resource.Get; import org.restlet.resource.ResourceException; import org.restlet.security.Role; import org.restlet.security.User; import com.github.ansell.restletutils.RestletUtilRole; import com.github.ansell.restletutils.SesameRealmConstants; import com.github.podd.restlet.PoddAction; import com.github.podd.restlet.PoddSesameRealm; import com.github.podd.restlet.PoddWebServiceApplication; import com.github.podd.restlet.RestletUtils; import com.github.podd.utils.PODD; import com.github.podd.utils.PoddRoles; import com.github.podd.utils.PoddUser; import com.github.podd.utils.PoddWebConstants; /** * * User Details resource * * @author kutila * */ public class UserDetailsResourceImpl extends AbstractUserResourceImpl { @Get(":html") public Representation getUserDetailsPageHtml(final Representation entity) throws ResourceException { this.log.info("getUserDetailsHtml"); final String requestedUserIdentifier = this.getUserParameter(); final PoddAction action = this.getAction(requestedUserIdentifier, PoddAction.OTHER_USER_READ, PoddAction.CURRENT_USER_READ); this.log.info("requesting details of user: {}", requestedUserIdentifier); final User user = this.getRequest().getClientInfo().getUser(); this.log.info("authenticated user: {}", user); if(requestedUserIdentifier == null) { // no identifier specified. throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Did not specify user to view"); } this.checkAuthentication(action); // completed checking authorization final Map<String, Object> dataModel = RestletUtils.getBaseDataModel(this.getRequest()); dataModel.put("contentTemplate", "userDetails.html.ftl"); dataModel.put("pageTitle", "PODD User Details Page"); dataModel.put("authenticatedUsername", user.getIdentifier()); final PoddSesameRealm realm = ((PoddWebServiceApplication)this.getApplication()).getRealm(); final PoddUser poddUser = realm.findUser(requestedUserIdentifier); if(poddUser == null) { throw new ResourceException(Status.CLIENT_ERROR_NOT_FOUND, "User not found."); } else { dataModel.put("requestedUser", poddUser); final Set<Role> roles = realm.findRoles(poddUser); dataModel.put("repositoryRoleList", roles); } // Output the base template, with contentTemplate from the dataModel // defining the // template to use for the content in the body of the page return RestletUtils.getHtmlRepresentation( this.getPoddApplication().getPropertyUtil() .get(PoddWebConstants.PROPERTY_TEMPLATE_BASE, PoddWebConstants.DEFAULT_TEMPLATE_BASE), dataModel, MediaType.TEXT_HTML, this.getPoddApplication().getTemplateConfiguration()); } @Get(":rdf|rj|ttl") public Representation getUserRdf(final Representation entity, final Variant variant) throws ResourceException { this.log.info("getUserRdf"); final String requestedUserIdentifier = this.getUserParameter(); final PoddAction action = this.getAction(requestedUserIdentifier, PoddAction.OTHER_USER_READ, PoddAction.CURRENT_USER_READ); this.log.info("requesting details of user: {}", requestedUserIdentifier); if(requestedUserIdentifier == null) { this.log.info("Could not find user identifier parameter"); // no identifier specified. throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Did not specify user to view"); } final User user = this.getRequest().getClientInfo().getUser(); this.log.info("authenticated user: {}", user); this.checkAuthentication(action); final PoddSesameRealm realm = ((PoddWebServiceApplication)this.getApplication()).getRealm(); final PoddUser poddUser = realm.findUser(requestedUserIdentifier); if(poddUser == null) { this.log.info("User not found: {}", requestedUserIdentifier); throw new ResourceException(Status.CLIENT_ERROR_NOT_FOUND, "User not found."); } // final Set<Role> roles = realm.findRoles(poddUser); final Collection<Entry<Role, URI>> rolesWithObjectMappings = realm.getRolesWithObjectMappings(poddUser); final Model userInfoModel = this.userToModel(poddUser, rolesWithObjectMappings); // - prepare response final ByteArrayOutputStream output = new ByteArrayOutputStream(8096); final RDFFormat outputFormat = Rio.getWriterFormatForMIMEType(variant.getMediaType().getName(), RDFFormat.RDFXML); try { Rio.write(userInfoModel, output, outputFormat); } catch(final OpenRDFException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Could not create response", e); } return new ByteArrayRepresentation(output.toByteArray(), MediaType.valueOf(outputFormat.getDefaultMIMEType())); } /** * Helper method to create a Model containing PoddUser details and Role mappings. */ private Model userToModel(final PoddUser user, final Collection<Entry<Role, URI>> roles) { final Model userInfoModel = new LinkedHashModel(); user.toModel(userInfoModel, false); this.log.debug("User has {} roles", roles.size()); for(final Entry<Role, URI> entry2 : roles) { final Entry<Role, URI> entry = entry2; final RestletUtilRole roleByName = PoddRoles.getRoleByName(entry.getKey().getName()); final URI roleMapping = PODD.VF.createURI("urn:podd:rolemapping:", UUID.randomUUID().toString()); userInfoModel.add(roleMapping, RDF.TYPE, SesameRealmConstants.OAS_ROLEMAPPING); userInfoModel.add(roleMapping, SesameRealmConstants.OAS_ROLEMAPPEDUSER, user.getUri()); userInfoModel.add(roleMapping, SesameRealmConstants.OAS_ROLEMAPPEDROLE, roleByName.getURI()); if(entry.getValue() != null) { userInfoModel.add(roleMapping, PODD.PODD_ROLEMAPPEDOBJECT, entry.getValue()); } } return userInfoModel; } }