/**
   * @see
   *     org.alfresco.repo.action.executer.TransformActionExecuter#doTransform(org.alfresco.service.cmr.action.Action,
   *     org.alfresco.service.cmr.repository.ContentReader,
   *     org.alfresco.service.cmr.repository.ContentWriter)
   */
  protected void doSplit(
      Action ruleAction, NodeRef actionedUponNodeRef, ContentReader contentReader) {
    Map<String, Object> options = new HashMap<String, Object>(INITIAL_OPTIONS);
    options.put(PARAM_DESTINATION_FOLDER, ruleAction.getParameterValue(PARAM_DESTINATION_FOLDER));
    options.put(PARAM_SPLIT_AT_PAGE, ruleAction.getParameterValue(PARAM_SPLIT_AT_PAGE));

    try {
      this.action(ruleAction, actionedUponNodeRef, contentReader, options);
    } catch (AlfrescoRuntimeException e) {
      throw new AlfrescoRuntimeException(e.getMessage(), e);
    }
  }
  @Test
  public void testGetPasswordHash() throws Exception {

    Map<QName, Serializable> properties = new HashMap<>();
    cpe.setPreferredEncoding("bcrypt10");

    try {
      RepositoryAuthenticationDao.determinePasswordHash(properties);
      fail("Should throw exception");
    } catch (AlfrescoRuntimeException are) {
      assertTrue(are.getMessage().contains("Unable to find a password for user"));
    }

    // if the PROP_PASSWORD field is the only one availble then we are using MD4
    properties.put(ContentModel.PROP_PASSWORD, "mypassword");
    Pair<List<String>, String> passwordHashed =
        RepositoryAuthenticationDao.determinePasswordHash(properties);
    assertEquals(CompositePasswordEncoder.MD4, passwordHashed.getFirst());
    assertEquals("mypassword", passwordHashed.getSecond());

    // if the PROP_PASSWORD_SHA256 field is used then we are using SHA256
    properties.put(ContentModel.PROP_PASSWORD_SHA256, "sha_password");
    passwordHashed = RepositoryAuthenticationDao.determinePasswordHash(properties);
    assertEquals(CompositePasswordEncoder.SHA256, passwordHashed.getFirst());
    assertEquals("sha_password", passwordHashed.getSecond());

    properties.put(ContentModel.PROP_HASH_INDICATOR, null);
    // If the indicator is NULL then it still uses the old password field
    passwordHashed = RepositoryAuthenticationDao.determinePasswordHash(properties);
    assertEquals(CompositePasswordEncoder.SHA256, passwordHashed.getFirst());
    assertEquals("sha_password", passwordHashed.getSecond());

    properties.put(ContentModel.PROP_HASH_INDICATOR, new ArrayList<String>(0));
    // If the indicator doesn't have a value
    passwordHashed = RepositoryAuthenticationDao.determinePasswordHash(properties);
    assertEquals(CompositePasswordEncoder.SHA256, passwordHashed.getFirst());
    assertEquals("sha_password", passwordHashed.getSecond());

    // Now it uses the correct property
    properties.put(ContentModel.PROP_HASH_INDICATOR, (Serializable) Arrays.asList("myencoding"));
    properties.put(ContentModel.PROP_PASSWORD_HASH, "hashed this time");
    passwordHashed = RepositoryAuthenticationDao.determinePasswordHash(properties);
    assertEquals(Arrays.asList("myencoding"), passwordHashed.getFirst());
    assertEquals("hashed this time", passwordHashed.getSecond());
  }
  /**
   * Sign file.
   *
   * @param signingDTO sign informations
   * @param pdfSignedFile signed pdf returned
   */
  public void sign(final DigitalSigningDTO signingDTO) {
    if (signingDTO != null) {

      try {
        Security.addProvider(new BouncyCastleProvider());
        final File alfTempDir = TempFileProvider.getTempDir();

        if (alfTempDir != null) {
          final String keyType =
              (String) nodeService.getProperty(signingDTO.getKeyFile(), SigningModel.PROP_KEYTYPE);

          if (SigningConstants.KEY_TYPE_X509.equals(keyType)) {
            // Sign the file
            final KeyStore ks = KeyStore.getInstance("pkcs12");
            final ContentReader keyContentReader = getReader(signingDTO.getKeyFile());

            if (keyContentReader != null && ks != null && signingDTO.getKeyPassword() != null) {

              final List<AlfrescoRuntimeException> errors =
                  new ArrayList<AlfrescoRuntimeException>();

              // Get crypted secret key and decrypt it
              final Serializable encryptedPropertyValue =
                  nodeService.getProperty(
                      signingDTO.getKeyFile(), SigningModel.PROP_KEYCRYPTSECRET);
              final Serializable decryptedPropertyValue =
                  metadataEncryptor.decrypt(
                      SigningModel.PROP_KEYCRYPTSECRET, encryptedPropertyValue);

              // Decrypt key content
              InputStream decryptedKeyContent;
              try {
                decryptedKeyContent =
                    CryptUtils.decrypt(
                        decryptedPropertyValue.toString(),
                        keyContentReader.getContentInputStream());
              } catch (Throwable e) {
                log.error(e);
                throw new AlfrescoRuntimeException(e.getMessage(), e);
              }

              ks.load(
                  new ByteArrayInputStream(IOUtils.toByteArray(decryptedKeyContent)),
                  signingDTO.getKeyPassword().toCharArray());

              final String alias =
                  (String)
                      nodeService.getProperty(signingDTO.getKeyFile(), SigningModel.PROP_KEYALIAS);

              final PrivateKey key =
                  (PrivateKey) ks.getKey(alias, signingDTO.getKeyPassword().toCharArray());
              final Certificate[] chain = ks.getCertificateChain(alias);

              final Iterator<NodeRef> itFilesToSign = signingDTO.getFilesToSign().iterator();
              while (itFilesToSign.hasNext()) {
                final NodeRef nodeRefToSign = itFilesToSign.next();
                final AlfrescoRuntimeException exception =
                    signFile(nodeRefToSign, signingDTO, alfTempDir, alias, ks, key, chain);
                if (exception != null) {
                  // Error on the file process
                  errors.add(exception);
                }
              }

              if (errors != null && errors.size() > 0) {
                final StringBuffer allErrors = new StringBuffer();
                final Iterator<AlfrescoRuntimeException> itErrors = errors.iterator();
                if (errors.size() > 1) {
                  allErrors.append("\n");
                }
                while (itErrors.hasNext()) {
                  final AlfrescoRuntimeException alfrescoRuntimeException = itErrors.next();
                  allErrors.append(alfrescoRuntimeException.getMessage());
                  if (itErrors.hasNext()) {
                    allErrors.append("\n");
                  }
                }
                throw new RuntimeException(allErrors.toString());
              }

            } else {
              log.error("Unable to get key content, key type or key password.");
              throw new AlfrescoRuntimeException(
                  "Unable to get key content, key type or key password.");
            }
          }
        } else {
          log.error("Unable to get temporary directory.");
          throw new AlfrescoRuntimeException("Unable to get temporary directory.");
        }
      } catch (KeyStoreException e) {
        log.error(e);
        throw new AlfrescoRuntimeException(e.getMessage(), e);
      } catch (NoSuchAlgorithmException e) {
        log.error(e);
        throw new AlfrescoRuntimeException(e.getMessage(), e);
      } catch (CertificateException e) {
        log.error(e);
        throw new AlfrescoRuntimeException(e.getMessage(), e);
      } catch (IOException e) {
        log.error(e);
        throw new AlfrescoRuntimeException(e.getMessage(), e);
      } catch (UnrecoverableKeyException e) {
        log.error(e);
        throw new AlfrescoRuntimeException(e.getMessage(), e);
      }
    } else {
      log.error("No object with signing informations.");
      throw new AlfrescoRuntimeException("No object with signing informations.");
    }
  }