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

net.anotheria.anosite.access.AnoSiteAccessAPIImpl Maven / Gradle / Ivy

There is a newer version: 4.1.2
Show newest version
package net.anotheria.anosite.access;

import net.anotheria.access.AccessService;
import net.anotheria.access.AccessServiceException;
import net.anotheria.access.SOAttribute;
import net.anotheria.access.SecurityObject;
import net.anotheria.access.impl.PermissionCollection;
import net.anotheria.access.impl.PermissionImpl;
import net.anotheria.access.impl.SecurityBox;
import net.anotheria.access.impl.StaticRole;
import net.anotheria.access.storage.persistence.SecurityBoxPersistenceService;
import net.anotheria.anodoc.data.NoSuchDocumentException;
import net.anotheria.anoplass.api.APIException;
import net.anotheria.anoplass.api.APIFinder;
import net.anotheria.anoplass.api.APIInitException;
import net.anotheria.anoplass.api.generic.login.LoginAPI;
import net.anotheria.anoprise.dualcrud.CrudServiceException;
import net.anotheria.anoprise.dualcrud.SaveableID;
import net.anotheria.anoprise.metafactory.MetaFactory;
import net.anotheria.anoprise.metafactory.MetaFactoryException;
import net.anotheria.anosite.access.constraint.ParametrizedConstraint;
import net.anotheria.anosite.access.context.SecurityContextInitializer;
import net.anotheria.anosite.gen.anoaccessapplicationdata.data.UserData;
import net.anotheria.anosite.gen.anoaccessapplicationdata.service.AnoAccessApplicationDataServiceException;
import net.anotheria.anosite.gen.anoaccessapplicationdata.service.IAnoAccessApplicationDataService;
import net.anotheria.anosite.gen.anoaccessconfiguration.data.AccessOperation;
import net.anotheria.anosite.gen.anoaccessconfiguration.data.Constraint;
import net.anotheria.anosite.gen.anoaccessconfiguration.data.ContextInitializer;
import net.anotheria.anosite.gen.anoaccessconfiguration.data.Permission;
import net.anotheria.anosite.gen.anoaccessconfiguration.data.PermissionSortType;
import net.anotheria.anosite.gen.anoaccessconfiguration.data.Role;
import net.anotheria.anosite.gen.anoaccessconfiguration.data.RoleSortType;
import net.anotheria.anosite.gen.anoaccessconfiguration.service.AccessOperationNotFoundInAnoAccessConfigurationServiceException;
import net.anotheria.anosite.gen.anoaccessconfiguration.service.AnoAccessConfigurationServiceException;
import net.anotheria.anosite.gen.anoaccessconfiguration.service.IAnoAccessConfigurationService;
import net.anotheria.anosite.gen.ascustomaction.data.CustomActionDef;
import net.anotheria.anosite.gen.ascustomaction.service.ASCustomActionServiceException;
import net.anotheria.anosite.gen.ascustomaction.service.IASCustomActionService;
import net.anotheria.anosite.gen.assitedata.data.NaviItem;
import net.anotheria.anosite.gen.assitedata.service.ASSiteDataServiceException;
import net.anotheria.anosite.gen.assitedata.service.IASSiteDataService;
import net.anotheria.anosite.gen.asuserdata.data.UserDef;
import net.anotheria.anosite.gen.asuserdata.service.ASUserDataServiceException;
import net.anotheria.anosite.gen.asuserdata.service.IASUserDataService;
import net.anotheria.anosite.gen.aswebdata.data.Box;
import net.anotheria.anosite.gen.aswebdata.data.Pagex;
import net.anotheria.anosite.gen.aswebdata.service.ASWebDataServiceException;
import net.anotheria.anosite.gen.aswebdata.service.IASWebDataService;
import net.anotheria.anosite.gen.aswizarddata.data.WizardDef;
import net.anotheria.anosite.gen.aswizarddata.service.ASWizardDataServiceException;
import net.anotheria.anosite.gen.aswizarddata.service.IASWizardDataService;
import net.anotheria.asg.data.DataObject;
import net.anotheria.asg.util.listener.IServiceListener;
import net.anotheria.util.StringUtils;
import net.anotheria.util.log.LogMessageUtil;
import net.anotheria.util.sorter.SortType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MarkerFactory;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 * {@link AnoSiteAccessAPI} implementation.
 * 
 * @author Alexandr Bolbat
 */
