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

com.pushtechnology.diffusion.client.features.control.clients.SecurityControl Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2023 DiffusionData Ltd., All Rights Reserved.
 *
 * Use is subject to license terms.
 *
 * NOTICE: All information contained herein is, and remains the
 * property of Push Technology. The intellectual and technical
 * concepts contained herein are proprietary to Push Technology and
 * may be covered by U.S. and Foreign Patents, patents in process, and
 * are protected by trade secret or copyright law.
 *******************************************************************************/
package com.pushtechnology.diffusion.client.features.control.clients;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

import com.pushtechnology.diffusion.client.callbacks.Callback;
import com.pushtechnology.diffusion.client.callbacks.ContextCallback;
import com.pushtechnology.diffusion.client.session.PermissionsException;
import com.pushtechnology.diffusion.client.session.Session;
import com.pushtechnology.diffusion.client.session.SessionClosedException;
import com.pushtechnology.diffusion.client.types.GlobalPermission;
import com.pushtechnology.diffusion.client.types.PathPermission;
import com.pushtechnology.diffusion.client.types.TopicPermission;

/**
 * This feature allows a client session to query and update the security store.
 * The security store is a persistent database maintained by the server
 * containing authorisation rules that control what sessions can do.
 * 

* Access rights to read and write data and to perform actions on the server are * controlled by a fixed set of permissions. When a session is opened, the * server assigns it a set of roles based on the principal used to authenticate. * The rules in the security store assign each role to a set of permissions. * Each role can be assigned zero, one, or many permissions. The same permission * can be assigned to multiple roles. Roles can also include other roles to form * a role hierarchy, and so inherit permissions from the other roles. Roles are * defined implicitly by specifying them in permission assignments or inclusion * relationships; there is no need to explicitly create roles in the security * store. *

* Permissions either have 'path' or 'global' scope. {@link GlobalPermission * Global permissions} apply to actions that are server-wide and not specific to * a particular path. {@link PathPermission Path permissions} apply to * hierarchical context, such as a branch of the topic tree or a branch of the * message path hierarchy. * *

Evaluation of global permissions

* * A session has a global permission if any of its roles are assigned the * permission. * *

Evaluation of path permissions

* * A session has a permission for a path if any of its roles have the permission * for the path. * *

* {@link ScriptBuilder#setPathPermissions Path permissions} can be assigned to * a role for a path. The permissions are inherited by all descendant paths for * the role, except paths that have a separate permission assignment for the * role or that are {@link ScriptBuilder#isolatePath(String) isolated} and their * descendant paths. * *

* {@link ScriptBuilder#setDefaultPathPermissions Default path permissions} can * be assigned to a role to set permissions at the root of the path hierarchy. A * default permission assignment applies to all paths without direct or * inherited path permission assignments, except paths that are * {@link ScriptBuilder#isolatePath(String) isolated} and their descendant * paths. * *

* The permissions a session has for a path are determined as follows: * *

    *
  1. If the path has permission assignments for one or more of the sessions * roles, the applicable permissions are the union of all of the assigned * permissions. *
  2. Otherwise, if the path is not isolated, and its parent path has * permission assignments for one or more of the sessions roles, the applicable * permissions are the union of all of the permissions assigned to the parent * path. This rule is applied recursively, for each remaining parent path. *
  3. Otherwise, if the neither the path nor any of its parent paths have * permission assignments for one of the sessions role or are isolated, the * applicable permissions are the union of the default permissions assigned to * each role. *
  4. If no applicable permissions are found, the session has no permissions * for that path. *
* *

Path permission evaluation prior to Diffusion 6.5

* * The way path permissions are evaluated changed in Diffusion 6.5. In previous * releases, permissions assigned to a path for a role blocked the inheritance * of path permissions assigned to other roles. This made it hard to compose * authorisation polices for differing roles. * *

* The path permissions model was changed in Diffusion 6.5 so the set of * permissions granted to a session for a path is formed by independently * evaluating the permissions for each of its roles. * *

* In addition, Diffusion 6.5 added the ability to isolate paths. To convert a * Diffusion 6.4 security store to an equivalent Diffusion 6.5 store, for each * path in a path permission assignment for a role, add a separate statement to * isolate the path. This produces a strictly equivalent model, but in practice * it is typical that many of these path isolation statements can be removed * without affecting an application's security policy, resulting in a simpler * configuration. * *

Access control

* * To query the store the session needs {@link GlobalPermission#VIEW_SECURITY * VIEW_SECURITY} permission and to update the store it needs * {@link GlobalPermission#MODIFY_SECURITY MODIFY_SECURITY} permission. * *

Accessing the feature

* * This feature can be obtained from a {@link Session session} as follows: * *
 * SecurityControl securityControl = session.feature(SecurityControl.class);
 * 
* * @author DiffusionData Limited * @since 5.3 */ public interface SecurityControl extends SecurityStoreFeature { /** * Obtain the current contents of the security store. * * @return a CompletableFuture that completes when a response is received * from the server. * *

* If the request was successful, the CompletableFuture will * complete successfully with a {@link SecurityConfiguration} * result. * *

* Otherwise, the CompletableFuture will complete exceptionally with * a {@link CompletionException}. Common reasons for failure, listed * by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    * *
  • {@link PermissionsException} – if the session does * not have {@code VIEW_SECURITY} permission; * *
  • {@link SessionClosedException} – if the session is * closed. *
* * @since 6.0 */ CompletableFuture getSecurity(); /** * Obtain the current contents of the security store. * * @param callback the operation callback * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void getSecurity(ConfigurationCallback callback); /** * Obtain the current contents of the security store, with a contextual * callback. * * @param context the context to pass to the callback, may be null * * @param callback the operation callback * * @param the context type * * @see #getSecurity(ConfigurationCallback) * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void getSecurity( C context, ConfigurationContextCallback callback); /** * The callback interface for use with * {@link SecurityControl#getSecurity(ConfigurationCallback) getSecurity}. * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated interface ConfigurationCallback extends Callback { /** * This is called to return the requested security configuration. * * @param configuration snapshot of information from the security store */ void onReply(SecurityConfiguration configuration); } /** * The contextual callback interface for use with * {@link SecurityControl#getSecurity(Object, ConfigurationContextCallback) * getSecurity} . * *

* Attaches an arbitrary context object to callback notifications. * * @param the context type * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated interface ConfigurationContextCallback extends ContextCallback { /** * This is called to return the requested security configuration. * * @param configuration snapshot of information from the security store * * @param context the context object supplied when making the call */ void onReply( C context, SecurityConfiguration configuration); } /** * Snapshot of information from the security store. * * @see SecurityControl#getSecurity(ConfigurationCallback) * @see SecurityControl#getSecurity(Object, ConfigurationContextCallback) */ interface SecurityConfiguration { /** * Returns the default set of roles to be assigned to anonymous * sessions. * * @return set of roles. This may be empty. */ Set getRolesForAnonymousSessions(); /** * Returns the default set of roles to be assigned to named sessions. * * @return set of roles. This may be empty. */ Set getRolesForNamedSessions(); /** * Returns a list of the roles defined including their permissions * assignments and included roles. * * @return list of roles */ List getRoles(); /** * Returns the set of isolated paths. * * @see ScriptBuilder#isolatePath(String) * @since 6.5 */ Set getIsolatedPaths(); } /** * Encapsulates the defined details for an individual role. */ interface Role { /** * Returns the role name. * * @return the name */ String getName(); /** * Returns the set of global permissions assigned to the role. * * @return the set of global permissions. This may be empty indicating * that the role has no global permissions assigned. */ Set getGlobalPermissions(); /** * Returns the set of default path permissions assigned to the role. * * @return the set of default path permissions. This may be empty * indicating that the role has no default path permissions * assigned. */ Set getDefaultPathPermissions(); /** * Returns the set of default path permissions assigned to the role. * * @return the set of default path permissions. This may be empty * indicating that the role has no default path permissions * assigned. * @deprecated since 6.5. Use {@link #getDefaultPathPermissions()} * instead. */ @Deprecated Set getDefaultTopicPermissions(); /** * Returns a map of path to path permission assignments for the * role. * * @return a map of paths to path permission assignments. The * returned map may be empty if there are no specific path * permission assignments for the role. Any individual set of * permissions may also be empty if the role has explicitly had * no permissions specified for the path. */ Map> getPathPermissions(); /** * Returns a map of path to path permission assignments for the role. * * @return a map of paths to path permission assignments. The returned * map may be empty if there are no specific path permission * assignments for the role. Any individual set of permissions * may also be empty if the role has explicitly had no * permissions specified for the path. * @deprecated since 6.5. Use {@link #getPathPermissions()} instead. */ @Deprecated Map> getTopicPermissions(); /** * Returns a set of roles included within the role. * * @return included roles. This may be empty if the role includes no * other roles. */ Set getIncludedRoles(); /** * Returns an {@link Optional}, if the role is locked this will return * the name of the principal that can update the role. * * @return the locking principal. This will not return a value if the * role is not locked. */ Optional getLockingPrincipal(); } /** * Returns a builder that can be used to create scripts for use with * {@link SecurityStoreFeature#updateStore updateStore}. * * @return an initial builder that creates an empty script */ ScriptBuilder scriptBuilder(); /** * A script builder may be used to create a script of commands to apply to * the security store at the server. *

* Each method call on the builder adds a line to the script and then the * script may be built using the {@link ScriptBuilder#script() script} * method which produces a String script which may be sent to the server * using {@link SecurityStoreFeature#updateStore updateStore}. *

* Such a builder may be created using the * {@link SecurityControl#scriptBuilder() scriptBuilder} method. *

* From Diffusion 6.5, script builders are no longer immutable. Each builder * operation mutates this script builder and returns it. */ interface ScriptBuilder { /** * Sets the roles to be assigned by default to all anonymous sessions. * * @param roles the roles to be assigned to anonymous sessions. This may * be empty which would mean that no roles are to be assigned by * default to anonymous sessions. * * @return this builder, modified to set the roles for * anonymous sessions */ ScriptBuilder setRolesForAnonymousSessions(Set roles); /** * Sets the roles to be assigned by default to all named sessions. * * @param roles the roles to be assigned to all named sessions. This may * be empty which would mean that no roles are to be assigned by * default to named sessions. * * @return this builder, modified to set the roles for named * sessions */ ScriptBuilder setRolesForNamedSessions(Set roles); /** * Sets the global permissions to be assigned to a role. * * @param role the role * * @param permissions the global permissions to assign to the role. This * set may be empty, in which case the role will be assigned no * global permissions. * * @return this builder, modified to set the global * permissions for the role */ ScriptBuilder setGlobalPermissions( String role, Set permissions); /** * Sets the default path permissions to be assigned to a role. *

* The role will have the given permissions for all paths unless * specifically overridden by path-scoped assignments. * * @param role the role * * @param permissions the default permissions to assigned to the role. * This may be empty, in which case the role will be * assigned no default path permissions. * * @return this builder, modified to set the default path * permissions for the role */ ScriptBuilder setDefaultPathPermissions( String role, Set permissions); /** * Sets the default path permissions to be assigned to a role. *

* The role will have the given permissions for all paths unless * specifically overridden by path-scoped assignments. * * @param role the role * * @param permissions the default permissions to assigned to the role. * This may be empty, in which case the role will be assigned no * default path permissions. * * @return this builder, modified to set the default path * permissions for the role * @deprecated since 6.5. Use {@link #setDefaultPathPermissions} instead. */ @Deprecated ScriptBuilder setDefaultTopicPermissions( String role, Set permissions); /** * Sets specific path permissions to be assigned for a role for a path. * * @param role the role * * @param path specifies the point in the path hierarchy at which the * permissions are to be applied for the role * * @param permissions the permissions to assign to the role for the * path. This may be empty, in which case the role will have no * permissions to the specified path, which is different from not * having a permission assignment for the path (see * {@link #removePathPermissions(String, String)}). * * @return this builder, modified to set the path permissions * for the role at the given path in the path hierarchy */ ScriptBuilder setPathPermissions( String role, String path, Set permissions); /** * Sets specific path permissions to be assigned for a role for a path. * * @param role the role * * @param path specifies the point in the path hierarchy at which the * permissions are to be applied for the role * * @param permissions the permissions to assign to the role for the * path. This may be empty, in which case the role will have no * permissions to the specified path, which is different from not * having a permission assignment for the path (see * {@link #removePathPermissions(String, String)}). * * @return this builder, modified to set the path permissions * for the role at the given path in the path hierarchy * @deprecated since 6.5. Use {@link #setPathPermissions} instead. */ @Deprecated ScriptBuilder setTopicPermissions( String role, String path, Set permissions); /** * Set a path not to inherit path permissions from its parent paths or * the default path permissions. * *

* By default, a path without specific * {@link #setPathPermissions(String, String, Set) path permission * assignments} inherits the permission assignments from the first * parent path that has them. If neither the path nor any of its parent * paths have permission assignments, the * {@link #setDefaultPathPermissions(String, Set) default path * permissions are used}. * * @param path the path * * @return this builder, modified to isolates the given path * in the path hierarchy * @since 6.5 */ ScriptBuilder isolatePath(String path); /** * Re-instate inheritance of path permission assignments from parents of * the given path. * * @param path the path * * @return this builder, modified to re-instates the * inheritance of path permission assignments from parents of * the given path * @see #isolatePath(String) * @since 6.5 */ ScriptBuilder deisolatePath(String path); /** * Removes any path permissions previously assigned to a particular path * for a given role. *

* This is different from setting no path permissions for the path and * role. By removing permissions set for a particular branch of the path * hierarchy, the permissions become inherited from assignments made * against parent paths in the hierarchy or from the default path * permissions. * * @param role the role from which to remove path permissions * * @param path the path for which permissions are to be removed * * @return this builder, modified to removes the path * permissions for the role at the given point in the path * hierarchy */ ScriptBuilder removePathPermissions(String role, String path); /** * Removes any path permissions previously assigned to a particular path * for a given role. *

* This is different from setting no path permissions for the path and * role. By removing permissions set for a particular branch of the path * hierarchy, the permissions become inherited from assignments made * against parent paths in the hierarchy or from the default path * permissions. * * @param role the role from which to remove path permissions * * @param path the path for which permissions are to be removed * * @return this builder, modified to removes the path * permissions for the role at the given point in the path * hierarchy * @deprecated since 6.5. Use {@link #removePathPermissions} instead. */ @Deprecated ScriptBuilder removeTopicPermissions(String role, String path); /** * Sets the roles that are to be included within a specified role. * * @param role the role * * @param includedRoles the roles to include. This may be empty, which * would mean that the given role should not include any other * roles. * * @return this builder, modified to set the given role * relationship */ ScriptBuilder setRoleIncludes(String role, Set includedRoles); /** * Restrict a role so it can only be edited by a specific principal. * * @param role the role * @param lockingPrincipal the locking principal * * @return this builder, modified to locks a role to a single * principal that can edit it */ ScriptBuilder setRoleLockedByPrincipal(String role, String lockingPrincipal); /** * Append all the operations of {@code other} to this ScriptBuilder. * * @return a combined script builder * @since 6.0 */ ScriptBuilder append(ScriptBuilder other); /** * Create a script. * * @return the script */ String script(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy