From efec736a040674b66159d5a9ba4d8f808b0e0e05 Mon Sep 17 00:00:00 2001 From: Alex Bogdanovski Date: Thu, 24 Oct 2024 19:20:10 +0300 Subject: [PATCH] added support for setting a preffered starting space each user individually, closes #461 --- .../java/com/erudika/scoold/ScooldConfig.java | 8 ++++++++ .../scoold/controllers/ProfileController.java | 18 ++++++++++++++++++ .../scoold/controllers/SigninController.java | 4 ++-- .../java/com/erudika/scoold/core/Profile.java | 13 +++++++++++++ .../com/erudika/scoold/utils/HttpUtils.java | 18 +++++++++++++----- .../com/erudika/scoold/utils/ScooldUtils.java | 5 +++-- src/main/resources/static/styles/style.css | 2 +- src/main/resources/templates/profile.vm | 14 ++++++++++++++ 8 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/erudika/scoold/ScooldConfig.java b/src/main/java/com/erudika/scoold/ScooldConfig.java index 65c4478b..f8af4331 100644 --- a/src/main/java/com/erudika/scoold/ScooldConfig.java +++ b/src/main/java/com/erudika/scoold/ScooldConfig.java @@ -1807,6 +1807,14 @@ public String autoAssignSpaces() { return getConfigParam("auto_assign_spaces", ""); } + @Documented(position = 1681, + identifier = "default_starting_space", + category = "Spaces", + description = "The starting space to be selected for all users upon sign in.") + public String defaultStartingSpace() { + return getConfigParam("default_starting_space", ""); + } + @Documented(position = 1690, identifier = "reset_spaces_on_new_assignment", value = "true", diff --git a/src/main/java/com/erudika/scoold/controllers/ProfileController.java b/src/main/java/com/erudika/scoold/controllers/ProfileController.java index e116e418..cd3c2dba 100755 --- a/src/main/java/com/erudika/scoold/controllers/ProfileController.java +++ b/src/main/java/com/erudika/scoold/controllers/ProfileController.java @@ -414,6 +414,24 @@ public String toggleEditorRole(HttpServletRequest req, Model model) { return "redirect:" + HttpUtils.getBackToUrl(req, true); } + @PostMapping("/{id}/set-preferred-space") + public String setPreferredSpace(@PathVariable String id, @RequestParam String preferredSpace, + HttpServletRequest req, HttpServletResponse res, Model model) { + Profile authUser = utils.getAuthUser(req); + Profile showUser = getProfileForEditing(id, authUser); + if (authUser != null && !StringUtils.isBlank(preferredSpace) && + StringUtils.equalsAny(authUser.getGroups(), User.Groups.ADMINS.toString(), User.Groups.MODS.toString())) { + showUser.setPreferredSpace(preferredSpace); + showUser.update(); + } + if (utils.isAjaxRequest(req)) { + res.setStatus(200); + return "base"; + } else { + return "redirect:" + HttpUtils.getBackToUrl(req, true); + } + } + private String changeEmail(User u, Profile showUser, String email) { boolean approvedDomain = utils.isEmailDomainApproved(email); if (approvedDomain && canChangeEmail(u, email)) { diff --git a/src/main/java/com/erudika/scoold/controllers/SigninController.java b/src/main/java/com/erudika/scoold/controllers/SigninController.java index ecc9f621..8c101ffa 100755 --- a/src/main/java/com/erudika/scoold/controllers/SigninController.java +++ b/src/main/java/com/erudika/scoold/controllers/SigninController.java @@ -166,7 +166,7 @@ public String signup(@RequestParam String name, @RequestParam String email, @Req if (!isEmailRegistered(email) && approvedDomain && isSubmittedByHuman(req) && goodPass) { User u = pc.signIn("password", email + ":" + name + ":" + passw, false); if (u != null && u.getActive()) { - setAuthCookie(u.getPassword(), req, res); + setAuthCookie(u, req, res); triggerLoginEvent(u, req); return "redirect:" + getBackToUrl(req); } else { @@ -359,7 +359,7 @@ private String loginWithIdToken(String jwt, HttpServletRequest req, HttpServletR private String onAuthSuccess(User u, HttpServletRequest req, HttpServletResponse res) { if (u != null && utils.isEmailDomainApproved(u.getEmail())) { // the user password in this case is a Bearer token (JWT) - setAuthCookie(u.getPassword(), req, res); + setAuthCookie(u, req, res); triggerLoginEvent(u, req); return "redirect:" + getBackToUrl(req); } else if (u != null && !utils.isEmailDomainApproved(u.getEmail())) { diff --git a/src/main/java/com/erudika/scoold/core/Profile.java b/src/main/java/com/erudika/scoold/core/Profile.java index 41351dd7..c91c3958 100755 --- a/src/main/java/com/erudika/scoold/core/Profile.java +++ b/src/main/java/com/erudika/scoold/core/Profile.java @@ -77,6 +77,7 @@ public class Profile extends Sysprop { @Stored private List> customBadges; @Stored private String pendingEmail; @Stored private Boolean editorRoleEnabled; + @Stored private String preferredSpace; private transient String currentSpace; private transient String newbadges; @@ -368,6 +369,18 @@ public void setFavspaces(Set favspaces) { this.favspaces = favspaces; } + public String getPreferredSpace() { + // returns a preferred staring space upon login + if (StringUtils.isBlank(preferredSpace)) { + preferredSpace = ScooldUtils.getConfig().defaultStartingSpace(); + } + return preferredSpace; + } + + public void setPreferredSpace(String preferredSpace) { + this.preferredSpace = preferredSpace; + } + public boolean isModInCurrentSpace() { return isModInSpace(currentSpace); } diff --git a/src/main/java/com/erudika/scoold/utils/HttpUtils.java b/src/main/java/com/erudika/scoold/utils/HttpUtils.java index cbdcc308..3d8ce48d 100644 --- a/src/main/java/com/erudika/scoold/utils/HttpUtils.java +++ b/src/main/java/com/erudika/scoold/utils/HttpUtils.java @@ -23,6 +23,7 @@ import com.erudika.para.core.utils.Utils; import com.erudika.scoold.ScooldConfig; import static com.erudika.scoold.ScooldServer.HOMEPAGE; +import com.erudika.scoold.core.Profile; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -269,15 +270,22 @@ public static void getDefaultAvatarImage(HttpServletResponse res) { /** * Sets the session cookie. - * @param jwt a JWT from Para + * @param authUser auth user * @param req req * @param res res */ - public static void setAuthCookie(String jwt, HttpServletRequest req, HttpServletResponse res) { - if (StringUtils.isBlank(jwt)) { - return; + public static void setAuthCookie(User authUser, HttpServletRequest req, HttpServletResponse res) { + if (!StringUtils.isBlank(authUser.getPassword())) { + setRawCookie(CONF.authCookie(), authUser.getPassword(), req, res, "Lax", CONF.sessionTimeoutSec()); + } + try { + Profile authu = ScooldUtils.getInstance().getParaClient().read(Profile.id(authUser.getId())); + if (authu != null && !StringUtils.isBlank(authu.getPreferredSpace())) { + ScooldUtils.getInstance().storeSpaceIdInCookie(authu.getPreferredSpace(), req, res); + } + } catch (Exception ex) { + logger.error(null, ex); } - setRawCookie(CONF.authCookie(), jwt, req, res, "Lax", CONF.sessionTimeoutSec()); } /** diff --git a/src/main/java/com/erudika/scoold/utils/ScooldUtils.java b/src/main/java/com/erudika/scoold/utils/ScooldUtils.java index cc7a7fe8..176cb40e 100755 --- a/src/main/java/com/erudika/scoold/utils/ScooldUtils.java +++ b/src/main/java/com/erudika/scoold/utils/ScooldUtils.java @@ -67,6 +67,7 @@ import jakarta.validation.ConstraintViolation; import java.io.IOException; import java.io.InputStream; +import java.net.URI; import java.net.URL; import java.nio.ByteBuffer; import java.security.InvalidKeyException; @@ -233,7 +234,7 @@ public static ScooldConfig getConfig() { public static void setParaEndpointAndApiPath(ParaClient pc) { try { - URL endpoint = new URL(CONF.paraEndpoint()); + URL endpoint = new URI(CONF.paraEndpoint()).toURL(); if (!StringUtils.isBlank(endpoint.getPath()) && !"/".equals(endpoint.getPath())) { // support Para deployed under a specific context path pc.setEndpoint(StringUtils.removeEnd(CONF.paraEndpoint(), endpoint.getPath())); @@ -1455,7 +1456,7 @@ public void storeSpaceIdInCookie(String space, HttpServletRequest req, HttpServl // used for setting the space from a direct URL to a particular space req.setAttribute(CONF.spaceCookie(), space); HttpUtils.setRawCookie(CONF.spaceCookie(), Utils.base64encURL(space.getBytes()), - req, res, "Strict", StringUtils.isBlank(space) ? 0 : 365 * 24 * 60 * 60); + req, res, "Lax", StringUtils.isBlank(space) ? 0 : 365 * 24 * 60 * 60); } public String verifyExistingSpace(Profile authUser, String space) { diff --git a/src/main/resources/static/styles/style.css b/src/main/resources/static/styles/style.css index 05788368..c60c815a 100755 --- a/src/main/resources/static/styles/style.css +++ b/src/main/resources/static/styles/style.css @@ -344,7 +344,7 @@ img.profile-pic { } .user-card img.profile-pic, .user-card-compact img.profile-pic { width: 100%; - padding: 6px 0px 0px 6px; + padding: 6px 0px 0px 7px; } img.profile-pic:before { content: " "; diff --git a/src/main/resources/templates/profile.vm b/src/main/resources/templates/profile.vm index d9583d64..a8494a10 100755 --- a/src/main/resources/templates/profile.vm +++ b/src/main/resources/templates/profile.vm @@ -361,6 +361,20 @@ + #if($isMod && (!$scooldUtils.isMod($showUser) || $isMyProfile)) + Preferred starting space: +
+ + +
+ #end +