// region Processing model invocation
  @Override
  public HookOperationMode processModelInvocation(
      ModelContext context, Task taskFromModel, OperationResult result) throws SchemaException {

    if (processorConfigurationType.getScenario().isEmpty()) {
      LOGGER.warn("No scenarios for " + getBeanName());
    }

    for (GeneralChangeProcessorScenarioType scenarioType :
        processorConfigurationType.getScenario()) {
      GcpScenarioBean scenarioBean = findScenarioBean(scenarioType.getBeanName());
      if (Boolean.FALSE.equals(scenarioType.isEnabled())) {
        LOGGER.trace("scenario {} is disabled, skipping", scenarioType.getName());
      } else if (!gcpExpressionHelper.evaluateActivationCondition(
          scenarioType, context, taskFromModel, result)) {
        LOGGER.trace(
            "activationCondition was evaluated to FALSE for scenario named {}",
            scenarioType.getName());
      } else if (!scenarioBean.determineActivation(scenarioType, context, taskFromModel, result)) {
        LOGGER.trace("scenarioBean decided to skip scenario named {}", scenarioType.getName());
      } else {
        LOGGER.trace(
            "Applying scenario {} (process name {})",
            scenarioType.getName(),
            scenarioType.getProcessName());
        return applyScenario(scenarioType, scenarioBean, context, taskFromModel, result);
      }
    }
    LOGGER.trace("No scenario found to be applicable, exiting the change processor.");
    return HookOperationMode.FOREGROUND;
  }
  /* (non-Javadoc)
   * @see javax.xml.xpath.XPathFunctionResolver#resolveFunction(javax.xml.namespace.QName, int)
   */
  @Override
  public XPathFunction resolveFunction(QName functionQName, int arity) {
    boolean enableDebug = false;
    String namespace = functionQName.getNamespaceURI();
    if (StringUtils.isEmpty(namespace)) {
      namespace = MidPointConstants.NS_FUNC_BASIC;
      enableDebug = true;
    } else if (namespace.equals(MidPointConstants.NS_FUNC_BASIC)) {
      enableDebug = true;
    }

    FunctionLibrary lib = findLibrary(namespace);
    if (lib == null) {
      LOGGER.trace(
          "Unknown namespace for function {} function with {} arguments", functionQName, arity);
      return null;
    }

    Object functionObject = null;
    if (lib.getXmlFunctions() != null) {
      functionObject = lib.getXmlFunctions();
    } else {
      functionObject = lib.getGenericFunctions();
    }

    String functionName = functionQName.getLocalPart();

    LOGGER.trace("Resolving to {} function with {} arguments", functionName, arity);
    ReflectionXPathFunctionWrapper xPathFunction =
        new ReflectionXPathFunctionWrapper(functionObject, functionName, arity, enableDebug);
    return xPathFunction;
  }
 private void log(String message, Object... params) {
   if (LOGGER.isTraceEnabled()) {
     LOGGER.trace(message, params);
   }
   if (PERFORMANCE_ADVISOR.isTraceEnabled()) {
     PERFORMANCE_ADVISOR.trace(message, params);
   }
 }
  <F extends ObjectType> void processPasswordPolicy(
      LensProjectionContext projectionContext,
      LensContext<F> context,
      Task task,
      OperationResult result)
      throws SchemaException, PolicyViolationException {

    ObjectDelta accountDelta = projectionContext.getDelta();

    if (accountDelta == null) {
      LOGGER.trace("Skipping processing password policies. Shadow delta not specified.");
      return;
    }

    if (ChangeType.DELETE == accountDelta.getChangeType()) {
      return;
    }

    PrismObject<ShadowType> accountShadow = null;
    PrismProperty<PasswordType> password = null;
    if (ChangeType.ADD == accountDelta.getChangeType()) {
      accountShadow = accountDelta.getObjectToAdd();
      if (accountShadow != null) {
        password = accountShadow.findProperty(SchemaConstants.PATH_PASSWORD_VALUE);
      }
    }
    if (ChangeType.MODIFY == accountDelta.getChangeType() || password == null) {
      PropertyDelta<PasswordType> passwordValueDelta = null;
      if (accountDelta != null) {
        passwordValueDelta = accountDelta.findPropertyDelta(SchemaConstants.PATH_PASSWORD_VALUE);
        // Modification sanity check
        if (accountDelta.getChangeType() == ChangeType.MODIFY
            && passwordValueDelta != null
            && (passwordValueDelta.isAdd() || passwordValueDelta.isDelete())) {
          throw new SchemaException(
              "Shadow password value cannot be added or deleted, it can only be replaced");
        }
        if (passwordValueDelta == null) {
          LOGGER.trace(
              "Skipping processing password policies. Shadow delta does not contain password change.");
          return;
        }
        password = (PrismProperty<PasswordType>) passwordValueDelta.getItemNewMatchingPath(null);
      }
    }

    //		PrismProperty<PasswordType> password = getPassword(projectionContext);
    ValuePolicyType passwordPolicy = null;
    if (isCheckOrgPolicy(context)) {
      passwordPolicy = determineValuePolicy(context.getFocusContext().getObjectAny(), task, result);
      context.getFocusContext().setOrgPasswordPolicy(passwordPolicy);
    } else {
      passwordPolicy = projectionContext.getEffectivePasswordPolicy();
    }

    processPasswordPolicy(passwordPolicy, password, result);
  }
  // TODO: maybe some caching of orgs?????
  private <T extends ObjectType, F extends ObjectType> ValuePolicyType determineValuePolicy(
      ObjectDelta<UserType> userDelta,
      PrismObject<T> object,
      LensContext<F> context,
      Task task,
      OperationResult result)
      throws SchemaException {
    // check the modification of organization first
    ValuePolicyType valuePolicy = determineValuePolicy(userDelta, task, result);

    // if null, check the existing organization
    if (valuePolicy == null) {
      valuePolicy = determineValuePolicy(object, task, result);
    }

    // if still null, just use global policy
    if (valuePolicy == null) {
      valuePolicy = context.getEffectivePasswordPolicy();
    }

    if (valuePolicy != null) {
      LOGGER.trace(
          "Value policy {} will be user to check password.", valuePolicy.getName().getOrig());
    }

    return valuePolicy;
  }
Example #6
0
 private static void addMapping(Class javaClass, QName xsdType, boolean both) {
   LOGGER.trace("Adding XSD type mapping {} {} {} ", javaClass, both ? "<->" : " ->", xsdType);
   javaToXsdTypeMap.put(javaClass, xsdType);
   if (both) {
     xsdToJavaTypeMap.put(xsdType, javaClass);
   }
 }
  public static InputStream createReport(
      ReportOutputType report,
      AjaxDownloadBehaviorFromStream ajaxDownloadBehaviorFromStream,
      PageBase pageBase) {
    OperationResult result = new OperationResult(OPERATION_DOWNLOAD_REPORT);
    ReportManager reportManager = pageBase.getReportManager();

    if (report == null) {
      return null;
    }

    String contentType = reportExportTypeMap.get(report.getExportType());
    if (StringUtils.isEmpty(contentType)) {
      contentType = "multipart/mixed; charset=UTF-8";
    }
    ajaxDownloadBehaviorFromStream.setContentType(contentType);

    InputStream input = null;
    try {
      input = reportManager.getReportOutputData(report.getOid(), result);
    } catch (Exception e) {
      pageBase.error(
          pageBase.getString("pageCreatedReports.message.downloadError") + " " + e.getMessage());
      LoggingUtils.logUnexpectedException(LOGGER, "Couldn't download report.", e);
      LOGGER.trace(result.debugDump());
    } finally {
      result.computeStatusIfUnknown();
    }

    if (WebComponentUtil.showResultInPage(result)) {
      pageBase.showResult(result);
    }

    return input;
  }
 @PostConstruct
 private void initialize() {
   if (LOGGER.isTraceEnabled()) {
     LOGGER.trace("Registering with taskManager as a handler for " + MODEL_OPERATION_TASK_URI);
   }
   taskManager.registerHandler(MODEL_OPERATION_TASK_URI, this);
 }
Example #9
0
  private InputStream createReport() {
    OperationResult result = new OperationResult(OPERATION_DOWNLOAD_REPORT);
    ReportManager reportManager = getReportManager();

    if (currentReport == null) {
      return null;
    }

    InputStream input = null;
    try {
      input = reportManager.getReportOutputData(currentReport.getOid(), result);
    } catch (Exception e) {
      error(getString("pageCreatedReports.message.downloadError") + " " + e.getMessage());
      LoggingUtils.logException(LOGGER, "Couldn't download report.", e);
      LOGGER.trace(result.debugDump());
    } finally {
      result.computeStatusIfUnknown();
    }

    if (WebMiscUtil.showResultInPage(result)) {
      showResultInSession(result);
    }

    return input;
  }