public class AnoSiteAccessAPIImpl implements AnoSiteAccessAPI {

	/**
	 * {@link Logger} instance.
	 */
	private static final Logger LOGGER = LoggerFactory.getLogger(AnoSiteAccessAPIImpl.class);

	/**
	 * {@link AccessService} instance.
	 */
	private AccessService accessService;

	/**
	 * Ano-site configuration for {@link AccessService}.
	 */
	private IAnoAccessConfigurationService accessConfigurationService;

	/**
	 * Ano-site persistence for access user2roles data.
	 */
	private IAnoAccessApplicationDataService accessApplicationDataService;

	/**
	 * Pages and boxes configuration.
	 */
	private IASWebDataService pagesConfigurationPersistence;

	/**
	 * Navigation items configuration.
	 */
	private IASSiteDataService siteDataService;

	/**
	 * Custom actions configuration.
	 */
	private IASCustomActionService customActionsConfigurationPersistence;

	/**
	 * Wizards configuration.
	 */
	private IASWizardDataService wizardConfigurationPersistence;

	/**
	 * User data service.
	 * */
	private IASUserDataService userDataService;

	/**
	 * Security box service
	 * */
	private SecurityBoxPersistenceService securityBoxPersistenceService;

	/**
	 * {@link LoginAPI} instance.
	 */
	private LoginAPI loginAPI;

	@Override
	public void init() throws APIInitException {
		try {
			accessService = MetaFactory.get(AccessService.class);
			accessConfigurationService = MetaFactory.get(IAnoAccessConfigurationService.class);
			accessApplicationDataService = MetaFactory.get(IAnoAccessApplicationDataService.class);
			pagesConfigurationPersistence = MetaFactory.get(IASWebDataService.class);
			siteDataService = MetaFactory.get(IASSiteDataService.class);
			customActionsConfigurationPersistence = MetaFactory.get(IASCustomActionService.class);
			wizardConfigurationPersistence = MetaFactory.get(IASWizardDataService.class);
			userDataService = MetaFactory.get(IASUserDataService.class);
			securityBoxPersistenceService = MetaFactory.get(SecurityBoxPersistenceService.class);
		} catch (MetaFactoryException e) {
			String message = LogMessageUtil.failMsg(e) + " Can't initialize required services.";
			LOGGER.error(MarkerFactory.getMarker("FATAL"), message, e);
			throw new APIInitException(message, e);
		}

		loginAPI = APIFinder.findAPI(LoginAPI.class);

		try {
			configureAccessService();
		} catch (AnoSiteAccessAPIException e) {
			String message = LogMessageUtil.failMsg(e) + " Can't initialize access service with current configuration.";
			LOGGER.error(MarkerFactory.getMarker("FATAL"), message, e);
			throw new APIInitException(message, e);
		}

		accessConfigurationService.addServiceListener(new AccessConfigurationChangeListener());
		accessApplicationDataService.addServiceListener(new AccessUserDataChangeListener());
	}

	@Override
	public void deInit() {
	}

	@Override
	public boolean isAllowedForPage(final String pageId) throws AnoSiteAccessAPIException {
		if (!AnoSiteAccessAPIConfig.getInstance().isEnabled()) // allowing access if access control disabled by configuration
			return true;

		try {
			Pagex page = pagesConfigurationPersistence.getPagex(pageId);
			return isAllowed(page.getAccessOperation());
		} catch (ASWebDataServiceException e) {
			String message = LogMessageUtil.failMsg(e, pageId);
			LOGGER.error(message, e);
			throw new AnoSiteAccessAPIException(message, e);
		}
	}

