All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geomajas.internal.security.SecurityContextImpl Maven / Gradle / Ivy

/*
 * This file is part of Geomajas, a component framework for building
 * rich Internet applications (RIA) with sophisticated capabilities for the
 * display, analysis and management of geographic information.
 * It is a building block that allows developers to add maps
 * and other geographic data capabilities to their web applications.
 *
 * Copyright 2008-2010 Geosparc, http://www.geosparc.com, Belgium
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see .
 */

package org.geomajas.internal.security;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.geomajas.configuration.LayerInfo;
import org.geomajas.layer.Layer;
import org.geomajas.layer.VectorLayer;
import org.geomajas.layer.feature.InternalFeature;
import org.geomajas.security.AreaAuthorization;
import org.geomajas.security.AttributeAuthorization;
import org.geomajas.security.Authentication;
import org.geomajas.security.BaseAuthorization;
import org.geomajas.security.FeatureAuthorization;
import org.geomajas.security.SecurityContext;
import org.geomajas.security.VectorLayerSelectFilterAuthorization;
import org.geomajas.service.ConfigurationService;
import org.geomajas.service.DtoConverterService;
import org.geomajas.service.FilterService;
import org.geomajas.service.GeoService;
import org.opengis.filter.Filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.PrecisionModel;

/**
 * {@link org.geomajas.security.SecurityContext} implementation.
 * 

* The security context is a thread scoped service which allows you to query the authorization details for the logged in * user. * * @author Joachim Van der Auwera */ @Component @Scope(value = "thread", proxyMode = ScopedProxyMode.TARGET_CLASS) public class SecurityContextImpl implements SecurityContext { private Logger log = LoggerFactory.getLogger(SecurityManagerImpl.class); private List authentications = new ArrayList(); private String token; private String id; // SecurityContext id // user info private String userId; private String userName; private Locale userLocale; private String userOrganization; private String userDivision; @Autowired private FilterService filterService; @Autowired private ConfigurationService configurationService; @Autowired private DtoConverterService converterService; @Autowired private GeoService geoService; public void setAuthentications(String token, List authentications) { this.token = token; this.authentications.clear(); if (null != authentications) { this.authentications.addAll(authentications); } userInfoInit(); } /** * @inheritDoc */ public List getSecurityServiceResults() { return authentications; } public String getToken() { return token; } /** * @inheritDoc */ public String getUserId() { return userId; } /** * @inheritDoc */ public String getUserName() { return userName; } /** * @inheritDoc */ public Locale getUserLocale() { return userLocale; } /** * @inheritDoc */ public String getUserOrganization() { return userOrganization; } /** * @inheritDoc */ public String getUserDivision() { return userDivision; } /** * Calculate UserInfo strings. */ private void userInfoInit() { boolean first = true; userId = null; userLocale = null; userName = null; userOrganization = null; userDivision = null; if (null != authentications) { for (Authentication auth : authentications) { userId = combine(userId, auth.getUserId()); userName = combine(userName, auth.getUserName()); if (first) { userLocale = auth.getUserLocale(); first = false; } else { if (null != auth.getUserLocale()) { if (null == userLocale || !userLocale.equals(auth.getUserLocale())) { userLocale = null; } } } userOrganization = combine(userOrganization, auth.getUserOrganization()); userDivision = combine(userDivision, auth.getUserDivision()); } } // now calculate the "id" for this context, this should be independent of the data order, so sort Map> idParts = new HashMap>(); if (null != authentications) { for (Authentication auth : authentications) { List auths = new ArrayList(); for (BaseAuthorization ba : auth.getAuthorizations()) { auths.add(ba.getId()); } Collections.sort(auths); idParts.put(auth.getSecurityServiceId(), auths); } } StringBuilder sb = new StringBuilder(); List sortedKeys = new ArrayList(idParts.keySet()); Collections.sort(sortedKeys); for (String key : sortedKeys) { if (sb.length() > 0) { sb.append('|'); } List auths = idParts.get(key); first = true; for (String ak : auths) { if (first) { first = false; } else { sb.append('|'); } sb.append(ak); } sb.append('@'); sb.append(key); } id = sb.toString(); } /** * Combine user information strings. *

* Extra information is appended (separated by a comma) if not yet present in the string. * * @param org * base string to append to (avoiding duplication). * @param add * string to add * @return org + ", " + add */ private String combine(String org, String add) { if (null == org) { return add; } if (null == add || org.equals(add) || org.startsWith(add + ", ") || org.endsWith(", " + add)) { return org; } return org + ", " + add; } /** * @inheritDoc */ public String getId() { return id; } /** * @inheritDoc */ public boolean isToolAuthorized(String toolId) { for (Authentication authentication : authentications) { for (BaseAuthorization authorization : authentication.getAuthorizations()) { if (authorization.isToolAuthorized(toolId)) { return true; } } } return false; } /** * @inheritDoc */ public boolean isCommandAuthorized(String commandName) { for (Authentication authentication : authentications) { for (BaseAuthorization authorization : authentication.getAuthorizations()) { if (authorization.isCommandAuthorized(commandName)) { return true; } } } return false; } /** * @inheritDoc */ public boolean isLayerVisible(String layerId) { for (Authentication authentication : authentications) { for (BaseAuthorization authorization : authentication.getAuthorizations()) { if (authorization.isLayerVisible(layerId)) { return true; } } } return false; } /** * @inheritDoc */ public boolean isLayerUpdateAuthorized(String layerId) { if (isLayerUpdateCapable(layerId)) { for (Authentication authentication : authentications) { for (BaseAuthorization authorization : authentication.getAuthorizations()) { if (authorization.isLayerUpdateAuthorized(layerId)) { return true; } } } } return false; } /** * @inheritDoc */ public boolean isLayerCreateAuthorized(String layerId) { if (isLayerCreateCapable(layerId)) { for (Authentication authentication : authentications) { for (BaseAuthorization authorization : authentication.getAuthorizations()) { if (authorization.isLayerCreateAuthorized(layerId)) { return true; } } } } return false; } /** * @inheritDoc */ public boolean isLayerDeleteAuthorized(String layerId) { if (isLayerUpdateCapable(layerId)) { for (Authentication authentication : authentications) { for (BaseAuthorization authorization : authentication.getAuthorizations()) { if (authorization.isLayerDeleteAuthorized(layerId)) { return true; } } } } return false; } /** * @inheritDoc */ public Filter getFeatureFilter(String layerId) { Filter filter = null; for (Authentication authentication : authentications) { for (BaseAuthorization authorization : authentication.getAuthorizations()) { if (authorization instanceof VectorLayerSelectFilterAuthorization) { Filter part = ((VectorLayerSelectFilterAuthorization) authorization).getFeatureFilter(layerId); if (null != part) { filter = combineFilter(filter, part); } } } } return filter; } private Filter combineFilter(Filter base, Filter add) { if (null == base) { return add; } if (null == add) { return base; } return filterService.createAndFilter(base, add); } /** * @inheritDoc */ public Geometry getVisibleArea(final String layerId) { return areaCombine(layerId, new AreaCombineGetter() { public Geometry get(AreaAuthorization auth) { return auth.getVisibleArea(layerId); } }); } private Geometry areaCombine(String layerId, AreaCombineGetter areaGetter) { Layer layer = configurationService.getLayer(layerId); if (null == layer) { log.error("areaCombine on unknown layer " + layerId); return null; } LayerInfo layerInfo = layer.getLayerInfo(); // base is the max bounds of the layer Envelope maxBounds = converterService.toInternal(layerInfo.getMaxExtent()); PrecisionModel precisionModel = new PrecisionModel(PrecisionModel.FLOATING); int srid = geoService.getSridFromCrs(layer.getLayerInfo().getCrs()); GeometryFactory geometryFactory = new GeometryFactory(precisionModel, srid); Geometry geometry = geometryFactory.toGeometry(maxBounds); // limit based on authorizations for (Authentication authentication : authentications) { for (BaseAuthorization authorization : authentication.getAuthorizations()) { if (authorization instanceof AreaAuthorization) { geometry = geometry.intersection(areaGetter.get((AreaAuthorization) authorization)); } } } geometry.setSRID(srid); // force srid, even when not set correctly by security service return geometry; } /** * @inheritDoc */ public boolean isPartlyVisibleSufficient(final String layerId) { return areaPartlySufficientCombine(new AuthorizationGetter() { public boolean get(AreaAuthorization auth) { return auth.isPartlyVisibleSufficient(layerId); } }); } private boolean areaPartlySufficientCombine(AuthorizationGetter partlySufficientGetter) { boolean res = false; for (Authentication authentication : authentications) { for (BaseAuthorization authorization : authentication.getAuthorizations()) { if (authorization instanceof AreaAuthorization) { if (!partlySufficientGetter.get((AreaAuthorization) authorization)) { return false; } res = true; } } } return res; } /** * @inheritDoc */ public Geometry getUpdateAuthorizedArea(final String layerId) { if (!isLayerUpdateCapable(layerId)) { return null; } return areaCombine(layerId, new AreaCombineGetter() { public Geometry get(AreaAuthorization auth) { return auth.getUpdateAuthorizedArea(layerId); } }); } /** * @inheritDoc */ public boolean isPartlyUpdateAuthorizedSufficient(final String layerId) { return areaPartlySufficientCombine(new AuthorizationGetter() { public boolean get(AreaAuthorization auth) { return auth.isPartlyUpdateAuthorizedSufficient(layerId); } }); } /** * @inheritDoc */ public Geometry getCreateAuthorizedArea(final String layerId) { if (!isLayerCreateCapable(layerId)) { return null; } return areaCombine(layerId, new AreaCombineGetter() { public Geometry get(AreaAuthorization auth) { return auth.getCreateAuthorizedArea(layerId); } }); } /** * @inheritDoc */ public boolean isPartlyCreateAuthorizedSufficient(final String layerId) { return areaPartlySufficientCombine(new AuthorizationGetter() { public boolean get(AreaAuthorization auth) { return auth.isPartlyCreateAuthorizedSufficient(layerId); } }); } /** * @inheritDoc */ public Geometry getDeleteAuthorizedArea(final String layerId) { if (!isLayerDeleteCapable(layerId)) { return null; } return areaCombine(layerId, new AreaCombineGetter() { public Geometry get(AreaAuthorization auth) { return auth.getDeleteAuthorizedArea(layerId); } }); } /** * @inheritDoc */ public boolean isPartlyDeleteAuthorizedSufficient(final String layerId) { return areaPartlySufficientCombine(new AuthorizationGetter() { public boolean get(AreaAuthorization auth) { return auth.isPartlyDeleteAuthorizedSufficient(layerId); } }); } /** * @inheritDoc */ public boolean isFeatureVisible(final String layerId, final InternalFeature feature) { return policyCombine(new AuthorizationGetter() { public boolean get(BaseAuthorization auth) { if (auth instanceof FeatureAuthorization) { return ((FeatureAuthorization) auth).isFeatureVisible(layerId, feature); } else { return auth.isLayerVisible(layerId); } } }); } private boolean policyCombine(AuthorizationGetter auth) { for (Authentication authentication : authentications) { for (BaseAuthorization authorization : authentication.getAuthorizations()) { if (auth.get(authorization)) { return true; } } } return false; } /** @inheritDoc */ public boolean isFeatureUpdateAuthorized(final String layerId, final InternalFeature feature) { if (!isLayerUpdateCapable(layerId)) { return false; } return policyCombine(new AuthorizationGetter() { public boolean get(BaseAuthorization auth) { if (auth instanceof FeatureAuthorization) { return ((FeatureAuthorization) auth).isFeatureUpdateAuthorized(layerId, feature); } else { return auth.isLayerUpdateAuthorized(layerId); } } }); } /** @inheritDoc */ public boolean isFeatureUpdateAuthorized(final String layerId, final InternalFeature orgFeature, final InternalFeature newFeature) { if (!isLayerUpdateCapable(layerId)) { return false; } return policyCombine(new AuthorizationGetter() { public boolean get(BaseAuthorization auth) { if (auth instanceof FeatureAuthorization) { return ((FeatureAuthorization) auth).isFeatureUpdateAuthorized(layerId, orgFeature, newFeature); } else { return auth.isLayerUpdateAuthorized(layerId); } } }); } /** @inheritDoc */ public boolean isFeatureDeleteAuthorized(final String layerId, final InternalFeature feature) { if (!isLayerDeleteCapable(layerId)) { return false; } return policyCombine(new AuthorizationGetter() { public boolean get(BaseAuthorization auth) { if (auth instanceof FeatureAuthorization) { return ((FeatureAuthorization) auth).isFeatureDeleteAuthorized(layerId, feature); } else { return auth.isLayerDeleteAuthorized(layerId); } } }); } /** @inheritDoc */ public boolean isFeatureCreateAuthorized(final String layerId, final InternalFeature feature) { if (!isLayerCreateCapable(layerId)) { return false; } return policyCombine(new AuthorizationGetter() { public boolean get(BaseAuthorization auth) { if (auth instanceof FeatureAuthorization) { return ((FeatureAuthorization) auth).isFeatureCreateAuthorized(layerId, feature); } else { return auth.isLayerCreateAuthorized(layerId); } } }); } /** * @inheritDoc */ public boolean isAttributeReadable(final String layerId, final InternalFeature feature, final String attributeName) { return policyCombine(new AuthorizationGetter() { public boolean get(BaseAuthorization auth) { if (auth instanceof AttributeAuthorization) { return ((AttributeAuthorization) auth).isAttributeReadable(layerId, feature, attributeName); } else if (auth instanceof FeatureAuthorization) { return ((FeatureAuthorization) auth).isFeatureVisible(layerId, feature); } else { return auth.isLayerVisible(layerId); } } }); } /** * @inheritDoc */ public boolean isAttributeWritable(final String layerId, final InternalFeature feature, final String attributeName) { if (!isLayerUpdateCapable(layerId)) { return false; } return policyCombine(new AuthorizationGetter() { public boolean get(BaseAuthorization auth) { if (auth instanceof AttributeAuthorization) { return ((AttributeAuthorization) auth).isAttributeWritable(layerId, feature, attributeName); } else if (auth instanceof FeatureAuthorization) { return ((FeatureAuthorization) auth).isFeatureUpdateAuthorized(layerId, feature); } else { return auth.isLayerUpdateAuthorized(layerId); } } }); } private boolean isLayerUpdateCapable(String layerId) { if (null == configurationService) { return true; // for testing, when there is no spring context } VectorLayer layer = configurationService.getVectorLayer(layerId); return null != layer && layer.isUpdateCapable(); } private boolean isLayerCreateCapable(String layerId) { if (null == configurationService) { return true; // for testing, when there is no spring context } VectorLayer layer = configurationService.getVectorLayer(layerId); return null != layer && layer.isCreateCapable(); } private boolean isLayerDeleteCapable(String layerId) { if (null == configurationService) { return true; // for testing, when there is no spring context } VectorLayer layer = configurationService.getVectorLayer(layerId); return null != layer && layer.isDeleteCapable(); } /** * Interface to unify/generalise the different areas. */ private interface AreaCombineGetter { /** * Get the area which needs to be combined. * * @param auth * authorization object to get data from * @return area to combine */ Geometry get(AreaAuthorization auth); } /** * Interface to unify/generalise the different areas. */ private interface AuthorizationGetter { /** * Get the "partly sufficient" status. * * @param auth * authorization object to get data from * @return true when part in area is sufficient */ boolean get(AUTH auth); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy