001package com.nimbusds.openid.connect.sdk.op;
002
003
004import java.util.ArrayList;
005import java.util.List;
006
007import net.jcip.annotations.Immutable;
008
009import com.nimbusds.openid.connect.sdk.AuthenticationRequest;
010import com.nimbusds.openid.connect.sdk.ClaimsRequest;
011import com.nimbusds.openid.connect.sdk.claims.ACR;
012import com.nimbusds.openid.connect.sdk.claims.ClaimRequirement;
013
014
015/**
016 * Resolved authentication Context Class Reference (ACR) request.
017 */
018@Immutable 
019public final class ACRRequest {
020
021
022        /**
023         * The essential ACR values.
024         */
025        private final List<ACR> essentialACRs;
026
027
028        /**
029         * The voluntary ACR values.
030         */
031        private final List<ACR> voluntaryACRs;
032
033
034        /**
035         * Creates a new Authentication Context Class Reference (ACR) request.
036         *
037         * @param essentialACRs The requested essential ACR values, by order of
038         *                      preference, {@code null} if not specified.
039         * @param voluntaryACRs The requested voluntary ACR values, by order of
040         *                      preference, {@code null} if not specified.
041         */
042        public ACRRequest(final List<ACR> essentialACRs, final List<ACR> voluntaryACRs) {
043
044                this.essentialACRs = essentialACRs;
045                this.voluntaryACRs = voluntaryACRs;
046        }
047        
048
049        /**
050         * Gets the requested essential ACR values.
051         * 
052         * @return The essential ACR values, by order of preference, 
053         *         {@code null} if not specified.
054         */
055        public List<ACR> getEssentialACRs() {
056                
057                return essentialACRs;
058        }
059        
060        
061        /**
062         * Gets the requested voluntary ACR values.
063         * 
064         * @return The voluntary ACR values, by order of preference, 
065         *         {@code null} if not specified.
066         */
067        public List<ACR> getVoluntaryACRs() {
068                
069                return voluntaryACRs;
070        }
071        
072        
073        /**
074         * Checks if this authentication Context Class Reference (ACR) request
075         * has not essential or voluntary values specified.
076         * 
077         * @return {@code true} if this ACR request doesn't specify any 
078         *         essential or voluntary values, else {@code false}.
079         */
080        public boolean isEmpty() {
081
082                return !(essentialACRs != null && !essentialACRs.isEmpty()) &&
083                       !(voluntaryACRs != null && !voluntaryACRs.isEmpty());
084        }
085        
086        
087        
088        /**
089         * Resolves the requested essential and voluntary ACR values from the
090         * specified OpenID Connect authentication request.
091         * 
092         * @param authRequest The OpenID Connect authentication request. Should
093         *                    be resolved. Must not be {@code null}.
094         * 
095         * @return The resolved ACR request.
096         */
097        public static ACRRequest resolve(final AuthenticationRequest authRequest) {
098                
099                List<ACR> essentialACRs = null;
100                List<ACR> voluntaryACRs = null;
101                
102                ClaimsRequest claimsRequest = authRequest.getClaims();
103                
104                if (claimsRequest != null) {
105                        
106                        for (ClaimsRequest.Entry claimEntry: claimsRequest.getIDTokenClaims()) {
107                                
108                                if (! claimEntry.getClaimName().equals("acr"))
109                                        continue;
110                                
111                                if (claimEntry.getClaimRequirement().equals(ClaimRequirement.ESSENTIAL)) {
112                                        
113                                        essentialACRs = new ArrayList<>();
114                                        
115                                        if (claimEntry.getValue() != null)
116                                                essentialACRs.add(new ACR(claimEntry.getValue()));
117                                        
118                                        if (claimEntry.getValues() != null) {
119                                                
120                                                for (String v: claimEntry.getValues())
121                                                        essentialACRs.add(new ACR(v));
122                                        }
123                                        
124                                } else {
125                                        voluntaryACRs = new ArrayList<>();
126                                        
127                                        if (claimEntry.getValue() != null)
128                                                voluntaryACRs.add(new ACR(claimEntry.getValue()));
129                                        
130                                        if (claimEntry.getValues() != null) {
131                                                
132                                                for (String v: claimEntry.getValues())
133                                                        voluntaryACRs.add(new ACR(v));
134                                        }
135                                }
136                        }
137                }
138                
139                
140                List<ACR> topLevelACRs = authRequest.getACRValues();
141                
142                if (topLevelACRs != null) {
143                        
144                        if (voluntaryACRs == null)
145                                voluntaryACRs = new ArrayList<>();
146                        
147                        voluntaryACRs.addAll(topLevelACRs);
148                }
149                
150                return new ACRRequest(essentialACRs, voluntaryACRs);
151        }
152}