Commit aff06fd6 authored by michael.simon's avatar michael.simon
Browse files

Adding first create user methods for oidc

parent 5b14ca78
/*******************************************************************************
* Copyright (c) 2014 Michael Simon.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Michael Simon - initial
******************************************************************************/
package edu.kit.scc.webreg.dao.jpa.oidc;
import java.io.Serializable;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import edu.kit.scc.webreg.dao.jpa.JpaBaseDao;
import edu.kit.scc.webreg.dao.oidc.OidcTokenDao;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.entity.oidc.OidcTokenEntity;
@Named
@ApplicationScoped
public class JpaTokenEntityDao extends JpaBaseDao<OidcTokenEntity, Long> implements OidcTokenDao, Serializable {
private static final long serialVersionUID = 1L;
@Override
public void deleteTokenForUser(UserEntity user) {
Query query = em.createQuery("delete from OidcTokenEntity where user=:user");
query.setParameter("user", user);
query.executeUpdate();
}
@Override
public OidcTokenEntity findByUserId(Long userId) {
try {
return (OidcTokenEntity) em.createQuery("select e from OidcTokenEntity e " +
"where e.user.id = :userId")
.setParameter("userId", userId)
.getSingleResult();
}
catch (NoResultException e) {
return null;
}
}
@Override
public Class<OidcTokenEntity> getEntityClass() {
return OidcTokenEntity.class;
}
}
/*******************************************************************************
* Copyright (c) 2014 Michael Simon.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Michael Simon - initial
******************************************************************************/
package edu.kit.scc.webreg.dao.oidc;
import edu.kit.scc.webreg.dao.BaseDao;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.entity.oidc.OidcTokenEntity;
public interface OidcTokenDao extends BaseDao<OidcTokenEntity, Long> {
void deleteTokenForUser(UserEntity user);
OidcTokenEntity findByUserId(Long userId);
}
package edu.kit.scc.webreg.entity.oidc;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
import edu.kit.scc.webreg.entity.AbstractBaseEntity;
@Entity(name = "OidcTokenEntity")
@Table(name = "oidctoken")
public class OidcTokenEntity extends AbstractBaseEntity {
private static final long serialVersionUID = 1L;
@Column(name = "id_token_data")
@Basic(fetch = FetchType.LAZY)
@Lob
@Type(type = "org.hibernate.type.TextType")
private String idTokenData;
@Column(name = "user_info_data")
@Basic(fetch = FetchType.LAZY)
@Lob
@Type(type = "org.hibernate.type.TextType")
private String userInfoData;
@ManyToOne(targetEntity = OidcUserEntity.class)
private OidcUserEntity user;
public String getIdTokenData() {
return idTokenData;
}
public void setIdTokenData(String idTokenData) {
this.idTokenData = idTokenData;
}
public String getUserInfoData() {
return userInfoData;
}
public void setUserInfoData(String userInfoData) {
this.userInfoData = userInfoData;
}
public OidcUserEntity getUser() {
return user;
}
public void setUser(OidcUserEntity user) {
this.user = user;
}
}
package edu.kit.scc.webreg.entity.oidc;
import javax.annotation.Generated;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(OidcTokenEntity.class)
public abstract class OidcTokenEntity_ extends edu.kit.scc.webreg.entity.AbstractBaseEntity_ {
public static volatile SingularAttribute<OidcTokenEntity, String> idTokenData;
public static volatile SingularAttribute<OidcTokenEntity, String> userInfoData;
public static volatile SingularAttribute<OidcTokenEntity, OidcUserEntity> user;
}
......@@ -81,6 +81,9 @@ public class OidcClientCallbackServiceImpl implements OidcClientCallbackService
@Inject
private ApplicationConfig appConfig;
@Inject
private OidcTokenHelper oidcTokenHelper;
@Inject
private SessionManager session;
......@@ -175,8 +178,7 @@ public class OidcClientCallbackServiceImpl implements OidcClientCallbackService
// Store OIDC Data temporarily in Session
logger.debug("Storing relevant Oidc data in session");
session.setSubjectId(claims.getSubject().getValue());
// TODO: setAttributeMap in Session with attributes from OIDC
session.setAttributeMap(oidcTokenHelper.convertToAttributeMap(claims, userInfo));
httpServletResponse.sendRedirect("/register/register-oidc.xhtml");
return;
......
package edu.kit.scc.webreg.service.oidc.client;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.enterprise.context.ApplicationScoped;
import com.nimbusds.openid.connect.sdk.claims.IDTokenClaimsSet;
import com.nimbusds.openid.connect.sdk.claims.UserInfo;
@ApplicationScoped
public class OidcTokenHelper {
public Map<String, List<Object>> convertToAttributeMap(IDTokenClaimsSet claims, UserInfo userInfo) {
Map<String, List<Object>> attributeMap = new HashMap<String, List<Object>>();
List<Object> tempList = new ArrayList<Object>();
tempList.add(claims);
attributeMap.put("claims", tempList);
tempList = new ArrayList<Object>();
tempList.add(userInfo);
attributeMap.put("userInfo", tempList);
return attributeMap;
}
public IDTokenClaimsSet claimsFromMap(Map<String, List<Object>> attributeMap) {
IDTokenClaimsSet claims;
if (attributeMap.containsKey("claims") &&
attributeMap.get("claims").get(0) instanceof IDTokenClaimsSet) {
claims = (IDTokenClaimsSet) attributeMap.get("claims").get(0);
return claims;
}
else {
return null;
}
}
public UserInfo userInfoFromMap(Map<String, List<Object>> attributeMap) {
UserInfo userInfo;
if (attributeMap.containsKey("userInfo") &&
attributeMap.get("userInfo").get(0) instanceof UserInfo) {
userInfo = (UserInfo) attributeMap.get("userInfo").get(0);
return userInfo;
}
else {
return null;
}
}
}
/*******************************************************************************
* Copyright (c) 2014 Michael Simon.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Michael Simon - initial
******************************************************************************/
package edu.kit.scc.webreg.service.oidc.client;
import java.util.List;
import java.util.Map;
import edu.kit.scc.webreg.entity.oidc.OidcUserEntity;
import edu.kit.scc.webreg.exc.UserUpdateException;
public interface OidcUserCreateService {
OidcUserEntity createUser(OidcUserEntity user, Map<String, List<Object>> attributeMap, String executor)
throws UserUpdateException;
OidcUserEntity preCreateUser(Long rpConfigId,
String locale, Map<String, List<Object>> attributeMap) throws UserUpdateException;
}
/*******************************************************************************
* Copyright (c) 2014 Michael Simon.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Michael Simon - initial
******************************************************************************/
package edu.kit.scc.webreg.service.oidc.client;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.ejb.Stateless;
import javax.inject.Inject;
import org.slf4j.Logger;
import com.nimbusds.openid.connect.sdk.claims.IDTokenClaimsSet;
import com.nimbusds.openid.connect.sdk.claims.UserInfo;
import edu.kit.scc.webreg.audit.UserCreateAuditor;
import edu.kit.scc.webreg.bootstrap.ApplicationConfig;
import edu.kit.scc.webreg.dao.RoleDao;
import edu.kit.scc.webreg.dao.SerialDao;
import edu.kit.scc.webreg.dao.audit.AuditDetailDao;
import edu.kit.scc.webreg.dao.audit.AuditEntryDao;
import edu.kit.scc.webreg.dao.identity.IdentityDao;
import edu.kit.scc.webreg.dao.oidc.OidcRpConfigurationDao;
import edu.kit.scc.webreg.dao.oidc.OidcUserDao;
import edu.kit.scc.webreg.entity.EventType;
import edu.kit.scc.webreg.entity.SamlUserEntity;
import edu.kit.scc.webreg.entity.UserRoleEntity;
import edu.kit.scc.webreg.entity.UserStatus;
import edu.kit.scc.webreg.entity.audit.AuditStatus;
import edu.kit.scc.webreg.entity.identity.IdentityEntity;
import edu.kit.scc.webreg.entity.oidc.OidcRpConfigurationEntity;
import edu.kit.scc.webreg.entity.oidc.OidcUserEntity;
import edu.kit.scc.webreg.event.EventSubmitter;
import edu.kit.scc.webreg.event.UserEvent;
import edu.kit.scc.webreg.exc.EventSubmitException;
import edu.kit.scc.webreg.exc.UserUpdateException;
import edu.kit.scc.webreg.service.impl.AttributeMapHelper;
import edu.kit.scc.webreg.service.impl.HomeOrgGroupUpdater;
import edu.kit.scc.webreg.service.impl.UserUpdater;
@Stateless
public class OidcUserCreateServiceImpl implements OidcUserCreateService {
@Inject
private Logger logger;
@Inject
private AuditEntryDao auditDao;
@Inject
private AuditDetailDao auditDetailDao;
@Inject
private OidcUserDao oidcUserDao;
@Inject
private OidcTokenHelper tokenHelper;
@Inject
private UserUpdater userUpdater;
@Inject
private HomeOrgGroupUpdater homeOrgGroupUpdater;
@Inject
private RoleDao roleDao;
@Inject
private OidcRpConfigurationDao rpConfigDao;
@Inject
private IdentityDao identityDao;
@Inject
private SerialDao serialDao;
@Inject
private EventSubmitter eventSubmitter;
@Inject
private AttributeMapHelper attrHelper;
@Inject
private ApplicationConfig appConfig;
@Override
public OidcUserEntity preCreateUser(Long rpConfigId,
String locale, Map<String, List<Object>> attributeMap)
throws UserUpdateException {
OidcRpConfigurationEntity rpConfig = rpConfigDao.findById(rpConfigId);
if (rpConfig == null) {
throw new UserUpdateException("No such issuer/replying party");
}
IDTokenClaimsSet claims = tokenHelper.claimsFromMap(attributeMap);
if (claims == null) {
throw new UserUpdateException("ID claims are missing in session");
}
UserInfo userInfo = tokenHelper.userInfoFromMap(attributeMap);
if (userInfo == null) {
userInfo = (UserInfo) attributeMap.get("userInfo").get(0);
}
logger.debug("User {} from {} is being preCreated", claims.getSubject().getValue(), rpConfig.getName());
OidcUserEntity entity = oidcUserDao.createNew();
entity.setSubjectId(claims.getSubject().getValue());
entity.setIssuer(rpConfig);
entity.setRoles(new HashSet<UserRoleEntity>());
entity.setAttributeStore(new HashMap<String, String>());
entity.setGenericStore(new HashMap<String, String>());
entity.setLocale(locale);
entity.setEmail(userInfo.getEmailAddress());
entity.setGivenName(userInfo.getGivenName());
entity.setSurName(userInfo.getFamilyName());
entity.setEppn(userInfo.getStringClaim("eduPersonPrincipalName"));
return entity;
}
@Override
public OidcUserEntity createUser(OidcUserEntity user,
Map<String, List<Object>> attributeMap, String executor)
throws UserUpdateException {
logger.debug("Creating user {}", user.getSubjectId());
UserCreateAuditor auditor = new UserCreateAuditor(auditDao, auditDetailDao, appConfig);
auditor.startAuditTrail(executor);
auditor.setName(getClass().getName() + "-OidcUserCreate-Audit");
auditor.setDetail("Create OIDC user " + user.getSubjectId());
// userUpdater.updateUserFromAttribute(user, attributeMap, true, auditor);
/**
* if user has no uid number yet, generate one
*/
if (user.getUidNumber() == null) {
user.setUidNumber(serialDao.next("uid-number-serial").intValue());
logger.info("Setting UID Number {} for user {}", user.getUidNumber(), user.getEppn());
}
// Map<String, String> attributeStore = user.getAttributeStore();
// for (Entry<String, List<Object>> entry : attributeMap.entrySet()) {
// attributeStore.put(entry.getKey(), attrHelper.attributeListToString(entry.getValue()));
// }
user.setLastUpdate(new Date());
if (! UserStatus.ACTIVE.equals(user.getUserStatus())) {
user.setUserStatus(UserStatus.ACTIVE);
user.setLastStatusChange(new Date());
}
/**
* TODO: Apply mapping rules at this point. At the moment every account gets one
* identity. Should possibly be mapped to existing identity in some cases.
*/
IdentityEntity id = identityDao.createNew();
id = identityDao.persist(id);
user.setIdentity(id);
user = oidcUserDao.persist(user);
roleDao.addUserToRole(user, "User");
// homeOrgGroupUpdater.updateGroupsForUser(user, attributeMap, auditor);
auditor.setUser(user);
auditor.auditUserCreate();
auditor.logAction(user.getEppn(), "CREATE USER", null, null, AuditStatus.SUCCESS);
auditor.finishAuditTrail();
auditor.commitAuditTrail();
UserEvent userEvent = new UserEvent(user);
try {
eventSubmitter.submit(userEvent, EventType.USER_CREATE, executor);
} catch (EventSubmitException e) {
logger.warn("Could not submit event", e);
}
return user;
}
}
/*******************************************************************************
* Copyright (c) 2014 Michael Simon.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Michael Simon - initial
******************************************************************************/
package edu.kit.scc.webreg.bean;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ComponentSystemEvent;
import javax.inject.Inject;
import org.slf4j.Logger;
import com.nimbusds.openid.connect.sdk.claims.IDTokenClaimsSet;
import com.nimbusds.openid.connect.sdk.claims.UserInfo;
import edu.kit.scc.webreg.entity.SamlIdpMetadataEntity;
import edu.kit.scc.webreg.entity.SamlUserEntity;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.entity.oidc.OidcRpConfigurationEntity;
import edu.kit.scc.webreg.entity.oidc.OidcUserEntity;
import edu.kit.scc.webreg.exc.UserUpdateException;
import edu.kit.scc.webreg.service.UserCreateService;
import edu.kit.scc.webreg.service.UserService;
import edu.kit.scc.webreg.service.oidc.OidcRpConfigurationService;
import edu.kit.scc.webreg.service.oidc.client.OidcTokenHelper;
import edu.kit.scc.webreg.service.oidc.client.OidcUserCreateService;
import edu.kit.scc.webreg.session.SessionManager;
import edu.kit.scc.webreg.util.FacesMessageGenerator;
@ManagedBean
@ViewScoped
public class RegisterOidcUserBean implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private Logger logger;
@Inject
private SessionManager sessionManager;
@Inject
private UserService service;
@Inject
private OidcUserCreateService userCreateService;
@Inject
private OidcTokenHelper tokenHelper;
@Inject
private OidcRpConfigurationService rpConfigService;
@Inject
private FacesMessageGenerator messageGenerator;
private OidcUserEntity entity;
private OidcRpConfigurationEntity rpConfig;
private Boolean errorState = false;
private Map<String, String> printableAttributesMap;
private Map<String, String> unprintableAttributesMap;
private List<String> printableAttributesList;
public void preRenderView(ComponentSystemEvent ev) {
if (sessionManager.getOidcRelyingPartyId() == null) {
errorState = true;
messageGenerator.addResolvedErrorMessage("page-not-directly-accessible", "page-not-directly-accessible-text", true);
return;
}
rpConfig = rpConfigService.findById(sessionManager.getOidcRelyingPartyId());
if (rpConfig == null) {
errorState = true;
messageGenerator.addResolvedErrorMessage("page-not-directly-accessible", "page-not-directly-accessible-text", true);
return;
}
printableAttributesMap = new HashMap<String, String>();
unprintableAttributesMap = new HashMap<String, String>();
printableAttributesList = new ArrayList<String>();
if (sessionManager.getAttributeMap() != null) {
}
try {
entity = userCreateService.preCreateUser(rpConfig.getId(),
sessionManager.getLocale(), sessionManager.getAttributeMap());
} catch (UserUpdateException e) {
errorState = true;