001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2020, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.openid.connect.sdk.federation.trust; 019 020 021import java.util.HashSet; 022 023import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement; 024import com.nimbusds.openid.connect.sdk.federation.trust.constraints.TrustChainConstraints; 025 026 027/** 028 * Trust chain set with methods for {@link #getShortest getting the shortest 029 * chain} and {@link #filter filtering according to path length and entity ID 030 * constraints}. 031 */ 032public class TrustChainSet extends HashSet<TrustChain> { 033 034 035 private static final long serialVersionUID = -2449324224888772451L; 036 037 038 /** 039 * Returns the shortest trust chain in this set. 040 * 041 * @return The (first) shortest chain, {@code null} for an empty set. 042 */ 043 public TrustChain getShortest() { 044 045 TrustChain shortest = null; 046 047 for (TrustChain chain: this) { 048 if (chain.length() == 1) { 049 return chain; // return immediately 050 } else if (shortest == null) { 051 shortest = chain; // record first 052 } else if (chain.length() < shortest.length()) { 053 shortest = chain; 054 } 055 } 056 057 return shortest; 058 } 059 060 061 /** 062 * Returns a filtered trust chain set according to constraints. 063 * 064 * @param constraints The constraints. Must not be {@code null}. 065 * 066 * @return The filtered trust chain set. 067 */ 068 public TrustChainSet filter(final TrustChainConstraints constraints) { 069 070 TrustChainSet permitted = new TrustChainSet(); 071 072 for (TrustChain chain: this) { 073 074 if (constraints.getMaxPathLength() < 0 || chain.length() -1 <= constraints.getMaxPathLength()) { 075 076 boolean foundNonPermitted = false; 077 078 for (EntityStatement stmt: chain.getSuperiorStatements()) { 079 080 if (! constraints.isPermitted(stmt.getClaimsSet().getIssuerEntityID())) { 081 foundNonPermitted = true; 082 break; 083 } 084 } 085 086 if (! foundNonPermitted) { 087 permitted.add(chain); 088 } 089 } 090 } 091 092 return permitted; 093 } 094}