/* * Copyright (C) 2005-2012 BetaCONCEPT Limited * * This file is part of Astroboa. * * Astroboa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Astroboa 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Astroboa. If not, see <http://www.gnu.org/licenses/>. */ package org.betaconceptframework.astroboa.resourceapi.resource; import java.net.HttpURLConnection; import java.util.Map; import javax.ws.rs.POST; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.betaconceptframework.astroboa.api.model.definition.CmsDefinition; import org.betaconceptframework.astroboa.api.model.definition.StringPropertyDefinition; import org.betaconceptframework.astroboa.api.model.io.ResourceRepresentationType; import org.betaconceptframework.astroboa.api.service.DefinitionService; import org.betaconceptframework.astroboa.client.AstroboaClient; import org.betaconceptframework.astroboa.resourceapi.utility.ContentApiUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ public class SecurityResource extends AstroboaResource{ private final Logger logger = LoggerFactory.getLogger(getClass()); public SecurityResource(AstroboaClient astroboaClient) { super(astroboaClient); } // The methods which produce JSON or XML allow "callback" as one extra query parameter // in order to support XML with Padding or JSON with Padding (JSONP) and overcome the SPO restriction of browsers // This means that if a "callback" query parameter is provided then the XML or JSON result will be wrapped inside a "callback" script @POST @Produces("*/*") public Response encrypt(String requestContent, @QueryParam("output") String output, @QueryParam("callback") String callback){ Output outputEnum = ContentApiUtils.getOutputType(output, Output.JSON); return encryptInternal(requestContent, outputEnum, callback); } @POST @Produces(MediaType.APPLICATION_JSON) public Response encryptAsJson(String requestContent, @QueryParam("output") String output, @QueryParam("callback") String callback) { Output outputEnum = ContentApiUtils.getOutputType(output, Output.JSON); return encryptInternal(requestContent, outputEnum, callback); } @POST @Produces(MediaType.APPLICATION_XML) public Response encryptAsXml(String requestContent, @QueryParam("output") String output, @QueryParam("callback") String callback) { Output outputEnum = ContentApiUtils.getOutputType(output, Output.XML); return encryptInternal(requestContent, outputEnum, callback); } private Response encryptInternal(String requestContent, Output output, String callback){ try { if (StringUtils.isBlank(requestContent)){ throw new WebApplicationException(HttpURLConnection.HTTP_BAD_REQUEST); } checkUserIsAuthorizedToUseEncryptionUtility(); Map<String, Object> userData = ContentApiUtils.parse(requestContent); String propertyPath = (String) userData.get("fullPropertyPath"); if (StringUtils.isBlank(propertyPath)){ logger.error("No property path found. Request {} does not contain field {} or its value is blank. User info {}", new Object[]{requestContent, "fullPropertyPath", astroboaClient.getInfo()}); throw new WebApplicationException(HttpURLConnection.HTTP_BAD_REQUEST); } String password = (String) userData.get("password"); if (StringUtils.isBlank(password)){ logger.error("No value for password found. Request {} does not contain field {} or its value is blank. User info {}", new Object[]{requestContent, "password", astroboaClient.getInfo()}); throw new WebApplicationException(HttpURLConnection.HTTP_BAD_REQUEST); } DefinitionService definitionService = astroboaClient.getDefinitionService(); CmsDefinition definition = definitionService.getCmsDefinition(propertyPath, ResourceRepresentationType.DEFINITION_INSTANCE, false); if (definition == null){ logger.error("No definition found for property {}. Request {} - User info {}", new Object[]{propertyPath, requestContent, astroboaClient.getInfo()}); throw new WebApplicationException(HttpURLConnection.HTTP_BAD_REQUEST); } if ( !(definition instanceof StringPropertyDefinition) || ! ((StringPropertyDefinition)definition).isPasswordType()){ logger.error("Property {}'s type is not password type. Request {} - User info {}", new Object[]{propertyPath, requestContent, astroboaClient.getInfo()}); throw new WebApplicationException(HttpURLConnection.HTTP_BAD_REQUEST); } String encryptedPassword = StringEscapeUtils.escapeJava(((StringPropertyDefinition)definition).getPasswordEncryptor().encrypt(password)); StringBuilder encryptedPasswordBuidler = new StringBuilder(); switch (output) { case XML:{ encryptedPassword = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><encryptedPassword>"+encryptedPassword+"</encryptedPassword>"; if (StringUtils.isBlank(callback)) { encryptedPasswordBuidler.append(encryptedPassword); } else { ContentApiUtils.generateXMLP(encryptedPasswordBuidler, encryptedPassword, callback); } break; } case JSON: encryptedPassword = "{\"encryptedPassword\" : \""+encryptedPassword+"\"}"; if (StringUtils.isBlank(callback)) { encryptedPasswordBuidler.append(encryptedPassword); } else { ContentApiUtils.generateJSONP(encryptedPasswordBuidler, encryptedPassword, callback); } break; } return ContentApiUtils.createResponse(encryptedPasswordBuidler, output, callback, null); } catch (WebApplicationException wae){ throw wae; } catch(Exception e){ logger.error("Encrytpion failed. Request "+requestContent+" - User info "+astroboaClient.getInfo(), e); throw new WebApplicationException(HttpURLConnection.HTTP_INTERNAL_ERROR); } } private void checkUserIsAuthorizedToUseEncryptionUtility() { //Anonymous user is not authorized to use encryption utility if (astroboaClient.isUserAnonymous()){ logger.warn("Anonymous User tried to use the Resource API encrypt utility for repository "+ astroboaClient.getConnectedRepositoryId()); throw new WebApplicationException(HttpURLConnection.HTTP_UNAUTHORIZED); } } }