001/******************************************************************************* 002 * Copyright 2017 The MIT Internet Trust Consortium 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 *******************************************************************************/ 016 017package org.mitre.uma.service.impl; 018 019import java.util.Collection; 020import java.util.HashSet; 021 022import org.mitre.uma.model.Claim; 023import org.mitre.uma.model.ClaimProcessingResult; 024import org.mitre.uma.model.PermissionTicket; 025import org.mitre.uma.model.Policy; 026import org.mitre.uma.model.ResourceSet; 027import org.mitre.uma.service.ClaimsProcessingService; 028import org.springframework.stereotype.Service; 029 030/** 031 * Tests if all the claims in the required set have a matching 032 * value in the supplied set. 033 * 034 * @author jricher 035 * 036 */ 037@Service("matchAllClaimsOnAnyPolicy") 038public class MatchAllClaimsOnAnyPolicy implements ClaimsProcessingService { 039 040 /* (non-Javadoc) 041 * @see org.mitre.uma.service.ClaimsProcessingService#claimsAreSatisfied(java.util.Collection, java.util.Collection) 042 */ 043 @Override 044 public ClaimProcessingResult claimsAreSatisfied(ResourceSet rs, PermissionTicket ticket) { 045 Collection<Claim> allUnmatched = new HashSet<>(); 046 for (Policy policy : rs.getPolicies()) { 047 Collection<Claim> unmatched = checkIndividualClaims(policy.getClaimsRequired(), ticket.getClaimsSupplied()); 048 if (unmatched.isEmpty()) { 049 // we found something that's satisfied the claims, let's go with it! 050 return new ClaimProcessingResult(policy); 051 } else { 052 // otherwise add it to the stack to send back 053 allUnmatched.addAll(unmatched); 054 } 055 } 056 057 // otherwise, tell the caller that we'll need some set of these fulfilled somehow 058 return new ClaimProcessingResult(allUnmatched); 059 } 060 061 private Collection<Claim> checkIndividualClaims(Collection<Claim> claimsRequired, Collection<Claim> claimsSupplied) { 062 063 Collection<Claim> claimsUnmatched = new HashSet<>(claimsRequired); 064 065 // see if each of the required claims has a counterpart in the supplied claims set 066 for (Claim required : claimsRequired) { 067 for (Claim supplied : claimsSupplied) { 068 069 if (required.getIssuer().containsAll(supplied.getIssuer())) { 070 // it's from the right issuer 071 072 if (required.getName().equals(supplied.getName()) && 073 required.getValue().equals(supplied.getValue())) { 074 075 // the claim matched, pull it from the set 076 claimsUnmatched.remove(required); 077 078 } 079 080 } 081 } 082 } 083 084 // if there's anything left then the claims aren't satisfied, return the leftovers 085 return claimsUnmatched; 086 087 } 088 089}