001/*******************************************************************************
002 * Copyright 2017 The MIT Internet Trust Consortium
003 *
004 * Portions copyright 2011-2013 The MITRE Corporation
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the 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
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 *******************************************************************************/
018package org.mitre.oauth2.model;
019
020import java.io.Serializable;
021import java.util.Collection;
022import java.util.HashMap;
023import java.util.HashSet;
024import java.util.Map;
025import java.util.Set;
026
027import javax.persistence.Basic;
028import javax.persistence.CascadeType;
029import javax.persistence.CollectionTable;
030import javax.persistence.Column;
031import javax.persistence.Convert;
032import javax.persistence.ElementCollection;
033import javax.persistence.Entity;
034import javax.persistence.FetchType;
035import javax.persistence.GeneratedValue;
036import javax.persistence.GenerationType;
037import javax.persistence.Id;
038import javax.persistence.JoinColumn;
039import javax.persistence.MapKeyColumn;
040import javax.persistence.NamedQueries;
041import javax.persistence.NamedQuery;
042import javax.persistence.OneToOne;
043import javax.persistence.Table;
044import javax.persistence.Transient;
045
046import org.mitre.oauth2.model.convert.SerializableStringConverter;
047import org.mitre.oauth2.model.convert.SimpleGrantedAuthorityStringConverter;
048import org.springframework.security.core.GrantedAuthority;
049import org.springframework.security.oauth2.provider.OAuth2Authentication;
050import org.springframework.security.oauth2.provider.OAuth2Request;
051
052@Entity
053@Table(name = "authentication_holder")
054@NamedQueries ({
055        @NamedQuery(name = AuthenticationHolderEntity.QUERY_ALL, query = "select a from AuthenticationHolderEntity a"),
056        @NamedQuery(name = AuthenticationHolderEntity.QUERY_GET_UNUSED, query = "select a from AuthenticationHolderEntity a where " +
057                        "a.id not in (select t.authenticationHolder.id from OAuth2AccessTokenEntity t) and " +
058                        "a.id not in (select r.authenticationHolder.id from OAuth2RefreshTokenEntity r) and " +
059                        "a.id not in (select c.authenticationHolder.id from AuthorizationCodeEntity c)")
060})
061public class AuthenticationHolderEntity {
062
063        public static final String QUERY_GET_UNUSED = "AuthenticationHolderEntity.getUnusedAuthenticationHolders";
064        public static final String QUERY_ALL = "AuthenticationHolderEntity.getAll";
065
066        private Long id;
067
068        private SavedUserAuthentication userAuth;
069
070        private Collection<GrantedAuthority> authorities;
071
072        private Set<String> resourceIds;
073
074        private boolean approved;
075
076        private String redirectUri;
077
078        private Set<String> responseTypes;
079
080        private Map<String, Serializable> extensions;
081
082        private String clientId;
083
084        private Set<String> scope;
085
086        private Map<String, String> requestParameters;
087
088        public AuthenticationHolderEntity() {
089
090        }
091
092        @Id
093        @GeneratedValue(strategy = GenerationType.IDENTITY)
094        @Column(name = "id")
095        public Long getId() {
096                return id;
097        }
098
099        public void setId(Long id) {
100                this.id = id;
101        }
102
103        @Transient
104        public OAuth2Authentication getAuthentication() {
105                // TODO: memoize this
106                return new OAuth2Authentication(createOAuth2Request(), getUserAuth());
107        }
108
109        /**
110         * @return
111         */
112        private OAuth2Request createOAuth2Request() {
113                return new OAuth2Request(requestParameters, clientId, authorities, approved, scope, resourceIds, redirectUri, responseTypes, extensions);
114        }
115
116        public void setAuthentication(OAuth2Authentication authentication) {
117
118                // pull apart the request and save its bits
119                OAuth2Request o2Request = authentication.getOAuth2Request();
120                setAuthorities(o2Request.getAuthorities() == null ? null : new HashSet<>(o2Request.getAuthorities()));
121                setClientId(o2Request.getClientId());
122                setExtensions(o2Request.getExtensions() == null ? null : new HashMap<>(o2Request.getExtensions()));
123                setRedirectUri(o2Request.getRedirectUri());
124                setRequestParameters(o2Request.getRequestParameters() == null ? null : new HashMap<>(o2Request.getRequestParameters()));
125                setResourceIds(o2Request.getResourceIds() == null ? null : new HashSet<>(o2Request.getResourceIds()));
126                setResponseTypes(o2Request.getResponseTypes() == null ? null : new HashSet<>(o2Request.getResponseTypes()));
127                setScope(o2Request.getScope() == null ? null : new HashSet<>(o2Request.getScope()));
128                setApproved(o2Request.isApproved());
129
130                if (authentication.getUserAuthentication() != null) {
131                        this.userAuth = new SavedUserAuthentication(authentication.getUserAuthentication());
132                } else {
133                        this.userAuth = null;
134                }
135        }
136
137        /**
138         * @return the userAuth
139         */
140        @OneToOne(cascade=CascadeType.ALL)
141        @JoinColumn(name = "user_auth_id")
142        public SavedUserAuthentication getUserAuth() {
143                return userAuth;
144        }
145
146        /**
147         * @param userAuth the userAuth to set
148         */
149        public void setUserAuth(SavedUserAuthentication userAuth) {
150                this.userAuth = userAuth;
151        }
152
153        /**
154         * @return the authorities
155         */
156        @ElementCollection(fetch = FetchType.EAGER)
157        @CollectionTable(
158                        name="authentication_holder_authority",
159                        joinColumns=@JoinColumn(name="owner_id")
160                        )
161        @Convert(converter = SimpleGrantedAuthorityStringConverter.class)
162        @Column(name="authority")
163        public Collection<GrantedAuthority> getAuthorities() {
164                return authorities;
165        }
166
167        /**
168         * @param authorities the authorities to set
169         */
170        public void setAuthorities(Collection<GrantedAuthority> authorities) {
171                this.authorities = authorities;
172        }
173
174        /**
175         * @return the resourceIds
176         */
177        @ElementCollection(fetch = FetchType.EAGER)
178        @CollectionTable(
179                        name="authentication_holder_resource_id",
180                        joinColumns=@JoinColumn(name="owner_id")
181                        )
182        @Column(name="resource_id")
183        public Set<String> getResourceIds() {
184                return resourceIds;
185        }
186
187        /**
188         * @param resourceIds the resourceIds to set
189         */
190        public void setResourceIds(Set<String> resourceIds) {
191                this.resourceIds = resourceIds;
192        }
193
194        /**
195         * @return the approved
196         */
197        @Basic
198        @Column(name="approved")
199        public boolean isApproved() {
200                return approved;
201        }
202
203        /**
204         * @param approved the approved to set
205         */
206        public void setApproved(boolean approved) {
207                this.approved = approved;
208        }
209
210        /**
211         * @return the redirectUri
212         */
213        @Basic
214        @Column(name="redirect_uri")
215        public String getRedirectUri() {
216                return redirectUri;
217        }
218
219        /**
220         * @param redirectUri the redirectUri to set
221         */
222        public void setRedirectUri(String redirectUri) {
223                this.redirectUri = redirectUri;
224        }
225
226        /**
227         * @return the responseTypes
228         */
229        @ElementCollection(fetch = FetchType.EAGER)
230        @CollectionTable(
231                        name="authentication_holder_response_type",
232                        joinColumns=@JoinColumn(name="owner_id")
233                        )
234        @Column(name="response_type")
235        public Set<String> getResponseTypes() {
236                return responseTypes;
237        }
238
239        /**
240         * @param responseTypes the responseTypes to set
241         */
242        public void setResponseTypes(Set<String> responseTypes) {
243                this.responseTypes = responseTypes;
244        }
245
246        /**
247         * @return the extensions
248         */
249        @ElementCollection(fetch = FetchType.EAGER)
250        @CollectionTable(
251                        name="authentication_holder_extension",
252                        joinColumns=@JoinColumn(name="owner_id")
253                        )
254        @Column(name="val")
255        @MapKeyColumn(name="extension")
256        @Convert(converter=SerializableStringConverter.class)
257        public Map<String, Serializable> getExtensions() {
258                return extensions;
259        }
260
261        /**
262         * @param extensions the extensions to set
263         */
264        public void setExtensions(Map<String, Serializable> extensions) {
265                this.extensions = extensions;
266        }
267
268        /**
269         * @return the clientId
270         */
271        @Basic
272        @Column(name="client_id")
273        public String getClientId() {
274                return clientId;
275        }
276
277        /**
278         * @param clientId the clientId to set
279         */
280        public void setClientId(String clientId) {
281                this.clientId = clientId;
282        }
283
284        /**
285         * @return the scope
286         */
287        @ElementCollection(fetch = FetchType.EAGER)
288        @CollectionTable(
289                        name="authentication_holder_scope",
290                        joinColumns=@JoinColumn(name="owner_id")
291                        )
292        @Column(name="scope")
293        public Set<String> getScope() {
294                return scope;
295        }
296
297        /**
298         * @param scope the scope to set
299         */
300        public void setScope(Set<String> scope) {
301                this.scope = scope;
302        }
303
304        /**
305         * @return the requestParameters
306         */
307        @ElementCollection(fetch = FetchType.EAGER)
308        @CollectionTable(
309                        name="authentication_holder_request_parameter",
310                        joinColumns=@JoinColumn(name="owner_id")
311                        )
312        @Column(name="val")
313        @MapKeyColumn(name="param")
314        public Map<String, String> getRequestParameters() {
315                return requestParameters;
316        }
317
318        /**
319         * @param requestParameters the requestParameters to set
320         */
321        public void setRequestParameters(Map<String, String> requestParameters) {
322                this.requestParameters = requestParameters;
323        }
324
325
326
327}