Skip to content

Commit

Permalink
Added user group mapping on external authenticate; update user profil…
Browse files Browse the repository at this point in the history
…e on external authenticate

Signed-off-by: sugarylump <alexcarvalhoflores@gmail.com>
  • Loading branch information
SugaryLump committed Jul 25, 2024
1 parent 766ac5b commit 505c2e9
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1588,7 +1588,11 @@ private void setMemberGroups(final String memberDN, final Set<String> groups) th
final Set<String> newgroupDNs = new HashSet<>();
for (String groupName : newGroups) {
LdapGroup ldapGroup = ldapGroupRepository.findByCommonName(groupName);
newgroupDNs.add(ldapGroup.getId().toString());
if (ldapGroup == null) {
LOGGER.warn("Group {} doesn't exist", groupName);
} else {
newgroupDNs.add(ldapGroup.getId().toString());
}
}

// removing all the groups in newgroups, oldgroups becomes the Set
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.roda.core.plugins;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -100,6 +103,7 @@ public User processLogin(final String username, final Map<String, Object> attrib
User user = null;

try {
// find user with username
user = RodaCoreFactory.getModelService().retrieveUser(username);
} catch (GenericException e) {
if (!(e.getCause() instanceof NamingException)) {
Expand All @@ -108,31 +112,54 @@ public User processLogin(final String username, final Map<String, Object> attrib
}

if (user == null || user.equals(new User())) {
User newUser = new User(username);
newUser = UserUtility.resetGroupsAndRoles(newUser);

// try to set user email from cas principal attributes
mapAttribute(newUser, attributes, "fullname", (u, a) -> u.setFullName(a));
mapAttribute(newUser, attributes, "email", (u, a) -> u.setEmail(a));

// Try to find a user with email
User retrievedUserByEmail = null;
if (StringUtils.isNotBlank(newUser.getEmail())) {
// couldn't find with username, so try to find with email
Object emailAttribute = attributes.get("email");
if (emailAttribute instanceof String email && StringUtils.isNotBlank(email)) {
try {
retrievedUserByEmail = RodaCoreFactory.getModelService().retrieveUserByEmail(newUser.getEmail());
user = RodaCoreFactory.getModelService().retrieveUserByEmail(email);
} catch (GenericException e) {
if (!(e.getCause() instanceof NamingException)) {
throw e;
}
}
}
}

if (user == null || user.equals(new User())) {
// couldn't find user with username nor email, so create a new one
user = new User(username);
user = UserUtility.resetGroupsAndRoles(user);

if (retrievedUserByEmail != null) {
user = retrievedUserByEmail;
} else {
// If no user was found with username or e-mail, a new one is created.
user = RodaCoreFactory.getModelService().createUser(newUser, true);
// try to set user email, full name and groups from cas principal attributes
mapStringAttribute(user, attributes, "fullname", (u, a) -> u.setFullName(a));
mapStringAttribute(user, attributes, "email", (u, a) -> u.setEmail(a));
mapSetAttribute(user, attributes, "memberOf", (u, a) -> u.setGroups(a));

user = RodaCoreFactory.getModelService().createUser(user, true);
}
else {
// found user and authentication externally, so update user email, full name and
// groups from cas principal
// attributes if they have changed
if (attributes.get("email") instanceof String email && !user.getEmail().equals(attributes.get("email"))) {
user.setEmail(email);
}
if (attributes.get("fullname") instanceof String fullname
&& !user.getFullName().equals(attributes.get("fullname"))) {
user.setFullName(fullname);
}
if (attributes.get("memberOf") instanceof Collection<?> memberOf) {
Set<String> groups = new HashSet<>();
for (Object group : memberOf) {
if (group instanceof String groupString) {
groups.add(groupString);
}
}
if (!user.getGroups().equals(groups)) {
user.setGroups(groups);
}
}
RodaCoreFactory.getModelService().updateUser(user, null, true);
}

if (!user.isActive()) {
Expand All @@ -143,14 +170,31 @@ public User processLogin(final String username, final Map<String, Object> attrib
return user;
}

private void mapAttribute(User user, Map<String, Object> attributes, String attributeKey,
private void mapStringAttribute(User user, Map<String, Object> attributes, String attributeKey,
BiConsumer<User, String> mapping) {
Object attributeValue = attributes.get(attributeKey);
if (attributeValue instanceof String value) {
mapping.accept(user, value);
}
}

private void mapSetAttribute(User user, Map<String, Object> attributes, String attributeKey,
BiConsumer<User, Set<String>> mapping) {
Object attributeValue = attributes.get(attributeKey);
Set<String> newCollection = new HashSet<>();
if (attributeValue instanceof Collection<?> valueCollection) {
for (Object value : valueCollection) {
if (value instanceof String valueString) {
newCollection.add(valueString);
}
}
}
else if (attributeValue instanceof String group) {
newCollection.add(group);
}
mapping.accept(user, newCollection);
}

public void logout(HttpServletRequest request, List<String> extraAttributesToBeRemovedFromSession) {
String loginMethod = (String) request.getSession().getAttribute(RODA_LOGIN_METHOD);
request.getSession().removeAttribute(RODA_LOGIN_METHOD);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

import javax.crypto.SecretKey;

import org.apache.commons.lang3.StringUtils;
import org.apereo.cas.client.authentication.AttributePrincipal;
import org.roda.core.RodaCoreFactory;
import org.roda.core.common.JwtUtils;
Expand Down Expand Up @@ -60,7 +63,6 @@
import org.roda.wui.client.management.recaptcha.RecaptchaException;
import org.roda.wui.client.services.MembersRestService;
import org.roda.wui.common.ControllerAssistant;
import org.roda.wui.common.client.tools.StringUtils;
import org.roda.wui.common.model.RequestContext;
import org.roda.wui.common.utils.RequestUtils;
import org.slf4j.Logger;
Expand Down Expand Up @@ -134,43 +136,67 @@ public static User casLoginHelper(final String username, final HttpServletReques
User user = null;

try {
// find user with username
user = RodaCoreFactory.getModelService().retrieveUser(username);
} catch (GenericException e) {
if (!(e.getCause() instanceof NamingException)) {
throw e;
}
}

if (user == null) {
User newUser = new User(username);
newUser = UserUtility.resetGroupsAndRoles(newUser);

// try to set user email from cas principal attributes
if (request.getUserPrincipal() instanceof AttributePrincipal attributePrincipal) {
Map<String, Object> attributes = attributePrincipal.getAttributes();

mapCasAttribute(newUser, attributes, "fullname", (u, a) -> u.setFullName(a));
mapCasAttribute(newUser, attributes, "email", (u, a) -> u.setEmail(a));
}
Map<String, Object> attributes = null;
if (request.getUserPrincipal() instanceof AttributePrincipal attributesPrincipal) {
attributes = attributesPrincipal.getAttributes();
}

// Try to find a user with email
User retrievedUserByEmail = null;
if (StringUtils.isNotBlank(newUser.getEmail())) {
if ((user == null || user.equals(new User())) && attributes != null) {
// couldn't find with username, so try to find with email
Object emailAttribute = attributes.get("email");
if (emailAttribute instanceof String email && StringUtils.isNotBlank(email)) {
try {
retrievedUserByEmail = RodaCoreFactory.getModelService().retrieveUserByEmail(newUser.getEmail());
user = RodaCoreFactory.getModelService().retrieveUserByEmail(email);
} catch (GenericException e) {
if (!(e.getCause() instanceof NamingException)) {
throw e;
}
}
}
}

if (retrievedUserByEmail != null) {
user = retrievedUserByEmail;
} else {
// If no user was found with username or e-mail, a new one is created.
user = RodaCoreFactory.getModelService().createUser(newUser, true);
if ((user == null || user.equals(new User())) && attributes != null) {
// couldn't find user with username nor email, so create a new one
user = new User(username);
user = UserUtility.resetGroupsAndRoles(user);

// try to set user email, full name and groups from cas principal attributes
mapCasStringAttribute(user, attributes, "fullname", (u, a) -> u.setFullName(a));
mapCasStringAttribute(user, attributes, "email", (u, a) -> u.setEmail(a));
mapCasSetAttribute(user, attributes, "memberOf", (u, a) -> u.setGroups(a));

user = RodaCoreFactory.getModelService().createUser(user, true);
} else {
// found user and authentication externally, so update user email, full name and
// groups from cas principal
// attributes if they have changed
if (attributes.get("email") instanceof String email && !user.getEmail().equals(attributes.get("email"))) {
user.setEmail(email);
}
if (attributes.get("fullname") instanceof String fullname
&& !user.getFullName().equals(attributes.get("fullname"))) {
user.setFullName(fullname);
}
if (attributes.get("memberOf") instanceof Collection<?> memberOf) {
Set<String> groups = new HashSet<>();
for (Object group : memberOf) {
if (group instanceof String groupString) {
groups.add(groupString);
}
}
if (!user.getGroups().equals(groups)) {
user.setGroups(groups);
}
}
RodaCoreFactory.getModelService().updateUser(user, null, true);
}

if (!user.isActive()) {
Expand All @@ -181,14 +207,30 @@ public static User casLoginHelper(final String username, final HttpServletReques
return user;
}

private static void mapCasAttribute(User user, Map<String, Object> attributes, String attributeKey,
private static void mapCasStringAttribute(User user, Map<String, Object> attributes, String attributeKey,
BiConsumer<User, String> mapping) {
Object attributeValue = attributes.get(attributeKey);
if (attributeValue instanceof String value) {
mapping.accept(user, value);
}
}

private static void mapCasSetAttribute(User user, Map<String, Object> attributes, String attributeKey,
BiConsumer<User, Set<String>> mapping) {
Object attributeValue = attributes.get(attributeKey);
Set<String> newCollection = new HashSet<>();
if (attributeValue instanceof Collection<?> valueCollection) {
for (Object value : valueCollection) {
if (value instanceof String valueString) {
newCollection.add(valueString);
}
}
} else if (attributeValue instanceof String group) {
newCollection.add(group);
}
mapping.accept(user, newCollection);
}

@Override
public User getUser(String name) {
RequestContext requestContext = RequestUtils.parseHTTPRequest(request);
Expand Down

0 comments on commit 505c2e9

Please sign in to comment.