/** * Whether the IdP attribute is empty. * * @param input the IdP Attribute * @return true if the IdP attribute has no values or empty values, false otherwise */ private boolean isEmpty(@Nonnull final IdPAttribute input) { for (final IdPAttributeValue value : input.getValues()) { if (!(value instanceof EmptyAttributeValue)) { return false; } } return true; } }
/** {@inheritDoc} */ @Override public Set<IdPAttributeValue<?>> getMatchingValues(@Nonnull final IdPAttribute attribute, @Nonnull final AttributeFilterContext filterContext) { return ImmutableSet.copyOf(attribute.getValues()); }
/** * Adds the values of the given attribute to the set of attribute values. * * @param source the source attribute * @param target current set attribute values */ @Nonnull private static void mergeAttributeValues(@Nullable final IdPAttribute source, @Nonnull final List<IdPAttributeValue<?>> target) { if (source != null) { target.addAll(source.getValues()); } } }
/** * Gets attribute value. * * @param attribute the attribute * @return the attribute value */ protected IdPAttributeValue<?> getAttributeValue(final IdPAttribute attribute) { if (!attribute.getValues().isEmpty()) { return attribute.getValues().get(0); } return new EmptyAttributeValue(EmptyAttributeValue.EmptyType.NULL_VALUE); }
/** {@inheritDoc} */ @Override @Nullable public List<IdPAttributeValue<?>> apply(@Nullable final Principal principal) { if (null != principal && principal instanceof IdPAttributePrincipal) { final IdPAttributePrincipal attributePrincipal = (IdPAttributePrincipal) principal; final IdPAttribute attribute = attributePrincipal.getAttribute(); if (null != attribute && attributeName.equals(attribute.getId())) { return attribute.getValues(); } } return null; } }
/** {@inheritDoc} */ @Override @Nullable public String apply(@Nullable final ProfileRequestContext input) { final AttributeContext attributeContext = attributeContextLookupStrategy.apply(input); if (attributeContext == null) { log.debug("No attribute context within profile request context"); return null; } final IdPAttribute attribute = attributeContext.getIdPAttributes().get(attributeId); if (attribute == null || attribute.getValues().isEmpty()) { log.debug("Attribute '{}' does not exist or has no values", attributeId); return null; } if (attribute.getValues().size() != 1) { log.debug("Returning first string value of attribute '{}'", attributeId); } for (final IdPAttributeValue value : attribute.getValues()) { if (value instanceof StringAttributeValue) { log.debug("Returning value '{}' of attribute '{}'", ((StringAttributeValue) value).getValue(), attributeId); return ((StringAttributeValue) value).getValue(); } } return null; }
/** * We use an internal list of attribute values to allow the legacy use of getValues().add(). */ private void setupAttributeValues() { if (null != attributeValues) { return; } log.debug("{} values being prepared", getLogPrefix()); // NOTE. This has to be a List - the examples use get(0) final ArrayList<Object> newValues = new ArrayList<>(encapsulatedAttribute.getValues().size()); for (final IdPAttributeValue value : encapsulatedAttribute.getValues()) { if ((value instanceof StringAttributeValue) && !(value instanceof ScopedStringAttributeValue)) { newValues.add(((StringAttributeValue) value).getValue()); } else if (value instanceof EmptyAttributeValue) { // Shib2 made both empty strings and nulls null newValues.add(null); } else { newValues.add(value); } } attributeValues = newValues; log.debug("{} values are : {}", getLogPrefix(), newValues); }
/** {@inheritDoc} */ @Override protected boolean hasMatch(@Nonnull @NonnullElements final Map<String, IdPAttribute> attributeMap) { final IdPAttribute attribute = attributeMap.get(attributeName); if (attribute == null) { log.debug("Attribute {} not found in context, returning {}", attributeName, resultIfMissing); return resultIfMissing; } else if (attribute.getValues().isEmpty()) { log.debug("Attribute {} has no values, returning {}", attributeName, resultIfMissing); return resultIfMissing; } String dateString; for (final IdPAttributeValue<?> value : attribute.getValues()) { if (value instanceof StringAttributeValue) { dateString = ((StringAttributeValue) value).getValue(); try { if (dateTimeFormatter.parseDateTime(dateString).plus(systemTimeOffset).isAfterNow()) { return true; } } catch (final RuntimeException e) { log.info("{} is not a valid date for the configured date parser", dateString); } } } return false; }
/** {@inheritDoc} */ @Override protected boolean hasMatch(@Nonnull @NonnullElements final Map<String, IdPAttribute> attributeMap) { if (attributeId == null || pattern == null) { log.warn("Attribute ID or regular expression were not set"); return false; } final IdPAttribute attribute = attributeMap.get(attributeId); if (attribute == null) { log.debug("Attribute '{}' not found in context", attributeId); return false; } for (final IdPAttributeValue<?> value : attribute.getValues()) { if (value instanceof StringAttributeValue) { final Matcher m = pattern.matcher((String) value.getValue()); if (m.matches()) { log.debug("Found matching value '{}' in attribute '{}'", m.group(), attributeId); return true; } } } log.debug("Attribute '{}' values not matched", attributeId); return false; }
/** {@inheritDoc} */ @Override @Nullable public Set<IdPAttributeValue<?>> getMatchingValues(@Nonnull final IdPAttribute attribute, @Nonnull final AttributeFilterContext filterContext) { final Tristate result= rule.matches(filterContext); if (Tristate.FAIL == result) { log.warn("{} The rule returned FAIL, returning null", getLogPrefix()); return null; } else if (Tristate.FALSE == result) { log.debug("{} The rule returned FALSE, no values returned", getLogPrefix()); return Collections.EMPTY_SET; } else { log.debug("{} The rule returned TRUE, all values returned", getLogPrefix()); return ImmutableSet.copyOf(attribute.getValues()); } }
/** * Compare the flow's custom principal names to the string values of the attribute. * * @param flow flow to examine * * @return a match between the flow's principal names and the attribute's string values, or null */ @Nullable private String getMatch(@Nonnull final AuthenticationFlowDescriptor flow) { log.debug("{} Looking for match for flow {} against values for attribute {}", getLogPrefix(), flow.getId(), attribute.getId()); for (final Principal p : flow.getSupportedPrincipals()) { log.debug("{} Comparing principal {} against attribute values {}", getLogPrefix(), p.getName(), attribute.getValues()); for (final IdPAttributeValue val : attribute.getValues()) { if (val instanceof StringAttributeValue && Objects.equals(val.getValue(), p.getName())) { return p.getName(); } } } return null; }
/** {@inheritDoc} */ @Override protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext, @Nonnull final AuthenticationContext authenticationContext) { if (!super.doPreExecute(profileRequestContext, authenticationContext) || attributeId == null) { return false; } DeprecationSupport.warnOnce(ObjectType.ACTION, getClass().getSimpleName(), null, "the MFA login flow"); final AttributeContext attributeCtx = attributeContextLookupStrategy.apply(profileRequestContext); if (attributeCtx == null) { log.debug("{} Request does not contain an AttributeContext, nothing to do", getLogPrefix()); return false; } attribute = attributeCtx.getIdPAttributes().get(attributeId); if (attribute == null || attribute.getValues().isEmpty()) { log.debug("{} Attribute {} has no values, nothing to do", getLogPrefix(), attributeId); return false; } return true; }
/** * Compare the result's custom principal names to the string values of the attribute. * * @param result result to examine * * @return a match between the result's principal names and the attribute's string values, or null */ @Nullable private String getMatch(@Nonnull final AuthenticationResult result) { log.debug("{} Looking for match for active result of flow {} against values for attribute {}", getLogPrefix(), result.getAuthenticationFlowId(), attribute.getId()); for (final Principal p : result.getSupportedPrincipals(Principal.class)) { log.debug("{} Comparing principal {} against attribute values {}", getLogPrefix(), p.getName(), attribute.getValues()); for (final IdPAttributeValue val : attribute.getValues()) { if (val instanceof StringAttributeValue && Objects.equals(val.getValue(), p.getName())) { return p.getName(); } } } return null; }
/** * Ensure that all the values in the attribute are of the correct type. * * @param attribute the attribute to look at */ private void checkValues(final IdPAttribute attribute) { if (null == attribute.getValues()) { log.info("{} Attribute '{}' has no values provided.", getLogPrefix(), attribute.getId()); attribute.setValues(Collections.<IdPAttributeValue<?>> emptyList()); return; } log.debug("{} Attribute '{}' has {} value(s).", getLogPrefix(), attribute.getId(), attribute.getValues().size()); final List<IdPAttributeValue<?>> inputValues = attribute.getValues(); final List<IdPAttributeValue<?>> outputValues = new ArrayList<>(inputValues.size()); for (final Object o : inputValues) { if (o instanceof IdPAttributeValue<?>) { outputValues.add((IdPAttributeValue<?>) o); } else { log.error("{} Attribute '{} has attribute value of type {}. This will be ignored", getLogPrefix(), attribute.getId(), o.getClass().getName()); } } attribute.setValues(outputValues); } }
/** * Ensure that all the values in the attribute are of the correct type. * * @param attribute the attribute to look at */ private void checkValues(final IdPAttribute attribute) { if (null == attribute.getValues()) { log.info("{} Attribute '{}' has no values provided.", getLogPrefix(), attribute.getId()); attribute.setValues(Collections.<IdPAttributeValue<?>> emptyList()); return; } log.debug("{} Attribute '{}' has {} value(s).", getLogPrefix(), attribute.getId(), attribute.getValues().size()); final List<IdPAttributeValue<?>> inputValues = attribute.getValues(); final List<IdPAttributeValue<?>> outputValues = new ArrayList<>(inputValues.size()); for (final Object o : inputValues) { if (o instanceof IdPAttributeValue<?>) { outputValues.add((IdPAttributeValue<?>) o); } else { log.error("{} Attribute '{} has attribute value of type {}. This will be ignored", getLogPrefix(), attribute.getId(), o.getClass().getName()); } } attribute.setValues(outputValues); }
/** * Look for a matching value in an attribute. * * @param toMatch value to look for * @param attribute attribute to check * * @return true iff the value is one of the attribute's values */ protected boolean findMatch(@Nonnull @NotEmpty final String toMatch, @Nonnull final IdPAttribute attribute) { if ("*".equals(toMatch)) { log.debug("Wildcard (*) value rule for attribute {}", attribute.getId()); return true; } else { for (final IdPAttributeValue<?> value : attribute.getValues()) { if (value instanceof StringAttributeValue) { if (toMatch.equals(value.getValue())) { log.debug("Found matching value ({}) in attribute {}", toMatch, attribute.getId()); return true; } } } } return false; }
/** * Look for a matching value in an attribute. * * @param toMatch value to look for * @param attribute attribute to check * * @return true iff the value is one of the attribute's values */ protected boolean findMatch(@Nonnull @NotEmpty final String toMatch, @Nonnull final IdPAttribute attribute) { if ("*".equals(toMatch)) { log.debug("Wildcard (*) value rule for attribute {}", attribute.getId()); return true; } else { for (final IdPAttributeValue<?> value : attribute.getValues()) { if (value instanceof StringAttributeValue) { if (toMatch.equals(value.getValue())) { log.debug("Found matching value ({}) in attribute {}", toMatch, attribute.getId()); return true; } } } } return false; }
/** * Clones an attribute. The clone will contains defensive copies of this objects display descriptions and names, * encoders, and values. The elements of each collection, however, are not themselves cloned. * * {@inheritDoc} */ @Override @Nonnull public IdPAttribute clone() throws CloneNotSupportedException { final IdPAttribute clone = (IdPAttribute) super.clone(); clone.setDisplayDescriptions(getDisplayDescriptions()); clone.setDisplayNames(getDisplayNames()); clone.setEncoders(getEncoders()); clone.setValues(getValues()); return clone; }
/** * Applies this filter policy to the given filter context if it is applicable. * * @param filterContext current filter context * * @throws AttributeFilterException thrown if there is a problem filtering out the attributes and values for this * request */ public void apply(@Nonnull final AttributeFilterContext filterContext) throws AttributeFilterException { ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this); ComponentSupport.ifDestroyedThrowDestroyedComponentException(this); Constraint.isNotNull(filterContext, "Attribute filter context can not be null"); if (!isApplicable(filterContext)) { return; } final Map<String, IdPAttribute> attributes = filterContext.getPrefilteredIdPAttributes(); log.debug("{} Applying attribute filter policy to current set of attributes: {}", getLogPrefix(), attributes.keySet()); IdPAttribute attribute; for (final AttributeRule valuePolicy : valuePolicies) { attribute = attributes.get(valuePolicy.getAttributeId()); if (attribute != null) { if (!attribute.getValues().isEmpty()) { valuePolicy.apply(attribute, filterContext); } } } }
/** {@inheritDoc} */ @Override @Nonnull @NotEmpty public String serialize(@Nonnull final Principal principal) throws IOException { final StringWriter sink = new StringWriter(128); final JsonGenerator gen = getJsonGenerator(sink); gen.writeStartObject() .write(PRINCIPAL_NAME_FIELD, principal.getName()); final IdPAttribute attribute = ((IdPAttributePrincipal) principal).getAttribute(); final JsonArrayBuilder arrayBuilder = getJsonArrayBuilder(); for (final IdPAttributeValue<?> value : attribute.getValues()) { final JsonObject obj = serializeValue(value); if (obj != null) { arrayBuilder.add(obj); } else { log.warn("Skipping unsupported attribute value type ({})", value.getClass()); } } gen.write(PRINCIPAL_ENTRY_FIELD, arrayBuilder.build()); gen.writeEnd(); gen.close(); return sink.toString(); }