:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Application Tenancy is the idea that certain information "belongs" to one party and should be either not visible or at least not modifiable by some other party.

The SecMan extension provides a very flexible way of implementing this, through the `ApplicationTenancyEvaluator` SPI.
This allows a domain service to decide whether to hide or to disable each object for the current user.

For example:

[source,java]
----
include::ApplicationTenancyEvaluatorForDemo.java[tags=class]
----
<.> implements the SPI.
There can be multiple implementations; all will be checked.

<.> whether this implementation handles the type of the domain object being considered.
This demo application deals only with the `TenantedJdo` entity type.

<.> whether the current user can view the domain object.

<.> whether the current user can interact (invoke actions, modify the properties of) the domain object.

This demo example doesn't in fact use the current `ApplicationUser` at all.
A typical implementation though can exploit the fact that `ApplicationUser` implements `HasAtPath` and therefore can return an `atPath`: the "application tenancy path":

[source,java]
----
public interface ApplicationUser extends HasAtPath {
    String getAtPath();
    //  ...
}
----

The `atPath` is just a string and can take any format and be processed in any way that makes sense.
One algorithm is to use it to define a hierarchy path, for example "/GBR/LON" represents a user based in London, Great Britain while "/ITA/MIL" is a user based in Milan, Italy.
If the domain object also implements `HasAtPath`, then the `ApplicationTenancyEvaluator` can compare the two ``atPath``s to determine if the location/tenancy of the user is compatible with the location/tenancy of the domain object.

This particular demo though simply uses a regular expression to control visibility and usability, with two properties (to the left-hand side of this page) used to control the domain service.
For example:

[source,java]
----
include::AppTenancyVm.java[tags=hideRegex]
----

[IMPORTANT]
====
This SPI is a presentation-layer concern only.
It does not prevent the domain objects from being retrieved from the data store.

In particular, there is nothing to prevent "malicious" code from retrieving and interacting with objects from another tenancy.
====
