7.5:dev:architecture:filters

Filters

Expand the introduction

A mechanism for dynamic registry and composing of filters has been developed in the application for searching the data in IdM (identities, roles, tree structure components, etc.). A new filter can be registered for existing REST services in any module. Filter can be used by authoritazation policy evaluator for securing data access.

The filter (FilterBuilder) is registered with the given key (FilterKey):

  • entityClass - a domain type for which it is intended
  • name - the name of the item during which the filter is actively evaluated if it is stated in the filtering criteria (⇒ get parameter)

Evaluating of filters is done by FilterManager, which searches over the domain type during construction:

  • collects all registered active filters by a key:
    • complying with the given domain type
    • complying with the name of the item existing in the parameters by which it is being filtered
  • and calls method getPredicate over all the found filters the results of which (if there are some) are merged into unified searching criteria via operator and.

A filter must implement these methods:

  • getName - returns the item name - see above
  • getPredicate - construction of the searching criteria themselves
  • find - returns data (objects by the domain type - see above) solely by the predicate constructed above

The following ready-made abstract classes can be used for constructing a new filter:

  • BaseFilterBuilder - provides the base implementation for working with the configuration (see below)
  • AbstractFilterBuilder - provides the base implementation of find method based on the repository handed in the constructor

This example filter is meant for searching for identities by the username.

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Description;
import org.springframework.stereotype.Component;
 
import eu.bcvsolutions.idm.core.api.dto.filter.IdentityFilter;
import eu.bcvsolutions.idm.core.api.repository.filter.AbstractFilterBuilder;
import eu.bcvsolutions.idm.core.model.entity.IdmIdentity;
import eu.bcvsolutions.idm.core.model.entity.IdmIdentity_;
import eu.bcvsolutions.idm.core.model.repository.IdmIdentityRepository;
 
@Component
@Description("Filter by identity's username")
public class UsernameIdentityFilter extends AbstractFilterBuilder<IdmIdentity, IdentityFilter> {
 
	@Autowired
	public UsernameIdentityFilter(IdmIdentityRepository repository) {
		super(repository);
	}
 
	@Override
	public String getName() {
		return IdentityFilter.PARAMETER_USERNAME;
	}
 
	@Override
	public Predicate getPredicate(Root<IdmIdentity> root, CriteriaQuery<?> query, CriteriaBuilder builder, IdentityFilter filter) {
		if (filter.getUsername() == null) {
			return null;
		}
		return builder.equal(root.get(IdmIdentity_.username), filter.getUsername());
	}
}

Filters are configurable thanks to interface Configurable via the standard application configuration.

There can be more filters with the same key ⇒ the one that is going to be used can be chosen via configuration item impl. Any module can be registered in this way and also the behaviour of the existing filters, which are implemented via interface FilterBuilder, can be changed.

A generic filter for finding any entity (child of AbstractEntity) by its uuid (parameter in the filter - id).

Finding any entity by its username (parameter in the filter - username).

Finding mangers of the entity by the IR, tree structures and set guarantees. The manager is the identity which has its IR on an organizational structure component superordinate to a structure component of the subordinate's IR. The manager (guarantee) can also be configured directly to the IR.

Filter parameters

  • managersFor - a key parameter; uuid of the subordinate for which the searched are managers
  • managersByTreeType - an additional parameter; if it is entered, the managers are being searched for only by the IR with the given structure type
  • managersByContract - an additional parameter; if it is entered, the managers are being searched for only by the given IR
  • includeGuarantees - true by default ⇒ it is being searched for managers by tree structures and managers (guarantee) configured directly to the IR. False ⇒ only managers by tree structures.

Configuration:

## identity filters
## managers by standard tree structure (manager will be found by contract on parent node)
idm.sec.core.filter.IdmIdentity.managersFor.impl=defaultManagersFilter

Finding subordinates of the entity by the IR, tree structures and set guarantees. The subordinate is the identity which has its IR on an organizational structure component subordinate to a structure component of the manager's IR. The guarantee can also be configured directly to the IR.

Filter parameters

  • subordinatesFor - a key parameter; uuid of the manager for which the searched are subordinates
  • subordinatesByTreeType - an additional parameter; if it is entered, the subordinates are being searched for only by the IR with the given structure type

Configuration:

## identity filters
## subordinates by standard tree structure (manager will be found by contract on parent node)
idm.sec.core.filter.IdmIdentity.subordinatesFor.impl=defaultSubordinatesFilter

The second option for finding managers in the same way as DefaultSubordinatesFilter with a difference that the superordinate component is not being searched for by tree structure but by the value of an extended (eav) tree component parameter - a code of a different component is stated in the tree component, where there are managers (having IR on the given component) defined.

## identity filters
## managers by relation in eav attribute (manager will be found by code in eav on parent node)
idm.sec.core.filter.IdmIdentity.managersFor.impl=eavCodeManagersFilter
# extended form definition code
idm.sec.core.filter.IdmIdentity.managersFor.formDefinition=default
# extended attribute code - value contains superior node code
idm.sec.core.filter.IdmIdentity.managersFor.formAttribute=parentCode

The second option for finding subordinates in the same way as DefaultManagersFilter with a difference that the superordinate component is not being searched for by tree structure but by the value of an extended (eav) tree component parameter - a code of a different component is stated in the tree component, where there are managers (having IR on the given component) defined. Otherwise the functions and parameters are identical.

## identity filters
## subordinates by relation in eav attribute (subordinates will be found by code in eav on parent node)
idm.sec.core.filter.IdmIdentity.subordinatesFor.impl=eavCodeSubordinatesFilter
# extended form definition code
idm.sec.core.filter.IdmIdentity.subordinatesFor.formDefinition=default
# extended attribute code - value contains superior node code
idm.sec.core.filter.IdmIdentity.subordinatesFor.formAttribute=parentCode