Example #10
0
  private void updateDebugPerformed(AjaxRequestTarget target) {
    internalsModel.getObject().saveDebugUtil();

    LOGGER.trace("Updated debug util, detailedDebugDump={}", DebugUtil.isDetailedDebugDump());
    success(
        getString("PageInternals.message.debugUpdatePerformed", DebugUtil.isDetailedDebugDump()));
    target.add(getFeedbackPanel(), getDebugUtilForm());
  }
  /** Remove the intermediate results of values processing such as secondary deltas. */
  private <F extends FocusType> void cleanupContext(LensFocusContext<F> focusContext)
      throws SchemaException {
    // We must NOT clean up activation computation. This has happened before, it will not happen
    // again
    // and it does not depend on iteration
    LOGGER.trace("Cleaning up focus context");
    focusContext.setProjectionWaveSecondaryDelta(null);

    focusContext.clearIntermediateResults();
    focusContext.recompute();
  }
  /**
   * Check whether system configuration has not changed in repository (e.g. by another node in
   * cluster). Applies new configuration if so.
   *
   * @param parentResult
   */
  public void checkSystemConfigurationChanged(OperationResult parentResult) {

    OperationResult result = parentResult.createSubresult(CHECK_SYSTEM_CONFIGURATION_CHANGED);

    PrismObject<SystemConfigurationType> systemConfiguration;
    try {
      PrismObject<SystemConfigurationType> config =
          getRepositoryService()
              .getObject(
                  SystemConfigurationType.class,
                  SystemObjectsType.SYSTEM_CONFIGURATION.value(),
                  null,
                  result);

      String versionInRepo = config.getVersion();
      String versionApplied = LoggingConfigurationManager.getCurrentlyUsedVersion();

      // we do not try to determine which one is "newer" - we simply use the one from repo
      if (!versionInRepo.equals(versionApplied)) {
        LoggingConfigurationType loggingConfig =
            ProfilingConfigurationManager.checkSystemProfilingConfiguration(config);
        LoggingConfigurationManager.configure(loggingConfig, versionInRepo, result);
      } else {
        if (LOGGER.isTraceEnabled()) {
          LOGGER.trace(
              "System configuration change check: version in repo = version currently applied = {}",
              versionApplied);
        }
      }

      if (result.isUnknown()) {
        result.computeStatus();
      }

    } catch (ObjectNotFoundException e) {
      LoggingConfigurationManager
          .resetCurrentlyUsedVersion(); // because the new config (if any) will have version number
                                        // probably starting at 1 - so to be sure to read it when it
                                        // comes [hope this never occurs :)]
      String message = "No system configuration found, skipping application of system settings";
      LOGGER.error(message + ": " + e.getMessage(), e);
      result.recordWarning(message, e);
    } catch (SchemaException e) {
      String message =
          "Schema error in system configuration, skipping application of system settings";
      LOGGER.error(message + ": " + e.getMessage(), e);
      result.recordWarning(message, e);
    } catch (RuntimeException e) {
      String message =
          "Runtime exception in system configuration processing, skipping application of system settings";
      LOGGER.error(message + ": " + e.getMessage(), e);
      result.recordWarning(message, e);
    }
  }
Example #13
0
  private <T extends ObjectFilter> Restriction findAndCreateRestriction(
      T filter, InterpretationContext context, Restriction parent) throws QueryException {

    Validate.notNull(filter, "filter");
    Validate.notNull(context, "context");

    LOGGER.trace("Determining restriction for filter {}", filter);

    ItemPathResolver helper = context.getItemPathResolver();
    JpaEntityDefinition baseEntityDefinition;
    if (parent != null) {
      baseEntityDefinition = parent.getBaseHqlEntityForChildren().getJpaDefinition();
    } else {
      baseEntityDefinition = context.getRootEntityDefinition();
    }
    Restriction restriction =
        findAndCreateRestrictionInternal(filter, context, parent, helper, baseEntityDefinition);

    LOGGER.trace("Restriction for {} is {}", filter.getClass().getSimpleName(), restriction);
    return restriction;
  }
  @Override
  public void notify(DelegateTask delegateTask) {

    if (LOGGER.isTraceEnabled()) {
      LOGGER.trace(
          "notify called; event name = {}, name = {}",
          delegateTask.getEventName(),
          delegateTask.getName());
    }

    ActivitiInterface activitiInterface = SpringApplicationContextHolder.getActivitiInterface();
    activitiInterface.notifyMidpointAboutTaskEvent(delegateTask);
  }
  private ValuePolicyType determineValuePolicy(
      ObjectDelta<UserType> userDelta, Task task, OperationResult result) throws SchemaException {
    ReferenceDelta orgDelta = userDelta.findReferenceModification(UserType.F_PARENT_ORG_REF);
    ValuePolicyType passwordPolicy = null;
    LOGGER.trace("Determining password policy from org delta.");
    if (orgDelta != null) {
      PrismReferenceValue orgRefValue = orgDelta.getAnyValue();

      try {
        PrismObject<OrgType> org =
            resolver.resolve(orgRefValue, "resolving parent org ref", null, null, result);
        OrgType orgType = org.asObjectable();
        ObjectReferenceType ref = orgType.getPasswordPolicyRef();
        if (ref != null) {
          LOGGER.trace("Org {} has specified password policy.", orgType);
          passwordPolicy =
              resolver.resolve(
                  ref,
                  ValuePolicyType.class,
                  null,
                  "resolving password policy for organization",
                  task,
                  result);
          LOGGER.trace("Resolved password policy {}", passwordPolicy);
        }

        if (passwordPolicy == null) {
          passwordPolicy = determineValuePolicy(org, task, result);
        }

      } catch (ObjectNotFoundException e) {
        throw new IllegalStateException(e);
      }
    }

    return passwordPolicy;
  }
Example #16
0
 private void traceFailure(
     ExpressionEvaluationContext context, ExpressionVariables processedVariables, Exception e) {
   LOGGER.error(
       "Error evaluating expression in {}: {}",
       new Object[] {context.getContextDescription(), e.getMessage(), e});
   if (!LOGGER.isTraceEnabled()) {
     return;
   }
   StringBuilder sb = new StringBuilder();
   sb.append("Expression failure:\n");
   appendTraceHeader(sb, context, processedVariables);
   sb.append("\nERROR: ").append(e.getClass().getSimpleName()).append(": ").append(e.getMessage());
   appendTraceFooter(sb);
   LOGGER.trace(sb.toString());
 }
Example #17
0
  public RootHibernateQuery interpret(
      ObjectQuery query,
      Class<? extends Containerable> type,
      Collection<SelectorOptions<GetOperationOptions>> options,
      PrismContext prismContext,
      boolean countingObjects,
      Session session)
      throws QueryException {
    Validate.notNull(type, "Type must not be null.");
    Validate.notNull(session, "Session must not be null.");
    Validate.notNull(prismContext, "Prism context must not be null.");

    if (LOGGER.isTraceEnabled()) {
      LOGGER.trace("Interpreting query for type '{}', query:\n{}", new Object[] {type, query});
    }

    InterpretationContext context = new InterpretationContext(this, type, prismContext, session);

    interpretQueryFilter(context, query);
    interpretPagingAndSorting(context, query, countingObjects);

    RootHibernateQuery hibernateQuery = context.getHibernateQuery();

    if (countingObjects) {
      hibernateQuery.addProjectionElement(new ProjectionElement("count(*)"));
    } else {
      String rootAlias = hibernateQuery.getPrimaryEntityAlias();
      hibernateQuery.addProjectionElement(new ProjectionElement(rootAlias + ".fullObject"));
      // TODO other objects if parent is requested?
      if (context.isObject()) {
        hibernateQuery.addProjectionElement(new ProjectionElement(rootAlias + ".stringsCount"));
        hibernateQuery.addProjectionElement(new ProjectionElement(rootAlias + ".longsCount"));
        hibernateQuery.addProjectionElement(new ProjectionElement(rootAlias + ".datesCount"));
        hibernateQuery.addProjectionElement(new ProjectionElement(rootAlias + ".referencesCount"));
        hibernateQuery.addProjectionElement(new ProjectionElement(rootAlias + ".polysCount"));
        hibernateQuery.addProjectionElement(new ProjectionElement(rootAlias + ".booleansCount"));
        hibernateQuery.setResultTransformer(GetObjectResult.RESULT_TRANSFORMER);
      } else {
        hibernateQuery.addProjectionElement(new ProjectionElement(rootAlias + ".ownerOid"));
        hibernateQuery.setResultTransformer(GetContainerableResult.RESULT_TRANSFORMER);
      }
    }

    return hibernateQuery;
  }
  void processPasswordPolicy(
      ValuePolicyType passwordPolicy, PrismProperty password, OperationResult result)
      throws PolicyViolationException, SchemaException {

    if (passwordPolicy == null) {
      LOGGER.trace("Skipping processing password policies. Password policy not specified.");
      return;
    }

    String passwordValue = determinePasswordValue(password);

    boolean isValid = PasswordPolicyUtils.validatePassword(passwordValue, passwordPolicy, result);

    if (!isValid) {
      result.computeStatus();
      throw new PolicyViolationException(
          "Provided password does not satisfy password policies. " + result.getMessage());
    }
  }
