package com.nubisware.oidc.lr62; import java.util.Arrays; import java.util.Calendar; import java.util.Locale; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.util.LocaleUtil; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.model.User; import com.liferay.portal.security.auth.BaseAutoLogin; import com.liferay.portal.service.ServiceContext; import com.liferay.portal.service.UserLocalServiceUtil; import com.liferay.portal.util.PortalUtil; import com.liferay.util.PwdGenerator; import com.nubisware.oidc.gcube.URLEncodedContextMapper; import com.nubisware.oidc.rest.JWTToken; public class OpenIdConnectAutoLogin extends BaseAutoLogin { private static final Log log = LogFactoryUtil.getLog(OpenIdConnectAutoLogin.class); @Override public String[] doLogin(HttpServletRequest request, HttpServletResponse response) throws Exception { if (log.isTraceEnabled() && request.getSession(false) != null) { log.trace("Session details: id=" + request.getSession(false).getId() + ", instance=" + request.getSession(false)); } JWTToken token = JWTTokenUtil.getOIDCFromRequest(request); if (token == null) { if (log.isTraceEnabled() && request.getSession(false) != null) { log.trace("OIDC token is null. Can't perform auto login"); } return null; } LiferayOpenIdConnectConfiguration configuration = LiferayOpenIdConnectConfiguration.getConfiguration(request); long companyId = PortalUtil.getCompanyId(request); long groupId = PortalUtil.getScopeGroupId(request); String portalURL = PortalUtil.getPortalURL(request, true); User user = createOrUpdateUser(token, companyId, groupId, portalURL, configuration); if (user != null) { log.info("Applying sites and roles strategy"); try { UserSitesToGroupsAndRolesMapper mapper = new UserSitesToGroupsAndRolesMapper( user, new URLEncodedContextMapper( token.getResourceNameToAccessRolesMap(Arrays.asList(JWTToken.ACCOUNT_RESOURCE)))); mapper.map(); } catch (Throwable t) { // TODO: to be removed when tested in depth log.error("Applying strategy", t); } log.debug("Returning logged in user's info"); return new String[] { String.valueOf(user.getUserId()), UUID.randomUUID().toString(), "false" }; } else { log.warn("User is null"); return null; } } public static User createOrUpdateUser(JWTToken token, long companyId, long groupId, String portalURL, LiferayOpenIdConnectConfiguration configuration) throws Exception { String email = token.getEmail(); String given = token.getGiven(); String family = token.getFamily(); String subject = token.getSub(); User user = null; try { boolean updateUser = false; // Search by email first user = UserLocalServiceUtil.fetchUserByEmailAddress(companyId, email); if (user == null) { log.debug("No Liferay user found with email address=" + email + ", trying with openId"); // Then search by openId, in case user has changed the email address user = UserLocalServiceUtil.fetchUserByOpenId(companyId, subject); if (user == null) { log.debug("No Liferay user found with openid=" + subject + " and email address=" + email); if (configuration.createUnexistingUser()) { log.info("A new user will be created"); user = addUser(companyId, groupId, portalURL, email, given, family, subject); } else { log.info("User will not be created according to configuration"); return null; } } else { log.info("User found by its openId, the email will be updated"); updateUser = true; } } if (user != null) { log.debug("User found, updating name details with info from userinfo if changed"); if (given != user.getFirstName()) { user.setFirstName(given); updateUser = true; } if (family != user.getLastName()) { user.setLastName(family); updateUser = true; } if (email != user.getEmailAddress()) { user.setEmailAddress(email); updateUser = true; } } if (updateUser) { UserLocalServiceUtil.updateUser(user); } } catch (SystemException | PortalException e) { throw new RuntimeException(e); } return user; } public static User addUser(long companyId, long groupId, String portalURL, String emailAddress, String firstName, String lastName, String openid) throws SystemException, PortalException { Locale locale = LocaleUtil.getMostRelevantLocale(); long creatorUserId = 0; boolean autoPassword = false; String password1 = PwdGenerator.getPassword(); String password2 = password1; boolean autoScreenName = true; String screenName = StringPool.BLANK; long facebookId = 0; String openId = openid; String middleName = StringPool.BLANK; int prefixId = 0; int suffixId = 0; boolean male = true; int birthdayMonth = Calendar.JANUARY; int birthdayDay = 1; int birthdayYear = 1970; String jobTitle = StringPool.BLANK; long[] groupIds = null; long[] organizationIds = null; long[] roleIds = null; long[] userGroupIds = null; boolean sendEmail = false; ServiceContext serviceContext = new ServiceContext(); serviceContext.setScopeGroupId(groupId); serviceContext.setPortalURL(portalURL); User user = UserLocalServiceUtil.addUser(creatorUserId, companyId, autoPassword, password1, password2, autoScreenName, screenName, emailAddress, facebookId, openId, locale, firstName, middleName, lastName, prefixId, suffixId, male, birthdayMonth, birthdayDay, birthdayYear, jobTitle, groupIds, organizationIds, roleIds, userGroupIds, sendEmail, serviceContext); // No password user.setPasswordReset(false); // email is already verified by oidc connect provider user.setEmailAddressVerified(true); // No reminder query at first login. user.setReminderQueryQuestion("x"); user.setReminderQueryAnswer("y"); UserLocalServiceUtil.updateUser(user); return user; } }