# HG changeset patch # User Raimund Renkert # Date 1427129406 -3600 # Node ID b2db328122605d39fc265069a992674febd10fc0 # Parent fb1f7418e1fcce9d408ad378b3ad0c3602eaa991 Added OpenId authorization and user info class. diff -r fb1f7418e1fc -r b2db32812260 src/main/java/de/intevation/lada/util/auth/OpenIdAuthorization.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/intevation/lada/util/auth/OpenIdAuthorization.java Mon Mar 23 17:50:06 2015 +0100 @@ -0,0 +1,339 @@ +package de.intevation.lada.util.auth; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.ejb.Stateful; +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.Query; +import javax.servlet.http.HttpServletRequest; + +import de.intevation.lada.model.land.LMessung; +import de.intevation.lada.model.land.LProbe; +import de.intevation.lada.util.annotation.AuthorizationConfig; +import de.intevation.lada.util.annotation.RepositoryConfig; +import de.intevation.lada.util.data.QueryBuilder; +import de.intevation.lada.util.data.Repository; +import de.intevation.lada.util.data.RepositoryType; +import de.intevation.lada.util.rest.RequestMethod; +import de.intevation.lada.util.rest.Response; + +@Stateful +@AuthorizationConfig(type=AuthorizationType.OPEN_ID) +public class OpenIdAuthorization implements Authorization { + + @Inject + @RepositoryConfig(type=RepositoryType.RO) + private Repository repository; + + @Override + public UserInfo getInfo(Object source) { + if (source instanceof HttpServletRequest) { + HttpServletRequest request = (HttpServletRequest)source; + String roleString = + request.getAttribute("lada.user.roles").toString(); + String[] roles = roleString.split(","); + UserInfo info = getGroupsFromDB(roleString); + info.setRoles(new ArrayList(Arrays.asList(roles))); + info.setName(request.getAttribute("lada.user.name").toString()); + return info; + } + return null; + } + + @Override + public Response filter(Object source, Response data, Class clazz) { + UserInfo userInfo = this.getInfo(source); + if (userInfo == null) { + return data; + } + if (clazz == LProbe.class) { + return this.authorizeProbe(userInfo, data); + } + Method[] methods = clazz.getMethods(); + for (Method method: methods) { + if (method.getName().equals("getProbeId")) { + return this.authorizeWithProbeId(userInfo, data, clazz); + } + if (method.getName().equals("getMessungsId")) { + return this.authorizeWithMessungsId(userInfo, data, clazz); + } + } + return data; + } + + @Override + public boolean isAuthorized( + Object source, + Object data, + RequestMethod method, + Class clazz + ) { + UserInfo userInfo = this.getInfo(source); + if (userInfo == null) { + return false; + } + if (clazz == LProbe.class) { + LProbe probe = (LProbe)data; + if (method == RequestMethod.POST) { + return getAuthorization(userInfo, probe); + } + else if (method == RequestMethod.PUT || + method == RequestMethod.DELETE) { + return isReadOnly(probe.getId()); + } + else { + return false; + } + } + else if (clazz == LMessung.class) { + LMessung messung = (LMessung)data; + Response response = + repository.getById(LProbe.class, messung.getProbeId(), "land"); + LProbe probe = (LProbe)response.getData(); + if (method == RequestMethod.POST) { + return getAuthorization(userInfo, probe); + } + else if (method == RequestMethod.PUT || + method == RequestMethod.DELETE) { + return isReadOnly(probe.getId()); + } + } + else { + Method[] methods = clazz.getMethods(); + for (Method m: methods) { + if (m.getName().equals("getProbeId")) { + Integer id; + try { + id = (Integer) m.invoke(data); + } catch (IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + return false; + } + Response response = + repository.getById(LProbe.class, id, "land"); + LProbe probe = (LProbe)response.getData(); + return isReadOnly(id) && getAuthorization(userInfo, probe); + + } + if (m.getName().equals("getMessungsId")) { + Integer id; + try { + id = (Integer) m.invoke(data); + } catch (IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + return false; + } + Response mResponse = + repository.getById(LMessung.class, id, "land"); + LMessung messung = (LMessung)mResponse.getData(); + Response pResponse = + repository.getById(LProbe.class, messung.getProbeId(), "land"); + LProbe probe = (LProbe)pResponse.getData(); + return isReadOnly(probe.getId()) && getAuthorization(userInfo, probe); + } + } + } + return true; + } + + private boolean getAuthorization(UserInfo userInfo, LProbe probe) { + if (userInfo.getMessstellen().contains(probe.getMstId()) && + userInfo.getNetzbetreiber().contains(probe.getNetzbetreiberId()) + ) { + return true; + } + else { + return false; + } + } + + private UserInfo getGroupsFromDB(String roles) { + String nativeQuery = "select * from stammdaten.auth where ldap_group in "; + roles = roles.replaceAll(",", "', '"); + nativeQuery += "('" + roles + "')"; + Query query = repository.entityManager("land").createNativeQuery(nativeQuery); + @SuppressWarnings("unchecked") + List result = query.getResultList(); + List netzbetreiber = new ArrayList(); + List messstellen = new ArrayList(); + for (Object[] row: result) { + if (row[2] != null) { + netzbetreiber.add(row[2].toString()); + } + if (row[3] != null) { + messstellen.add(row[3].toString()); + } + } + UserInfo userInfo = new UserInfo(); + userInfo.setNetzbetreiber(netzbetreiber); + userInfo.setMessstellen(messstellen); + return userInfo; + } + + + @SuppressWarnings("unchecked") + private Response authorizeWithMessungsId(UserInfo userInfo, Response data, Class clazz) { + if (data.getData() instanceof List) { + List objects = new ArrayList(); + for (Object object :(List)data.getData()) { + objects.add(authorizeSingleWithMessungsId(userInfo, object, clazz)); + } + data.setData(objects); + } + else { + Object object = data.getData(); + data.setData(authorizeSingleWithMessungsId(userInfo, object, clazz)); + } + return data; + } + + @SuppressWarnings("unchecked") + private Response authorizeWithProbeId(UserInfo userInfo, Response data, Class clazz) { + if (data.getData() instanceof List) { + List objects = new ArrayList(); + for (Object object :(List)data.getData()) { + objects.add(authorizeSingleWithProbeId(userInfo, object, clazz)); + } + data.setData(objects); + } + else { + Object object = data.getData(); + data.setData(authorizeSingleWithProbeId(userInfo, object, clazz)); + } + return data; + } + + private Object authorizeSingleWithMessungsId(UserInfo userInfo, Object data, Class clazz) { + try { + Method getMessungsId = clazz.getMethod("getMessungsId"); + Integer id = (Integer)getMessungsId.invoke(data); + LMessung messung = (LMessung) repository.getById(LMessung.class, id, "land").getData(); + LProbe probe = (LProbe) repository.getById(LProbe.class, messung.getProbeId(), "land").getData(); + + boolean readOnly = true; + boolean owner = false; + if (!userInfo.getNetzbetreiber().contains(probe.getNetzbetreiberId())) { + owner = false; + readOnly = true; + } + else { + if (userInfo.getMessstellen().contains(probe.getMstId())) { + owner = true; + } + else { + owner = false; + } + readOnly = this.isReadOnly(probe.getId()); + } + + Method setOwner = clazz.getMethod("setOwner", boolean.class); + Method setReadonly = clazz.getMethod("setReadonly", boolean.class); + setOwner.invoke(data, owner); + setReadonly.invoke(data, readOnly); + } catch (NoSuchMethodException | SecurityException + | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + return null; + } + return data; + } + + private Object authorizeSingleWithProbeId(UserInfo userInfo, Object data, Class clazz) { + try { + Method getProbeId = clazz.getMethod("getProbeId"); + Integer id = null; + if (getProbeId != null) { + id = (Integer) getProbeId.invoke(data); + } + else { + return null; + } + LProbe probe = (LProbe)repository.getById(LProbe.class, id, "land").getData(); + + boolean readOnly = true; + boolean owner = false; + if (!userInfo.getNetzbetreiber().contains(probe.getNetzbetreiberId())) { + owner = false; + readOnly = true; + } + else { + if (userInfo.getMessstellen().contains(probe.getMstId())) { + owner = true; + } + else { + owner = false; + } + readOnly = this.isReadOnly(id); + } + + Method setOwner = clazz.getMethod("setOwner", boolean.class); + Method setReadonly = clazz.getMethod("setReadonly", boolean.class); + setOwner.invoke(data, owner); + setReadonly.invoke(data, readOnly); + } catch (NoSuchMethodException | SecurityException + | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + return null; + } + return data; + } + + @SuppressWarnings("unchecked") + private Response authorizeProbe(UserInfo userInfo, Response data) { + if (data.getData() instanceof List) { + List proben = new ArrayList(); + for (LProbe probe :(List)data.getData()) { + proben.add(authorizeSingleProbe(userInfo, probe)); + } + data.setData(proben); + } + else if (data.getData() instanceof LProbe) { + LProbe probe = (LProbe)data.getData(); + data.setData(authorizeSingleProbe(userInfo, probe)); + } + return data; + } + + private LProbe authorizeSingleProbe(UserInfo userInfo, LProbe probe) { + if (!userInfo.getNetzbetreiber().contains(probe.getNetzbetreiberId())) { + probe.setIsOwner(false); + probe.setReadonly(true); + return probe; + } + if (userInfo.getMessstellen().contains(probe.getMstId())) { + probe.setIsOwner(true); + } + else { + probe.setIsOwner(false); + } + probe.setReadonly(this.isReadOnly(probe.getId())); + return probe; + } + + @Override + public boolean isReadOnly(Integer probeId) { + EntityManager manager = repository.entityManager("land"); + QueryBuilder builder = + new QueryBuilder( + manager, + LMessung.class); + builder.and("probeId", probeId); + Response response = repository.filter(builder.getQuery(), "land"); + @SuppressWarnings("unchecked") + List messungen = (List) response.getData(); + if (messungen.isEmpty()) { + return false; + } + for(LMessung messung : messungen) { + if (messung.getFertig()) { + return true; + } + } + return false; + } +} diff -r fb1f7418e1fc -r b2db32812260 src/main/java/de/intevation/lada/util/auth/UserInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/intevation/lada/util/auth/UserInfo.java Mon Mar 23 17:50:06 2015 +0100 @@ -0,0 +1,72 @@ +package de.intevation.lada.util.auth; + +import java.util.ArrayList; +import java.util.List; + +public class UserInfo { + private String name; + private List messstellen; + private List netzbetreiber; + private List roles; + + public UserInfo() { + messstellen = new ArrayList(); + netzbetreiber = new ArrayList(); + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the messstellen + */ + public List getMessstellen() { + return messstellen; + } + + /** + * @param messstellen the messstellen to set + */ + public void setMessstellen(List messstellen) { + this.messstellen = messstellen; + } + + /** + * @return the netzbetreiber + */ + public List getNetzbetreiber() { + return netzbetreiber; + } + + /** + * @param netzbetreiber the netzbetreiber to set + */ + public void setNetzbetreiber(List netzbetreiber) { + this.netzbetreiber = netzbetreiber; + } + + /** + * @return the roles + */ + public List getRoles() { + return roles; + } + + /** + * @param roles the roles to set + */ + public void setRoles(List roles) { + this.roles = roles; + } +}