View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.core.persistence.jpa.entity;
20  
21  import com.fasterxml.jackson.core.type.TypeReference;
22  import java.util.ArrayList;
23  import java.util.List;
24  import java.util.Optional;
25  import java.util.stream.Collectors;
26  import java.util.stream.Stream;
27  import javax.persistence.Cacheable;
28  import javax.persistence.CascadeType;
29  import javax.persistence.Column;
30  import javax.persistence.Entity;
31  import javax.persistence.FetchType;
32  import javax.persistence.JoinColumn;
33  import javax.persistence.JoinTable;
34  import javax.persistence.Lob;
35  import javax.persistence.ManyToMany;
36  import javax.persistence.OneToOne;
37  import javax.persistence.PostLoad;
38  import javax.persistence.PostPersist;
39  import javax.persistence.PostUpdate;
40  import javax.persistence.PrePersist;
41  import javax.persistence.PreUpdate;
42  import javax.persistence.Table;
43  import javax.persistence.Transient;
44  import javax.validation.constraints.NotNull;
45  import org.apache.syncope.common.lib.to.Item;
46  import org.apache.syncope.common.lib.types.OIDCClientImplementationType;
47  import org.apache.syncope.core.persistence.api.entity.Implementation;
48  import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
49  import org.apache.syncope.core.persistence.api.entity.OIDCC4UIUserTemplate;
50  import org.apache.syncope.core.persistence.jpa.validation.entity.OIDCC4UIProviderCheck;
51  import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
52  import org.springframework.util.CollectionUtils;
53  
54  @Entity
55  @Table(name = JPAOIDCC4UIProvider.TABLE)
56  @Cacheable
57  @OIDCC4UIProviderCheck
58  public class JPAOIDCC4UIProvider extends AbstractGeneratedKeyEntity implements OIDCC4UIProvider {
59  
60      public static final String TABLE = "OIDCProvider";
61  
62      private static final long serialVersionUID = 1423093003585826403L;
63  
64      @Column(unique = true, nullable = false)
65      private String name;
66  
67      @Column(unique = true, nullable = false)
68      private String clientID;
69  
70      @Column(unique = true, nullable = false)
71      private String clientSecret;
72  
73      @Column(nullable = false)
74      private String authorizationEndpoint;
75  
76      @Column(nullable = false)
77      private String tokenEndpoint;
78  
79      @Column(nullable = false)
80      private String jwksUri;
81  
82      @Column(nullable = false)
83      private String issuer;
84  
85      @Column(nullable = true)
86      private String userinfoEndpoint;
87  
88      @Column(nullable = true)
89      private String endSessionEndpoint;
90  
91      private String scopes;
92  
93      @Column(nullable = false)
94      private boolean hasDiscovery;
95  
96      @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "op")
97      private JPAOIDCC4UIUserTemplate userTemplate;
98  
99      @Lob
100     private String items;
101 
102     @Transient
103     private final List<Item> itemList = new ArrayList<>();
104 
105     @NotNull
106     private Boolean createUnmatching = false;
107 
108     @NotNull
109     private Boolean selfRegUnmatching = false;
110 
111     @NotNull
112     private Boolean updateMatching = false;
113 
114     @ManyToMany(fetch = FetchType.EAGER)
115     @JoinTable(name = "OIDCProviderAction",
116             joinColumns =
117             @JoinColumn(name = "op_id"),
118             inverseJoinColumns =
119             @JoinColumn(name = "implementation_id"))
120     private List<JPAImplementation> actions = new ArrayList<>();
121 
122     @Override
123     public String getName() {
124         return name;
125     }
126 
127     @Override
128     public void setName(final String name) {
129         this.name = name;
130     }
131 
132     @Override
133     public String getClientID() {
134         return clientID;
135     }
136 
137     @Override
138     public void setClientID(final String clientID) {
139         this.clientID = clientID;
140     }
141 
142     @Override
143     public String getClientSecret() {
144         return clientSecret;
145     }
146 
147     @Override
148     public void setClientSecret(final String clientSecret) {
149         this.clientSecret = clientSecret;
150     }
151 
152     @Override
153     public String getAuthorizationEndpoint() {
154         return authorizationEndpoint;
155     }
156 
157     @Override
158     public void setAuthorizationEndpoint(final String authorizationEndpoint) {
159         this.authorizationEndpoint = authorizationEndpoint;
160     }
161 
162     @Override
163     public String getTokenEndpoint() {
164         return tokenEndpoint;
165     }
166 
167     @Override
168     public void setTokenEndpoint(final String tokenEndpoint) {
169         this.tokenEndpoint = tokenEndpoint;
170     }
171 
172     @Override
173     public String getJwksUri() {
174         return jwksUri;
175     }
176 
177     @Override
178     public void setJwksUri(final String jwksUri) {
179         this.jwksUri = jwksUri;
180     }
181 
182     @Override
183     public String getIssuer() {
184         return issuer;
185     }
186 
187     @Override
188     public void setIssuer(final String issuer) {
189         this.issuer = issuer;
190     }
191 
192     @Override
193     public String getUserinfoEndpoint() {
194         return userinfoEndpoint;
195     }
196 
197     @Override
198     public void setUserinfoEndpoint(final String userinfoEndpoint) {
199         this.userinfoEndpoint = userinfoEndpoint;
200     }
201 
202     @Override
203     public String getEndSessionEndpoint() {
204         return endSessionEndpoint;
205     }
206 
207     @Override
208     public void setEndSessionEndpoint(final String endSessionEndpoint) {
209         this.endSessionEndpoint = endSessionEndpoint;
210     }
211 
212     @Override
213     public List<String> getScopes() {
214         return Optional.ofNullable(scopes).
215                 map(s -> Stream.of(s.split(" ")).collect(Collectors.toList())).
216                 orElse(List.of());
217     }
218 
219     @Override
220     public void setScopes(final List<String> scopes) {
221         this.scopes = CollectionUtils.isEmpty(scopes)
222                 ? ""
223                 : scopes.stream().collect(Collectors.joining(" "));
224     }
225 
226     @Override
227     public boolean getHasDiscovery() {
228         return hasDiscovery;
229     }
230 
231     @Override
232     public void setHasDiscovery(final boolean hasDiscovery) {
233         this.hasDiscovery = hasDiscovery;
234     }
235 
236     @Override
237     public boolean isCreateUnmatching() {
238         return createUnmatching;
239     }
240 
241     @Override
242     public void setCreateUnmatching(final boolean createUnmatching) {
243         this.createUnmatching = createUnmatching;
244     }
245 
246     @Override
247     public boolean isSelfRegUnmatching() {
248         return selfRegUnmatching;
249     }
250 
251     @Override
252     public void setSelfRegUnmatching(final boolean selfRegUnmatching) {
253         this.selfRegUnmatching = selfRegUnmatching;
254     }
255 
256     @Override
257     public boolean isUpdateMatching() {
258         return updateMatching;
259     }
260 
261     @Override
262     public void setUpdateMatching(final boolean updateMatching) {
263         this.updateMatching = updateMatching;
264     }
265 
266     @Override
267     public OIDCC4UIUserTemplate getUserTemplate() {
268         return userTemplate;
269     }
270 
271     @Override
272     public void setUserTemplate(final OIDCC4UIUserTemplate userTemplate) {
273         checkType(userTemplate, JPAOIDCC4UIUserTemplate.class);
274         this.userTemplate = (JPAOIDCC4UIUserTemplate) userTemplate;
275     }
276 
277     @Override
278     public List<Item> getItems() {
279         return itemList;
280     }
281 
282     @Override
283     public Optional<Item> getConnObjectKeyItem() {
284         return getItems().stream().filter(Item::isConnObjectKey).findFirst();
285     }
286 
287     @Override
288     public void setConnObjectKeyItem(final Item item) {
289         item.setConnObjectKey(true);
290         getItems().add(item);
291     }
292 
293     @Override
294     public boolean add(final Implementation action) {
295         checkType(action, JPAImplementation.class);
296         checkImplementationType(action, OIDCClientImplementationType.OP_ACTIONS);
297         return actions.contains((JPAImplementation) action) || actions.add((JPAImplementation) action);
298     }
299 
300     @Override
301     public List<? extends Implementation> getActions() {
302         return actions;
303     }
304 
305     protected void json2list(final boolean clearFirst) {
306         if (clearFirst) {
307             getItems().clear();
308         }
309         if (items != null) {
310             getItems().addAll(
311                     POJOHelper.deserialize(items, new TypeReference<List<Item>>() {
312                     }));
313         }
314     }
315 
316     @PostLoad
317     public void postLoad() {
318         json2list(false);
319     }
320 
321     @PostPersist
322     @PostUpdate
323     public void postSave() {
324         json2list(true);
325     }
326 
327     @PrePersist
328     @PreUpdate
329     public void list2json() {
330         items = POJOHelper.serialize(getItems());
331     }
332 }