Example #19
0
 private void traceSuccess(
     ExpressionEvaluationContext context,
     ExpressionVariables processedVariables,
     PrismValueDeltaSetTriple<V> outputTriple) {
   if (!LOGGER.isTraceEnabled()) {
     return;
   }
   StringBuilder sb = new StringBuilder();
   sb.append("Expression trace:\n");
   appendTraceHeader(sb, context, processedVariables);
   sb.append("\nResult: ");
   if (outputTriple == null) {
     sb.append("null");
   } else {
     sb.append(outputTriple.toHumanReadableString());
   }
   appendTraceFooter(sb);
   LOGGER.trace(sb.toString());
 }
Example #20
0
  private void updateInternalConfig(AjaxRequestTarget target) {
    internalsModel.getObject().saveInternalsConfig();

    LOGGER.trace(
        "Updated internals config, consistencyChecks={},encryptionChecks={},readEncryptionChecks={}, QNameUtil.tolerateUndeclaredPrefixes={}",
        new Object[] {
          InternalsConfig.consistencyChecks,
          InternalsConfig.encryptionChecks,
          InternalsConfig.readEncryptionChecks,
          QNameUtil.isTolerateUndeclaredPrefixes()
        });
    success(
        getString(
            "PageInternals.message.internalsConfigUpdate",
            InternalsConfig.consistencyChecks,
            InternalsConfig.encryptionChecks,
            InternalsConfig.readEncryptionChecks,
            QNameUtil.isTolerateUndeclaredPrefixes()));
    target.add(getFeedbackPanel(), getInternalsConfigForm());
  }
  // region Finalizing the processing
  @Override
  public void onProcessEnd(ProcessEvent event, Job job, OperationResult result)
      throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException {

    Task task = job.getTask();
    // we simply put model context back into parent task
    // (or if it is null, we set the task to skip model context processing)

    // it is safe to directly access the parent, because (1) it is in waiting state, (2) we are its
    // only child

    Task rootTask = task.getParentTask(result);

    SerializationSafeContainer<LensContextType> contextContainer =
        (SerializationSafeContainer<LensContextType>)
            event.getVariable(GcpProcessVariableNames.VARIABLE_MODEL_CONTEXT);
    LensContextType lensContextType = null;
    if (contextContainer != null) {
      contextContainer.setPrismContext(prismContext);
      lensContextType = contextContainer.getValue();
    }

    if (lensContextType == null) {
      LOGGER.debug(
          GcpProcessVariableNames.VARIABLE_MODEL_CONTEXT
              + " not present in process, this means we should stop processing. Task = {}",
          rootTask);
      wfTaskUtil.setSkipModelContextProcessingProperty(rootTask, true, result);
    } else {
      LOGGER.debug(
          "Putting (changed or unchanged) value of {} into the task {}",
          GcpProcessVariableNames.VARIABLE_MODEL_CONTEXT,
          rootTask);
      wfTaskUtil.storeModelContext(
          rootTask, lensContextType.asPrismContainerValue().getContainer());
    }

    rootTask.savePendingModifications(result);
    LOGGER.trace("onProcessEnd ending for task {}", task);
  }
  private ValuePolicyType determineValuePolicy(
      PrismObject object, Task task, OperationResult result) throws SchemaException {
    LOGGER.trace("Determining password policies from object", object);
    PrismReference orgRef = object.findReference(ObjectType.F_PARENT_ORG_REF);
    if (orgRef == null) {
      return null;
    }
    List<PrismReferenceValue> values = orgRef.getValues();
    ValuePolicyType valuePolicy = null;
    List<PrismObject<OrgType>> orgs = new ArrayList<PrismObject<OrgType>>();
    try {
      for (PrismReferenceValue orgRefValue : values) {
        if (orgRefValue != null) {

          if (valuePolicy != null) {
            throw new IllegalStateException(
                "Found more than one policy while trying to validate user's password. Please check your configuration");
          }

          PrismObject<OrgType> org =
              resolver.resolve(orgRefValue, "resolving parent org ref", null, null, result);
          orgs.add(org);
          valuePolicy = resolvePolicy(org, task, result);
        }
      }
    } catch (ObjectNotFoundException ex) {
      throw new IllegalStateException(ex);
    }
    // go deeper
    if (valuePolicy == null) {
      for (PrismObject<OrgType> orgType : orgs) {
        valuePolicy = determineValuePolicy(orgType, task, result);
        if (valuePolicy != null) {
          return valuePolicy;
        }
      }
    }
    return valuePolicy;
  }
  @Override
  public void initSystem(Task initTask, OperationResult initResult) throws Exception {
    super.initSystem(initTask, initResult);
    LOGGER.trace("initSystem");

    // Resources
    File targetDir = new File(TEST_TARGET_DIR);
    if (!targetDir.exists()) {
      targetDir.mkdirs();
    }

    MiscUtil.copyFile(new File(BROKEN_CSV_SOURCE_FILE_NAME), new File(BROKEN_CSV_TARGET_FILE_NAME));

    repoAddObjectFromFile(CONNECTOR_DUMMY_NOJARS_FILENAME, ConnectorType.class, initResult);

    dummyResourceCtl = DummyResourceContoller.create(null);
    dummyResourceCtl.extendSchemaPirate();
    dummyResource = dummyResourceCtl.getDummyResource();

    resourceDummy =
        importAndGetObjectFromFile(
            ResourceType.class, RESOURCE_DUMMY_FILE, RESOURCE_DUMMY_OID, initTask, initResult);
    resourceDummyType = resourceDummy.asObjectable();
    dummyResourceCtl.setResource(resourceDummy);

    importObjectFromFile(RESOURCE_CSVFILE_BROKEN_FILENAME, initResult);
    importObjectFromFile(RESOURCE_CSVFILE_NOTFOUND_FILENAME, initResult);
    importObjectFromFile(RESOURCE_DUMMY_NOJARS_FILENAME, initResult);

    // Accounts
    repoAddObjectFromFile(ACCOUNT_SHADOW_MURRAY_CSVFILE_FILENAME, ShadowType.class, initResult);

    // Users
    userTypeJack = repoAddObjectFromFile(USER_JACK_FILE, UserType.class, initResult).asObjectable();

    assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE);
  }
  <F extends FocusType> void processPasswordPolicy(
      LensFocusContext<F> focusContext, LensContext<F> context, Task task, OperationResult result)
      throws PolicyViolationException, SchemaException {

    if (!UserType.class.isAssignableFrom(focusContext.getObjectTypeClass())) {
      LOGGER.trace("Skipping processing password policies because focus is not user");
      return;
    }

    //		PrismProperty<PasswordType> password = getPassword(focusContext);
    ObjectDelta userDelta = focusContext.getDelta();

    if (userDelta == null) {
      LOGGER.trace("Skipping processing password policies. User delta not specified.");
      return;
    }

    if (userDelta.isDelete()) {
      LOGGER.trace("Skipping processing password policies. User will be deleted.");
      return;
    }

    PrismProperty<PasswordType> password = null;
    PrismObject<F> user;
    if (ChangeType.ADD == userDelta.getChangeType()) {
      user = focusContext.getDelta().getObjectToAdd();
      if (user != null) {
        password = user.findProperty(SchemaConstants.PATH_PASSWORD_VALUE);
      }
      if (password == null) {
        if (wasExecuted(userDelta, focusContext)) {
          LOGGER.trace(
              "Skipping processing password policies. User addition was already executed.");
          return;
        }
      }
    } else if (ChangeType.MODIFY == userDelta.getChangeType()) {
      PropertyDelta<PasswordType> passwordValueDelta;
      if (userDelta != null) {
        passwordValueDelta = userDelta.findPropertyDelta(SchemaConstants.PATH_PASSWORD_VALUE);
        if (passwordValueDelta == null) {
          LOGGER.trace(
              "Skipping processing password policies. User delta does not contain password change.");
          return;
        }
        if (userDelta.getChangeType() == ChangeType.MODIFY && passwordValueDelta != null) {
          if (passwordValueDelta.isAdd()) {
            password =
                (PrismProperty<PasswordType>) passwordValueDelta.getItemNewMatchingPath(null);
          } else if (passwordValueDelta.isDelete()) {
            password = null;
          } else {
            password =
                (PrismProperty<PasswordType>) passwordValueDelta.getItemNewMatchingPath(null);
          }
        } else {
          password = (PrismProperty<PasswordType>) passwordValueDelta.getItemNewMatchingPath(null);
        }
      }
    }

    ValuePolicyType passwordPolicy;
    if (focusContext.getOrgPasswordPolicy() == null) {
      passwordPolicy =
          determineValuePolicy(userDelta, focusContext.getObjectAny(), context, task, result);
      focusContext.setOrgPasswordPolicy(passwordPolicy);
    } else {
      passwordPolicy = focusContext.getOrgPasswordPolicy();
    }

    processPasswordPolicy(passwordPolicy, password, result);
  }
  @Override
  public void initSystem(Task initTask, OperationResult initResult) throws Exception {
    LOGGER.trace("initSystem");
    super.initSystem(initTask, initResult);

    mappingFactory.setProfiling(true);
    lensDebugListener = new ProfilingLensDebugListener();
    clockwork.setDebugListener(lensDebugListener);

    // Resources

    dummyResourceCtl = DummyResourceContoller.create(null);
    dummyResourceCtl.extendSchemaPirate();
    dummyResource = dummyResourceCtl.getDummyResource();
    dummyResourceCtl.addAttrDef(
        dummyResource.getAccountObjectClass(),
        DUMMY_ACCOUNT_ATTRIBUTE_SEA_NAME,
        String.class,
        false,
        false);
    resourceDummy =
        importAndGetObjectFromFile(
            ResourceType.class, getResourceDummyFile(), RESOURCE_DUMMY_OID, initTask, initResult);
    resourceDummyType = resourceDummy.asObjectable();
    dummyResourceCtl.setResource(resourceDummy);

    dummyResourceCtlRed = DummyResourceContoller.create(RESOURCE_DUMMY_RED_NAME, resourceDummyRed);
    dummyResourceCtlRed.extendSchemaPirate();
    dummyResourceRed = dummyResourceCtlRed.getDummyResource();
    resourceDummyRed =
        importAndGetObjectFromFile(
            ResourceType.class,
            RESOURCE_DUMMY_RED_FILE,
            RESOURCE_DUMMY_RED_OID,
            initTask,
            initResult);
    resourceDummyRedType = resourceDummyRed.asObjectable();
    dummyResourceCtlRed.setResource(resourceDummyRed);

    dummyResourceCtlBlue =
        DummyResourceContoller.create(RESOURCE_DUMMY_BLUE_NAME, resourceDummyBlue);
    dummyResourceCtlBlue.extendSchemaPirate();
    dummyResourceBlue = dummyResourceCtlBlue.getDummyResource();
    resourceDummyBlue =
        importAndGetObjectFromFile(
            ResourceType.class,
            getResourceDummyBlueFile(),
            RESOURCE_DUMMY_BLUE_OID,
            initTask,
            initResult);
    resourceDummyBlueType = resourceDummyBlue.asObjectable();
    dummyResourceCtlBlue.setResource(resourceDummyBlue);

    dummyResourceCtlWhite =
        DummyResourceContoller.create(RESOURCE_DUMMY_WHITE_NAME, resourceDummyWhite);
    dummyResourceCtlWhite.extendSchemaPirate();
    dummyResourceWhite = dummyResourceCtlWhite.getDummyResource();
    resourceDummyWhite =
        importAndGetObjectFromFile(
            ResourceType.class,
            RESOURCE_DUMMY_WHITE_FILENAME,
            RESOURCE_DUMMY_WHITE_OID,
            initTask,
            initResult);
    resourceDummyWhiteType = resourceDummyWhite.asObjectable();
    dummyResourceCtlWhite.setResource(resourceDummyWhite);

    dummyResourceCtlYellow =
        DummyResourceContoller.create(RESOURCE_DUMMY_YELLOW_NAME, resourceDummyYellow);
    dummyResourceCtlYellow.extendSchemaPirate();
    dummyResourceYellow = dummyResourceCtlYellow.getDummyResource();
    resourceDummyYellow =
        importAndGetObjectFromFile(
            ResourceType.class,
            RESOURCE_DUMMY_YELLOW_FILENAME,
            RESOURCE_DUMMY_YELLOW_OID,
            initTask,
            initResult);
    resourceDummyYellowType = resourceDummyYellow.asObjectable();
    dummyResourceCtlYellow.setResource(resourceDummyYellow);

    dummyResourceCtlGreen =
        DummyResourceContoller.create(RESOURCE_DUMMY_GREEN_NAME, resourceDummyGreen);
    dummyResourceCtlGreen.extendSchemaPirate();
    dummyResourceGreen = dummyResourceCtlGreen.getDummyResource();
    resourceDummyGreen =
        importAndGetObjectFromFile(
            ResourceType.class,
            getResourceDummyGreenFile(),
            RESOURCE_DUMMY_GREEN_OID,
            initTask,
            initResult);
    resourceDummyGreenType = resourceDummyGreen.asObjectable();
    dummyResourceCtlGreen.setResource(resourceDummyGreen);

    dummyResourceCtlBlack =
        DummyResourceContoller.create(RESOURCE_DUMMY_BLACK_NAME, resourceDummyBlack);
    dummyResourceCtlBlack.extendSchemaPirate();
    dummyResourceBlack = dummyResourceCtlBlack.getDummyResource();
    resourceDummyBlack =
        importAndGetObjectFromFile(
            ResourceType.class,
            RESOURCE_DUMMY_BLACK_FILENAME,
            RESOURCE_DUMMY_BLACK_OID,
            initTask,
            initResult);
    resourceDummyBlackType = resourceDummyBlack.asObjectable();
    dummyResourceCtlBlack.setResource(resourceDummyBlack);

    dummyResourceCtlOrange =
        DummyResourceContoller.create(RESOURCE_DUMMY_ORANGE_NAME, resourceDummyOrange);
    dummyResourceCtlOrange.extendSchemaPirate();
    dummyResourceOrange = dummyResourceCtlOrange.getDummyResource();
    resourceDummyOrange =
        importAndGetObjectFromFile(
            ResourceType.class,
            RESOURCE_DUMMY_ORANGE_FILENAME,
            RESOURCE_DUMMY_ORANGE_OID,
            initTask,
            initResult);
    resourceDummyOrangeType = resourceDummyOrange.asObjectable();
    dummyResourceCtlOrange.setResource(resourceDummyOrange);

    dummyResourceCtlUpcase =
        DummyResourceContoller.create(RESOURCE_DUMMY_UPCASE_NAME, resourceDummyUpcase);
    dummyResourceCtlUpcase.extendSchemaPirate();
    dummyResourceUpcase = dummyResourceCtlUpcase.getDummyResource();
    resourceDummyUpcase =
        importAndGetObjectFromFile(
            ResourceType.class,
            RESOURCE_DUMMY_UPCASE_FILE,
            RESOURCE_DUMMY_UPCASE_OID,
            initTask,
            initResult);
    resourceDummyUpcaseType = resourceDummyUpcase.asObjectable();
    dummyResourceCtlUpcase.setResource(resourceDummyUpcase);
    dummyResourceCtlUpcase.addGroup(GROUP_JOKER_DUMMY_UPCASE_NAME);

    resourceDummySchemaless =
        importAndGetObjectFromFile(
            ResourceType.class,
            RESOURCE_DUMMY_SCHEMALESS_FILENAME,
            RESOURCE_DUMMY_SCHEMALESS_OID,
            initTask,
            initResult);
    resourceDummySchemalessType = resourceDummySchemaless.asObjectable();

    postInitDummyResouce();

    dummyResourceCtl.addAccount(ACCOUNT_HERMAN_DUMMY_USERNAME, "Herman Toothrot", "Monkey Island");
    dummyResourceCtl.addAccount(
        ACCOUNT_GUYBRUSH_DUMMY_USERNAME, "Guybrush Threepwood", "Melee Island");
    dummyResourceCtl.addAccount(
        ACCOUNT_DAVIEJONES_DUMMY_USERNAME, "Davie Jones", "Davie Jones' Locker");
    dummyResourceCtl.addAccount(ACCOUNT_CALYPSO_DUMMY_USERNAME, "Tia Dalma", "Pantano River");

    dummyResourceCtl.addAccount(ACCOUNT_ELAINE_DUMMY_USERNAME, "Elaine Marley", "Melee Island");
    dummyResourceCtlRed.addAccount(ACCOUNT_ELAINE_DUMMY_USERNAME, "Elaine Marley", "Melee Island");
    dummyResourceCtlBlue.addAccount(ACCOUNT_ELAINE_DUMMY_USERNAME, "Elaine Marley", "Melee Island");

    repoAddObjectFromFile(LOOKUP_LANGUAGES_FILE, ObjectTemplateType.class, initResult);

    repoAddObjectFromFile(SECURITY_POLICY_FILE, SecurityPolicyType.class, initResult);

    // User Templates
    repoAddObjectFromFile(USER_TEMPLATE_FILENAME, ObjectTemplateType.class, initResult);
    repoAddObjectFromFile(USER_TEMPLATE_COMPLEX_FILENAME, ObjectTemplateType.class, initResult);
    repoAddObjectFromFile(
        USER_TEMPLATE_COMPLEX_INCLUDE_FILENAME, ObjectTemplateType.class, initResult);
    repoAddObjectFromFile(
        USER_TEMPLATE_ORG_ASSIGNMENT_FILENAME, ObjectTemplateType.class, initResult);

    // Shadows
    repoAddObjectFromFile(ACCOUNT_SHADOW_GUYBRUSH_DUMMY_FILE, ShadowType.class, initResult);
    repoAddObjectFromFile(ACCOUNT_SHADOW_ELAINE_DUMMY_FILE, ShadowType.class, initResult);
    repoAddObjectFromFile(ACCOUNT_SHADOW_ELAINE_DUMMY_RED_FILE, ShadowType.class, initResult);
    repoAddObjectFromFile(ACCOUNT_SHADOW_ELAINE_DUMMY_BLUE_FILE, ShadowType.class, initResult);
    repoAddObjectFromFile(GROUP_SHADOW_JOKER_DUMMY_UPCASE_FILE, ShadowType.class, initResult);

    // Users
    userTypeJack =
        repoAddObjectFromFile(USER_JACK_FILE, UserType.class, true, initResult).asObjectable();
    userTypeBarbossa =
        repoAddObjectFromFile(USER_BARBOSSA_FILE, UserType.class, initResult).asObjectable();
    userTypeGuybrush =
        repoAddObjectFromFile(USER_GUYBRUSH_FILE, UserType.class, initResult).asObjectable();
    userTypeElaine =
        repoAddObjectFromFile(USER_ELAINE_FILENAME, UserType.class, initResult).asObjectable();

    // Roles
    repoAddObjectFromFile(ROLE_PIRATE_FILE, RoleType.class, initResult);
    repoAddObjectFromFile(ROLE_NICE_PIRATE_FILENAME, RoleType.class, initResult);
    repoAddObjectFromFile(ROLE_CAPTAIN_FILENAME, RoleType.class, initResult);
    repoAddObjectFromFile(ROLE_JUDGE_FILE, RoleType.class, initResult);
    repoAddObjectFromFile(ROLE_JUDGE_DEPRECATED_FILE, RoleType.class, initResult);
    repoAddObjectFromFile(ROLE_THIEF_FILE, RoleType.class, initResult);
    repoAddObjectFromFile(ROLE_EMPTY_FILE, RoleType.class, initResult);
    repoAddObjectFromFile(ROLE_SAILOR_FILE, RoleType.class, initResult);

    // Orgstruct
    if (doAddOrgstruct()) {
      repoAddObjectsFromFile(ORG_MONKEY_ISLAND_FILE, OrgType.class, initResult);
    }
  }
  private List<ItemWrapper> createProperties(PageBase pageBase) {
    result = new OperationResult(CREATE_PROPERTIES);

    List<ItemWrapper> properties = new ArrayList<ItemWrapper>();

    PrismContainerDefinition definition = null;
    PrismObject parent = getObject().getObject();
    Class clazz = parent.getCompileTimeClass();
    if (ShadowType.class.isAssignableFrom(clazz)) {
      QName name = containerDefinition.getName();

      if (ShadowType.F_ATTRIBUTES.equals(name)) {
        try {
          definition = objectWrapper.getRefinedAttributeDefinition();

          if (definition == null) {
            PrismReference resourceRef = parent.findReference(ShadowType.F_RESOURCE_REF);
            PrismObject<ResourceType> resource = resourceRef.getValue().getObject();

            definition =
                pageBase
                    .getModelInteractionService()
                    .getEditObjectClassDefinition(
                        (PrismObject<ShadowType>) objectWrapper.getObject(),
                        resource,
                        AuthorizationPhaseType.REQUEST)
                    .toResourceAttributeContainerDefinition();

            if (LOGGER.isTraceEnabled()) {
              LOGGER.trace("Refined account def:\n{}", definition.debugDump());
            }
          }
        } catch (Exception ex) {
          LoggingUtils.logException(
              LOGGER, "Couldn't load definitions from refined schema for shadow", ex);
          result.recordFatalError(
              "Couldn't load definitions from refined schema for shadow, reason: "
                  + ex.getMessage(),
              ex);

          return properties;
        }
      } else {
        definition = containerDefinition;
      }
    } else if (ResourceType.class.isAssignableFrom(clazz)) {
      if (containerDefinition != null) {
        definition = containerDefinition;
      } else {
        definition = container.getDefinition();
      }
    } else {
      definition = containerDefinition;
    }

    if (definition == null) {
      LOGGER.error(
          "Couldn't get property list from null definition {}",
          new Object[] {container.getElementName()});
      return properties;
    }

    // assignments are treated in a special way -- we display names of
    // org.units and roles
    // (but only if ObjectWrapper.isShowAssignments() is true; otherwise
    // they are filtered out by ObjectWrapper)
    if (container.getCompileTimeClass() != null
        && AssignmentType.class.isAssignableFrom(container.getCompileTimeClass())) {

      for (Object o : container.getValues()) {
        PrismContainerValue<AssignmentType> pcv = (PrismContainerValue<AssignmentType>) o;

        AssignmentType assignmentType = pcv.asContainerable();

        if (assignmentType.getTargetRef() == null) {
          continue;
        }

        // hack... we want to create a definition for Name
        // PrismPropertyDefinition def = ((PrismContainerValue)
        // pcv.getContainer().getParent()).getContainer().findProperty(ObjectType.F_NAME).getDefinition();
        PrismPropertyDefinition def =
            new PrismPropertyDefinition(
                ObjectType.F_NAME, DOMUtil.XSD_STRING, pcv.getPrismContext());

        if (OrgType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) {
          def.setDisplayName("Org.Unit");
          def.setDisplayOrder(100);
        } else if (RoleType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) {
          def.setDisplayName("Role");
          def.setDisplayOrder(200);
        } else {
          continue;
        }

        PrismProperty<Object> temp = def.instantiate();

        String value = formatAssignmentBrief(assignmentType);

        temp.setValue(new PrismPropertyValue<Object>(value));
        // TODO: do this.isReadOnly() - is that OK? (originally it was the default behavior for all
        // cases)
        properties.add(new PropertyWrapper(this, temp, this.isReadonly(), ValueStatus.NOT_CHANGED));
      }

    } else if (isShadowAssociation()) {
      PrismContext prismContext = objectWrapper.getObject().getPrismContext();
      Map<QName, PrismContainer<ShadowAssociationType>> assocMap = new HashMap<>();
      if (objectWrapper.getAssociations() != null) {
        for (PrismContainerValue<ShadowAssociationType> cval : objectWrapper.getAssociations()) {
          ShadowAssociationType associationType = cval.asContainerable();
          QName assocName = associationType.getName();
          PrismContainer<ShadowAssociationType> fractionalContainer = assocMap.get(assocName);
          if (fractionalContainer == null) {
            fractionalContainer =
                new PrismContainer<>(
                    ShadowType.F_ASSOCIATION, ShadowAssociationType.class, cval.getPrismContext());
            fractionalContainer.setDefinition(cval.getParent().getDefinition());
            // HACK: set the name of the association as the element name so wrapper.getName() will
            // return correct data.
            fractionalContainer.setElementName(assocName);
            assocMap.put(assocName, fractionalContainer);
          }
          try {
            fractionalContainer.add(cval.clone());
          } catch (SchemaException e) {
            // Should not happen
            throw new SystemException("Unexpected error: " + e.getMessage(), e);
          }
        }
      }

      PrismReference resourceRef = parent.findReference(ShadowType.F_RESOURCE_REF);
      PrismObject<ResourceType> resource = resourceRef.getValue().getObject();

      // HACK. The revive should not be here. Revive is no good. The next use of the resource will
      // cause parsing of resource schema. We need some centralized place to maintain live cached
      // copies
      // of resources.
      try {
        resource.revive(prismContext);
      } catch (SchemaException e) {
        throw new SystemException(e.getMessage(), e);
      }
      RefinedResourceSchema refinedSchema;
      CompositeRefinedObjectClassDefinition rOcDef;
      try {
        refinedSchema = RefinedResourceSchema.getRefinedSchema(resource);
        rOcDef = refinedSchema.determineCompositeObjectClassDefinition(parent);
      } catch (SchemaException e) {
        throw new SystemException(e.getMessage(), e);
      }
      // Make sure even empty associations have their wrappers so they can be displayed and edited
      for (RefinedAssociationDefinition assocDef : rOcDef.getAssociations()) {
        QName name = assocDef.getName();
        if (!assocMap.containsKey(name)) {
          PrismContainer<ShadowAssociationType> fractionalContainer =
              new PrismContainer<>(
                  ShadowType.F_ASSOCIATION, ShadowAssociationType.class, prismContext);
          fractionalContainer.setDefinition(getItemDefinition());
          // HACK: set the name of the association as the element name so wrapper.getName() will
          // return correct data.
          fractionalContainer.setElementName(name);
          assocMap.put(name, fractionalContainer);
        }
      }

      for (Entry<QName, PrismContainer<ShadowAssociationType>> assocEntry : assocMap.entrySet()) {
        // HACK HACK HACK, the container wrapper should not parse itself. This code should not be
        // here.
        AssociationWrapper assocWrapper =
            new AssociationWrapper(
                this, assocEntry.getValue(), this.isReadonly(), ValueStatus.NOT_CHANGED);
        properties.add(assocWrapper);
      }

    } else { // if not an assignment

      if ((container.getValues().size() == 1 || container.getValues().isEmpty())
          && (containerDefinition == null || containerDefinition.isSingleValue())) {

        // there's no point in showing properties for non-single-valued
        // parent containers,
        // so we continue only if the parent is single-valued

        Collection<ItemDefinition> propertyDefinitions = definition.getDefinitions();
        for (ItemDefinition itemDef : propertyDefinitions) {
          if (itemDef instanceof PrismPropertyDefinition) {

            PrismPropertyDefinition def = (PrismPropertyDefinition) itemDef;
            if (def.isIgnored() || skipProperty(def)) {
              continue;
            }
            if (!showInheritedObjectAttributes
                && INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) {
              continue;
            }

            // capability handling for activation properties
            if (isShadowActivation() && !hasCapability(def)) {
              continue;
            }

            if (isShadowAssociation()) {
              continue;
            }

            PrismProperty property = container.findProperty(def.getName());
            boolean propertyIsReadOnly;
            // decision is based on parent object status, not this
            // container's one (because container can be added also
            // to an existing object)
            if (objectWrapper.getStatus() == ContainerStatus.MODIFYING) {

              propertyIsReadOnly = !def.canModify();
            } else {
              propertyIsReadOnly = !def.canAdd();
            }
            if (property == null) {
              properties.add(
                  new PropertyWrapper(
                      this, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED));
            } else {
              properties.add(
                  new PropertyWrapper(this, property, propertyIsReadOnly, ValueStatus.NOT_CHANGED));
            }
          } else if (itemDef instanceof PrismReferenceDefinition) {
            PrismReferenceDefinition def = (PrismReferenceDefinition) itemDef;

            if (INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) {
              continue;
            }

            PrismReference reference = container.findReference(def.getName());
            boolean propertyIsReadOnly;
            // decision is based on parent object status, not this
            // container's one (because container can be added also
            // to an existing object)
            if (objectWrapper.getStatus() == ContainerStatus.MODIFYING) {

              propertyIsReadOnly = !def.canModify();
            } else {
              propertyIsReadOnly = !def.canAdd();
            }
            if (reference == null) {
              properties.add(
                  new ReferenceWrapper(
                      this, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED));
            } else {
              properties.add(
                  new ReferenceWrapper(
                      this, reference, propertyIsReadOnly, ValueStatus.NOT_CHANGED));
            }
          }
        }
      }
    }

    Collections.sort(properties, new ItemWrapperComparator());

    result.recomputeStatus();

    return properties;
  }
  private void repositorySelfTestUser(Task task, OperationResult testResult) {
    OperationResult result = testResult.createSubresult(REPOSITORY_SELF_TEST_USER);

    PrismObject<UserType> user = getObjectDefinition(UserType.class).instantiate();
    UserType userType = user.asObjectable();

    String name = generateRandomName();
    PolyStringType namePolyStringType = toPolyStringType(name);
    userType.setName(namePolyStringType);
    result.addContext("name", name);
    userType.setDescription(SelfTestData.POLICIJA);
    userType.setFullName(toPolyStringType(USER_FULL_NAME));
    userType.setGivenName(toPolyStringType(USER_GIVEN_NAME));
    userType.setFamilyName(toPolyStringType(USER_FAMILY_NAME));
    userType.setTitle(toPolyStringType(INSANE_NATIONAL_STRING));
    userType.getEmployeeType().add(USER_EMPLOYEE_TYPE[0]);
    userType.getEmployeeType().add(USER_EMPLOYEE_TYPE[1]);
    userType.getOrganization().add(toPolyStringType(USER_ORGANIZATION[0]));
    userType.getOrganization().add(toPolyStringType(USER_ORGANIZATION[1]));

    String oid;
    try {
      oid = repositoryService.addObject(user, null, result);
    } catch (ObjectAlreadyExistsException e) {
      result.recordFatalError(e);
      return;
    } catch (SchemaException e) {
      result.recordFatalError(e);
      return;
    } catch (RuntimeException e) {
      result.recordFatalError(e);
      return;
    }

    try {

      {
        OperationResult subresult = result.createSubresult(result.getOperation() + ".getObject");

        PrismObject<UserType> userRetrieved;
        try {
          userRetrieved = repositoryService.getObject(UserType.class, oid, null, subresult);
        } catch (ObjectNotFoundException e) {
          result.recordFatalError(e);
          return;
        } catch (SchemaException e) {
          result.recordFatalError(e);
          return;
        } catch (RuntimeException e) {
          result.recordFatalError(e);
          return;
        }

        if (LOGGER.isTraceEnabled()) {
          LOGGER.trace("Self-test:user getObject:\n{}", userRetrieved.debugDump());
        }

        checkUser(userRetrieved, name, subresult);

        subresult.recordSuccessIfUnknown();
      }

      {
        OperationResult subresult =
            result.createSubresult(result.getOperation() + ".searchObjects.fullName");
        try {

          ObjectQuery query = new ObjectQuery();
          ObjectFilter filter =
              EqualFilter.createEqual(
                  UserType.F_FULL_NAME,
                  UserType.class,
                  prismContext,
                  null,
                  toPolyString(USER_FULL_NAME));
          query.setFilter(filter);
          subresult.addParam("query", query);
          List<PrismObject<UserType>> foundObjects =
              repositoryService.searchObjects(UserType.class, query, null, subresult);
          if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Self-test:user searchObjects:\n{}", DebugUtil.debugDump(foundObjects));
          }
          assertSingleSearchResult("user", foundObjects, subresult);

          PrismObject<UserType> userRetrieved = foundObjects.iterator().next();
          checkUser(userRetrieved, name, subresult);

          subresult.recordSuccessIfUnknown();
        } catch (SchemaException e) {
          subresult.recordFatalError(e);
          return;
        } catch (RuntimeException e) {
          subresult.recordFatalError(e);
          return;
        }
      }

      // MID-1116
      {
        OperationResult subresult =
            result.createSubresult(result.getOperation() + ".searchObjects.employeeType");
        try {

          ObjectQuery query = new ObjectQuery();
          ObjectFilter filter =
              EqualFilter.createEqual(
                  UserType.F_EMPLOYEE_TYPE,
                  UserType.class,
                  prismContext,
                  null,
                  USER_EMPLOYEE_TYPE[0]);
          query.setFilter(filter);
          subresult.addParam("query", query);
          List<PrismObject<UserType>> foundObjects =
              repositoryService.searchObjects(UserType.class, query, null, subresult);
          if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Self-test:user searchObjects:\n{}", DebugUtil.debugDump(foundObjects));
          }
          assertSingleSearchResult("user", foundObjects, subresult);

          PrismObject<UserType> userRetrieved = foundObjects.iterator().next();
          checkUser(userRetrieved, name, subresult);

          subresult.recordSuccessIfUnknown();
        } catch (SchemaException e) {
          subresult.recordFatalError(e);
          return;
        } catch (RuntimeException e) {
          subresult.recordFatalError(e);
          return;
        }
      }

      // MID-1116
      {
        OperationResult subresult =
            result.createSubresult(result.getOperation() + ".searchObjects.organization");
        try {

          ObjectQuery query = new ObjectQuery();
          ObjectFilter filter =
              EqualFilter.createEqual(
                  UserType.F_ORGANIZATION,
                  UserType.class,
                  prismContext,
                  null,
                  toPolyString(USER_ORGANIZATION[1]));
          query.setFilter(filter);
          subresult.addParam("query", query);
          List<PrismObject<UserType>> foundObjects =
              repositoryService.searchObjects(UserType.class, query, null, subresult);
          if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Self-test:user searchObjects:\n{}", DebugUtil.debugDump(foundObjects));
          }
          assertSingleSearchResult("user", foundObjects, subresult);

          PrismObject<UserType> userRetrieved = foundObjects.iterator().next();
          checkUser(userRetrieved, name, subresult);

          subresult.recordSuccessIfUnknown();
        } catch (SchemaException e) {
          subresult.recordFatalError(e);
          return;
        } catch (RuntimeException e) {
          subresult.recordFatalError(e);
          return;
        }
      }

    } finally {

      try {
        repositoryService.deleteObject(UserType.class, oid, testResult);
      } catch (ObjectNotFoundException e) {
        result.recordFatalError(e);
        return;
      } catch (RuntimeException e) {
        result.recordFatalError(e);
        return;
      }

      result.computeStatus();
    }
  }