	@Override
	public boolean isAllowedForBox(final String boxId) throws AnoSiteAccessAPIException {
		if (!AnoSiteAccessAPIConfig.getInstance().isEnabled()) // allowing access if access control disabled by configuration
			return true;

		try {
			Box box = pagesConfigurationPersistence.getBox(boxId);
			return isAllowed(box.getAccessOperation());
		} catch (ASWebDataServiceException e) {
			String message = LogMessageUtil.failMsg(e, boxId);
			LOGGER.error(message, e);
			throw new AnoSiteAccessAPIException(message, e);
		}
	}

	@Override
	public boolean isAllowedForNaviItem(String naviItemId) throws AnoSiteAccessAPIException {
		if (!AnoSiteAccessAPIConfig.getInstance().isEnabled()) // allowing access if access control disabled by configuration
			return true;

		try {
			NaviItem naviItem = siteDataService.getNaviItem(naviItemId);
			return isAllowed(naviItem.getAccessOperation());
		} catch (ASSiteDataServiceException e) {
			String message = LogMessageUtil.failMsg(e, naviItemId);
			LOGGER.error(message, e);
			throw new AnoSiteAccessAPIException(message, e);
		}
	}

	@Override
	public boolean isAllowedForAction(final String actionId) throws AnoSiteAccessAPIException {
		if (!AnoSiteAccessAPIConfig.getInstance().isEnabled()) // allowing access if access control disabled by configuration
			return true;

		try {
			CustomActionDef action = customActionsConfigurationPersistence.getCustomActionDef(actionId);
			return isAllowed(action.getAccessOperation());
		} catch (ASCustomActionServiceException e) {
			String message = LogMessageUtil.failMsg(e, actionId);
			LOGGER.error(message, e);
			throw new AnoSiteAccessAPIException(message, e);
		}
	}

	@Override
	public boolean isAllowedForWizard(final String wizardId) throws AnoSiteAccessAPIException {
		if (!AnoSiteAccessAPIConfig.getInstance().isEnabled()) // allowing access if access control disabled by configuration
			return true;

		try {
			WizardDef wizard = wizardConfigurationPersistence.getWizardDef(wizardId);
			return isAllowed(wizard.getAccessOperation());
		} catch (ASWizardDataServiceException e) {
			String message = LogMessageUtil.failMsg(e, wizardId);
			LOGGER.error(message, e);
			throw new AnoSiteAccessAPIException(message, e);
		}
	}

