001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2021, 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.attachment;
019
020
021import java.util.LinkedList;
022import java.util.List;
023import java.util.Objects;
024
025import net.minidev.json.JSONArray;
026import net.minidev.json.JSONObject;
027
028import com.nimbusds.oauth2.sdk.ParseException;
029import com.nimbusds.oauth2.sdk.util.JSONArrayUtils;
030
031
032/**
033 * Identity evidence attachment.
034 *
035 * <p>Related specifications:
036 *
037 * <ul>
038 *     <li>OpenID Connect for Identity Assurance 1.0, section 5.1.2.
039 * </ul>
040 */
041public abstract class Attachment {
042        
043        
044        /**
045         * The attachment type.
046         */
047        private final AttachmentType type;
048        
049        
050        /**
051         * The optional description.
052         */
053        private final String description;
054        
055        
056        /**
057         * Creates a new attachment with the specified description.
058         *
059         * @param type        The type. Must not be {@code null}.
060         * @param description The description, {@code null} if not specified.
061         */
062        protected Attachment(final AttachmentType type, final String description) {
063                Objects.requireNonNull(type);
064                this.type = type;
065                this.description = description;
066        }
067        
068        
069        /**
070         * Returns the type of this attachment.
071         *
072         * @return The type.
073         */
074        public AttachmentType getType() {
075                return type;
076        }
077        
078        
079        /**
080         * Returns the description.
081         *
082         * @return The description string.
083         */
084        public String getDescriptionString() {
085                return description;
086        }
087        
088        
089        /**
090         * Returns a JSON object representation of this attachment.
091         *
092         * @return The JSON object.
093         */
094        public JSONObject toJSONObject() {
095                
096                JSONObject o = new JSONObject();
097                if (getDescriptionString() != null) {
098                        o.put("desc", getDescriptionString());
099                }
100                return o;
101        }
102        
103        
104        @Override
105        public boolean equals(Object o) {
106                if (this == o) return true;
107                if (!(o instanceof Attachment)) return false;
108                Attachment that = (Attachment) o;
109                return Objects.equals(description, that.description);
110        }
111        
112        
113        @Override
114        public int hashCode() {
115                return Objects.hash(description);
116        }
117        
118        
119        /**
120         * Casts this attachment to an embedded attachment.
121         *
122         * @return The embedded attachment.
123         *
124         * @throws ClassCastException If the cast failed.
125         */
126        public EmbeddedAttachment toEmbeddedAttachment() {
127                
128                return (EmbeddedAttachment) this;
129        }
130        
131        
132        /**
133         * Casts this attachment to an external attachment.
134         *
135         * @return The external attachment.
136         *
137         * @throws ClassCastException If the cast failed.
138         */
139        public ExternalAttachment toExternalAttachment() {
140                
141                return (ExternalAttachment) this;
142        }
143        
144        
145        /**
146         * Parses an identity evidence attachment from the specified JSON
147         * object.
148         *
149         * @param jsonObject The JSON object. Must not be {@code null}.
150         *
151         * @return The identity evidence attachment.
152         *
153         * @throws ParseException If parsing failed.
154         */
155        public static Attachment parse(final JSONObject jsonObject)
156                throws ParseException {
157                
158                if (jsonObject.get("content") != null) {
159                        return EmbeddedAttachment.parse(jsonObject);
160                } else if (jsonObject.get("url") != null) {
161                        return ExternalAttachment.parse(jsonObject);
162                } else {
163                        throw new ParseException("Missing required attachment parameter(s)");
164                }
165        }
166        
167        
168        /**
169         * Parses a list of identity evidence attachments from the specified
170         * JSON array.
171         *
172         * @param jsonArray The JSON array, {@code null} if not specified.
173         *
174         * @return The list of identity evidence attachments, {@code null} if
175         *         not specified.
176         *
177         * @throws ParseException If parsing failed.
178         */
179        public static List<Attachment> parseList(final JSONArray jsonArray)
180                throws ParseException {
181                
182                if (jsonArray == null) {
183                        return null;
184                }
185                
186                List<Attachment> attachments = new LinkedList<>();
187                for (JSONObject attachmentObject: JSONArrayUtils.toJSONObjectList(jsonArray)) {
188                        attachments.add(Attachment.parse(attachmentObject));
189                }
190                return attachments;
191        }
192}