protected Any<?> update(final Any<?> any, final Boolean enabled) { boolean changepwd; Collection<String> resourceNames; if (any instanceof User) { changepwd = true; resourceNames = userDAO.findAllResourceNames((User) any); } else if (any instanceof AnyObject) { changepwd = false; resourceNames = anyObjectDAO.findAllResourceNames((AnyObject) any); } else { changepwd = false; resourceNames = ((Group) any).getResourceNames(); } List<String> noPropResources = new ArrayList<>(resourceNames); noPropResources.remove(profile.getTask().getResource().getKey()); PropagationByResource propByRes = new PropagationByResource(); propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey()); taskExecutor.execute( propagationManager.getUpdateTasks( any.getType().getKind(), any.getKey(), changepwd, null, propByRes, null, noPropResources)); return getAny(any.getKey()); }
protected void deprovision(final Any<?> any) { AnyTO before = getAnyTO(any.getKey()); List<String> noPropResources = new ArrayList<>(before.getResources()); noPropResources.remove(profile.getTask().getResource().getKey()); taskExecutor.execute( propagationManager.getDeleteTasks( any.getType().getKind(), any.getKey(), null, noPropResources)); }
protected void provision(final Any<?> any, final Boolean enabled) { AnyTO before = getAnyTO(any.getKey()); List<String> noPropResources = new ArrayList<>(before.getResources()); noPropResources.remove(profile.getTask().getResource().getKey()); PropagationByResource propByRes = new PropagationByResource(); propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey()); taskExecutor.execute( propagationManager.getCreateTasks( any.getType().getKind(), any.getKey(), propByRes, before.getVirAttrs(), noPropResources)); }
@SuppressWarnings("unchecked") protected void link(final Any<?> any, final Boolean unlink) { AnyPatch patch = newPatch(any.getKey()); patch .getResources() .add( new StringPatchItem.Builder() .operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE) .value(profile.getTask().getResource().getKey()) .build()); update(patch); }
@Transactional(propagation = Propagation.REQUIRES_NEW) @Override public boolean handle(final long anyKey) { Any<?> any = null; try { any = getAny(anyKey); doHandle(any); return true; } catch (IgnoreProvisionException e) { ProvisioningReport result = new ProvisioningReport(); result.setOperation(ResourceOperation.NONE); result.setAnyType(any == null ? null : any.getType().getKey()); result.setStatus(ProvisioningReport.Status.IGNORE); result.setKey(anyKey); profile.getResults().add(result); LOG.warn("Ignoring during push", e); return true; } catch (JobExecutionException e) { LOG.error("Push failed", e); return false; } }
protected void assign(final Any<?> any, final Boolean enabled) { AnyPatch patch = newPatch(any.getKey()); patch .getResources() .add( new StringPatchItem.Builder() .operation(PatchOperation.ADD_REPLACE) .value(profile.getTask().getResource().getKey()) .build()); update(patch); provision(any, enabled); }
@SuppressWarnings("unchecked") protected void unassign(final Any<?> any) { AnyPatch patch = newPatch(any.getKey()); patch .getResources() .add( new StringPatchItem.Builder() .operation(PatchOperation.DELETE) .value(profile.getTask().getResource().getKey()) .build()); update(patch); deprovision(any); }
protected final void doHandle(final Any<?> any) throws JobExecutionException { AnyUtils anyUtils = anyUtilsFactory.getInstance(any); ProvisioningReport result = new ProvisioningReport(); profile.getResults().add(result); result.setKey(any.getKey()); result.setAnyType(any.getType().getKey()); result.setName(getName(any)); Boolean enabled = any instanceof User && profile.getTask().isSyncStatus() ? ((User) any).isSuspended() ? Boolean.FALSE : Boolean.TRUE : null; LOG.debug( "Propagating {} with key {} towards {}", anyUtils.getAnyTypeKind(), any.getKey(), profile.getTask().getResource()); Object output = null; Result resultStatus = null; String operation = null; // Try to read remote object BEFORE any actual operation Provision provision = profile.getTask().getResource().getProvision(any.getType()); String connObjecKey = mappingUtils.getConnObjectKeyValue(any, provision); ConnectorObject beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass()); Boolean status = profile.getTask().isSyncStatus() ? enabled : null; if (profile.isDryRun()) { if (beforeObj == null) { result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule())); } else { result.setOperation(getResourceOperation(profile.getTask().getMatchingRule())); } result.setStatus(ProvisioningReport.Status.SUCCESS); } else { try { if (beforeObj == null) { operation = UnmatchingRule.toEventName(profile.getTask().getUnmatchingRule()); result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule())); switch (profile.getTask().getUnmatchingRule()) { case ASSIGN: for (PushActions action : profile.getActions()) { action.beforeAssign(this.getProfile(), any); } if (!profile.getTask().isPerformCreate()) { LOG.debug("PushTask not configured for create"); } else { assign(any, status); } break; case PROVISION: for (PushActions action : profile.getActions()) { action.beforeProvision(this.getProfile(), any); } if (!profile.getTask().isPerformCreate()) { LOG.debug("PushTask not configured for create"); } else { provision(any, status); } break; case UNLINK: for (PushActions action : profile.getActions()) { action.beforeUnlink(this.getProfile(), any); } if (!profile.getTask().isPerformUpdate()) { LOG.debug("PushTask not configured for update"); } else { link(any, true); } break; case IGNORE: LOG.debug("Ignored any: {}", any); break; default: // do nothing } } else { operation = MatchingRule.toEventName(profile.getTask().getMatchingRule()); result.setOperation(getResourceOperation(profile.getTask().getMatchingRule())); switch (profile.getTask().getMatchingRule()) { case UPDATE: for (PushActions action : profile.getActions()) { action.beforeUpdate(this.getProfile(), any); } if (!profile.getTask().isPerformUpdate()) { LOG.debug("PushTask not configured for update"); } else { update(any, status); } break; case DEPROVISION: for (PushActions action : profile.getActions()) { action.beforeDeprovision(this.getProfile(), any); } if (!profile.getTask().isPerformDelete()) { LOG.debug("PushTask not configured for delete"); } else { deprovision(any); } break; case UNASSIGN: for (PushActions action : profile.getActions()) { action.beforeUnassign(this.getProfile(), any); } if (!profile.getTask().isPerformDelete()) { LOG.debug("PushTask not configured for delete"); } else { unassign(any); } break; case LINK: for (PushActions action : profile.getActions()) { action.beforeLink(this.getProfile(), any); } if (!profile.getTask().isPerformUpdate()) { LOG.debug("PushTask not configured for update"); } else { link(any, false); } break; case UNLINK: for (PushActions action : profile.getActions()) { action.beforeUnlink(this.getProfile(), any); } if (!profile.getTask().isPerformUpdate()) { LOG.debug("PushTask not configured for update"); } else { link(any, true); } break; case IGNORE: LOG.debug("Ignored any: {}", any); break; default: // do nothing } } for (PushActions action : profile.getActions()) { action.after(this.getProfile(), any, result); } result.setStatus(ProvisioningReport.Status.SUCCESS); resultStatus = AuditElements.Result.SUCCESS; output = getRemoteObject(connObjecKey, provision.getObjectClass()); } catch (IgnoreProvisionException e) { throw e; } catch (Exception e) { result.setStatus(ProvisioningReport.Status.FAILURE); result.setMessage(ExceptionUtils.getRootCauseMessage(e)); resultStatus = AuditElements.Result.FAILURE; output = e; LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e); for (PushActions action : profile.getActions()) { action.onError(this.getProfile(), any, result, e); } throw new JobExecutionException(e); } finally { notificationManager.createTasks( AuditElements.EventCategoryType.PUSH, any.getType().getKind().name().toLowerCase(), profile.getTask().getResource().getKey(), operation, resultStatus, beforeObj, output, any); auditManager.audit( AuditElements.EventCategoryType.PUSH, any.getType().getKind().name().toLowerCase(), profile.getTask().getResource().getKey(), operation, resultStatus, connObjectUtils.getConnObjectTO(beforeObj), output instanceof ConnectorObject ? connObjectUtils.getConnObjectTO((ConnectorObject) output) : output, any); } } }
@SuppressWarnings("unchecked") public <T extends PolicySpec> T evaluate(final Policy policy, final Any<?, ?, ?> any) { if (policy == null) { return null; } T result = null; switch (policy.getType()) { case PASSWORD: PasswordPolicySpec ppSpec = policy.getSpecification(PasswordPolicySpec.class); PasswordPolicySpec evaluatedPPSpec = new PasswordPolicySpec(); BeanUtils.copyProperties(ppSpec, evaluatedPPSpec, new String[] {"schemasNotPermitted"}); for (String schema : ppSpec.getSchemasNotPermitted()) { PlainAttr attr = any.getPlainAttr(schema); if (attr != null) { List<String> values = attr.getValuesAsStrings(); if (values != null && !values.isEmpty()) { evaluatedPPSpec.getWordsNotPermitted().add(values.get(0)); } } } // Password history verification and update if (!(any instanceof User)) { LOG.error( "Cannot check previous passwords. instance is not user object: {}", any.getClass().getName()); result = (T) evaluatedPPSpec; break; } User user = (User) any; if (user.verifyPasswordHistory(user.getClearPassword(), ppSpec.getHistoryLength())) { evaluatedPPSpec.getWordsNotPermitted().add(user.getClearPassword()); } result = (T) evaluatedPPSpec; break; case ACCOUNT: final AccountPolicySpec spec = policy.getSpecification(AccountPolicySpec.class); final AccountPolicySpec accountPolicy = new AccountPolicySpec(); BeanUtils.copyProperties(spec, accountPolicy, new String[] {"schemasNotPermitted"}); for (String schema : spec.getSchemasNotPermitted()) { PlainAttr attr = any.getPlainAttr(schema); if (attr != null) { List<String> values = attr.getValuesAsStrings(); if (values != null && !values.isEmpty()) { accountPolicy.getWordsNotPermitted().add(values.get(0)); } } } result = (T) accountPolicy; break; case SYNC: default: result = null; } return result; }
private Map<VirSchema, List<String>> getValues(final Any<?> any, final Set<VirSchema> schemas) { Collection<? extends ExternalResource> ownedResources = anyUtilsFactory.getInstance(any).getAllResources(any); Map<VirSchema, List<String>> result = new HashMap<>(); Map<Provision, Set<VirSchema>> toRead = new HashMap<>(); for (VirSchema schema : schemas) { if (ownedResources.contains(schema.getProvision().getResource())) { VirAttrCacheValue virAttrCacheValue = virAttrCache.get(any.getType().getKey(), any.getKey(), schema.getKey()); if (virAttrCache.isValidEntry(virAttrCacheValue)) { LOG.debug("Values for {} found in cache: {}", schema, virAttrCacheValue); result.put(schema, virAttrCacheValue.getValues()); } else { Set<VirSchema> schemasToRead = toRead.get(schema.getProvision()); if (schemasToRead == null) { schemasToRead = new HashSet<>(); toRead.put(schema.getProvision(), schemasToRead); } schemasToRead.add(schema); } } else { LOG.debug( "Not considering {} since {} is not assigned to {}", schema, any, schema.getProvision().getResource()); } } for (Map.Entry<Provision, Set<VirSchema>> entry : toRead.entrySet()) { LOG.debug("About to read from {}: {}", entry.getKey(), entry.getValue()); String connObjectKey = MappingUtils.getConnObjectKeyItem(entry.getKey()) == null ? null : mappingManager.getConnObjectKeyValue(any, entry.getKey()); if (StringUtils.isBlank(connObjectKey)) { LOG.error("No ConnObjectKey found for {}, ignoring...", entry.getKey()); } else { Set<MappingItem> linkingMappingItems = new HashSet<>(); for (VirSchema schema : entry.getValue()) { linkingMappingItems.add(schema.asLinkingMappingItem()); } Connector connector = connFactory.getConnector(entry.getKey().getResource()); try { ConnectorObject connectorObject = connector.getObject( entry.getKey().getObjectClass(), new Uid(connObjectKey), MappingUtils.buildOperationOptions(linkingMappingItems.iterator())); if (connectorObject == null) { LOG.debug("No read from {} about {}", entry.getKey(), connObjectKey); } else { for (VirSchema schema : entry.getValue()) { Attribute attr = connectorObject.getAttributeByName(schema.getExtAttrName()); if (attr != null) { VirAttrCacheValue virAttrCacheValue = new VirAttrCacheValue(); virAttrCacheValue.setValues(attr.getValue()); virAttrCache.put( any.getType().getKey(), any.getKey(), schema.getKey(), virAttrCacheValue); LOG.debug("Values for {} set in cache: {}", schema, virAttrCacheValue); result.put(schema, virAttrCacheValue.getValues()); } } } } catch (Exception e) { LOG.error("Error reading from {}", entry.getKey(), e); } } } return result; }