	/**
	 * Main API logic.
	 * 
	 * @param accessOperationId
	 *            - access operation id
	 * @return true if operation allowed or false
	 * @throws AnoSiteAccessAPIException
	 */
	private boolean isAllowed(final String accessOperationId) throws AnoSiteAccessAPIException {
		// if access operation not configured (not required)
		if (StringUtils.isEmpty(accessOperationId))
			return true;

		AccessOperation accessOperation = null;
		try {
			accessOperation = getAccessOperation(accessOperationId);
		} catch (AccessOperationNotFoundAPIException e) {
			LOGGER.warn(LogMessageUtil.failMsg(e, accessOperationId) + " AccessOperation not found. Skipping security check.");
			return true;
		}

		if (accessOperation == null) { // to be sure
			LOGGER.warn(LogMessageUtil.failMsg(new RuntimeException(), accessOperationId) + " AccessOperation not found. Skipping security check.");
			return true;
		}

		// if no logged user
		if (!isLoggedIn())
			return false;

		// loading context initializers required for current access operation
		Set initializers = new HashSet();
		for (Permission permission : getPermissions(accessOperationId))
			for (Constraint constraint : getConstraint(permission.getConstraints()))
				for (ContextInitializer contextInitializer : getContextInitializers(constraint.getContextInitializers()))
					if (contextInitializer != null && !StringUtils.isEmpty(contextInitializer.getClassName()))
						initializers.add(contextInitializer.getClassName());

		// prepare access security context
		SecurityObject securityObject = new SecurityObject(getCurrentUserId());

		for (String clazz : initializers) {
			try {
				Class undefinedClass = Class.forName(clazz); // loading class by name
				if (!SecurityContextInitializer.class.isAssignableFrom(undefinedClass)) { // validating class type
					String message = LogMessageUtil.failMsg(new RuntimeException(), accessOperationId) + " Wrong security context class[" + clazz + "] type.";
					LOGGER.warn(message);
					throw new AnoSiteAccessAPIException(message);
				}

				@SuppressWarnings("unchecked")
				Class initializerClass = (Class) undefinedClass;

				// instantiating initializer
				SecurityContextInitializer initializer = initializerClass.newInstance();

				// retrieving security context values
				Map initializedValues = initializer.initialize();

				// filling security object attributes with obtained values
				for (String key : initializedValues.keySet()) {
					SOAttribute attr = new SOAttribute(key, initializedValues.get(key));
					securityObject.addAttribute(attr);
				}
			} catch (ClassNotFoundException e) {
				String message = LogMessageUtil.failMsg(e, accessOperationId) + " Wrong security context class[" + clazz + "].";
				LOGGER.warn(message, e);
				throw new AnoSiteAccessAPIException(message, e);
			} catch (InstantiationException e) {
				String message = LogMessageUtil.failMsg(e, accessOperationId) + " Can't instantiate security context class[" + clazz + "].";
				LOGGER.warn(message, e);
				throw new AnoSiteAccessAPIException(message, e);
			} catch (IllegalAccessException e) {
				String message = LogMessageUtil.failMsg(e, accessOperationId) + " Can't instantiate security context class[" + clazz + "].";
				LOGGER.warn(message, e);
				throw new AnoSiteAccessAPIException(message, e);
			}
		}

		// executing main security logic
		try {
			return accessService.isAllowed(accessOperation.getId(), securityObject, null).isAllowed();
		} catch (AccessServiceException e) {
			LOGGER.warn(LogMessageUtil.failMsg(e, accessOperationId) + " Skipping exception and don't allow execution.", e);
			return false;
		}
	}

	/**
	 * Check is some user logged in.
	 * 
	 * @return true if logged or false
	 */
	private boolean isLoggedIn() {
		return loginAPI.isLogedIn();
	}

	/**
	 * Return currently logged user id.
	 * 
	 * @return {@link String} id of currently logged user
	 * @throws AnoSiteAccessAPIException
	 */
	private String getCurrentUserId() throws AnoSiteAccessAPIException {
		try {
			return loginAPI.getLogedUserId();
		} catch (APIException e) {
			throw new AnoSiteAccessAPIException("No logged user.");
		}
	}

	/**
	 * Return {@link AccessOperation} by given id.
	 * 
	 * @param id
	 *            - given access operation id
	 * @return {@link AccessOperation}, can't be null
	 * @throws AnoSiteAccessAPIException
	 */
	private AccessOperation getAccessOperation(final String id) throws AnoSiteAccessAPIException {
		try {
			return accessConfigurationService.getAccessOperation(id);
		} catch (AccessOperationNotFoundInAnoAccessConfigurationServiceException e) {
			throw new AccessOperationNotFoundAPIException("Access operation with given id[" + id + "] not found.", e);
		} catch (AnoAccessConfigurationServiceException e) {
			throw new AnoSiteAccessAPIException(LogMessageUtil.failMsg(e, id), e);
		}
	}

