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.constraints;
019
020
021import java.util.Objects;
022
023import net.jcip.annotations.Immutable;
024
025import com.nimbusds.openid.connect.sdk.federation.entities.EntityID;
026
027
028/**
029 * Subtree entity ID constraint.
030 *
031 * <p>Example: {@code https://.example.com} matches
032 * {@code https://my.example.com}, {@code https://my.host.example.com}, etc.
033 *
034 * <p>Related specifications:
035 *
036 * <ul>
037 *     <li>OpenID Connect Federation 1.0, section 5.2.2.
038 *     <li>RFC 5280, section 4.2.1.10.
039 * </ul>
040 */
041@Immutable
042public final class SubtreeEntityIDConstraint extends EntityIDConstraint {
043        
044        
045        private final String scheme;
046        
047        
048        private final String hostNameAndRemainderPattern;
049        
050        
051        /**
052         * Creates a new subtree entity ID constraint.
053         *
054         * @param entityIDPattern The entity ID pattern to match. Must not be
055         *                        {@code null}.
056         */
057        public SubtreeEntityIDConstraint(final String entityIDPattern) {
058                
059                if (entityIDPattern.startsWith("https://")) {
060                        scheme = "https://";
061                } else if (entityIDPattern.startsWith("http://")) {
062                        scheme = "http://";
063                } else {
064                        throw new IllegalArgumentException("The entity ID pattern must be an URI with https or http scheme");
065                }
066                
067                hostNameAndRemainderPattern = entityIDPattern.substring(scheme.length());
068                
069                if (! hostNameAndRemainderPattern.startsWith(".")) {
070                        throw new IllegalArgumentException("The host part of the entity ID pattern must start with dot (.)");
071                }
072        }
073        
074        
075        @Override
076        public boolean matches(final EntityID entityID) {
077                
078                String schemeIN;
079                
080                if (entityID.getValue().startsWith("https://")) {
081                        schemeIN = "https://";
082                } else if (entityID.getValue().startsWith("http://")) {
083                        schemeIN = "http://";
084                } else {
085                        return false;
086                }
087                
088                if (! schemeIN.equals(scheme)) {
089                        return false;
090                }
091                
092                String patternIN = entityID.getValue().substring(schemeIN.length());
093                
094                return patternIN.endsWith(hostNameAndRemainderPattern);
095        }
096        
097        
098        @Override
099        public String toString() {
100                return scheme + hostNameAndRemainderPattern;
101        }
102        
103        
104        @Override
105        public boolean equals(Object o) {
106                if (this == o) return true;
107                if (!(o instanceof SubtreeEntityIDConstraint)) return false;
108                SubtreeEntityIDConstraint that = (SubtreeEntityIDConstraint) o;
109                return scheme.equals(that.scheme) &&
110                        hostNameAndRemainderPattern.equals(that.hostNameAndRemainderPattern);
111        }
112        
113        
114        @Override
115        public int hashCode() {
116                return Objects.hash(scheme, hostNameAndRemainderPattern);
117        }
118}