Example #28
0
  @Override
  protected void initLayout() {

    final List<RichHyperlinkType> linksList = getModel().getObject();
    RepeatingView rowView = new RepeatingView(ID_LINKS_ROW);

    int linksListSize = linksList == null ? 0 : linksList.size();
    if (linksListSize > 0) {
      int currentColumn = 0;
      RepeatingView columnView = null;
      WebMarkupContainer row = null;
      boolean isRowAdded = false;
      for (int i = 0; i < linksListSize; i++) {
        final RichHyperlinkType link = linksList.get(i);
        if (WebMiscUtil.isAuthorized(link.getAuthorization())) {
          if (currentColumn == 0) {
            row = new WebMarkupContainer(rowView.newChildId());
            isRowAdded = false;
            columnView = new RepeatingView(ID_LINKS_COLUMN);
          }
          WebMarkupContainer column = new WebMarkupContainer(columnView.newChildId());
          Link linkItem =
              new Link(ID_LINK) {
                @Override
                public void onClick() {}

                @Override
                protected void onComponentTag(final ComponentTag tag) {
                  super.onComponentTag(tag);
                  String rootContext = "";
                  if (link.getTargetUrl() != null
                      && !link.getTargetUrl().startsWith("http://")
                      && !link.getTargetUrl().startsWith("https://")
                      && !link.getTargetUrl().startsWith("www://")
                      && !link.getTargetUrl().startsWith("//")) {
                    WebApplication webApplication = WebApplication.get();
                    if (webApplication != null) {
                      ServletContext servletContext = webApplication.getServletContext();
                      if (servletContext != null) {
                        rootContext = servletContext.getContextPath();
                      }
                    }
                  }
                  tag.put("href", rootContext + link.getTargetUrl());
                }
              };
          linkItem.add(
              new Label(ID_IMAGE) {
                @Override
                protected void onComponentTag(final ComponentTag tag) {
                  super.onComponentTag(tag);
                  String cssClass = ICON_DEFAULT_CSS_CLASS;
                  if (link.getIcon() != null) {
                    cssClass = link.getIcon().getCssClass();
                  }
                  tag.put(
                      "class",
                      "info-box-icon "
                          + (link.getColor() != null
                              ? (link.getColor().startsWith("bg-")
                                  ? link.getColor()
                                  : "bg-" + link.getColor())
                              : "")
                          + " "
                          + cssClass);
                }
              });

          linkItem.add(
              new Label(
                  ID_LABEL,
                  new Model<String>() {
                    public String getObject() {
                      return link.getLabel();
                    }
                  }));
          Label description =
              new Label(
                  ID_DESCRIPTION,
                  new Model<String>() {
                    public String getObject() {
                      return link.getDescription();
                    }
                  });
          description.setEnabled(false);
          linkItem.add(description);

          column.add(linkItem);
          columnView.add(column);
          if (currentColumn == 1 || (linksList.indexOf(link) == linksListSize - 1)) {
            row.add(columnView);
            rowView.add(row);
            currentColumn = 0;
            isRowAdded = true;
          } else {
            currentColumn++;
          }
        } else {
          LOGGER.trace("Link {} not authorized, skipping", link);
        }
      }
      if (row != null && columnView != null && !isRowAdded) {
        row.add(columnView);
        rowView.add(row);
      }
    }
    add(rowView);
  }
  private <F extends FocusType> void processActivation(
      LensContext<F> context, XMLGregorianCalendar now, OperationResult result)
      throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException,
          PolicyViolationException {
    LensFocusContext<F> focusContext = context.getFocusContext();

    if (focusContext.isDelete()) {
      LOGGER.trace("Skipping processing of focus activation: focus delete");
      return;
    }

    TimeIntervalStatusType validityStatusNew = null;
    TimeIntervalStatusType validityStatusOld = null;
    XMLGregorianCalendar validityChangeTimestamp = null;

    ActivationType activationNew = null;
    ActivationType activationOld = null;

    PrismObject<F> focusNew = focusContext.getObjectNew();
    if (focusNew != null) {
      activationNew = focusNew.asObjectable().getActivation();
      if (activationNew != null) {
        validityStatusNew = activationComputer.getValidityStatus(activationNew, now);
        validityChangeTimestamp = activationNew.getValidityChangeTimestamp();
      }
    }

    PrismObject<F> focusOld = focusContext.getObjectOld();
    if (focusOld != null) {
      activationOld = focusOld.asObjectable().getActivation();
      if (activationOld != null) {
        validityStatusOld =
            activationComputer.getValidityStatus(activationOld, validityChangeTimestamp);
      }
    }

    if (validityStatusOld == validityStatusNew) {
      // No change, (almost) no work
      if (validityStatusNew != null && activationNew.getValidityStatus() == null) {
        // There was no validity change. But the status is not recorded. So let's record it so it
        // can be used in searches.
        recordValidityDelta(focusContext, validityStatusNew, now);
      } else {
        LOGGER.trace(
            "Skipping validity processing because there was no change ({} -> {})",
            validityStatusOld,
            validityStatusNew);
      }
    } else {
      LOGGER.trace("Validity change {} -> {}", validityStatusOld, validityStatusNew);
      recordValidityDelta(focusContext, validityStatusNew, now);
    }

    ActivationStatusType effectiveStatusNew =
        activationComputer.getEffectiveStatus(
            activationNew, validityStatusNew, ActivationStatusType.DISABLED);
    ActivationStatusType effectiveStatusOld =
        activationComputer.getEffectiveStatus(
            activationOld, validityStatusOld, ActivationStatusType.DISABLED);

    if (effectiveStatusOld == effectiveStatusNew) {
      // No change, (almost) no work
      if (effectiveStatusNew != null
          && (activationNew == null || activationNew.getEffectiveStatus() == null)) {
        // There was no effective status change. But the status is not recorded. So let's record it
        // so it can be used in searches.
        recordEffectiveStatusDelta(focusContext, effectiveStatusNew, now);
      } else {
        if (focusContext.getPrimaryDelta() != null
            && focusContext
                .getPrimaryDelta()
                .hasItemDelta(SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS)) {
          LOGGER.trace(
              "Forcing effective status delta even though there was no change ({} -> {}) because there is explicit administrativeStatus delta",
              effectiveStatusOld,
              effectiveStatusNew);
          // We need this to force the change down to the projections later in the activation
          // processor
          // some of the mappings will use effectiveStatus as a source, therefore there has to be a
          // delta for the mapping to work correctly
          recordEffectiveStatusDelta(focusContext, effectiveStatusNew, now);
        } else {
          LOGGER.trace(
              "Skipping effective status processing because there was no change ({} -> {})",
              effectiveStatusOld,
              effectiveStatusNew);
        }
      }
    } else {
      LOGGER.trace("Effective status change {} -> {}", effectiveStatusOld, effectiveStatusNew);
      recordEffectiveStatusDelta(focusContext, effectiveStatusNew, now);
    }
  }
  private <F extends FocusType> void processFocusFocus(
      LensContext<F> context,
      String activityDescription,
      XMLGregorianCalendar now,
      Task task,
      OperationResult result)
      throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException,
          PolicyViolationException, ObjectAlreadyExistsException, CommunicationException,
          ConfigurationException, SecurityViolationException {

    LensFocusContext<F> focusContext = context.getFocusContext();
    ObjectTemplateType objectTemplate = context.getFocusTemplate();

    boolean resetOnRename = true; // This is fixed now. TODO: make it configurable
    int maxIterations = 0;
    IterationSpecificationType iterationSpecificationType = null;
    if (objectTemplate != null) {
      iterationSpecificationType = objectTemplate.getIteration();
      maxIterations = LensUtil.determineMaxIterations(iterationSpecificationType);
    }
    int iteration = focusContext.getIteration();
    String iterationToken = focusContext.getIterationToken();
    boolean wasResetIterationCounter = false;

    PrismObject<F> focusCurrent = focusContext.getObjectCurrent();
    if (focusCurrent != null && iterationToken == null) {
      Integer focusIteration = focusCurrent.asObjectable().getIteration();
      if (focusIteration != null) {
        iteration = focusIteration;
      }
      iterationToken = focusCurrent.asObjectable().getIterationToken();
    }

    while (true) {

      ObjectTypeTemplateType objectPolicyConfigurationType =
          focusContext.getObjectPolicyConfigurationType();
      if (objectPolicyConfigurationType != null
          && BooleanUtils.isTrue(objectPolicyConfigurationType.isOidNameBoundMode())) {
        // Generate the name now - unless it is already present
        PrismObject<F> focusNew = focusContext.getObjectNew();
        if (focusNew != null) {
          PolyStringType focusNewName = focusNew.asObjectable().getName();
          if (focusNewName == null) {
            String newName = focusNew.getOid();
            if (newName == null) {
              newName = OidUtil.generateOid();
            }
            LOGGER.trace("Generating new name (bound to OID): {}", newName);
            PrismObjectDefinition<F> focusDefinition = focusContext.getObjectDefinition();
            PrismPropertyDefinition<PolyString> focusNameDef =
                focusDefinition.findPropertyDefinition(FocusType.F_NAME);
            PropertyDelta<PolyString> nameDelta =
                focusNameDef.createEmptyDelta(new ItemPath(FocusType.F_NAME));
            nameDelta.setValueToReplace(
                new PrismPropertyValue<PolyString>(
                    new PolyString(newName), OriginType.USER_POLICY, null));
            focusContext.swallowToSecondaryDelta(nameDelta);
            focusContext.recompute();
          }
        }
      }

      ExpressionVariables variables =
          Utils.getDefaultExpressionVariables(
              focusContext.getObjectNew(), null, null, null, context.getSystemConfiguration());
      if (iterationToken == null) {
        iterationToken =
            LensUtil.formatIterationToken(
                context,
                focusContext,
                iterationSpecificationType,
                iteration,
                expressionFactory,
                variables,
                task,
                result);
      }

      // We have to remember the token and iteration in the context.
      // The context can be recomputed several times. But we always want
      // to use the same iterationToken if possible. If there is a random
      // part in the iterationToken expression that we need to avoid recomputing
      // the token otherwise the value can change all the time (even for the same inputs).
      // Storing the token in the secondary delta is not enough because secondary deltas can be
      // dropped
      // if the context is re-projected.
      focusContext.setIteration(iteration);
      focusContext.setIterationToken(iterationToken);
      LOGGER.trace(
          "Focus {} processing, iteration {}, token '{}'",
          new Object[] {focusContext.getHumanReadableName(), iteration, iterationToken});

      String conflictMessage;
      if (!LensUtil.evaluateIterationCondition(
          context,
          focusContext,
          iterationSpecificationType,
          iteration,
          iterationToken,
          true,
          expressionFactory,
          variables,
          task,
          result)) {

        conflictMessage = "pre-iteration condition was false";
        LOGGER.debug(
            "Skipping iteration {}, token '{}' for {} because the pre-iteration condition was false",
            new Object[] {iteration, iterationToken, focusContext.getHumanReadableName()});
      } else {

        // INBOUND

        if (consistencyChecks) context.checkConsistence();
        // Loop through the account changes, apply inbound expressions
        inboundProcessor.processInbound(context, now, task, result);
        if (consistencyChecks) context.checkConsistence();
        context.recomputeFocus();
        LensUtil.traceContext(LOGGER, activityDescription, "inbound", false, context, false);
        if (consistencyChecks) context.checkConsistence();

        // ACTIVATION

        processActivation(context, now, result);

        // OBJECT TEMPLATE (before assignments)

        objectTemplateProcessor.processTemplate(
            context,
            ObjectTemplateMappingEvaluationPhaseType.BEFORE_ASSIGNMENTS,
            now,
            task,
            result);

        // ASSIGNMENTS

        assignmentProcessor.processAssignmentsProjections(context, now, task, result);
        assignmentProcessor.processOrgAssignments(context, result);
        context.recompute();

        assignmentProcessor.checkForAssignmentConflicts(context, result);

        // OBJECT TEMPLATE (after assignments)

        objectTemplateProcessor.processTemplate(
            context, ObjectTemplateMappingEvaluationPhaseType.AFTER_ASSIGNMENTS, now, task, result);
        context.recompute();

        // PASSWORD POLICY

        passwordPolicyProcessor.processPasswordPolicy(focusContext, context, result);

        // Processing done, check for success

        if (resetOnRename && !wasResetIterationCounter && willResetIterationCounter(focusContext)) {
          // Make sure this happens only the very first time during the first recompute.
          // Otherwise it will always change the token (especially if the token expression has a
          // random part)
          // hence the focusContext.getIterationToken() == null
          wasResetIterationCounter = true;
          if (iteration != 0) {
            iteration = 0;
            iterationToken = null;
            LOGGER.trace("Resetting iteration counter and token because rename was detected");
            cleanupContext(focusContext);
            continue;
          }
        }

        PrismObject<F> previewObjectNew = focusContext.getObjectNew();
        if (previewObjectNew == null) {
          // this must be delete
        } else {
          // Explicitly check for name. The checker would check for this also. But checking it here
          // will produce better error message
          PolyStringType objectName = previewObjectNew.asObjectable().getName();
          if (objectName == null || objectName.getOrig().isEmpty()) {
            throw new SchemaException(
                "No name in new object "
                    + objectName
                    + " as produced by template "
                    + objectTemplate
                    + " in iteration "
                    + iteration
                    + ", we cannot process an object without a name");
          }
        }

        // Check if iteration constraints are OK
        FocusConstraintsChecker<F> checker = new FocusConstraintsChecker<>();
        checker.setPrismContext(prismContext);
        checker.setContext(context);
        checker.setRepositoryService(cacheRepositoryService);
        checker.check(previewObjectNew, result);
        if (checker.isSatisfiesConstraints()) {
          LOGGER.trace(
              "Current focus satisfies uniqueness constraints. Iteration {}, token '{}'",
              iteration,
              iterationToken);

          if (LensUtil.evaluateIterationCondition(
              context,
              focusContext,
              iterationSpecificationType,
              iteration,
              iterationToken,
              false,
              expressionFactory,
              variables,
              task,
              result)) {
            // stop the iterations
            break;
          } else {
            conflictMessage = "post-iteration condition was false";
            LOGGER.debug(
                "Skipping iteration {}, token '{}' for {} because the post-iteration condition was false",
                new Object[] {iteration, iterationToken, focusContext.getHumanReadableName()});
          }
        } else {
          LOGGER.trace(
              "Current focus does not satisfy constraints. Conflicting object: {}; iteration={}, maxIterations={}",
              new Object[] {checker.getConflictingObject(), iteration, maxIterations});
          conflictMessage = checker.getMessages();
        }

        if (!wasResetIterationCounter) {
          wasResetIterationCounter = true;
          if (iteration != 0) {
            iterationToken = null;
            iteration = 0;
            LOGGER.trace("Resetting iteration counter and token after conflict");
            cleanupContext(focusContext);
            continue;
          }
        }
      }

      // Next iteration
      iteration++;
      iterationToken = null;
      if (iteration > maxIterations) {
        StringBuilder sb = new StringBuilder();
        if (iteration == 1) {
          sb.append("Error processing ");
        } else {
          sb.append("Too many iterations (" + iteration + ") for ");
        }
        sb.append(focusContext.getHumanReadableName());
        if (iteration == 1) {
          sb.append(": constraint violation: ");
        } else {
          sb.append(": cannot determine values that satisfy constraints: ");
        }
        if (conflictMessage != null) {
          sb.append(conflictMessage);
        }
        throw new ObjectAlreadyExistsException(sb.toString());
      }
      cleanupContext(focusContext);
    }

    addIterationTokenDeltas(focusContext, iteration, iterationToken);
    if (consistencyChecks) context.checkConsistence();
  }