You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2020/04/16 07:21:56 UTC

[openmeetings] branch master updated: [OPENMEETINGS-2262] binary image processing is added

This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openmeetings.git


The following commit(s) were added to refs/heads/master by this push:
     new 1ba1986  [OPENMEETINGS-2262] binary image processing is added
1ba1986 is described below

commit 1ba19868f63b294ffca9eb44269799eb036e49a4
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Thu Apr 16 14:21:43 2020 +0700

    [OPENMEETINGS-2262] binary image processing is added
---
 .../openmeetings/core/ldap/LdapLoginManager.java   | 53 ++++++++++++++++++++--
 .../apache/openmeetings/core/ldap/LdapOptions.java |  2 +-
 .../org/apache/openmeetings/ldap/TestLdap.java     | 25 ++++++++++
 .../src/test/resources/schema/users.ldif           | 39 +++++++++++++++-
 4 files changed, 112 insertions(+), 7 deletions(-)

diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManager.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManager.java
index 7d530f4..292e822 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManager.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManager.java
@@ -26,8 +26,12 @@ import static org.apache.openmeetings.util.OmException.UNKNOWN;
 import static org.apache.openmeetings.util.OmFileHelper.loadLdapConf;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getDefaultGroup;
 
+import java.io.ByteArrayInputStream;
 import java.io.Closeable;
 import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.List;
@@ -35,6 +39,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
 
+import org.apache.commons.io.FileUtils;
 import org.apache.directory.api.ldap.model.cursor.CursorException;
 import org.apache.directory.api.ldap.model.cursor.CursorLdapReferralException;
 import org.apache.directory.api.ldap.model.cursor.EntryCursor;
@@ -51,6 +56,7 @@ import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.ldap.client.api.EntryCursorImpl;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.apache.openmeetings.core.converter.ImageConverter;
 import org.apache.openmeetings.db.dao.server.LdapConfigDao;
 import org.apache.openmeetings.db.dao.user.GroupDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
@@ -62,6 +68,7 @@ import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Right;
 import org.apache.openmeetings.db.entity.user.User.Type;
 import org.apache.openmeetings.util.OmException;