	/**
	 * Get {@link List} of {@link Role} by given id's.
	 * 
	 * @return {@link List} of {@link Role}, can be empty but not null
	 * @throws AnoSiteAccessAPIException
	 */
	private List getRoles() throws AnoSiteAccessAPIException {
		List result = new ArrayList();

		try {
			SortType sorting = new SortType(RoleSortType.SORT_BY_ID, RoleSortType.ASC);
			List loaded = accessConfigurationService.getRoles(sorting);
			if (loaded != null && !loaded.isEmpty())
				result.addAll(loaded);

			return result;
		} catch (AnoAccessConfigurationServiceException e) {
			String message = LogMessageUtil.failMsg(e) + " Can't load roles.";
			LOGGER.error(message, e);
			throw new AnoSiteAccessAPIException(message, e);
		}
	}

	/**
	 * Get {@link List} of {@link Permission} who have given access operation.
	 * 
	 * @param accessOperationId
	 *            - access operation id
	 * @return {@link List} of {@link Permission}, can be empty but not null
	 * @throws AnoSiteAccessAPIException
	 */
	private List getPermissions(final String accessOperationId) throws AnoSiteAccessAPIException {
		List result = new ArrayList();

		try {
			SortType sorting = new SortType(PermissionSortType.SORT_BY_PRIORITY, PermissionSortType.DESC);
			List loaded = accessConfigurationService.getPermissionsByProperty(Permission.LINK_PROP_ACCESS_OPERATION, accessOperationId, sorting);
			if (loaded != null && !loaded.isEmpty())
				result.addAll(loaded);

			return result;
		} catch (AnoAccessConfigurationServiceException e) {
			String message = LogMessageUtil.failMsg(e, accessOperationId) + " Can't load permissions.";
			LOGGER.error(message, e);
			throw new AnoSiteAccessAPIException(message, e);
		}
	}

	/**
	 * Get {@link List} of {@link Permission} by given id's.
	 * 
	 * @param ids
	 *            - id's
	 * @return {@link List} of {@link Permission}, can be empty but not null
	 * @throws AnoSiteAccessAPIException
	 */
	private List getPermissions(final List ids) throws AnoSiteAccessAPIException {
		List result = new ArrayList();

		if (ids == null || ids.isEmpty())
			return result;

		try {
			for (String id : ids)
				result.add(accessConfigurationService.getPermission(id));

			return result;
		} catch (AnoAccessConfigurationServiceException e) {
			String message = LogMessageUtil.failMsg(e, ids) + " Can't load permissions.";
			LOGGER.error(message, e);
			throw new AnoSiteAccessAPIException(message, e);
		}
	}

	/**
	 * Get {@link List} of {@link Constraint} by given id's.
	 * 
	 * @param ids
	 *            - id's
	 * @return {@link List} of {@link Constraint}, can be empty but not null
	 * @throws AnoSiteAccessAPIException
	 */
	private List getConstraint(final List ids) throws AnoSiteAccessAPIException {
		List result = new ArrayList();

		if (ids == null || ids.isEmpty())
			return result;

		try {
			for (String id : ids)
				result.add(accessConfigurationService.getConstraint(id));

			return result;
		} catch (AnoAccessConfigurationServiceException e) {
			String message = LogMessageUtil.failMsg(e, ids) + " Can't load constraints.";
			LOGGER.error(message, e);
			throw new AnoSiteAccessAPIException(message, e);
		}
	}

	/**
	 * Get {@link List} of {@link ContextInitializer} by given id's.
	 * 
	 * @param ids
	 *            - id's
	 * @return {@link List} of {@link ContextInitializer}, can be empty but not null
	 * @throws AnoSiteAccessAPIException
	 */
	private List getContextInitializers(final List ids) throws AnoSiteAccessAPIException {
		List result = new ArrayList();

		if (ids == null || ids.isEmpty())
			return result;

		try {
			for (String id : ids)
				result.add(accessConfigurationService.getContextInitializer(id));

			return result;
		} catch (AnoAccessConfigurationServiceException e) {
			String message = LogMessageUtil.failMsg(e, ids) + " Can't load context initializers.";
			LOGGER.error(message, e);
			throw new AnoSiteAccessAPIException(message, e);
		}
	}

