1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.persistence.jpa.inner;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertNotEquals;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertNull;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26 import static org.junit.jupiter.api.Assertions.fail;
27
28 import java.io.UnsupportedEncodingException;
29 import java.util.Arrays;
30 import java.util.Base64;
31 import java.util.Random;
32 import javax.validation.ValidationException;
33 import org.apache.syncope.common.lib.SyncopeConstants;
34 import org.apache.syncope.common.lib.types.AnyTypeKind;
35 import org.apache.syncope.common.lib.types.AttrSchemaType;
36 import org.apache.syncope.common.lib.types.CipherAlgorithm;
37 import org.apache.syncope.common.lib.types.EntityViolationType;
38 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
39 import org.apache.syncope.core.persistence.api.attrvalue.validation.PlainAttrValidationManager;
40 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
41 import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
42 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
43 import org.apache.syncope.core.persistence.api.dao.UserDAO;
44 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
45 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
46 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
47 import org.apache.syncope.core.persistence.api.entity.user.User;
48 import org.apache.syncope.core.persistence.jpa.AbstractTest;
49 import org.apache.syncope.core.spring.security.Encryptor;
50 import org.apache.syncope.core.spring.security.SecureRandomUtils;
51 import org.junit.jupiter.api.Tag;
52 import org.junit.jupiter.api.Test;
53 import org.springframework.beans.factory.annotation.Autowired;
54 import org.springframework.transaction.annotation.Transactional;
55
56 @Transactional("Master")
57 public class PlainAttrTest extends AbstractTest {
58
59 @Autowired
60 private UserDAO userDAO;
61
62 @Autowired
63 private PlainAttrDAO plainAttrDAO;
64
65 @Autowired
66 private PlainSchemaDAO plainSchemaDAO;
67
68 @Autowired
69 private AnyTypeClassDAO anyTypeClassDAO;
70
71 @Autowired
72 private PlainAttrValidationManager validator;
73
74 @Tag("plainAttrTable")
75 @Test
76 public void findByKey() {
77 UPlainAttr attribute = findPlainAttr("01f22fbd-b672-40af-b528-686d9b27ebc4", UPlainAttr.class);
78 assertNotNull(attribute);
79 attribute = findPlainAttr("9d0d9e40-1b18-488e-9482-37dab82163c9", UPlainAttr.class);
80 assertNotNull(attribute);
81 }
82
83 @Tag("plainAttrTable")
84 @Test
85 public void read() {
86 UPlainAttr attribute = findPlainAttr("01f22fbd-b672-40af-b528-686d9b27ebc4", UPlainAttr.class);
87 assertNotNull(attribute);
88 assertTrue(attribute.getValues().isEmpty());
89 assertNotNull(attribute.getUniqueValue());
90 }
91
92 @Test
93 public void save() throws ClassNotFoundException {
94 User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
95
96 PlainSchema emailSchema = plainSchemaDAO.find("email");
97 assertNotNull(emailSchema);
98
99 UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
100 attr.setOwner(user);
101 attr.setSchema(emailSchema);
102
103 Exception thrown = null;
104 try {
105 attr.add(validator, "john.doe@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
106 attr.add(validator, "mario.rossi@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
107 } catch (ValidationException e) {
108 thrown = e;
109 }
110 assertNull(thrown);
111
112 try {
113 attr.add(validator, "http://www.apache.org", anyUtilsFactory.getInstance(AnyTypeKind.USER));
114 } catch (ValidationException e) {
115 thrown = e;
116 }
117 assertNotNull(thrown);
118 }
119
120 @Test
121 public void saveWithEnum() throws ClassNotFoundException {
122 User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
123 assertNotNull(user);
124
125 PlainSchema gender = plainSchemaDAO.find("gender");
126 assertNotNull(gender);
127 assertNotNull(gender.getType());
128 assertNotNull(gender.getEnumerationValues());
129
130 UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
131 attribute.setOwner(user);
132 attribute.setSchema(gender);
133 user.add(attribute);
134
135 Exception thrown = null;
136 try {
137 attribute.add(validator, "A", anyUtilsFactory.getInstance(AnyTypeKind.USER));
138 } catch (ValidationException e) {
139 thrown = e;
140 }
141 assertNotNull(thrown);
142
143 attribute.add(validator, "M", anyUtilsFactory.getInstance(AnyTypeKind.USER));
144
145 InvalidEntityException iee = null;
146 try {
147 userDAO.save(user);
148 } catch (InvalidEntityException e) {
149 iee = e;
150 }
151 assertNull(iee);
152 }
153
154 @Test
155 public void invalidValueList() {
156 User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
157
158 PlainSchema emailSchema = plainSchemaDAO.find("email");
159 assertNotNull(emailSchema);
160
161 PlainSchema fullnameSchema = plainSchemaDAO.find("fullname");
162 assertNotNull(fullnameSchema);
163
164 UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
165 attr.setOwner(user);
166 attr.setSchema(emailSchema);
167
168 user.add(attr);
169
170 InvalidEntityException iee = null;
171 try {
172 userDAO.save(user);
173 fail("This should not happen");
174 } catch (InvalidEntityException e) {
175 iee = e;
176 }
177 assertNotNull(iee);
178
179 assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList));
180 }
181
182 @Tag("plainAttrTable")
183 @Test
184 public void invalidPlainAttr() {
185 User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
186
187 PlainSchema emailSchema = plainSchemaDAO.find("email");
188 assertNotNull(emailSchema);
189
190 PlainSchema fullnameSchema = plainSchemaDAO.find("fullname");
191 assertNotNull(fullnameSchema);
192
193 UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
194 attr.setOwner(user);
195 attr.setSchema(emailSchema);
196
197 UPlainAttrUniqueValue uauv = entityFactory.newEntity(UPlainAttrUniqueValue.class);
198 uauv.setAttr(attr);
199 uauv.setSchema(fullnameSchema);
200 uauv.setStringValue("a value");
201
202 attr.setUniqueValue(uauv);
203
204 user.add(attr);
205
206 InvalidEntityException iee = null;
207 try {
208 userDAO.save(user);
209 fail("This should not happen");
210 } catch (InvalidEntityException e) {
211 iee = e;
212 }
213 assertNotNull(iee);
214
215 assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList));
216
217 assertTrue(iee.hasViolation(EntityViolationType.InvalidPlainAttr));
218 }
219
220 @Test
221 public void saveWithEncrypted() throws Exception {
222 User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
223
224 PlainSchema obscureSchema = plainSchemaDAO.find("obscure");
225 assertNotNull(obscureSchema);
226 assertNotNull(obscureSchema.getSecretKey());
227 assertNotNull(obscureSchema.getCipherAlgorithm());
228
229 UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
230 attr.setOwner(user);
231 attr.setSchema(obscureSchema);
232 attr.add(validator, "testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER));
233 user.add(attr);
234
235 userDAO.save(user);
236
237 UPlainAttr obscure = user.getPlainAttr("obscure").get();
238 assertNotNull(obscure);
239 assertEquals(1, obscure.getValues().size());
240 assertEquals(Encryptor.getInstance(obscureSchema.getSecretKey()).
241 encode("testvalue", obscureSchema.getCipherAlgorithm()), obscure.getValues().get(0).getStringValue());
242 }
243
244 @Test
245 public void encryptedWithKeyAsSysProp() throws Exception {
246 PlainSchema obscureSchema = plainSchemaDAO.find("obscure");
247 assertNotNull(obscureSchema);
248
249 PlainSchema obscureWithKeyAsSysprop = entityFactory.newEntity(PlainSchema.class);
250 obscureWithKeyAsSysprop.setKey("obscureWithKeyAsSysprop");
251 obscureWithKeyAsSysprop.setAnyTypeClass(obscureSchema.getAnyTypeClass());
252 obscureWithKeyAsSysprop.setType(AttrSchemaType.Encrypted);
253 obscureWithKeyAsSysprop.setCipherAlgorithm(obscureSchema.getCipherAlgorithm());
254 obscureWithKeyAsSysprop.setSecretKey("${obscureSecretKey}");
255
256 obscureWithKeyAsSysprop = plainSchemaDAO.save(obscureWithKeyAsSysprop);
257
258 System.setProperty("obscureSecretKey", obscureSchema.getSecretKey());
259
260 UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
261 attr.setSchema(obscureWithKeyAsSysprop);
262 attr.add(validator, "testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER));
263
264 assertEquals(Encryptor.getInstance(obscureSchema.getSecretKey()).
265 encode("testvalue", obscureSchema.getCipherAlgorithm()), attr.getValues().get(0).getStringValue());
266 }
267
268 @Test
269 public void encryptedWithDecodeConversionPattern() throws Exception {
270 PlainSchema obscureWithDecodeConversionPattern = entityFactory.newEntity(PlainSchema.class);
271 obscureWithDecodeConversionPattern.setKey("obscureWithDecodeConversionPattern");
272 obscureWithDecodeConversionPattern.setAnyTypeClass(anyTypeClassDAO.find("other"));
273 obscureWithDecodeConversionPattern.setType(AttrSchemaType.Encrypted);
274 obscureWithDecodeConversionPattern.setCipherAlgorithm(CipherAlgorithm.AES);
275 obscureWithDecodeConversionPattern.setSecretKey(SecureRandomUtils.generateRandomUUID().toString());
276
277 obscureWithDecodeConversionPattern = plainSchemaDAO.save(obscureWithDecodeConversionPattern);
278
279 UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
280 attr.setSchema(obscureWithDecodeConversionPattern);
281 attr.add(validator, "testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER));
282
283 assertEquals(Encryptor.getInstance(obscureWithDecodeConversionPattern.getSecretKey()).
284 encode("testvalue", obscureWithDecodeConversionPattern.getCipherAlgorithm()),
285 attr.getValues().get(0).getStringValue());
286
287 obscureWithDecodeConversionPattern.setConversionPattern(SyncopeConstants.ENCRYPTED_DECODE_CONVERSION_PATTERN);
288 plainSchemaDAO.save(obscureWithDecodeConversionPattern);
289
290 assertNotEquals("testvalue", attr.getValues().get(0).getStringValue());
291 assertEquals("testvalue", attr.getValuesAsStrings().get(0));
292 }
293
294 @Test
295 public void saveWithBinary() throws UnsupportedEncodingException {
296 User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
297
298 PlainSchema photoSchema = plainSchemaDAO.find("photo");
299 assertNotNull(photoSchema);
300 assertNotNull(photoSchema.getMimeType());
301
302 byte[] bytes = new byte[20];
303 new Random().nextBytes(bytes);
304 String photoB64Value = Base64.getEncoder().encodeToString(bytes);
305
306 UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
307 attr.setOwner(user);
308 attr.setSchema(photoSchema);
309 attr.add(validator, photoB64Value, anyUtilsFactory.getInstance(AnyTypeKind.USER));
310 user.add(attr);
311
312 userDAO.save(user);
313
314 UPlainAttr photo = user.getPlainAttr("photo").get();
315 assertNotNull(photo);
316 assertEquals(1, photo.getValues().size());
317 assertTrue(Arrays.equals(bytes, photo.getValues().get(0).getBinaryValue()));
318 }
319
320 @Tag("plainAttrTable")
321 @Test
322 public void delete() {
323 UPlainAttr attribute = findPlainAttr("9d0d9e40-1b18-488e-9482-37dab82163c9", UPlainAttr.class);
324 String attrSchemaName = attribute.getSchema().getKey();
325
326 plainAttrDAO.delete(attribute);
327
328 PlainSchema schema = plainSchemaDAO.find(attrSchemaName);
329 assertNotNull(schema);
330 }
331 }