+import org.apache.openmeetings.util.StoredFile;
 import org.apache.wicket.util.string.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -90,8 +97,8 @@ public class LdapLoginManager {
 	private static final String CONFIGKEY_LDAP_KEY_COUNTRY = "ldap_user_attr_country";
 	private static final String CONFIGKEY_LDAP_KEY_TOWN = "ldap_user_attr_town";
 	private static final String CONFIGKEY_LDAP_KEY_PHONE = "ldap_user_attr_phone";
-	private static final String CONFIGKEY_LDAP_KEY_PICTURE = "ldap_user_attr_picture";
 	private static final String CONFIGKEY_LDAP_KEY_GROUP = "ldap_group_attr";
+	public static final String CONFIGKEY_LDAP_KEY_PICTURE = "ldap_user_attr_picture";
 
 	// LDAP default attributes mapping
 	private static final String LDAP_KEY_LOGIN = "uid";
@@ -131,6 +138,8 @@ public class LdapLoginManager {
 	private UserDao userDao;
 	@Autowired
 	private GroupDao groupDao;
+	@Autowired
+	private ImageConverter imageConverter;
 
 	private static void bindAdmin(LdapConnection conn, LdapOptions options) throws LdapException {
 		if (!Strings.isEmpty(options.adminDn)) {
@@ -217,6 +226,7 @@ public class LdapLoginManager {
 						u.updatePassword(passwd);
 					}
 					u = userDao.update(u, null);
+					u = w.setUserPicture(entry, u);
 					break;
 				case NONE:
 				default:
@@ -333,6 +343,43 @@ public class LdapLoginManager {
 			conn = new LdapNetworkConnection(options.host, options.port, options.secure);
 		}
 
+		public User setUserPicture(Entry entry, User inUser) throws LdapInvalidAttributeValueException {
+			Attribute a = getAttr(config, entry, CONFIGKEY_LDAP_KEY_PICTURE, "");
+			User u = inUser;
+			if (a != null) {
+				Value val = a.get();
+				if (val != null && val.getBytes() != null) {
+					InputStream is = new ByteArrayInputStream(val.getBytes());
+					StoredFile sf = new StoredFile("picture", is);
+					if (sf.isImage()) {
+						Path tempImage = null;
+						try {
+							tempImage = Files.createTempFile("omLdap", "img");
+							FileUtils.copyToFile(is, tempImage.toFile());
+							imageConverter.convertImageUserProfile(tempImage.toFile(), inUser.getId(), sf.isAsIs());
+							u = userDao.get(inUser.getId());
+						} catch (Exception e) {
+							log.error("Unable to store binary image from LDAP", e);
+						} finally {
+							if (tempImage != null) {
+								try {
+									Files.deleteIfExists(tempImage);
+								} catch (IOException e) {
+									log.error("Unexpected error while clean-up", e);
+								}
+							}
+						}
+					} else {
+						u.setPictureUri(val.getString());
+					}
+				}
+			}
+			if (Strings.isEmpty(u.getPictureUri()) && !Strings.isEmpty(options.pictureUri)) {
+				u.setPictureUri(options.pictureUri);
+			}
+			return userDao.update(u, null);
+		}
+
 		public User getUser(Entry entry, User u) throws LdapException, CursorException, OmException, IOException {
 			if (entry == null) {
 				log.error("LDAP entry is null, search or lookup by Dn failed");
@@ -368,10 +415,6 @@ public class LdapLoginManager {
 			u.getAddress().setCountry(validateCountry(getStringAttr(config, entry, CONFIGKEY_LDAP_KEY_COUNTRY, LDAP_KEY_COUNTRY)));
 			u.getAddress().setTown(getStringAttr(config, entry, CONFIGKEY_LDAP_KEY_TOWN, LDAP_KEY_TOWN));
 			u.getAddress().setPhone(getStringAttr(config, entry, CONFIGKEY_LDAP_KEY_PHONE, LDAP_KEY_PHONE));
-			u.setPictureUri(getStringAttr(config, entry, CONFIGKEY_LDAP_KEY_PICTURE, ""));
-			if (Strings.isEmpty(u.getPictureUri()) && !Strings.isEmpty(options.pictureUri)) {
-				u.setPictureUri(options.pictureUri);
-			}
 			String tz = getStringAttr(config, entry, LdapOptions.CONFIGKEY_LDAP_TIMEZONE_NAME, LDAP_KEY_TIMEZONE);
 			if (tz == null) {
 				tz = options.tz;
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapOptions.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapOptions.java
index a2d7f8d..9cc9b03 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapOptions.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapOptions.java
@@ -52,7 +52,7 @@ public class LdapOptions {
 	private static final String CONFIGKEY_LDAP_USERDN_FORMAT = "ldap_userdn_format";
 	private static final String CONFIGKEY_LDAP_GROUP_QUERY = "ldap_group_query";
 	private static final String CONFIGKEY_LDAP_IMPORT_QUERY = "ldap_import_query";
-	private static final String CONFIGKEY_LDAP_PICTURE_URI = "ldap_user_picture_uri";
+	public static final String CONFIGKEY_LDAP_PICTURE_URI = "ldap_user_picture_uri";
 
 	AuthType type = AuthType.SIMPLEBIND;
 	Provisionning prov = Provisionning.AUTOCREATE;
diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/ldap/TestLdap.java b/openmeetings-web/src/test/java/org/apache/openmeetings/ldap/TestLdap.java
index d34939a..7daee77 100644
--- a/openmeetings-web/src/test/java/org/apache/openmeetings/ldap/TestLdap.java
+++ b/openmeetings-web/src/test/java/org/apache/openmeetings/ldap/TestLdap.java
@@ -20,16 +20,19 @@ package org.apache.openmeetings.ldap;
 
 import static org.apache.directory.server.constants.ServerDNConstants.ADMIN_SYSTEM_DN;
 import static org.apache.directory.server.core.api.partition.PartitionNexus.ADMIN_PASSWORD_BYTES;
+import static org.apache.openmeetings.core.ldap.LdapLoginManager.CONFIGKEY_LDAP_KEY_PICTURE;
 import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_ADMIN_DN;
 import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_ADMIN_PASSWD;
 import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_AUTH_TYPE;
 import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_HOST;
+import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_PICTURE_URI;
 import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_PORT;
 import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_SEARCH_BASE;
 import static org.apache.openmeetings.core.ldap.LdapOptions.CONFIGKEY_LDAP_SEARCH_SCOPE;
 import static org.apache.openmeetings.util.OmFileHelper.getLdapConf;
 import static org.apache.openmeetings.util.OmFileHelper.loadLdapConf;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -72,6 +75,8 @@ public class TestLdap extends AbstractWicketTester {
 	private static final String CFG_SEARCH_BIND = UUID.randomUUID().toString();
 	private static final String BAD_PASSWORD = "bad password";
 	private static final String USER1 = "ldaptest1";
+	private static final String USER2 = "ldaptest2";
+	private static final String USER3 = "ldaptest3";
 	private static final Map<String, LdapConfig> CFG_MAP = new HashMap<>();
 	private static final Properties PROPS = new Properties();
 	@Autowired
@@ -90,6 +95,8 @@ public class TestLdap extends AbstractWicketTester {
 		PROPS.put(CONFIGKEY_LDAP_ADMIN_PASSWD, new String(ADMIN_PASSWORD_BYTES));
 		PROPS.put(CONFIGKEY_LDAP_SEARCH_BASE, "dc=test,dc=openmeetings,dc=apache,dc=org");
 		PROPS.put(CONFIGKEY_LDAP_SEARCH_SCOPE, SearchScope.SUBTREE.name());
+		PROPS.put(CONFIGKEY_LDAP_KEY_PICTURE, "photo");
+		PROPS.put(CONFIGKEY_LDAP_PICTURE_URI, "profile.png"); // this one is for Jenkins
 	}
 
 	private void createSbnd() throws FileNotFoundException, IOException {
@@ -134,6 +141,24 @@ public class TestLdap extends AbstractWicketTester {
 	}
 
 	@Test
+	public void testPhoto1() throws OmException {
+		LdapConfig cfg = CFG_MAP.get(CFG_SEARCH_BIND);
+		assertTrue(WebSession.get().signIn(USER2, userpass, User.Type.LDAP, cfg.getId()), "Login should be successful");
+		User u = userDao.getByLogin(USER2, User.Type.LDAP, cfg.getId());
+		assertNotNull(u);
+		assertEquals("profile.png", u.getPictureUri());
+	}
+
+	@Test
+	public void testPhoto2() throws OmException {
+		LdapConfig cfg = CFG_MAP.get(CFG_SEARCH_BIND);
+		assertTrue(WebSession.get().signIn(USER3, userpass, User.Type.LDAP, cfg.getId()), "Login should be successful");
+		User u = userDao.getByLogin(USER3, User.Type.LDAP, cfg.getId());
+		assertNotNull(u);
+		assertEquals("user.jpg", u.getPictureUri());
+	}
+
+	@Test
 	public void testSbndSessionLoginBadPassword() {
 		LdapConfig cfg = CFG_MAP.get(CFG_SEARCH_BIND);
 		assertThrows(OmException.class, () -> WebSession.get().signIn(USER1, BAD_PASSWORD, User.Type.LDAP, cfg.getId()));
diff --git a/openmeetings-web/src/test/resources/schema/users.ldif b/openmeetings-web/src/test/resources/schema/users.ldif
index af54bf6..282ea48 100644
--- a/openmeetings-web/src/test/resources/schema/users.ldif
+++ b/openmeetings-web/src/test/resources/schema/users.ldif
@@ -33,7 +33,42 @@ objectClass: inetOrgPerson
 cn: Test2 Ldap
 sn: Ldap
 uid: ldaptest2
-userPassword: Q!w2e3r4t5
+userPassword:: USF3MmUzcjR0NQ==
+photo:: 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
 
 dn: cn=Test3 Ldap,ou=Users,dc=test,dc=openmeetings,dc=apache,dc=org
 objectClass: top
@@ -44,3 +79,5 @@ cn: Test3 Ldap
 sn: Ldap
 uid: ldaptest3
 userPassword: Q!w2e3r4t5
+photo: user.jpg
+