From 5f51fc5b47a67970e9b199c967125bcc3126ac7c Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Wed, 30 Mar 2016 12:47:52 +0200
Subject: [PATCH] CL-526: add logo to user profile

---
 .../org/olat/user/DisplayPortraitManager.java | 66 ++++++++++++++-----
 .../org/olat/user/ProfileFormController.java  | 55 +++++++++++++++-
 src/main/java/org/olat/user/UserModule.java   |  6 ++
 .../user/_i18n/LocalStrings_ar.properties     |  1 +
 .../user/_i18n/LocalStrings_bg.properties     |  1 +
 .../user/_i18n/LocalStrings_cs.properties     |  1 +
 .../user/_i18n/LocalStrings_da.properties     |  1 +
 .../user/_i18n/LocalStrings_de.properties     |  2 +
 .../user/_i18n/LocalStrings_el.properties     |  1 +
 .../user/_i18n/LocalStrings_en.properties     |  2 +
 .../user/_i18n/LocalStrings_es.properties     |  1 +
 .../user/_i18n/LocalStrings_et_EE.properties  |  1 +
 .../user/_i18n/LocalStrings_fa.properties     |  1 +
 .../user/_i18n/LocalStrings_fr.properties     |  2 +
 .../user/_i18n/LocalStrings_it.properties     |  1 +
 .../user/_i18n/LocalStrings_jp.properties     |  1 +
 .../user/_i18n/LocalStrings_lt.properties     |  1 +
 .../user/_i18n/LocalStrings_nl_NL.properties  |  1 +
 .../user/_i18n/LocalStrings_pl.properties     |  1 +
 .../user/_i18n/LocalStrings_pt_BR.properties  |  1 +
 .../user/_i18n/LocalStrings_pt_PT.properties  |  1 +
 .../user/_i18n/LocalStrings_ru.properties     |  1 +
 .../user/_i18n/LocalStrings_sq.properties     |  1 +
 .../user/_i18n/LocalStrings_zh_CN.properties  |  1 +
 .../user/_i18n/LocalStrings_zh_TW.properties  |  1 +
 .../org/olat/user/_spring/userContext.xml     | 41 ++++++------
 .../resources/serviceconfig/olat.properties   |  3 +
 27 files changed, 158 insertions(+), 38 deletions(-)

diff --git a/src/main/java/org/olat/user/DisplayPortraitManager.java b/src/main/java/org/olat/user/DisplayPortraitManager.java
index 5e597d79727..27f3554ca1c 100644
--- a/src/main/java/org/olat/user/DisplayPortraitManager.java
+++ b/src/main/java/org/olat/user/DisplayPortraitManager.java
@@ -51,8 +51,13 @@ public class DisplayPortraitManager extends BasicManager implements UserDataDele
 
 	private static DisplayPortraitManager singleton;
 	
-	private static final String PORTRAIT_BIG_FILENAME = "portrait_big";
-	private static final String PORTRAIT_SMALL_FILENAME = "portrait_small";
+	private static final String LOGO_PREFIX_FILENAME = "logo";
+	private static final String LOGO_BIG_FILENAME = LOGO_PREFIX_FILENAME + "_big";
+	private static final String LOGO_SMALL_FILENAME = LOGO_PREFIX_FILENAME + "_small";
+
+	private static final String PORTRAIT_PREFIX_FILENAME = "portrait";
+	private static final String PORTRAIT_BIG_FILENAME = PORTRAIT_PREFIX_FILENAME + "_big";
+	private static final String PORTRAIT_SMALL_FILENAME = PORTRAIT_PREFIX_FILENAME + "_small";
 	// The following class names refer to CSS class names in olat.css 
 	public static final String AVATAR_BIG_CSS_CLASS = "o_portrait_avatar";
 	public static final String AVATAR_SMALL_CSS_CLASS = "o_portrait_avatar_small";
@@ -127,7 +132,6 @@ public class DisplayPortraitManager extends BasicManager implements UserDataDele
 		return null;
 	}
 
-	
 	public File getSmallPortrait(String username) {
 		return getPortraitFile(username, PORTRAIT_SMALL_FILENAME);
 	}
@@ -135,6 +139,14 @@ public class DisplayPortraitManager extends BasicManager implements UserDataDele
 	public File getBigPortrait(String username) {
 		return getPortraitFile(username, PORTRAIT_BIG_FILENAME);
 	}
