Mercurial > lada > lada-server
view src/main/java/de/intevation/lada/util/auth/HeaderAuthorization.java @ 838:1ed347eb856b statusworkflow
Use auth objects in user info to keep mst <-> function association.
author | Raimund Renkert <raimund.renkert@intevation.de> |
---|---|
date | Thu, 14 Jan 2016 10:21:19 +0100 |
parents | d0510a89e701 |
children | 2fe625c91ab3 |
line wrap: on
line source
/* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz * Software engineering by Intevation GmbH * * This file is Free Software under the GNU GPL (v>=3) * and comes with ABSOLUTELY NO WARRANTY! Check out * the documentation coming with IMIS-Labordaten-Application for details. */ 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.inject.Inject; import javax.persistence.EntityManager; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; import de.intevation.lada.model.land.LMessung; import de.intevation.lada.model.land.LProbe; import de.intevation.lada.model.land.LStatusProtokoll; import de.intevation.lada.model.stamm.Auth; import de.intevation.lada.model.stamm.AuthLstUmw; 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; /** * Authorize a user via HttpServletRequest attributes. * * @author <a href="mailto:rrenkert@intevation.de">Raimund Renkert</a> */ @AuthorizationConfig(type=AuthorizationType.HEADER) public class HeaderAuthorization implements Authorization { /** * The logger used in this class. */ @Inject private Logger logger; /** * The Repository used to read from Database. */ @Inject @RepositoryConfig(type=RepositoryType.RO) private Repository repository; /** * Request user informations using the HttpServletRequest. * * @param source The HttpServletRequest * @return The UserInfo object containing username and groups. */ @Override public UserInfo getInfo(Object source) { if (source instanceof HttpServletRequest) { HttpServletRequest request = (HttpServletRequest)source; String roleString = request.getAttribute("lada.user.roles").toString(); UserInfo info = getGroupsFromDB(roleString); info.setName(request.getAttribute("lada.user.name").toString()); return info; } return null; } /** * Filter a list of data objects using the user informations contained in * the HttpServletRequest. * * @param source The HttpServletRequest * @param data The Response object containing the data. * @param clazz The data object class. * @return The Response object containing the filtered data. */ @Override public <T> Response filter(Object source, Response data, Class<T> clazz) { UserInfo userInfo = this.getInfo(source); if (userInfo == null) { return data; } if (clazz == LProbe.class) { return this.authorizeProbe(userInfo, data); } if (clazz == LMessung.class) { return this.authorizeMessung(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 <T> boolean isAuthorized(int id, Class<T> clazz) { if (clazz == LMessung.class) { LMessung messung = repository.getByIdPlain( LMessung.class, id, "land"); if (messung.getStatus() == null) { return false; } LStatusProtokoll status = repository.getByIdPlain( LStatusProtokoll.class, messung.getStatus(), "land"); if (status.getStatusWert() == 0) { return false; } return true; } return false; } /** * Check whether a user is authorized to operate on the given data. * * @param source The HttpServletRequest containing user information. * @param data The data to test. * @param method The Http request type. * @param clazz The data object class. * @return True if the user is authorized else returns false. */ @Override public <T> boolean isAuthorized( Object source, Object data, RequestMethod method, Class<T> 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 !this.isMessungReadOnly(messung) && getAuthorization(userInfo, probe); } } 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) { logger.warn(e.getCause() + ": " + e.getMessage()); 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) { logger.warn(e.getCause() + ": " + e.getMessage()); 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(); if (messung.getStatus() == null) { return false; } LStatusProtokoll status = repository.getByIdPlain( LStatusProtokoll.class, messung.getStatus(), "land"); return status.getStatusWert() == 0 && getAuthorization(userInfo, probe); } } } return true; } /** * Get the authorization of a single probe. * * @param userInfo The user information. * @param probe The probe to authorize. */ private boolean getAuthorization(UserInfo userInfo, LProbe probe) { if (userInfo.getMessstellen().contains(probe.getMstId())) { return true; } else { return false; } } /** * Request the lada specific groups. * * @param roles The roles defined in the OpenId server. * @return The UserInfo contianing roles and user name. */ private UserInfo getGroupsFromDB(String roles) { QueryBuilder<Auth> builder = new QueryBuilder<Auth>( repository.entityManager("stamm"), Auth.class); roles = roles.replace("[",""); roles = roles.replace("]",""); roles = roles.replace(" ",""); String[] mst = roles.split(","); builder.andIn("ldapGroup", Arrays.asList(mst)); Response response = repository.filter(builder.getQuery(), "stamm"); @SuppressWarnings("unchecked") List<Auth> auth = (List<Auth>)response.getData(); UserInfo userInfo = new UserInfo(); userInfo.setAuth(auth); return userInfo; } /** * Authorize data that has a messungsId Attribute. * * @param userInfo The user information. * @param data The Response object containing the data. * @param clazz The data object class. * @return A Response object containing the data. */ @SuppressWarnings("unchecked") private <T> Response authorizeWithMessungsId( UserInfo userInfo, Response data, Class<T> clazz ) { if (data.getData() instanceof List<?>) { List<Object> objects = new ArrayList<Object>(); for (Object object :(List<Object>)data.getData()) { objects.add(authorizeSingleWithMessungsId(userInfo, object, clazz)); } data.setData(objects); } else { Object object = data.getData(); data.setData(authorizeSingleWithMessungsId(userInfo, object, clazz)); } return data; } /** * Authorize data that has a probeId Attribute. * * @param userInfo The user information. * @param data The Response object containing the data. * @param clazz The data object class. * @return A Response object containing the data. */ @SuppressWarnings("unchecked") private <T> Response authorizeWithProbeId( UserInfo userInfo, Response data, Class<T> clazz ) { if (data.getData() instanceof List<?>) { List<Object> objects = new ArrayList<Object>(); for (Object object :(List<Object>)data.getData()) { objects.add(authorizeSingleWithProbeId( userInfo, object, clazz)); } data.setData(objects); } else { Object object = data.getData(); data.setData(authorizeSingleWithProbeId(userInfo, object, clazz)); } return data; } /** * Authorize a single data object that has a messungsId Attribute. * * @param userInfo The user information. * @param data The Response object containing the data. * @param clazz The data object class. * @return A Response object containing the data. */ private <T> Object authorizeSingleWithMessungsId( UserInfo userInfo, Object data, Class<T> 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.isMessungReadOnly(messung); } 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; } /** * Authorize a single data object that has a probeId Attribute. * * @param userInfo The user information. * @param data The Response object containing the data. * @param clazz The data object class. * @return A Response object containing the data. */ private <T> Object authorizeSingleWithProbeId( UserInfo userInfo, Object data, Class<T> 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; } /** * Authorize probe objects. * * @param userInfo The user information. * @param data The Response object containing the probe objects. * @return A Response object containing the data. */ @SuppressWarnings("unchecked") private Response authorizeProbe(UserInfo userInfo, Response data) { if (data.getData() instanceof List<?>) { List<LProbe> proben = new ArrayList<LProbe>(); for (LProbe probe :(List<LProbe>)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; } /** * Authorize a sinle probe object. * * @param userInfo The user information. * @param probe The probe object. * @return The probe. */ private LProbe authorizeSingleProbe(UserInfo userInfo, LProbe probe) { if (!userInfo.getNetzbetreiber().contains(probe.getNetzbetreiberId())) { probe.setOwner(false); probe.setReadonly(true); return probe; } if (userInfo.getMessstellen().contains(probe.getMstId())) { probe.setOwner(true); } else { probe.setOwner(false); } probe.setReadonly(this.isReadOnly(probe.getId())); return probe; } /** * Authorize messung objects. * * @param userInfo The user information. * @param data The Response object containing the messung objects. * @return A Response object containing the data. */ @SuppressWarnings("unchecked") private Response authorizeMessung(UserInfo userInfo, Response data) { if (data.getData() instanceof List<?>) { List<LMessung> messungen = new ArrayList<LMessung>(); for (LMessung messung :(List<LMessung>)data.getData()) { messungen.add(authorizeSingleMessung(userInfo, messung)); } data.setData(messungen); } else if (data.getData() instanceof LMessung) { LMessung messung = (LMessung)data.getData(); data.setData(authorizeSingleMessung(userInfo, messung)); } return data; } /** * Authorize a sinle messung object. * * @param userInfo The user information. * @param messung The messung object. * @return The messung. */ private LMessung authorizeSingleMessung( UserInfo userInfo, LMessung messung ) { LProbe probe = (LProbe)repository.getById( LProbe.class, messung.getProbeId(), "land").getData(); if (!userInfo.getNetzbetreiber().contains(probe.getNetzbetreiberId())) { messung.setOwner(false); messung.setReadonly(true); return messung; } if (userInfo.getMessstellen().contains(probe.getMstId())) { messung.setOwner(true); } else { messung.setOwner(false); } if (messung.getStatus() == null) { messung.setReadonly(false); } else { LStatusProtokoll status = repository.getByIdPlain( LStatusProtokoll.class, messung.getStatus(), "land"); messung.setReadonly( status.getStatusWert() != 0 && status.getStatusWert() != 4); } boolean statusEdit = false; if (userInfo.getFunktionen().contains(3)) { QueryBuilder<AuthLstUmw> lstFilter = new QueryBuilder<AuthLstUmw>( repository.entityManager("stamm"), AuthLstUmw.class); lstFilter.or("lstId", userInfo.getMessstellen()); List<AuthLstUmw> lsts = repository.filterPlain(lstFilter.getQuery(), "stamm"); for (int i = 0; i < lsts.size(); i++) { if (lsts.get(i).getUmwId().equals(probe.getUmwId())) { statusEdit = true; } } } else if (userInfo.getFunktionen().contains(2) && userInfo.getNetzbetreiber().contains(probe.getNetzbetreiberId())) { statusEdit = true; } else if (userInfo.getFunktionen().contains(1) && userInfo.getMessstellen().contains(probe.getMstId())) { statusEdit = true; } messung.setStatusEdit(statusEdit); return messung; } /** * Test whether a probe is readonly. * * @param probeId The probe Id. * @return True if the probe is readonly. */ @Override public boolean isReadOnly(Integer probeId) { EntityManager manager = repository.entityManager("land"); QueryBuilder<LMessung> builder = new QueryBuilder<LMessung>( manager, LMessung.class); builder.and("probeId", probeId); Response response = repository.filter(builder.getQuery(), "land"); @SuppressWarnings("unchecked") List<LMessung> messungen = (List<LMessung>) response.getData(); for (int i = 0; i < messungen.size(); i++) { if (messungen.get(i).getStatus() == null) { return false; } LStatusProtokoll status = repository.getByIdPlain( LStatusProtokoll.class, messungen.get(i).getStatus(), "land"); if (status.getStatusWert() != 0 && status.getStatusWert() != 4) { return true; } } return false; } /** * Check whether a user is authorized to operate on the given probe. * * @param userInfo The user information. * @param data The probe data to test. * @return True if the user is authorized else returns false. */ @Override public boolean isAuthorized(UserInfo userInfo, Object data) { if (data instanceof LProbe) { return getAuthorization(userInfo, (LProbe)data); } else if (data instanceof LMessung) { LProbe probe = repository.getByIdPlain(LProbe.class, ((LMessung)data).getProbeId(), "land"); return getAuthorization(userInfo, probe); } return false; } private boolean isMessungReadOnly(LMessung messung) { if (messung.getStatus() == null) { return false; } LStatusProtokoll status = repository.getByIdPlain( LStatusProtokoll.class, messung.getStatus(), "land"); return (status.getStatusWert() != 0 && status.getStatusWert() != 4); } }