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

add groups for oidc

parent fc2c8ec1
package edu.kit.scc.webreg.entity.oidc;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import edu.kit.scc.webreg.entity.ServiceBasedGroupEntity;
@Entity(name = "OidcGroupEntity")
public class OidcGroupEntity extends ServiceBasedGroupEntity {
private static final long serialVersionUID = 1L;
@ManyToOne(targetEntity = OidcRpConfigurationEntity.class)
private OidcRpConfigurationEntity issuer;
@Column(name = "group_prefix")
private String prefix;
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public OidcRpConfigurationEntity getIssuer() {
return issuer;
}
public void setIssuer(OidcRpConfigurationEntity issuer) {
this.issuer = issuer;
}
}
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(OidcGroupEntity.class)
public abstract class OidcGroupEntity_ extends edu.kit.scc.webreg.entity.ServiceBasedGroupEntity_ {
public static volatile SingularAttribute<OidcGroupEntity, OidcRpConfigurationEntity> issuer;
public static volatile SingularAttribute<OidcGroupEntity, String> prefix;
}
/*******************************************************************************
* Copyright (c) 2021 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.util.ArrayList;
import java.util.List;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Root;
import edu.kit.scc.webreg.dao.jpa.JpaBaseDao;
import edu.kit.scc.webreg.dao.oidc.OidcGroupDao;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.entity.oidc.OidcGroupEntity;
@Named
@ApplicationScoped
public class JpaOidcGroupDao extends JpaBaseDao<OidcGroupEntity, Long> implements OidcGroupDao {
@Override
public List<OidcGroupEntity> findByUser(UserEntity user) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<OidcGroupEntity> criteria = builder.createQuery(OidcGroupEntity.class);
Root<UserEntity> userRoot = criteria.from(UserEntity.class);
criteria.where(builder.equal(userRoot.get("id"), user.getId()));
Join<UserEntity, OidcGroupEntity> users = userRoot.join("groups");
CriteriaQuery<OidcGroupEntity> cq = criteria.select(users);
TypedQuery<OidcGroupEntity> query = em.createQuery(cq);
return query.getResultList();
}
@Override
public OidcGroupEntity findWithUsers(Long id) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<OidcGroupEntity> criteria = builder.createQuery(OidcGroupEntity.class);
Root<OidcGroupEntity> root = criteria.from(OidcGroupEntity.class);
criteria.where(
builder.equal(root.get("id"), id));
criteria.select(root);
root.fetch("users", JoinType.LEFT);
return em.createQuery(criteria).getSingleResult();
}
@Override
public OidcGroupEntity findByGidNumber(Integer gid) {
try {
return em.createQuery("select e from HomeOrgGroupEntity e where e.gidNumber = :gidNumber", OidcGroupEntity.class)
.setParameter("gidNumber", gid).getSingleResult();
}
catch (NoResultException e) {
return null;
}
}
@Override
public OidcGroupEntity findByName(String name) {
try {
return em.createQuery("select e from OidcGroupEntity e where e.name = :name", OidcGroupEntity.class)
.setParameter("name", name).getSingleResult();
}
catch (NoResultException e) {
return null;
}
}
@Override
public OidcGroupEntity findByNameAndPrefix(String name, String prefix) {
try {
return em.createQuery("select e from OidcGroupEntity e where e.name = :name and e.prefix = :prefix", OidcGroupEntity.class)
.setParameter("name", name).setParameter("prefix", prefix).getSingleResult();
}
catch (NoResultException e) {
return null;
}
}
@Override
public List<OidcGroupEntity> findByNameListAndPrefix(List<String> nameList, String prefix) {
if (nameList == null || nameList.size() == 0) {
return new ArrayList<OidcGroupEntity>();
}
else {
return em.createQuery("select e from HomeOrgGroupEntity e where e.prefix = :prefix and e.name in :nameList", OidcGroupEntity.class)
.setParameter("nameList", nameList).setParameter("prefix", prefix).getResultList();
}
}
@Override
public Class<OidcGroupEntity> getEntityClass() {
return OidcGroupEntity.class;
}
}
/*******************************************************************************
* Copyright (c) 2021 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 java.util.List;
import edu.kit.scc.webreg.dao.BaseDao;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.entity.oidc.OidcGroupEntity;
public interface OidcGroupDao extends BaseDao<OidcGroupEntity, Long> {
OidcGroupEntity findByGidNumber(Integer gid);
OidcGroupEntity findByName(String name);
OidcGroupEntity findByNameAndPrefix(String name, String prefix);
List<OidcGroupEntity> findByUser(UserEntity user);
OidcGroupEntity findWithUsers(Long id);
List<OidcGroupEntity> findByNameListAndPrefix(List<String> nameList,
String prefix);
}
......@@ -290,12 +290,10 @@ public class UserUpdater implements Serializable {
}
}
if (user instanceof SamlUserEntity) {
Set<GroupEntity> changedGroups = homeOrgGroupUpdater.updateGroupsForUser((SamlUserEntity) user, attributeMap, auditor);
Set<GroupEntity> changedGroups = homeOrgGroupUpdater.updateGroupsForUser(user, attributeMap, auditor);
if (changedGroups.size() > 0) {
changed = true;
}
if (changedGroups.size() > 0) {
changed = true;
}
Map<String, String> attributeStore = user.getAttributeStore();
......
package edu.kit.scc.webreg.service.oidc.client;
import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.slf4j.Logger;
import edu.kit.scc.webreg.audit.Auditor;
import edu.kit.scc.webreg.dao.GroupDao;
import edu.kit.scc.webreg.dao.ServiceGroupFlagDao;
import edu.kit.scc.webreg.dao.oidc.OidcGroupDao;
import edu.kit.scc.webreg.entity.EventType;
import edu.kit.scc.webreg.entity.GroupEntity;
import edu.kit.scc.webreg.entity.HomeOrgGroupEntity;
import edu.kit.scc.webreg.entity.ServiceBasedGroupEntity;
import edu.kit.scc.webreg.entity.ServiceGroupFlagEntity;
import edu.kit.scc.webreg.entity.ServiceGroupStatus;
import edu.kit.scc.webreg.entity.UserGroupEntity;
import edu.kit.scc.webreg.entity.audit.AuditStatus;
import edu.kit.scc.webreg.entity.oidc.OidcGroupEntity;
import edu.kit.scc.webreg.entity.oidc.OidcUserEntity;
import edu.kit.scc.webreg.event.EventSubmitter;
import edu.kit.scc.webreg.event.MultipleGroupEvent;
import edu.kit.scc.webreg.exc.EventSubmitException;
import edu.kit.scc.webreg.exc.UserUpdateException;
import edu.kit.scc.webreg.service.SerialService;
import edu.kit.scc.webreg.service.saml.HomeIdResolver;
@ApplicationScoped
public class OidcGroupUpdater implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private Logger logger;
@Inject
private OidcGroupDao dao;
@Inject
private GroupDao groupDao;
@Inject
private ServiceGroupFlagDao groupFlagDao;
@Inject
private SerialService serialService;
@Inject
private EventSubmitter eventSubmitter;
@Inject
private HomeIdResolver homeIdResolver;
public Set<GroupEntity> updateGroupsForUser(OidcUserEntity user, Map<String, List<Object>> attributeMap, Auditor auditor)
throws UserUpdateException {
HashSet<GroupEntity> changedGroups = new HashSet<GroupEntity>();
changedGroups.addAll(updatePrimary(user, attributeMap, auditor));
changedGroups.addAll(updateSecondary(user, attributeMap, auditor));
// Also add parent groups, to reflect changes
HashSet<GroupEntity> allChangedGroups = new HashSet<GroupEntity>(changedGroups.size());
for (GroupEntity group : changedGroups) {
allChangedGroups.add(group);
if (group.getParents() != null) {
for (GroupEntity parent : group.getParents()) {
logger.debug("Adding parent group to changed groups: {}", parent.getName());
allChangedGroups.add(parent);
}
}
}
for (GroupEntity group : allChangedGroups) {
if (group instanceof ServiceBasedGroupEntity) {
List<ServiceGroupFlagEntity> groupFlagList = groupFlagDao.findByGroup((ServiceBasedGroupEntity) group);
for (ServiceGroupFlagEntity groupFlag : groupFlagList) {
groupFlag.setStatus(ServiceGroupStatus.DIRTY);
groupFlagDao.persist(groupFlag);
}
}
}
MultipleGroupEvent mge = new MultipleGroupEvent(allChangedGroups);
try {
eventSubmitter.submit(mge, EventType.GROUP_UPDATE, auditor.getActualExecutor());
} catch (EventSubmitException e) {
logger.warn("Exeption", e);
}
return changedGroups;
}
protected Set<GroupEntity> updatePrimary(OidcUserEntity user, Map<String, List<Object>> attributeMap, Auditor auditor)
throws UserUpdateException {
Set<GroupEntity> changedGroups = new HashSet<GroupEntity>();
OidcGroupEntity group = null;
String homeId = homeIdResolver.resolveHomeId(user, attributeMap);
if (homeId == null) {
logger.warn("No Home ID is set for User {}, resetting primary group", user.getId());
}
else {
//Filter all non character from homeid
homeId = homeId.toLowerCase();
homeId = homeId.replaceAll("[^a-z0-9]", "");
String groupName = homeId;
logger.info("Setting standard HomeID group {} for user {}", homeId, user.getId());
group = dao.findByNameAndPrefix(groupName, homeId);
if (group == null) {
group = dao.createNew();
group.setUsers(new HashSet<UserGroupEntity>());
group.setName(groupName);
auditor.logAction(group.getName(), "SET FIELD", "name", group.getName(), AuditStatus.SUCCESS);
group.setPrefix(homeId);
auditor.logAction(group.getName(), "SET FIELD", "prefix", group.getPrefix(), AuditStatus.SUCCESS);
group.setGidNumber(serialService.next("gid-number-serial").intValue());
auditor.logAction(group.getName(), "SET FIELD", "gidNumber", "" + group.getGidNumber(), AuditStatus.SUCCESS);
group.setIssuer(user.getIssuer());
auditor.logAction(group.getName(), "SET FIELD", "oidcIssuer", "" + user.getIssuer().getName(), AuditStatus.SUCCESS);
group = (OidcGroupEntity) groupDao.persistWithServiceFlags(group);
auditor.logAction(group.getName(), "CREATE GROUP", null, "Group created", AuditStatus.SUCCESS);
changedGroups.add(group);
}
}
if (user.getPrimaryGroup() != null && (! user.getPrimaryGroup().equals(group))) {
if (group == null) {
auditor.logAction(user.getEppn(), "UPDATE FIELD", "primaryGroup",
user.getPrimaryGroup().getName() + " (" + user.getPrimaryGroup().getGidNumber() + ") -> " +
"null", AuditStatus.SUCCESS);
}
else {
auditor.logAction(user.getEppn(), "UPDATE FIELD", "primaryGroup",
user.getPrimaryGroup().getName() + " (" + user.getPrimaryGroup().getGidNumber() + ") -> " +
group.getName() + " (" + group.getGidNumber() + ")", AuditStatus.SUCCESS);
changedGroups.add(group);
}
}
else if (user.getPrimaryGroup() == null && group != null) {
auditor.logAction(user.getEppn(), "UPDATE FIELD", "primaryGroup",
"null -> " +
group.getName() + " (" + group.getGidNumber() + ")", AuditStatus.SUCCESS);
changedGroups.add(group);
}
user.setPrimaryGroup(group);
return changedGroups;
}
protected Set<GroupEntity> updateSecondary(OidcUserEntity user, Map<String, List<Object>> attributeMap, Auditor auditor)
throws UserUpdateException {
Set<GroupEntity> changedGroups = new HashSet<GroupEntity>();
/**
* TODO implement secondary groups for OIDC
*/
return changedGroups;
}
}
......@@ -85,6 +85,9 @@ public class OidcUserCreateServiceImpl implements OidcUserCreateService {
@Inject
private ApplicationConfig appConfig;
@Inject
private OidcGroupUpdater oidcGroupUpdater;
@Override
public OidcUserEntity preCreateUser(Long rpConfigId,
String locale, Map<String, List<Object>> attributeMap)
......@@ -237,7 +240,7 @@ public class OidcUserCreateServiceImpl implements OidcUserCreateService {
roleDao.addUserToRole(user, "User");
// homeOrgGroupUpdater.updateGroupsForUser(user, attributeMap, auditor);
oidcGroupUpdater.updateGroupsForUser(user, attributeMap, auditor);
auditor.setUser(user);
auditor.auditUserCreate();
......
......@@ -58,6 +58,7 @@ import edu.kit.scc.webreg.dao.audit.AuditDetailDao;
import edu.kit.scc.webreg.dao.audit.AuditEntryDao;
import edu.kit.scc.webreg.dao.oidc.OidcUserDao;
import edu.kit.scc.webreg.entity.EventType;
import edu.kit.scc.webreg.entity.GroupEntity;
import edu.kit.scc.webreg.entity.RegistryEntity;
import edu.kit.scc.webreg.entity.RegistryStatus;
import edu.kit.scc.webreg.entity.ServiceEntity;
......@@ -114,6 +115,9 @@ public class OidcUserUpdater implements Serializable {
@Inject
private HookManager hookManager;
@Inject
private OidcGroupUpdater oidcGroupUpdater;
@Inject
private ASUserAttrDao asUserAttrDao;
......@@ -363,6 +367,12 @@ public class OidcUserUpdater implements Serializable {
}
}
Set<GroupEntity> changedGroups = oidcGroupUpdater.updateGroupsForUser(user, attributeMap, auditor);
if (changedGroups.size() > 0) {
changed = true;
}
Map<String, String> attributeStore = user.getAttributeStore();
for (Entry<String, List<Object>> entry : attributeMap.entrySet()) {
attributeStore.put(entry.getKey(), attrHelper.attributeListToString(entry.getValue()));
......
......@@ -7,6 +7,8 @@ import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import edu.kit.scc.webreg.entity.SamlUserEntity;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.entity.oidc.OidcUserEntity;
import edu.kit.scc.webreg.service.impl.AttributeMapHelper;
@ApplicationScoped
......@@ -15,14 +17,26 @@ public class HomeIdResolver {
@Inject
private AttributeMapHelper attrHelper;
public String resolveHomeId(SamlUserEntity user, Map<String, List<Object>> attributeMap) {
public String resolveHomeId(UserEntity user, Map<String, List<Object>> attributeMap) {
String homeId = null;
if (user.getIdp().getGenericStore().containsKey("prefix")) {
homeId = user.getIdp().getGenericStore().get("prefix");
if (user instanceof SamlUserEntity) {
SamlUserEntity samlUser = (SamlUserEntity) user;
if (samlUser.getIdp().getGenericStore().containsKey("prefix")) {
homeId = samlUser.getIdp().getGenericStore().get("prefix");
}
else {
homeId = attrHelper.getSingleStringFirst(attributeMap, "http://bwidm.de/bwidmOrgId");
}
}
else {
homeId = attrHelper.getSingleStringFirst(attributeMap, "http://bwidm.de/bwidmOrgId");
else if (user instanceof OidcUserEntity) {
OidcUserEntity oidcUser = (OidcUserEntity) user;
if (oidcUser.getIssuer().getGenericStore().containsKey("prefix")) {
homeId = oidcUser.getIssuer().getGenericStore().get("prefix");
}
else {
homeId = oidcUser.getIssuer().getName();
}
}
return homeId;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment