/**
  * @param ent
  * @return
  */
 private Map<String, EnvironmentContent> getPromotedContent(Entitlement ent) {
   // Build a set of all content IDs promoted to the consumer's environment so
   // we can determine if anything needs to be skipped:
   Map<String, EnvironmentContent> promotedContent = new HashMap<String, EnvironmentContent>();
   if (ent.getConsumer().getEnvironment() != null) {
     log.debug(
         "Consumer has environment, checking for promoted content in: "
             + ent.getConsumer().getEnvironment());
     for (EnvironmentContent envContent :
         ent.getConsumer().getEnvironment().getEnvironmentContent()) {
       log.debug("  promoted content: " + envContent.getContentId());
       promotedContent.put(envContent.getContentId(), envContent);
     }
   }
   return promotedContent;
 }
 private Set<Product> getDerivedProductsForDistributor(Subscription sub, Entitlement ent) {
   Set<Product> derivedProducts = new HashSet<Product>();
   boolean derived = ent.getPool().hasAttribute("pool_derived");
   if (!derived && ent.getConsumer().getType().isManifest() && sub.getDerivedProduct() != null) {
     derivedProducts.add(sub.getDerivedProduct());
     derivedProducts.addAll(sub.getDerivedProvidedProducts());
   }
   return derivedProducts;
 }
  protected void runPostUnbind(PoolHelper postHelper, Entitlement entitlement) {
    Pool pool = entitlement.getPool();
    Consumer c = entitlement.getConsumer();

    Map<String, String> attributes = postHelper.getFlattenedAttributes(pool);

    if (attributes.containsKey("virt_limit")) {
      postUnbindVirtLimit(postHelper, entitlement, pool, c, attributes);
    }
  }
 /**
  * @param ent
  * @param useContentPrefix
  * @return
  * @throws IOException
  */
 private String getContentPrefix(Entitlement ent, boolean useContentPrefix) throws IOException {
   String contentPrefix = null;
   if (useContentPrefix) {
     contentPrefix = ent.getOwner().getContentPrefix();
     Environment env = ent.getConsumer().getEnvironment();
     if (contentPrefix != null && !contentPrefix.equals("")) {
       if (env != null) {
         contentPrefix = contentPrefix.replaceAll("\\$env", env.getName());
       }
       contentPrefix = this.cleanUpPrefix(contentPrefix);
     }
   }
   return contentPrefix;
 }
  private boolean shouldGenerateV3(Entitlement entitlement) {
    Consumer consumer = entitlement.getConsumer();

    if (consumer.getType().isManifest()) {
      for (ConsumerCapability capability : consumer.getCapabilities()) {
        if ("cert_v3".equals(capability.getName())) {
          return true;
        }
      }
      return false;
    } else if (consumer.getType().getLabel().equals(ConsumerTypeEnum.HYPERVISOR.getLabel())) {
      // Hypervisors in this context don't use content, so allow v3
      return true;
    } else {
      String entitlementVersion = consumer.getFact("system.certificate_version");
      return entitlementVersion != null && entitlementVersion.startsWith("3.");
    }
  }
  protected void runPostEntitlement(PoolHelper postHelper, Entitlement entitlement) {
    Pool pool = entitlement.getPool();
    Consumer c = entitlement.getConsumer();

    Map<String, String> attributes = postHelper.getFlattenedAttributes(pool);

    // Perform pool management based on the attributes of the pool:
    // TODO: should really be cleaned up, this used to be post rules but
    // because
    // it actually manages pools we pulled back to engine. Needs re-org.
    if (attributes.containsKey("user_license")) {
      postBindUserLicense(postHelper, pool, c, attributes);
    }

    if (attributes.containsKey("virt_limit")) {
      postBindVirtLimit(postHelper, entitlement, pool, c, attributes);
    }
  }
  private Date findPoolEndDate(Entitlement ent) {
    Pool pool = ent.getPool();
    Consumer consumer = ent.getConsumer();

    Date startDate = new Date();

    if (consumer.getCreated() != null) {
      startDate = consumer.getCreated();
    }

    Date oneDayFromRegistration = new Date(startDate.getTime() + (24 * 60 * 60 * 1000));

    boolean isUnmappedGuestPool =
        BooleanUtils.toBoolean(pool.getAttributeValue("unmapped_guests_only"));

    if (isUnmappedGuestPool) {
      return oneDayFromRegistration;
    } else {
      return pool.getEndDate();
    }
  }
 @Override
 public boolean canAccessTarget(Entitlement target, SubResource subResource, Access required) {
   return target.getConsumer().getUuid().equals(consumer.getUuid());
 }
  private EntitlementCertificate generateEntitlementCert(
      Entitlement entitlement, Subscription sub, Product product, boolean thisIsUeberCert)
      throws GeneralSecurityException, IOException {

    log.info("Generating entitlement cert.");

    KeyPair keyPair = keyPairCurator.getConsumerKeyPair(entitlement.getConsumer());
    CertificateSerial serial = new CertificateSerial(entitlement.getEndDate());
    // We need the sequence generated id before we create the EntitlementCertificate,
    // otherwise we could have used cascading create
    serial = serialCurator.create(serial);

    Set<Product> products = new HashSet<Product>(getProvidedProducts(entitlement.getPool(), sub));

    // If creating a certificate for a distributor, we need
    // to add any derived products as well so that their content
    // is available in the upstream certificate.
    products.addAll(getDerivedProductsForDistributor(sub, entitlement));

    log.info("Creating X509 cert.");
    X509Certificate x509Cert =
        createX509Certificate(
            entitlement,
            product,
            products,
            BigInteger.valueOf(serial.getId()),
            keyPair,
            !thisIsUeberCert);

    EntitlementCertificate cert = new EntitlementCertificate();
    cert.setSerial(serial);
    cert.setKeyAsBytes(pki.getPemEncoded(keyPair.getPrivate()));

    products.add(product);
    Map<String, EnvironmentContent> promotedContent = getPromotedContent(entitlement);
    String contentPrefix = getContentPrefix(entitlement, !thisIsUeberCert);

    log.info("Getting PEM encoded cert.");
    String pem = new String(this.pki.getPemEncoded(x509Cert));

    if (shouldGenerateV3(entitlement)) {
      byte[] payloadBytes =
          v3extensionUtil.createEntitlementDataPayload(
              products, entitlement, contentPrefix, promotedContent);
      String payload = "-----BEGIN ENTITLEMENT DATA-----\n";
      payload += Util.toBase64(payloadBytes);
      payload += "-----END ENTITLEMENT DATA-----\n";

      byte[] bytes = pki.getSHA256WithRSAHash(new ByteArrayInputStream(payloadBytes));
      String signature = "-----BEGIN RSA SIGNATURE-----\n";
      signature += Util.toBase64(bytes);
      signature += "-----END RSA SIGNATURE-----\n";

      pem += payload + signature;
    }

    cert.setCert(pem);

    cert.setEntitlement(entitlement);

    if (log.isDebugEnabled()) {
      log.debug("Generated cert serial number: " + serial.getId());
      log.debug("Key: " + cert.getKey());
      log.debug("Cert: " + cert.getCert());
    }

    log.info("Persisting cert.");
    entitlement.getCertificates().add(cert);
    entCertCurator.create(cert);
    return cert;
  }
  public Set<X509ExtensionWrapper> prepareV1Extensions(
      Set<Product> products,
      Entitlement ent,
      String contentPrefix,
      Map<String, EnvironmentContent> promotedContent) {
    Set<X509ExtensionWrapper> result = new LinkedHashSet<X509ExtensionWrapper>();

    Set<String> entitledProductIds =
        entCurator.listEntitledProductIds(
            ent.getConsumer(), ent.getPool().getStartDate(), ent.getPool().getEndDate());

    int contentCounter = 0;
    boolean enableEnvironmentFiltering = config.getBoolean(ConfigProperties.ENV_CONTENT_FILTERING);

    Product skuProd = productAdapter.getProductById(ent.getPool().getProductId());

    for (Product prod : Collections2.filter(products, X509Util.PROD_FILTER_PREDICATE)) {
      result.addAll(extensionUtil.productExtensions(prod));
      Set<ProductContent> filteredContent =
          extensionUtil.filterProductContent(
              prod,
              ent,
              entCurator,
              promotedContent,
              enableEnvironmentFiltering,
              entitledProductIds);

      filteredContent =
          extensionUtil.filterContentByContentArch(filteredContent, ent.getConsumer(), prod);

      // Keep track of the number of content sets that are being added.
      contentCounter += filteredContent.size();

      result.addAll(
          extensionUtil.contentExtensions(
              filteredContent, contentPrefix, promotedContent, ent.getConsumer(), skuProd));
    }

    // For V1 certificates we're going to error out if we exceed a limit which is
    // likely going to generate a certificate too large for the CDN, and return an
    // informative error message to the user.
    if (contentCounter > X509ExtensionUtil.V1_CONTENT_LIMIT) {
      String cause =
          i18n.tr(
              "Too many content sets for certificate {0}. A newer "
                  + "client may be available to address this problem. "
                  + "See kbase https://access.redhat.com/knowledge/node/129003 for more "
                  + "information.",
              ent.getPool().getProductName());
      throw new CertificateSizeException(cause);
    }

    result.addAll(extensionUtil.subscriptionExtensions(ent));

    result.addAll(extensionUtil.entitlementExtensions(ent));
    result.addAll(extensionUtil.consumerExtensions(ent.getConsumer()));

    if (log.isDebugEnabled()) {
      for (X509ExtensionWrapper eWrapper : result) {
        log.debug(
            String.format("Extension %s with value %s", eWrapper.getOid(), eWrapper.getValue()));
      }
    }
    return result;
  }