- Avatar for the user at login is now downloaded and saved/removed in a separate thread

- Redirect after the login to the original requested page is performed when response has not already commited due to redirect to another URI due to tokens expiration or errors
This commit is contained in:
Mauro Mugnaini 2024-09-26 18:08:39 +02:00
parent 558c3b45f8
commit 2351e01837
3 changed files with 77 additions and 64 deletions

18
pom.xml
View File

@ -17,6 +17,9 @@
<version>1.2.1-SNAPSHOT</version>
<properties>
<java.version>8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<liferay.version>6.2.5</liferay.version>
<liferay.maven.plugin.version>6.2.10.12</liferay.maven.plugin.version>
<liferay.auto.deploy.dir>/Users/themaxx/Development/Server/liferay-portal-6.2-ce-ga6/deploy</liferay.auto.deploy.dir>
@ -101,21 +104,6 @@
<pluginType>hook</pluginType>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- <plugin> -->
<!-- <artifactId>maven-resources-plugin</artifactId> -->
<!-- <version>2.5</version> -->
<!-- <configuration> -->
<!-- <encoding>UTF-8</encoding> -->
<!-- </configuration> -->
<!-- </plugin> -->
</plugins>
</build>

View File

@ -33,7 +33,7 @@ public class OpenIdConnectAutoLogin extends BaseAutoLogin {
private static final Log log = LogFactoryUtil.getLog(OpenIdConnectAutoLogin.class);
private static final boolean ASSURE_AVATAR_FORMAT = true;
private static final boolean ENSURE_AVATAR_FORMAT = true;
private static final String DEFAULT_AVATAR_FORMAT = "png";
private static final boolean DELETE_AVATAR_IF_NOT_FOUND_ON_SERVER = false;
@ -152,44 +152,8 @@ public class OpenIdConnectAutoLogin extends BaseAutoLogin {
UserLocalServiceUtil.updateUser(user);
}
try {
byte[] userAvatar = OpenIdConnectRESTHelper.getUserAvatar(configuration.getAvatarURL(), token);
if (userAvatar != null && userAvatar.length > 0) {
if (ASSURE_AVATAR_FORMAT) {
if (log.isDebugEnabled()) {
log.debug("Assuring avatar image format as: " + DEFAULT_AVATAR_FORMAT);
log.debug("Reading image stream with length: " + userAvatar.length);
}
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(userAvatar));
if (bi != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (log.isDebugEnabled()) {
log.debug("Converting avatar stream image format to: " + DEFAULT_AVATAR_FORMAT);
}
ImageIO.write(bi, DEFAULT_AVATAR_FORMAT, baos);
baos.flush();
baos.close();
if (log.isDebugEnabled()) {
log.debug("Reading converted image from the BAOS");
}
userAvatar = baos.toByteArray();
} else {
log.warn("Buffered image read is null!");
}
}
if (log.isDebugEnabled()) {
log.debug("Saving the retrieved avatar as user's portrait");
}
UserLocalServiceUtil.updatePortrait(user.getUserId(), userAvatar);
} else if (DELETE_AVATAR_IF_NOT_FOUND_ON_SERVER) {
if (log.isDebugEnabled()) {
log.debug("Deleting the user's portrait since no avatar has been found for the user");
}
UserLocalServiceUtil.deletePortrait(user.getUserId());
}
} catch (Throwable t) {
log.error("Cannot save/update/delete user's portrait", t);
}
// Performing avatar download and save/delete in new thread to avoid distributed network persistence delays
new AvatarThread(configuration, user, token).start();
} catch (SystemException | PortalException e) {
throw new RuntimeException(e);
}
@ -251,4 +215,60 @@ public class OpenIdConnectAutoLogin extends BaseAutoLogin {
return user;
}
public static class AvatarThread extends Thread {
private LiferayOpenIdConnectConfiguration configuration;
private User user;
private JWTToken token;
public AvatarThread(LiferayOpenIdConnectConfiguration configuration, User user, JWTToken token) {
this.configuration = configuration;
this.user = user;
this.token = token;
}
@Override
public void run() {
log.debug("Starting avatar download and save thread for: " + user.getScreenName());
try {
byte[] userAvatar = OpenIdConnectRESTHelper.getUserAvatar(configuration.getAvatarURL(), token);
if (userAvatar != null && userAvatar.length > 0) {
if (ENSURE_AVATAR_FORMAT) {
if (log.isDebugEnabled()) {
log.debug("Assuring avatar image format as: " + DEFAULT_AVATAR_FORMAT);
log.debug("Reading image stream with length: " + userAvatar.length);
}
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(userAvatar));
if (bi != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (log.isDebugEnabled()) {
log.debug("Converting avatar stream image format to: " + DEFAULT_AVATAR_FORMAT);
}
ImageIO.write(bi, DEFAULT_AVATAR_FORMAT, baos);
baos.flush();
baos.close();
if (log.isDebugEnabled()) {
log.debug("Reading converted image from the BAOS");
}
userAvatar = baos.toByteArray();
} else {
log.warn("Buffered image read is null!");
}
}
if (log.isDebugEnabled()) {
log.debug("Saving the retrieved avatar as user's portrait");
}
UserLocalServiceUtil.updatePortrait(user.getUserId(), userAvatar);
} else if (DELETE_AVATAR_IF_NOT_FOUND_ON_SERVER) {
if (log.isDebugEnabled()) {
log.debug("Deleting the user's portrait since no avatar has been found for the user");
}
UserLocalServiceUtil.deletePortrait(user.getUserId());
}
} catch (Throwable t) {
log.error("Cannot save/update/delete user's portrait", t);
}
}
}
}

View File

@ -61,16 +61,21 @@ public class PostLoginAction extends Action {
}
if (redirect != null) {
if (log.isDebugEnabled()) {
log.debug("Redirecting to the original requested URI: " + redirect);
}
try {
// I'm not sure I can use this LR facility since it's used also by landing-page-hook.
// Indeed perhaps it should also be discussed if it takes precedence over this redirect in the case.
// session.setAttribute(WebKeys.LAST_PATH, new LastPath(null, URLDecoder.decode(redirect, "UTF-8"))
response.sendRedirect(URLDecoder.decode(redirect, "UTF-8"));
} catch (IOException e) {
new ActionException("Redirecting to original requested URI: " + redirect, e);
// Checking if a redirect has been already set (e.g. after an exception and/or a redirect to the logout URI)
if (!response.isCommitted()) {
if (log.isDebugEnabled()) {
log.debug("Redirecting to the original requested URI: " + redirect);
}
try {
// I'm not sure I can use this LR facility since it's used also by landing-page-hook.
// Indeed perhaps it should also be discussed if it takes precedence over this redirect in the case.
// session.setAttribute(WebKeys.LAST_PATH, new LastPath(null, URLDecoder.decode(redirect, "UTF-8"))
response.sendRedirect(URLDecoder.decode(redirect, "UTF-8"));
} catch (IOException e) {
new ActionException("Redirecting to original requested URI: " + redirect, e);
}
} else {
log.warn("Cannot redirect to original redirect URI (" + redirect + ") since the response is already commited");
}
} else if (log.isDebugEnabled()) {
log.debug("No original requested URI has been found in session");