001package com.identityworksllc.iiq.common; 002 003import com.fasterxml.jackson.annotation.JsonInclude; 004import com.fasterxml.jackson.core.JsonProcessingException; 005import com.fasterxml.jackson.databind.ObjectMapper; 006import com.fasterxml.jackson.databind.type.MapType; 007import sailpoint.api.SailPointContext; 008import sailpoint.object.*; 009import sailpoint.tools.GeneralException; 010import sailpoint.tools.MapUtil; 011import sailpoint.transformer.IdentityTransformer; 012 013import java.util.HashMap; 014import java.util.Map; 015import java.util.stream.Collectors; 016 017/** 018 * Implements conversion utilities to extract a Map equivalent to a number of 019 * common IIQ objects. These can be passed as arguments to a Rule, for example, 020 * or used via MapMatcher. 021 */ 022public class Mapper { 023 024 /** 025 * Returns the default ObjectMapper instance. 026 * TOOD caching and cloning of the ObjectMapper? 027 * @return The ObjectMapper instance 028 */ 029 private static ObjectMapper getMapper() { 030 return new ObjectMapper(); 031 } 032 033 /** 034 * A static version of the utility implemented via {@link Mappable} 035 * @param anything Whatever object is needed 036 * @return The object converted to a Map 037 * @throws GeneralException if anything fails 038 */ 039 public static Map<String, Object> objectToMap(Object anything) throws GeneralException { 040 if (anything == null) { 041 return new HashMap<>(); 042 } 043 044 ObjectMapper mapper = getMapper(); 045 mapper.addMixIn(anything.getClass(), Mappable.FilterMixin.class); 046 mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 047 048 try { 049 String json = mapper.writeValueAsString(anything); 050 MapType javaType = mapper.getTypeFactory().constructMapType(Map.class, String.class, Object.class); 051 return mapper.readValue(json, javaType); 052 } catch(JsonProcessingException e) { 053 throw new GeneralException(e); 054 } 055 } 056 057 /** 058 * Transforms a Map with path-type keys (e.g., 'link.attributes[a]') to a 059 * model map that has nested keys and values. 060 * 061 * @param input The input map 062 * @return The output map 063 * @throws GeneralException if any failures occur 064 */ 065 public static Map<String, Object> pathMapToModelMap(Map<String, Object> input) throws GeneralException { 066 Map<String, Object> output = new HashMap<>(); 067 068 if (input != null) { 069 for (String key : input.keySet()) { 070 MapUtil.put(output, key, input.get(key)); 071 } 072 } 073 074 return output; 075 } 076 077 /** 078 * Transforms the given SailPointObject into a Map. If the object is one of 079 * the other types handled by this class, forwards to that method. Otherwise, 080 * returns the attributes. 081 * 082 * @param context The context, potentially used to load attributes 083 * @param spo The input object 084 * @return The resulting Map-ified object 085 * @throws GeneralException if any failures occur 086 */ 087 public static Map<String, Object> toMap(SailPointContext context, Object spo) throws GeneralException { 088 Map<String, Object> result = new HashMap<>(); 089 if (spo instanceof Link) { 090 result.putAll(toMap((Link)spo)); 091 } else if (spo instanceof Identity) { 092 result.putAll(toMap(context, (Identity)spo)); 093 } else if (spo instanceof Application) { 094 result.putAll(toMap((Application)spo)); 095 } else if (spo instanceof ProvisioningPlan) { 096 result.putAll(toMap((ProvisioningPlan)spo)); 097 } else if (spo instanceof ProvisioningPlan.AbstractRequest) { 098 result.putAll(toMap((ProvisioningPlan.AbstractRequest)spo)); 099 } else if (spo instanceof ManagedAttribute) { 100 result.putAll(toMap((ManagedAttribute)spo)); 101 } else { 102 Attributes<String, Object> attrs = Utilities.getAttributes(spo); 103 if (attrs != null) { 104 result.putAll(attrs); 105 } 106 } 107 return result; 108 } 109 110 public static Map<String, Object> toMap(AttributeAssignment aa) { 111 Map<String, Object> map = new HashMap<>(); 112 map.put("name", aa.getName()); 113 map.put("application.id", aa.getApplicationId()); 114 map.put("application.name", aa.getApplicationName()); 115 map.put("nativeIdentity", aa.getNativeIdentity()); 116 map.put("type", Utilities.safeString(aa.getType())); 117 map.put("value", aa.getStringValue()); 118 return map; 119 } 120 121 public static Map<String, Object> toMap(Application application) { 122 Map<String, Object> map = new HashMap<>(); 123 if (application.getAttributes() != null) { 124 map.putAll(application.getAttributes()); 125 } 126 map.put("schemas", application.getSchemas()); 127 map.put("accountSchema", application.getAccountSchema()); 128 map.put("name", application.getName()); 129 map.put("id", application.getId()); 130 map.put("connector", application.getConnector()); 131 map.put("features", application.getFeaturesString()); 132 map.put("beforeProvisioningRule", application.getBeforeProvisioningRule()); 133 map.put("afterProvisioningRule", application.getAfterProvisioningRule()); 134 map.put("formPath", application.getFormPath()); 135 if (application.getProxy() != null) { 136 map.put("proxy", toMap(application.getProxy())); 137 } 138 return map; 139 } 140 141 public static Map<String, Object> toMap(ProvisioningPlan.AbstractRequest request) { 142 return request.toMap(); 143 } 144 145 public static Map<String, Object> toMap(ProvisioningPlan plan) { 146 return plan.toMap(); 147 } 148 149 public static Map<String, Object> toMap(SailPointContext context, Identity identity) throws GeneralException { 150 IdentityTransformer transformer = new IdentityTransformer(context); 151 transformer.setLinkExpand(true); 152 return transformer.toMap(identity); 153 } 154 155 public static Map<String, Object> toMap(RoleAssignment ra) { 156 Map<String, Object> map = new HashMap<>(); 157 map.put("name", ra.getRoleName()); 158 map.put("source", ra.getSource()); 159 map.put("comments", ra.getComments()); 160 map.put("assigner", ra.getAssigner()); 161 map.put("assignmentId", ra.getAssignmentId()); 162 map.put("target.application.id", Utilities.safeStream(ra.getTargets()).map(RoleTarget::getApplicationId).collect(Collectors.toList())); 163 map.put("target.application.name", Utilities.safeStream(ra.getTargets()).map(RoleTarget::getApplicationName).collect(Collectors.toList())); 164 map.put("target.nativeIdentity", Utilities.safeStream(ra.getTargets()).map(RoleTarget::getNativeIdentity).collect(Collectors.toList())); 165 map.put("target.displayName", Utilities.safeStream(ra.getTargets()).map(RoleTarget::getDisplayName).collect(Collectors.toList())); 166 return map; 167 } 168 169 public static Map<String, Object> toMap(RoleDetection rd) { 170 Map<String, Object> map = new HashMap<>(); 171 map.put("name", rd.getRoleName()); 172 map.put("assignmentIds", rd.getAssignmentIdList()); 173 map.put("target.application.id", Utilities.safeStream(rd.getTargets()).map(RoleTarget::getApplicationId).collect(Collectors.toList())); 174 map.put("target.application.name", Utilities.safeStream(rd.getTargets()).map(RoleTarget::getApplicationName).collect(Collectors.toList())); 175 map.put("target.nativeIdentity", Utilities.safeStream(rd.getTargets()).map(RoleTarget::getNativeIdentity).collect(Collectors.toList())); 176 map.put("target.displayName", Utilities.safeStream(rd.getTargets()).map(RoleTarget::getDisplayName).collect(Collectors.toList())); 177 return map; 178 } 179 180 public static Map<String, Object> toMap(Link owner, ManagedAttribute ma) { 181 Map<String, Object> map = new HashMap<>(); 182 if (ma.getAttributes() != null) { 183 map.putAll(ma.getAttributes()); 184 } 185 if (owner.getAttributes() != null) { 186 Utilities.safeStream(owner.getAttributes().getKeys()).forEach(k -> { 187 map.put("link." + k, owner.getAttributes().get(k)); 188 }); 189 } 190 map.put("link.instance", owner.getInstance()); 191 map.put("link.nativeIdentity", owner.getNativeIdentity()); 192 map.put("value", ma.getValue()); 193 map.put("displayName", ma.getDisplayName()); 194 map.put("application.name", ma.getApplication().getName()); 195 map.put("application.id", ma.getApplicationId()); 196 map.put("attribute", ma.getAttribute()); 197 return map; 198 } 199 200 201 public static Map<String, Object> toMap(ManagedAttribute ma) { 202 Map<String, Object> map = new HashMap<>(); 203 if (ma.getAttributes() != null) { 204 map.putAll(ma.getAttributes()); 205 } 206 map.put("value", ma.getValue()); 207 map.put("displayName", ma.getDisplayName()); 208 map.put("application.name", ma.getApplication().getName()); 209 map.put("application.id", ma.getApplicationId()); 210 map.put("attribute", ma.getAttribute()); 211 return map; 212 } 213 214 public static Map<String, Object> toMap(Link link) { 215 Map<String, Object> map = new HashMap<>(); 216 if (link.getAttributes() != null) { 217 map.putAll(link.getAttributes()); 218 } 219 map.put("nativeIdentity", link.getNativeIdentity()); 220 map.put("displayName", link.getDisplayableName()); 221 map.put("instance", link.getInstance()); 222 map.put("identity.name", link.getIdentity().getName()); 223 map.put("identity.id", link.getIdentity().getId()); 224 map.put("application.name", link.getApplicationName()); 225 map.put("application.id", link.getApplicationId()); 226 return map; 227 } 228 229}