	/**
	 * Configuring {@link AccessService} instance with current configuration.
	 * 
	 * @throws AnoSiteAccessAPIException
	 */
	private synchronized void configureAccessService() throws AnoSiteAccessAPIException {
		accessService.reset(); // clearing current configuration

		for (Role role : getRoles()) {
			StaticRole configuredRole = new StaticRole(role.getId());

			PermissionCollection permissionCollection = new PermissionCollection(configuredRole.getName());
			for (Permission permission : getPermissions(role.getPermissions())) {
				PermissionImpl configuredPermission = new PermissionImpl();
				configuredPermission.setName(permission.getId());
				configuredPermission.setAction(permission.getAccessOperation());
				configuredPermission.setAllow(!permission.getDeny());

				for (Constraint constraint : getConstraint(permission.getConstraints())) {
					if (StringUtils.isEmpty(constraint.getClassName())) // skipping constraint if its class not configured
						continue;

					String clazz = constraint.getClassName();
					try {
						Class undefinedClass = Class.forName(clazz); // loading class by name
						if (!net.anotheria.access.impl.Constraint.class.isAssignableFrom(undefinedClass)) { // validating class type
							String message = LogMessageUtil.failMsg(new RuntimeException()) + " Wrong constraint class[" + clazz + "] type.";
							LOGGER.warn(message);
							throw new AnoSiteAccessAPIException(message);
						}

						@SuppressWarnings("unchecked")
						Class constraintClass = (Class) undefinedClass;
						net.anotheria.access.impl.Constraint instance = constraintClass.newInstance();

						if (instance instanceof ParametrizedConstraint) {
							ParametrizedConstraint parametrizedInstance = ParametrizedConstraint.class.cast(instance);
							parametrizedInstance.setParameter1(constraint.getParameter1());
							parametrizedInstance.setParameter2(constraint.getParameter2());
							parametrizedInstance.setParameter3(constraint.getParameter3());
							parametrizedInstance.setParameter4(constraint.getParameter4());
							parametrizedInstance.setParameter5(constraint.getParameter5());
						}

						configuredPermission.addConstraint(instance);
					} catch (ClassNotFoundException e) {
						String message = LogMessageUtil.failMsg(e) + " Wrong constraint class[" + clazz + "].";
						LOGGER.warn(message, e);
						throw new AnoSiteAccessAPIException(message, e);
					} catch (InstantiationException e) {
						String message = LogMessageUtil.failMsg(e) + " Can't instantiate constraint class[" + clazz + "].";
						LOGGER.warn(message, e);
						throw new AnoSiteAccessAPIException(message, e);
					} catch (IllegalAccessException e) {
						String message = LogMessageUtil.failMsg(e) + " Can't instantiate constraint class[" + clazz + "].";
						LOGGER.warn(message, e);
						throw new AnoSiteAccessAPIException(message, e);
					}
				}

				// adding permission to role permission collection
				permissionCollection.add(configuredPermission);
			}

			// configuring access service with role and its permission collection
			accessService.addPermissionCollection(permissionCollection);
			configuredRole.setPermissionSetId(permissionCollection.getId());
			accessService.addRole(configuredRole);
		}

		createSecureBoxes();
	}

