001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, 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.assurance.evidences;
019
020
021import java.util.LinkedList;
022import java.util.List;
023
024import net.minidev.json.JSONAware;
025import net.minidev.json.JSONObject;
026
027import com.nimbusds.oauth2.sdk.ParseException;
028import com.nimbusds.oauth2.sdk.util.CollectionUtils;
029import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
030import com.nimbusds.openid.connect.sdk.assurance.evidences.attachment.Attachment;
031
032
033/**
034 * The base abstract class for identity evidences.
035 *
036 * <p>Related specifications:
037 *
038 * <ul>
039 *     <li>OpenID Connect for Identity Assurance 1.0, section 5.1.1.
040 * </ul>
041 */
042public abstract class IdentityEvidence implements JSONAware {
043        
044        
045        /**
046         * The evidence type.
047         */
048        private final IdentityEvidenceType evidenceType;
049        
050        
051        /**
052         * The optional attachments.
053         */
054        private final List<Attachment> attachments;
055        
056        
057        /**
058         * Creates a new evidence with the specified type.
059         *
060         * @param evidenceType The evidence type. Must not be {@code null}.
061         * @param attachments  The optional attachments, {@code null} if not
062         *                     specified.
063         */
064        protected IdentityEvidence(final IdentityEvidenceType evidenceType,
065                                   final List<Attachment> attachments) {
066                if (evidenceType == null) {
067                        throw new IllegalArgumentException("The evidence type must not be null");
068                }
069                this.evidenceType = evidenceType;
070                
071                this.attachments = attachments;
072        }
073        
074        
075        /**
076         * Returns the evidence type.
077         *
078         * @return The evidence type.
079         */
080        public IdentityEvidenceType getEvidenceType() {
081                return evidenceType;
082        }
083        
084        
085        /**
086         * Returns the optional attachments.
087         *
088         * @return The attachments, {@code null} if not specified.
089         */
090        public List<Attachment> getAttachments() {
091                return attachments;
092        }
093        
094        
095        /**
096         * Casts this identity evidence to a document evidence.
097         *
098         * @return The document evidence.
099         */
100        public DocumentEvidence toDocumentEvidence() {
101                
102                return (DocumentEvidence)this;
103        }
104        
105        
106        /**
107         * Casts this identity evidence to an ID document evidence.
108         *
109         * @return The ID document evidence.
110         */
111        public IDDocumentEvidence toIDDocumentEvidence() {
112                
113                return (IDDocumentEvidence)this;
114        }
115        
116        
117        /**
118         * Casts this identity evidence to an electronic record evidence.
119         *
120         * @return The electronic record evidence.
121         */
122        public ElectronicRecordEvidence toElectronicRecordEvidence() {
123                
124                return (ElectronicRecordEvidence)this;
125        }
126        
127        
128        /**
129         * Casts this identity evidence to a vouch evidence.
130         *
131         * @return The vouch evidence.
132         */
133        public VouchEvidence toVouchEvidence() {
134                
135                return (VouchEvidence)this;
136        }
137        
138        
139        /**
140         * Casts this identity evidence to a utility bill evidence.
141         *
142         * @return The utility bill evidence.
143         */
144        public UtilityBillEvidence toUtilityBillEvidence() {
145                
146                return (UtilityBillEvidence)this;
147        }
148        
149        
150        /**
151         * Casts this identity evidence to an electronic signature evidence.
152         *
153         * @return The electronic signature evidence.
154         */
155        public ElectronicSignatureEvidence toElectronicSignatureEvidence() {
156                
157                return (ElectronicSignatureEvidence)this;
158        }
159        
160        
161        /**
162         * Casts this identity evidence to a QES evidence.
163         *
164         * @return The QES evidence.
165         */
166        public QESEvidence toQESEvidence() {
167                
168                return (QESEvidence)this;
169        }
170        
171        
172        /**
173         * Returns a JSON object representation of this evidence.
174         *
175         * @return The JSON object.
176         */
177        public JSONObject toJSONObject() {
178        
179                JSONObject o = new JSONObject();
180                
181                o.put("type", getEvidenceType().getValue());
182                
183                if (CollectionUtils.isNotEmpty(getAttachments())) {
184                        List<Object> attachmentsJSONArray = new LinkedList<>();
185                        for (Attachment attachment: getAttachments()) {
186                                attachmentsJSONArray.add(attachment.toJSONObject());
187                        }
188                        o.put("attachments", attachmentsJSONArray);
189                }
190                return o;
191        }
192        
193        
194        @Override
195        public String toJSONString() {
196                return toJSONObject().toJSONString();
197        }
198        
199        
200        /**
201         * Parses an identity evidence from the specified JSON object.
202         *
203         * @param jsonObject The JSON object. Must not be {@code null}.
204         *
205         * @return A {@link DocumentEvidence}, {@link IDDocumentEvidence},
206         *         {@link ElectronicRecordEvidence}, {@link VouchEvidence},
207         *         {@link QESEvidence}, {@link ElectronicSignatureEvidence}, or
208         *         {@link UtilityBillEvidence} instance.
209         *
210         * @throws ParseException If parsing failed or the evidence type isn't
211         *                        supported.
212         */
213        public static IdentityEvidence parse(final JSONObject jsonObject)
214                throws ParseException {
215                
216                IdentityEvidenceType type = new IdentityEvidenceType(JSONObjectUtils.getString(jsonObject, "type"));
217                
218                if (IdentityEvidenceType.DOCUMENT.equals(type)) {
219                        return DocumentEvidence.parse(jsonObject);
220                } else if (IdentityEvidenceType.ID_DOCUMENT.equals(type)) {
221                        return IDDocumentEvidence.parse(jsonObject);
222                } else if (IdentityEvidenceType.ELECTRONIC_RECORD.equals(type)) {
223                        return ElectronicRecordEvidence.parse(jsonObject);
224                } else if (IdentityEvidenceType.VOUCH.equals(type)) {
225                        return VouchEvidence.parse(jsonObject);
226                } else if (IdentityEvidenceType.ELECTRONIC_SIGNATURE.equals(type)) {
227                        return ElectronicSignatureEvidence.parse(jsonObject);
228                } else if (IdentityEvidenceType.QES.equals(type)) {
229                        return QESEvidence.parse(jsonObject);
230                } else if (IdentityEvidenceType.UTILITY_BILL.equals(type)) {
231                        return UtilityBillEvidence.parse(jsonObject);
232                } else {
233                        throw new ParseException("Unsupported type: " + type);
234                }
235        }
236        
237        
238        /**
239         * Ensures the {@code type} member of the specified JSON object matches
240         * the expected.
241         *
242         * @param expectedType The expected type. Must not be {@code null}.
243         * @param jsonObject The JSON object. Must not be {@code null}.
244         *
245         * @throws ParseException If parsing failed or mismatch.
246         */
247        protected static void ensureType(final IdentityEvidenceType expectedType, JSONObject jsonObject)
248                throws ParseException {
249                
250                String parsedType = JSONObjectUtils.getString(jsonObject, "type");
251                
252                if (! expectedType.getValue().equals(parsedType)) {
253                        throw new ParseException("The identity evidence type must be " + expectedType);
254                }
255        }
256}