+	
+	public File getSmallLogo(String username) {
+		return getPortraitFile(username, LOGO_SMALL_FILENAME);
+	}
+	
+	public File getBigLogo(String username) {
+		return getPortraitFile(username, LOGO_BIG_FILENAME);
+	}
 
 	private File getPortraitFile(String username, String prefix) {
 		File portraitDir = getPortraitDir(username);
@@ -149,14 +161,22 @@ public class DisplayPortraitManager extends BasicManager implements UserDataDele
 	}
 	
 	public void setPortrait(File file, String filename, String username) {
-		//first remove old ones
-		File portraitDir = getPortraitDir(username);
-		if(portraitDir != null) {
-			for(File currentPortrait:portraitDir.listFiles()) {
-				if(currentPortrait.equals(file)) {
+		setImage(file, filename, username, PORTRAIT_PREFIX_FILENAME, PORTRAIT_BIG_FILENAME, PORTRAIT_SMALL_FILENAME);
+	}
+	
+	public void setLogo(File file, String filename, String username) {
+		setImage(file, filename, username, LOGO_PREFIX_FILENAME, LOGO_BIG_FILENAME, LOGO_SMALL_FILENAME);
+	}
+
+	private void setImage(File file, String filename, String username, String prefix, String largeImagePrefix, String smallImagePrefix) {
+		File directory = getPortraitDir(username);
+		if(directory != null) {
+			for(File currentImage:directory.listFiles()) {
+				if(currentImage.equals(file)) {
 					continue;
+				} else if(currentImage.getName().startsWith(prefix)) {
+					currentImage.delete();
 				}
-				currentPortrait.delete();
 			}
 		}
 		
@@ -169,17 +189,33 @@ public class DisplayPortraitManager extends BasicManager implements UserDataDele
 				extension = "png";
 			}
 		}
-		File pBigFile = new File(portraitDir, DisplayPortraitManager.PORTRAIT_BIG_FILENAME + "." + extension);
-		File pSmallFile = new File(portraitDir, DisplayPortraitManager.PORTRAIT_SMALL_FILENAME + "." + extension);
+		File bigFile = new File(directory, largeImagePrefix + "." + extension);
+		File smallFile = new File(directory, smallImagePrefix + "." + extension);
 		ImageService imageHelper = CoreSpringFactory.getImpl(ImageService.class);
-		Size size = imageHelper.scaleImage(file, extension, pBigFile, DisplayPortraitManager.WIDTH_PORTRAIT_BIG, DisplayPortraitManager.WIDTH_PORTRAIT_BIG, false);
+		Size size = imageHelper.scaleImage(file, extension, bigFile, WIDTH_PORTRAIT_BIG, WIDTH_PORTRAIT_BIG, false);
 		if(size != null){
-			size = imageHelper.scaleImage(file, extension, pSmallFile, DisplayPortraitManager.WIDTH_PORTRAIT_SMALL, DisplayPortraitManager.WIDTH_PORTRAIT_SMALL, false);
+			size = imageHelper.scaleImage(file, extension, smallFile, WIDTH_PORTRAIT_SMALL, WIDTH_PORTRAIT_SMALL, false);
 		}
 	}
-	
+
 	public void deletePortrait(Identity identity) {
-		FileUtils.deleteDirsAndFiles(getPortraitDir(identity.getName()), true, true);
+		deleteImages(identity, PORTRAIT_PREFIX_FILENAME);
+	}
+	
+	public void deleteLogo(Identity identity) {
+		deleteImages(identity, LOGO_PREFIX_FILENAME);
+	}
+	
+	private void deleteImages(Identity identity, String prefix) {
+		File directory = getPortraitDir(identity.getName());
+		if(directory != null && directory.exists()) {
+			for(File file:directory.listFiles()) {
+				String filename = file.getName();
+				if(filename.startsWith(prefix)) {
+					file.delete();
+				}
+			}
+		}
 	}
 	
 	/**
diff --git a/src/main/java/org/olat/user/ProfileFormController.java b/src/main/java/org/olat/user/ProfileFormController.java
index bea3f69a99b..703799c411f 100644
--- a/src/main/java/org/olat/user/ProfileFormController.java
+++ b/src/main/java/org/olat/user/ProfileFormController.java
@@ -84,15 +84,17 @@ public class ProfileFormController extends FormBasicController {
 	private static final String usageIdentifier= ProfileFormController.class.getCanonicalName();
 	private static final String SEPARATOR = "\n____________________________________________________________________\n";
 
-	private final Map<String, FormItem> formItems = new HashMap<String, FormItem>();
-	private final Map<String, String> formContext = new HashMap<String, String>();
+	private final Map<String, FormItem> formItems = new HashMap<>();
+	private final Map<String, String> formContext = new HashMap<>();
 	private RichTextElement textAboutMe;
 
 	private Identity identityToModify;
 	private DialogBoxController dialogCtr;
 
+	private FileElement logoUpload;
 	private FileElement portraitUpload;
 	
+	private final boolean logoEnabled;
 	private final boolean isAdministrativeUser;
 	private final List<UserPropertyHandler> userPropertyHandlers;
 	
@@ -141,6 +143,7 @@ public class ProfileFormController extends FormBasicController {
 		
 		this.identityToModify = identityToModify;
 		this.isAdministrativeUser = isAdministrativeUser;
+		this.logoEnabled = UserModule.isLogoByProfileEnabled();
 		
 		userPropertyHandlers = userManager.getUserPropertyHandlersFor(usageIdentifier, isAdministrativeUser);
 		initForm(ureq);
@@ -255,6 +258,25 @@ public class ProfileFormController extends FormBasicController {
 		}
 		portraitUpload.limitToMimeType(mimeTypes, null, null);
 		
+		if(logoEnabled) {
+			//upload image
+			groupContainer = FormLayoutContainer.createDefaultFormLayout("logoupload", getTranslator());
+			groupContainer.setFormTitle(translate("logo.header"));
+			formLayout.add(groupContainer);
+
+			File logoFile = dps.getBigLogo(identityToModify.getName());
+			logoUpload = uifactory.addFileElement(getWindowControl(), "logo.select", "logo.select", groupContainer);
+			logoUpload.setMaxUploadSizeKB(10000, null, null);
+			logoUpload.setPreview(ureq.getUserSession(), true);
+			logoUpload.addActionListener(FormEvent.ONCHANGE);
+			logoUpload.setHelpTextKey("ul.select.fhelp", null);
+			logoUpload.setDeleteEnabled(true);
+			if(logoFile != null) {
+				logoUpload.setInitialFile(logoFile);
+			}
+			logoUpload.limitToMimeType(mimeTypes, null, null);
+		}
+		
 		// Create submit and cancel buttons
 		FormLayoutContainer buttonLayoutWrappper = FormLayoutContainer.createDefaultFormLayout("buttonLayoutWrappper", getTranslator());
 		formLayout.add(buttonLayoutWrappper);
@@ -377,6 +399,26 @@ public class ProfileFormController extends FormBasicController {
 			} else if (portraitUpload.isUploadSuccess()) {
 				flc.setDirty(true);
 			}
+		} else if (source == logoUpload) {
+			if(event instanceof FileElementEvent) {
+				if(FileElementEvent.DELETE.equals(event.getCommand())) {
+					File img = dps.getBigLogo(identityToModify.getName());
+					if(logoUpload.getUploadFile() != null) {
+						logoUpload.reset();
+						if(img != null) {
+							logoUpload.setInitialFile(img);
+						}
+					} else if(img != null) {
+						dps.deleteLogo(identityToModify);
+						logoUpload.setInitialFile(null);
+						notifyPortraitChanged();
+					}
+					flc.setDirty(true);
+					
+				}
+			} else if (logoUpload.isUploadSuccess()) {
+				flc.setDirty(true);
+			}
 		}
 
 		super.formInnerEvent(ureq, source, event);
@@ -406,6 +448,15 @@ public class ProfileFormController extends FormBasicController {
 			notifyPortraitChanged();
 		}
 		
+		if(logoUpload != null) {
+			File uploadedLogo = logoUpload.getUploadFile();
+			String uploadedLogoname = logoUpload.getUploadFileName();
+			if(uploadedLogo != null) {
+				dps.setLogo(uploadedLogo, uploadedLogoname, identityToModify.getName());
+				notifyPortraitChanged();
+			}
+		}
+		
 		// Store the "about me" text.
 		HomePageConfig conf = hpcm.loadConfigFor(identityToModify.getName());
 		conf.setTextAboutMe(textAboutMe.getValue());
diff --git a/src/main/java/org/olat/user/UserModule.java b/src/main/java/org/olat/user/UserModule.java
index 0e363be215e..e999e5eaaab 100644
--- a/src/main/java/org/olat/user/UserModule.java
+++ b/src/main/java/org/olat/user/UserModule.java
@@ -69,6 +69,7 @@ public class UserModule extends AbstractOLATModule {
 	private static boolean pwdchangeallowed;
 	private static boolean pwdchangeallowedLDAP;
 	private static String adminUserName;
+	private static boolean enabledLogoByProfile;
 	private List<DefaultUser> defaultUsers;
 	private List<DefaultUser> testUsers;
 	private static OLog log = Tracing.createLoggerFor(UserModule.class);
@@ -144,6 +145,7 @@ public class UserModule extends AbstractOLATModule {
 
 		// Autogeneration of test users
 		hasTestUsers = getBooleanConfigParameter("generateTestUsers", true);
+		enabledLogoByProfile = "enabled".equals(getStringConfigParameter("logoByProfileEnabled", "disabled", true));
 		
 		// Check if default users exists, if not create them
 		securityManager = BaseSecurityManager.getInstance();
@@ -323,6 +325,10 @@ public class UserModule extends AbstractOLATModule {
 		return pwdchangeallowed;
 	}
 	
+	public static boolean isLogoByProfileEnabled() {
+		return enabledLogoByProfile;
+	}
+	
 	public static String getAdminUserName() {
 		return adminUserName;
 	}
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_ar.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_ar.properties
index d481a2fc603..9429c3c1048 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_ar.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_ar.properties
@@ -58,6 +58,7 @@ interval.monthly=\u0643\u0644 \u0634\u0647\u0631
 interval.never=\u0625\u0637\u0644\u0627\u0642\u0627\u064B
 interval.two-hourly=\u0643\u0644 \u0633\u0627\u0639\u062A\u064A\u0646
 interval.weekly=\u0643\u0644 \u0623\u0633\u0628\u0648\u0639
+logo.select=$:ul.select
 menu.calendar=\u0627\u0644\u062A\u0642\u0648\u064A\u0645
 menu.calendar.alt=\u0627\u0644\u062A\u0642\u0648\u064A\u0645 \u0627\u0644\u0634\u062E\u0635\u0649 \u0644\u0644\u0645\u0633\u062A\u062E\u062F\u0645 \u0627\u0644\u0645\u062D\u062F\u062F
 menu.contact=\u0627\u062A\u0635\u0627\u0644
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_bg.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_bg.properties
index 63c1e78f84c..ef4e74a07a1 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_bg.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_bg.properties
@@ -50,6 +50,7 @@ info.password.aai=\u041C\u043E\u0436\u0435\u0442\u0435 \u0434\u0430 \u043F\u0440
 info.password.olat=\u0412 \u0441\u043B\u0443\u0447\u0430\u0439, \u0447\u0435 \u043F\u0440\u0438\u0442\u0435\u0436\u0430\u0432\u0430\u0442\u0435 \u043B\u0438\u0447\u043D\u0430 \u043F\u0430\u0440\u043E\u043B\u0430 \u0437\u0430 \u0441\u0438\u0441\u0442\u0435\u043C\u0430\u0442\u0430 / WebDAV, \u043C\u043E\u0436\u0435\u0442\u0435 \u0434\u0430 \u044F \u0441\u043C\u0435\u043D\u0438\u0442\u0435 \u0442\u0443\u043A.
 informSessionTimeout.false=\u041D\u0435
 informSessionTimeout.true=\u0414\u0430
+logo.select=$:ul.select
 menu.calendar=\u041A\u0430\u043B\u0435\u043D\u0434\u0430\u0440
 menu.calendar.alt=\u041B\u0438\u0447\u0435\u043D \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440 \u043D\u0430 \u0438\u0437\u0431\u0440\u0430\u043D\u0438\u044F \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B
 menu.contact=\u0421\u0432\u044A\u0440\u0436\u0435\u0442\u0435 \u0441\u0435
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_cs.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_cs.properties
index 2985ef4a216..ea7d8c7f0b1 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_cs.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_cs.properties
@@ -37,6 +37,7 @@ info.password.aai=M\u016F\u017Eete zm\u011Bnit sv\u00E9 heslo pro p\u0159\u00EDs
 info.password.olat=Pokud chcete zm\u011Bnit sv\u00E9 heslo pro p\u0159\u00EDstup do OLATu, m\u016F\u017Eete to ud\u011Blat zde.
 informSessionTimeout.false=Ne
 informSessionTimeout.true=Ano
+logo.select=$:ul.select
 menu.calendar=Kalend\u00E1\u0159
 menu.calendar.alt=Kalend\u00E1\u0159 vybran\u00E9ho u\u017Eivatele
 menu.contact=Kontakt
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_da.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_da.properties
index d305ffa010a..3107f030e7f 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_da.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_da.properties
@@ -33,6 +33,7 @@ info.password.aai=Du kan \u00E6ndre dit kodeord p\u00E5 det relevante institut p
 info.password.olat=Hvis du har et personligt OLAT / WebDAV kodeord, kan du \u00E6ndre det lige her.
 informSessionTimeout.false=Nej
 informSessionTimeout.true=Ja
+logo.select=$:ul.select
 menu.calendar=Kalender
 menu.calendar.alt=Kalender for den valgte bruger
 menu.contact=Kontakt
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_de.properties
index c3e5420fc20..1db12993019 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_de.properties
@@ -63,6 +63,8 @@ interval.never=ausgeschaltet
 interval.two-hourly=alle zwei Stunden
 interval.weekly=w\u00F6chentlich
 landing.pages=Startseite
+logo.header=Firmenlogo (Formate .jpg .jpeg .png .gif)
+logo.select=$:ul.select
 mail.intern.only=E-Mails an das interne OpenOLAT Postfach zustellen
 mail.send.copy=E-Mails an das interne OpenOLAT Postfach und die Adresse {0} zustellen
 mail.system=E-Mail Versand
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_el.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_el.properties
index b56aab4ab26..bc3f55c76d0 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_el.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_el.properties
@@ -58,6 +58,7 @@ interval.monthly=\u039C\u03B7\u03BD\u03B9\u03B1\u03AF\u03C9\u03C2
 interval.never=\u03A0\u03BF\u03C4\u03AD
 interval.two-hourly=\u039A\u03AC\u03B8\u03B5 \u03B4\u03CD\u03BF \u03CE\u03C1\u03B5\u03C2
 interval.weekly=\u0395\u03B2\u03B4\u03BF\u03BC\u03B1\u03B4\u03B9\u03B1\u03AF\u03C9\u03C2
+logo.select=$:ul.select
 menu.calendar=\u0397\u03BC\u03B5\u03C1\u03BF\u03BB\u03CC\u03B3\u03B9\u03BF
 menu.calendar.alt=\u03A0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC \u03B7\u03BC\u03B5\u03C1\u03BF\u03BB\u03CC\u03B3\u03B9\u03BF \u03C4\u03BF\u03C5 \u03B5\u03C0\u03B9\u03BB\u03B5\u03B3\u03BC\u03AD\u03BD\u03BF\u03C5 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7
 menu.contact=\u0395\u03C0\u03B9\u03BA\u03BF\u03B9\u03BD\u03C9\u03BD\u03AF\u03B1
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties
index 93dfcc53ffe..a69b8502dc3 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties
@@ -63,6 +63,8 @@ interval.never=Never
 interval.two-hourly=Every two hours
 interval.weekly=Weekly
 landing.pages=Landing page
+logo.header=Enterprise logo (Formats .jpg .jpeg .png .gif only)
+logo.select=$:ul.select
 mail.intern.only=Send e-mails to the OpenOLAT internal inbox
 mail.send.copy=Send e-mails to the OpenOLAT internal inbox and the address {0}
 mail.system=E-mail delivery
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_es.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_es.properties
index f0fe4de5874..01852a7e174 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_es.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_es.properties
@@ -50,6 +50,7 @@ info.password.aai=Puedes modificar tu contrase\u00F1a en el departamento corresp
 info.password.olat=En caso de que tengas una contrase\u00F1a personal OLAT / WebDAV, aqu\u00ED puedes cambiarla.
 informSessionTimeout.false=No
 informSessionTimeout.true=S\u00ED
+logo.select=$:ul.select
 menu.calendar=Calendario
 menu.calendar.alt=Calendario del usuario seleccionado 
 menu.contact=Contactar
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_et_EE.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_et_EE.properties
index 54c70e3cbd9..dab48d77477 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_et_EE.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_et_EE.properties
@@ -15,6 +15,7 @@ form.password.new2=Kinnita OLATi salas\u00F5na
 form.password.old=Eelmine OLATi salas\u00F5na
 form.please.enter.new=Palun sisesta enda uus OLATi salas\u00F5na.
 form.please.enter.old=Palun sisesta enda eelmine OLATi salas\u00F5na.
+logo.select=$:ul.select
 tab.hp=Minu visiitkaart
 tab.prefs=S\u00FCsteem
 tab.profile=Profiil
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_fa.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_fa.properties
index f1ad9c8055d..6e750912c15 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_fa.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_fa.properties
@@ -32,6 +32,7 @@ info.password.aai=\u0634\u0645\u0627 \u0645\u06CC\u062A\u0648\u0627\u0646\u06CC\
 info.password.olat=\u062F\u0631 \u0635\u0648\u0631\u062A\u06CC \u06A9\u0647 \u0634\u0645\u0627 \u06CC\u06A9 \u06A9\u0644\u0645\u0647 \u0639\u0628\u0648\u0631 \u0634\u062E\u0635\u06CC \u062F\u0627\u0631\u06CC\u062F \u0642\u0627\u062F\u0631 \u062E\u0648\u0627\u0647\u06CC\u062F \u0628\u0648\u062F \u062F\u0631 \u0647\u0645\u06CC\u0646 \u0645\u06A9\u0627\u0646 \u0622\u0646 \u0631\u0627 \u0639\u0648\u0636 \u06A9\u0646\u06CC\u062F
 informSessionTimeout.false=\u062E\u06CC\u0631
 informSessionTimeout.true=\u0628\u0644\u0647
+logo.select=$:ul.select
 menu.contact=\u062A\u0645\u0627\u0633
 menu.contact.alt=\u062A\u0645\u0627\u0633 \u0628\u0627 \u0627\u06CC\u0646 \u06A9\u0627\u0631\u0628\u0631
 menu.folder=\u067E\u0648\u0634\u0647
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_fr.properties
index 368309181a2..97c168b7a90 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_fr.properties
@@ -63,6 +63,8 @@ interval.never=Jamais
 interval.two-hourly=Toutes les deux heures
 interval.weekly=Hebdomadaire
 landing.pages=Page de d\u00E9part
+logo.header=Logo d'entreprise (.jpg .jpeg .png .gif)
+logo.select=$:ul.select
 mail.intern.only=Envoy\u00E9 les courriels au syst\u00E8me interne
 mail.send.copy=Envoy\u00E9 les courriels au syst\u00E8me interne \u00E0 \u00E0 l'addresse {0}
 mail.system=Envoi du courriel
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_it.properties
index 977cfeea766..a50460f9c2f 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_it.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_it.properties
@@ -59,6 +59,7 @@ interval.monthly=mensilmente
 interval.never=mai
 interval.two-hourly=ogni due ore
 interval.weekly=settimanalmente
+logo.select=$:ul.select
 menu.calendar=Calendario
 menu.calendar.alt=Calendario personale dell'utente selezionato
 menu.contact=Contatto
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_jp.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_jp.properties
index db5fcf2312f..26d2433e320 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_jp.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_jp.properties
@@ -42,6 +42,7 @@ form.username=\u30E6\u30FC\u30B6\u540D
 info.password.olat=\u30D1\u30FC\u30BD\u30CA\u30EBOLAT/WebDAV\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u6240\u6709\u3057\u3066\u3044\u308B\u5834\u5408\u3001\u3053\u3053\u3067\u3042\u306A\u305F\u306F\u5909\u66F4\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\u3002
 informSessionTimeout.false=No
 informSessionTimeout.true=Yes
+logo.select=$:ul.select
 menu.calendar=\u30AB\u30EC\u30F3\u30C0\u30FC
 menu.calendar.alt=\u9078\u629E\u3057\u305F\u30E6\u30FC\u30B6\u306E\u30D1\u30FC\u30BD\u30CA\u30EB\u30AB\u30EC\u30F3\u30C0\u30FC
 menu.contact=\u30B3\u30F3\u30BF\u30AF\u30C8
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_lt.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_lt.properties
index e44e5bec563..e72ee8fc1a5 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_lt.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_lt.properties
@@ -33,6 +33,7 @@ info.password.aai=J\u016Bs galite pakeisti slapta\u017Eod\u012F atitinkamame uni
 info.password.olat=Kadangi j\u016Bs valdote asmenin\u012F /WebDAV slapta\u017Eod\u012F, j\u016Bs galite j\u012F pakeisti \u010Dia.
 informSessionTimeout.false=Ne
 informSessionTimeout.true=Taip
+logo.select=$:ul.select
 menu.contact=U\u017Emegzti ry\u0161\u012F
 menu.contact.alt=U\u017Emegzti ry\u0161\u012F su \u0161iuo naudotoju
 menu.folder=Aplankas
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_nl_NL.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_nl_NL.properties
index 8b34b879339..412b9888ea5 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_nl_NL.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_nl_NL.properties
@@ -59,6 +59,7 @@ interval.monthly=Maandelijks
 interval.never=Nooit
 interval.two-hourly=Elke twee uur
 interval.weekly=Wekelijks
+logo.select=$:ul.select
 menu.calendar=Kalender
 menu.calendar.alt=Individuele kalender van de geselecteerde gebruiker
 menu.contact=Contact
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_pl.properties
index 3434d55969c..075c8866b1b 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_pl.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_pl.properties
@@ -61,6 +61,7 @@ interval.never=Nigdy
 interval.two-hourly=Co dwie godziny
 interval.weekly=Co tydzie\u0144
 landing.pages=Strona pocz\u0105tkowa
+logo.select=$:ul.select
 mail.intern.only=Wysy\u0142aj wiadomo\u015Bci na wewn\u0119trzn\u0105 skrzynk\u0119
 mail.send.copy=Wysy\u0142aj wiadomo\u015Bci na wewn\u0119trzn\u0105 skrzynk\u0119 i na adres e-mail
 mail.system=Dostarczanie e-maili
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_pt_BR.properties
index 569d6c4ffbb..5ec0ce7877a 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_pt_BR.properties
@@ -63,6 +63,7 @@ interval.never=Nunca
 interval.two-hourly=Cada duas horas
 interval.weekly=Semanal
 landing.pages=P\u00E1gina inicial
+logo.select=$:ul.select
 mail.intern.only=Enviar e-mails para a caixa de entrada interna do OLAT
 mail.send.copy=Enviar e-mails para a caixa de entrada interna do OLAT e para o endere\u00E7o {0}
 mail.system=Entrega de E-mail
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_pt_PT.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_pt_PT.properties
index b5fb2785952..51a44bce563 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_pt_PT.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_pt_PT.properties
@@ -33,6 +33,7 @@ info.password.aai=Voc\u00EA pode alterar sua senha no departamento pertinente em
 info.password.olat=No caso de voc\u00EA ter uma senha pessoal OLAT / WebDAV, voc\u00EA pode altera-la aqui.
 informSessionTimeout.false=N\u00E3o
 informSessionTimeout.true=Sim
+logo.select=$:ul.select
 menu.calendar=Calend\u00E1rio
 menu.calendar.alt=Calend\u00E1rio do usu\u00E1rio selecionado
 menu.contact=Contatar
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_ru.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_ru.properties
index a16d66bfd89..526a4b0fed2 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_ru.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_ru.properties
@@ -58,6 +58,7 @@ interval.monthly=\u0415\u0436\u0435\u043C\u0435\u0441\u044F\u0447\u043D\u043E
 interval.never=\u041D\u0438\u043A\u043E\u0433\u0434\u0430
 interval.two-hourly=\u041A\u0430\u0436\u0434\u044B\u0435 \u0434\u0432\u0430 \u0447\u0430\u0441\u0430
 interval.weekly=\u0415\u0436\u0435\u043D\u0435\u0434\u0435\u043B\u044C\u043D\u043E
+logo.select=$:ul.select
 menu.calendar=\u041A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044C
 menu.calendar.alt=\u041F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0439 \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044C \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F
 menu.contact=\u041A\u043E\u043D\u0442\u0430\u043A\u0442
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_sq.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_sq.properties
index eaa465e2fe0..597ef8abd35 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_sq.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_sq.properties
@@ -33,6 +33,7 @@ info.password.aai=Ju mund t\u00EB nd\u00EBrroni fjal\u00EBkalimin tuaj edhe tek
 info.password.olat=N\u00EB k\u00EBt\u00EB rast ju keni nj\u00EB fjal\u00EBkalim personal OLAT / WebDAV, ju mund ta nd\u00EBrroni at\u00EB q\u00EB k\u00EBtu.
 informSessionTimeout.false=Jo
 informSessionTimeout.true=Po
+logo.select=$:ul.select
 menu.calendar=Kalendar
 menu.calendar.alt=Kalendari i shfryt\u00EBzuesit t\u00EB p\u00EBrzgjedhur
 menu.contact=Kontakti
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_zh_CN.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_zh_CN.properties
index 923fe66a959..c252c66cca4 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_zh_CN.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_zh_CN.properties
@@ -58,6 +58,7 @@ interval.monthly=\u6BCF\u6708
 interval.never=\u4ECE\u4E0D\u63A5\u6536
 interval.two-hourly=\u6BCF\u96942\u5C0F\u65F6
 interval.weekly=\u6BCF\u5468
+logo.select=$:ul.select
 menu.calendar=\u65E5\u671F
 menu.calendar.alt=\u65E5\u671F\u9009\u62E9
 menu.contact=\u8054\u7CFB\u65B9\u5F0F
diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_zh_TW.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_zh_TW.properties
index ba66803d9c2..e3b87490a46 100644
--- a/src/main/java/org/olat/user/_i18n/LocalStrings_zh_TW.properties
+++ b/src/main/java/org/olat/user/_i18n/LocalStrings_zh_TW.properties
@@ -58,6 +58,7 @@ interval.monthly=\u6BCF\u6708
 interval.never=\u6C38\u4E0D
 interval.two-hourly=\u6BCF\u4E8C\u5C0F\u6642
 interval.weekly=\u6BCF\u9031
+logo.select=$:ul.select
 menu.calendar=\u884C\u4E8B\u66C6
 menu.calendar.alt=\u9078\u53D6\u7684\u4F7F\u7528\u8005\u4E4B\u500B\u4EBA\u884C\u4E8B\u66C6
 menu.contact=\u806F\u7D61
diff --git a/src/main/java/org/olat/user/_spring/userContext.xml b/src/main/java/org/olat/user/_spring/userContext.xml
index 7f7a8581b49..c360be48fa4 100644
--- a/src/main/java/org/olat/user/_spring/userContext.xml
+++ b/src/main/java/org/olat/user/_spring/userContext.xml
@@ -15,20 +15,19 @@
 
 <bean id="userModule" class="org.olat.user.UserModule" 
 	depends-on="notificationsManager, database, baseSecurityManager, triggerI18nModuleInit">
-<!-- default auth string -->
-<constructor-arg index="0" value="${default.auth.provider.identifier}" />
-<constructor-arg index="1" ref="userManager" />
-<constructor-arg index="2" ref="afterLoginInterceptionManager" />
-
-<property name="persistedProperties">
-  <bean class="org.olat.core.configuration.PersistedProperties" scope="prototype" init-method="init" destroy-method="destroy">
-    <constructor-arg index="0" ref="coordinatorManager"/>
-    <constructor-arg index="1" ref="userModule" />
-  </bean>
-</property>
-
-<!-- provide an admin user-->
-<property name="defaultUsers">
+	<!-- default auth string -->
+	<constructor-arg index="0" value="${default.auth.provider.identifier}" />
+	<constructor-arg index="1" ref="userManager" />
+	<constructor-arg index="2" ref="afterLoginInterceptionManager" />
+	<property name="persistedProperties">
+	  <bean class="org.olat.core.configuration.PersistedProperties" scope="prototype" init-method="init" destroy-method="destroy">
+	    <constructor-arg index="0" ref="coordinatorManager"/>
+	    <constructor-arg index="1" ref="userModule" />
+	  </bean>
+	</property>
+	
+	<!-- provide an admin user-->
+	<property name="defaultUsers">
         <list>
                 <bean class="org.olat.user.DefaultUser">
                         <!-- constructor arg is userName -->
@@ -41,10 +40,10 @@
                         <property name="admin" value="true" />
                 </bean>
         </list>
-</property>
+	</property>
 
-<!-- provide some test users -->
-<property name="testUsers">
+	<!-- provide some test users -->
+	<property name="testUsers">
         <list>
                 <bean class="org.olat.user.DefaultUser">
                         <!-- constructor arg is userName -->
@@ -134,8 +133,8 @@
                        <property name="admin" value="false" />
                </bean>
            </list>
-</property>
-<property name="loginBlacklist">
+	</property>
+	<property name="loginBlacklist">
 		<list>
 			<!--
 			Use regexp to define logins which are not allowed.
@@ -176,11 +175,10 @@
 			<value>[\.\-_].*</value>
 			<value>[\.\-_]*</value>
 		</list>
-</property> 
+	</property> 
 	<property name="afterLoginConfig">
 		<ref bean="org.olat.user.AfterLoginConfig"/>
 	</property>
-
 </bean>
 
 	<bean id="org.olat.user.AfterLoginConfig" class="org.olat.login.AfterLoginConfig" scope="prototype">	
@@ -253,6 +251,7 @@
                     passwordChangeAllowed=${password.change.allowed}
                     passwordChangeAllowedLDAP=${ldap.propagatePasswordChangedOnLdapServer}
                     adminUserName=administrator
+                    logoByProfileEnabled=${user.logoByProfile}
             </value>
 	    </property>
 	</bean>
diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties
index 814c34f664a..8b3062d4bbe 100644
--- a/src/main/resources/serviceconfig/olat.properties
+++ b/src/main/resources/serviceconfig/olat.properties
@@ -672,6 +672,9 @@ userinfos.tunnelcoursebuildingblock=disabled
 userDisplayName=userDisplayName_lastname_firstname
 userDisplayName.values=userDisplayName_firstname_lastname, userDisplayName_lastname_firstname
 
+user.logoByProfile=disabled
+user.logoByProfile.values=enabled,disabled
+
 ########################################################################
 # Fulltext Search settings
 ########################################################################
-- 
GitLab