From 9b60dcf3ae97fd4a03e858c197d1af194f743727 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Tue, 12 Jan 2016 15:47:44 +0100
Subject: [PATCH] CL-431: enhance REST API for more info on user property
 error, add HEAD request for portrait

---
 .../org/olat/restapi/support/vo/ErrorVO.java  |  5 +++
 .../org/olat/user/restapi/UserWebService.java | 40 +++++++++++++++++--
 .../java/org/olat/restapi/UserMgmtTest.java   | 38 ++++++++++++++++++
 3 files changed, 79 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/olat/restapi/support/vo/ErrorVO.java b/src/main/java/org/olat/restapi/support/vo/ErrorVO.java
index 9a5c9291a19..4423affbddc 100644
--- a/src/main/java/org/olat/restapi/support/vo/ErrorVO.java
+++ b/src/main/java/org/olat/restapi/support/vo/ErrorVO.java
@@ -43,6 +43,11 @@ public class ErrorVO {
 		//make jaxb happy
 	}
 	
+	public ErrorVO(String code, String translation) {
+		this.code = code;
+		this.translation = translation;
+	}
+	
 	public ErrorVO(String pack, String code, String translation) {
 		this.code = pack + ":" + code;
 		this.translation = translation;
diff --git a/src/main/java/org/olat/user/restapi/UserWebService.java b/src/main/java/org/olat/user/restapi/UserWebService.java
index fa49c2e324a..ef254e695fb 100644
--- a/src/main/java/org/olat/user/restapi/UserWebService.java
+++ b/src/main/java/org/olat/user/restapi/UserWebService.java
@@ -43,6 +43,7 @@ import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
@@ -546,7 +547,38 @@ public class UserWebService {
 	 * Retrieves the portrait of an user
 	 * @response.representation.200.mediaType application/octet-stream
 	 * @response.representation.200.doc The portrait as image
-   * @response.representation.404.doc The identity or the portrait not found
+	 * @response.representation.404.doc The identity or the portrait not found
+	 * @param identityKey The identity key of the user being searched
+	 * @param request The REST request
+	 * @return The image
+	 */
+	@HEAD
+	@Path("{identityKey}/portrait")
+	@Produces({"image/jpeg","image/jpg",MediaType.APPLICATION_OCTET_STREAM})
+	public Response getPortraitHead(@PathParam("identityKey") Long identityKey, @Context Request request) {
+		try {
+			IdentityShort identity = BaseSecurityManager.getInstance().loadIdentityShortByKey(identityKey);
+			if(identity == null) {
+				return Response.serverError().status(Status.NOT_FOUND).build();
+			}
+			
+			File portrait = DisplayPortraitManager.getInstance().getBigPortrait(identity.getName());
+			if(portrait == null || !portrait.exists()) {
+				return Response.serverError().status(Status.NOT_FOUND).build();
+			}
+
+			Date lastModified = new Date(portrait.lastModified());
+			return Response.ok().lastModified(lastModified).build();
+		} catch (Throwable e) {
+			throw new WebApplicationException(e);
+		}
+	}
+	
+	/**
+	 * Retrieves the portrait of an user
+	 * @response.representation.200.mediaType application/octet-stream
+	 * @response.representation.200.doc The portrait as image
+	 * @response.representation.404.doc The identity or the portrait not found
 	 * @param identityKey The identity key of the user being searched
 	 * @param request The REST request
 	 * @return The image
@@ -581,8 +613,8 @@ public class UserWebService {
 	 * Upload the portrait of an user
 	 * @response.representation.200.mediaType application/octet-stream
 	 * @response.representation.200.doc The portrait as image
-   * @response.representation.401.doc Not authorized
-   * @response.representation.404.doc The identity or the portrait not found
+	 * @response.representation.401.doc Not authorized
+	 * @response.representation.404.doc The identity or the portrait not found
 	 * @param identityKey The user key identifier of the user being searched
 	 * @param file The image
 	 * @param request The REST request
@@ -752,7 +784,7 @@ public class UserWebService {
 		if(!StringHelper.containsNonWhitespace(value) && um.isMandatoryUserProperty(PROPERTY_HANDLER_IDENTIFIER, userPropertyHandler)) {
 			Translator translator = new PackageTranslator("org.olat.core", locale);
 			String translation = translator.translate("new.form.mandatory");
-			errors.add(new ErrorVO("org.olat.core", "new.form.mandatory", translation));
+			errors.add(new ErrorVO("org.olat.core:new.form.mandatory:" + userPropertyHandler.getName(), translation));
 			return false;
 		}
 		
diff --git a/src/test/java/org/olat/restapi/UserMgmtTest.java b/src/test/java/org/olat/restapi/UserMgmtTest.java
index 2efa7c59c72..774df231122 100644
--- a/src/test/java/org/olat/restapi/UserMgmtTest.java
+++ b/src/test/java/org/olat/restapi/UserMgmtTest.java
@@ -53,6 +53,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.methods.HttpDelete;
 import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpPut;
 import org.apache.http.util.EntityUtils;
@@ -1365,6 +1366,43 @@ public class UserMgmtTest extends OlatJerseyTestCase {
 		conn.shutdown();
 	}
 	
+	@Test
+	public void testPortrait_HEAD() throws IOException, URISyntaxException {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("portrait-1");
+		Identity idWithoutPortrait = JunitTestHelper.createAndPersistIdentityAsRndUser("portrait-2");
+		
+		URL portraitUrl = UserMgmtTest.class.getResource("portrait.jpg");
+		Assert.assertNotNull(portraitUrl);
+		File portrait = new File(portraitUrl.toURI());
+		RestConnection conn = new RestConnection();
+		Assert.assertTrue(conn.login(id.getName(), "A6B7C8"));
+		
+		//upload portrait
+		URI request = UriBuilder.fromUri(getContextURI())
+				.path("users").path(id.getKey().toString()).path("portrait").build();
+		HttpPost method = conn.createPost(request, MediaType.APPLICATION_JSON);
+		conn.addMultipart(method, "portrait.jpg", portrait);
+		HttpResponse response = conn.execute(method);
+		assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		//check 200
+		URI headRequest = UriBuilder.fromUri(getContextURI())
+				.path("users").path(id.getKey().toString()).path("portrait").build();
+		HttpHead headMethod = conn.createHead(headRequest, MediaType.APPLICATION_OCTET_STREAM, true);
+		HttpResponse headResponse = conn.execute(headMethod);
+		assertEquals(200, headResponse.getStatusLine().getStatusCode());
+		EntityUtils.consume(headResponse.getEntity());
+		
+		//check 404
+		URI headNoRequest = UriBuilder.fromUri(getContextURI())
+				.path("users").path(idWithoutPortrait.getKey().toString()).path("portrait").build();
+		HttpHead headNoMethod = conn.createHead(headNoRequest, MediaType.APPLICATION_OCTET_STREAM, true);
+		HttpResponse headNoResponse = conn.execute(headNoMethod);
+		assertEquals(404, headNoResponse.getStatusLine().getStatusCode());
+		EntityUtils.consume(headNoResponse.getEntity());
+	}
+	
 	protected List<UserVO> parseUserArray(InputStream body) {
 		try {
 			ObjectMapper mapper = new ObjectMapper(jsonFactory); 
-- 
GitLab