001package com.identityworksllc.iiq.common; 002 003import com.identityworksllc.iiq.common.access.AccessCheck; 004import com.identityworksllc.iiq.common.access.AccessCheckInput; 005import com.identityworksllc.iiq.common.annotation.CoreStable; 006import com.identityworksllc.iiq.common.auth.DummyPluginResource; 007import org.apache.commons.logging.Log; 008import org.apache.commons.logging.LogFactory; 009import sailpoint.api.SailPointContext; 010import sailpoint.object.*; 011import sailpoint.rest.plugin.BasePluginResource; 012import sailpoint.tools.GeneralException; 013import sailpoint.web.UserContext; 014 015import java.util.Map; 016 017/** 018 * Implements the "Common Security" protocol described in the documentation. This 019 * allows more detailed authorization to check access to various objects within IIQ. 020 * 021 * There are two users involved in thing access: an subject Identity and a target 022 * Identity. The subject is the one doing the thing while the target is the one 023 * the thing is being done to. Some actions may be 'self' actions, where both the 024 * subject and the target are the same. Other actions don't have a 'target' concept 025 * and are treated as 'self' actions. 026 * 027 * See the `COMMON-SECURITY.adoc` documentation. 028 * 029 * @see AccessCheck 030 */ 031@CoreStable 032@SuppressWarnings("unused") 033public final class ThingAccessUtils { 034 035 /** 036 * The logger 037 */ 038 private static final Log log = LogFactory.getLog(ThingAccessUtils.class); 039 040 /** 041 * Returns true if the logged in user can access the item based on the Common Security configuration parameters. 042 * 043 * @param pluginContext The plugin context, which provides user details 044 * @param configuration The configuration for the field or button or other object 045 * @return True if the user has access to the thing based on the configuration 046 * @throws GeneralException if any check failures occur (this should be interpreted as "no access") 047 */ 048 public static boolean checkThingAccess(UserContext pluginContext, Map<String, Object> configuration) throws GeneralException { 049 return checkThingAccess(pluginContext, null, AccessCheck.ANONYMOUS_THING, configuration); 050 } 051 052 /** 053 * Returns true if the logged in user can access the item based on the Common Security configuration parameters. 054 * 055 * @param pluginContext The plugin context, which provides user details 056 * @param configuration The configuration for the field or button or other object 057 * @return True if the user has access to the thing based on the configuration 058 * @throws GeneralException if any check failures occur (this should be interpreted as "no access") 059 */ 060 public static boolean checkThingAccess(BasePluginResource pluginContext, Map<String, Object> configuration) throws GeneralException { 061 return checkThingAccess(pluginContext, null, AccessCheck.ANONYMOUS_THING, configuration); 062 } 063 064 /** 065 * Returns true if the logged in user can access the item based on the CommonSecurityConfig object 066 * 067 * @param pluginContext The plugin context, which provides user details 068 * @param config the CommonSecurityConfig object 069 * @return True if the user has access to the thing based on the configuration 070 * @throws GeneralException if any check failures occur (this should be interpreted as "no access") 071 */ 072 public static boolean checkThingAccess(UserContext pluginContext, CommonSecurityConfig config) throws GeneralException { 073 return checkThingAccess(pluginContext, null, AccessCheck.ANONYMOUS_THING, config); 074 } 075 076 /** 077 * Returns true if the logged in user can access the item based on the CommonSecurityConfig object 078 * 079 * @param pluginContext The plugin context, which provides user details 080 * @param config the CommonSecurityConfig object 081 * @return True if the user has access to the thing based on the configuration 082 * @throws GeneralException if any check failures occur (this should be interpreted as "no access") 083 */ 084 public static boolean checkThingAccess(BasePluginResource pluginContext, CommonSecurityConfig config) throws GeneralException { 085 return checkThingAccess(pluginContext, null, AccessCheck.ANONYMOUS_THING, config); 086 } 087 088 /** 089 * Returns true if the logged in user can access the item based on the common configuration parameters. 090 * 091 * @param pluginContext The login context, which provides user details 092 * @param targetIdentity The target identity for the action (as opposed to the actor) 093 * @param configuration The configuration for the field or button or other object 094 * @return True if the user has access to the thing based on the configuration 095 * @throws GeneralException if any check failures occur (this should be interpreted as "no access") 096 */ 097 public static boolean checkThingAccess(UserContext pluginContext, Identity targetIdentity, Map<String, Object> configuration) throws GeneralException { 098 return checkThingAccess(pluginContext, targetIdentity, AccessCheck.ANONYMOUS_THING, configuration); 099 } 100 101 /** 102 * Returns true if the logged in user can access the item based on the common configuration parameters. 103 * 104 * @param pluginContext The plugin context, which provides user details 105 * @param targetIdentity The target identity for the action (as opposed to the actor) 106 * @param configuration The configuration for the field or button or other object 107 * @return True if the user has access to the thing based on the configuration 108 * @throws GeneralException if any check failures occur (this should be interpreted as "no access") 109 */ 110 public static boolean checkThingAccess(BasePluginResource pluginContext, Identity targetIdentity, Map<String, Object> configuration) throws GeneralException { 111 return checkThingAccess(pluginContext, targetIdentity, AccessCheck.ANONYMOUS_THING, configuration); 112 } 113 114 /** 115 * Returns true if the logged in user can access the item based on the common configuration parameters. 116 * 117 * @param pluginContext The plugin context, which provides user details 118 * @param targetIdentity The target identity for the action (as opposed to the actor) 119 * @param configuration The configuration for the field or button or other object 120 * @return True if the user has access to the thing based on the configuration 121 * @throws GeneralException if any check failures occur (this should be interpreted as "no access") 122 */ 123 public static boolean checkThingAccess(BasePluginResource pluginContext, Identity targetIdentity, String thingName, Map<String, Object> configuration) throws GeneralException { 124 return checkThingAccess((UserContext) pluginContext, targetIdentity, AccessCheck.ANONYMOUS_THING, configuration); 125 } 126 127 /** 128 * Returns true if the logged in user can access the item based on the common configuration parameters. 129 * 130 * @param pluginContext A plugin REST API resource (or fake equivalent) used to get some details and settings. This must not be null. 131 * @param targetIdentity The target identity 132 * @param thingName The thing being checked 133 * @param configuration The configuration for the field or button or other object 134 * @return True if the user has access to the thing based on the configuration 135 * @throws GeneralException if any check failures occur (this should be interpreted as "no access") 136 */ 137 public static boolean checkThingAccess(UserContext pluginContext, Identity targetIdentity, String thingName, Map<String, Object> configuration) throws GeneralException { 138 Identity currentUser = pluginContext.getLoggedInUser(); 139 Identity target = targetIdentity; 140 if (target == null) { 141 target = currentUser; 142 } 143 if (configuration == null || configuration.isEmpty()) { 144 Configuration systemConfig = Configuration.getSystemConfig(); 145 boolean defaultDeny = systemConfig.getBoolean("IIQCommon.ThingAccessUtils.denyOnEmpty", false); 146 if (defaultDeny) { 147 log.debug("Configuration for " + thingName + " is empty; assuming that access is NOT allowed"); 148 return false; 149 } else { 150 log.debug("Configuration for " + thingName + " is empty; assuming that access is allowed"); 151 return true; 152 } 153 } 154 CommonSecurityConfig config = CommonSecurityConfig.decode(configuration); 155 return checkThingAccess(pluginContext, target, thingName, config); 156 } 157 158 /** 159 * Returns true if the logged in user can access the item based on the common configuration parameters. 160 * 161 * Results for the same CommonSecurityConfig, source, and target user will be cached for up to one minute 162 * unless the CommonSecurityConfig object has noCache set to true. 163 * 164 * @param pluginContext A plugin REST API resource (or fake equivalent) used to get some details and settings. This must not be null. 165 * @param target The target identity 166 * @param thingName The thing being checked, entirely for logging purposes 167 * @param config The configuration specifying security rights 168 * @return True if the user has access to the thing based on the configuration 169 * @throws GeneralException if any check failures occur (this should be interpreted as "no access") 170 */ 171 public static boolean checkThingAccess(UserContext pluginContext, Identity target, String thingName, CommonSecurityConfig config) throws GeneralException { 172 AccessCheckInput input = new AccessCheckInput(pluginContext, target, thingName, config); 173 174 return AccessCheck.accessCheck(input).isAllowed(); 175 } 176 177 /** 178 * An optional clear-cache method that can be used by plugin code 179 */ 180 public static void clearCachedResults() { 181 AccessCheck.clearCachedResults(); 182 } 183 184 /** 185 * Creates a fake plugin context for use with {@link ThingAccessUtils#checkThingAccess(UserContext, Identity, String, Map)} outside of a plugin. This constructs a new instance of a dummy BasePluginResource web service endpoint class. 186 * @param context The SailPointContext to return from {@link BasePluginResource#getContext()} 187 * @param loggedInUser The Identity to return from various getLoggedIn... methods 188 * @param pluginName The name of the plugin to include in the fake plugin context 189 * @return The fake plugin resource 190 */ 191 public static BasePluginResource createFakePluginContext(final SailPointContext context, final Identity loggedInUser, String pluginName) { 192 return new DummyPluginResource(context, loggedInUser, pluginName); 193 } 194 195}