	/**
	 * Create secure boxes to store roles and permissions if they do not exists yet.
	 * */
	private void createSecureBoxes() {

		List userDatas = null;
		SecurityBox securityBox = null;
		UserDef user = null;

		try {
			userDatas = accessApplicationDataService.getUserDatas();
		} catch (AnoAccessApplicationDataServiceException e) {
			LOGGER.error("Error occurred while getting UserDef by id", e);
			throw new RuntimeException("Error occurred while getting UserDef by id");
		}

		for (UserData userData : userDatas) {

			try {
				user = userDataService.getUserDef(userData.getUserId());
			} catch (NoSuchDocumentException e1) {
				LOGGER.warn("Couldn't get user by id "+userData.getUserId()+", {"+userData+"}", e1);
				continue;
			} catch (ASUserDataServiceException e) {
				LOGGER.error("Error occurred while getting UserDef by id", e);
				throw new RuntimeException("Error occurred while getting UserDef by id");
			}

			try {
				SaveableID saveableID = new SaveableID();
				saveableID.setSaveableId(user.getLogin());
				saveableID.setOwnerId(user.getLogin());
				securityBox = securityBoxPersistenceService.read(saveableID);
			} catch (CrudServiceException e) {
				LOGGER.warn("SecurityBox with id=" + user.getLogin() + " not found. Creating new one");
			}

			if (securityBox == null) {
				securityBox = new SecurityBox(user.getLogin());
			}

			for (String roleId : userData.getRoles()) {

				if (securityBox.hasRole(roleId)) {
					continue;
				}

				net.anotheria.access.Role role = accessService.getRole(roleId);

				try {
					accessService.grantRole(new SecurityObject(user.getLogin()), role.getName());
				} catch (AccessServiceException e) {
					LOGGER.error("Error occurred while granting role " + role.getName() + " to " + user.getLogin(), e);
					throw new RuntimeException();
				}
			}
		}
	}

	/**
	 * Listener for updating {@link AccessService} configuration if it's changed in CMS.
	 * 
	 * @author Alexandr Bolbat
	 */
	public final class AccessConfigurationChangeListener implements IServiceListener {

		/**
		 * {@link Logger} instance.
		 */
		private final Logger LOGGER = LoggerFactory.getLogger(AccessUserDataChangeListener.class);

		@Override
		public void documentUpdated(final DataObject oldVersion, final DataObject newVersion) {
			updateConfiguration();
		}

		@Override
		public void documentDeleted(final DataObject doc) {
			updateConfiguration();
		}

		@Override
		public void documentCreated(final DataObject doc) {
			updateConfiguration();
		}

		@Override
		public void documentImported(final DataObject doc) {
			updateConfiguration();
		}

		@Override
		public void persistenceChanged() {
			updateConfiguration();
		}

		/**
		 * Update configuration in {@link AccessService}.
		 */
		private void updateConfiguration() {
			try {
				LOGGER.debug("Access configuration changed. Re-Configuring AccessService...");
				configureAccessService();
				LOGGER.debug("Re-Configuration of AccessService finished.");
			} catch (AnoSiteAccessAPIException e) {
				LOGGER.warn(LogMessageUtil.failMsg(e), e);
			}
		}

	}

	/**
	 * Listener for clearing {@link AccessService} cache if user data (roles2user mapping) changed trough CMS.
	 * 
	 * @author Alexandr Bolbat
	 */
	public final class AccessUserDataChangeListener implements IServiceListener {

		/**
		 * {@link Logger} instance.
		 */
		private final Logger LOGGER = LoggerFactory.getLogger(AccessUserDataChangeListener.class);

		@Override
		public void documentUpdated(final DataObject oldVersion, final DataObject newVersion) {
			update(oldVersion); // clearing for old userId
			update(newVersion); // clearing for new userId
		}

		@Override
		public void documentDeleted(final DataObject doc) {
			update(doc);
		}

		@Override
		public void documentCreated(final DataObject doc) {
			update(doc);
		}

		@Override
		public void documentImported(final DataObject doc) {
		}

		@Override
		public void persistenceChanged() {
		}

		/**
		 * Update configuration in {@link AccessService}.
		 */
		private void update(final DataObject doc) {
			if (!(doc instanceof UserData))
				return;

			UserData userData = UserData.class.cast(doc);
			LOGGER.debug("Access user data changed. Clearing cached user[" + userData.getUserId() + "] data in AccessService...");
			accessService.reset(userData.getUserId());
			LOGGER.debug("Clearingfinished.");
		}

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy