blob: b2c4ceff53e4444d1012d05ce56818e212deacd9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.core.persistence.jpa.inner;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Base64;
import java.util.Random;
import javax.validation.ValidationException;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
import org.apache.syncope.common.lib.types.EntityViolationType;
import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
import org.apache.syncope.core.spring.security.Encryptor;
import org.apache.syncope.core.spring.security.SecureRandomUtils;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
@Transactional("Master")
public class PlainAttrTest extends AbstractTest {
@Autowired
private UserDAO userDAO;
@Autowired
private PlainAttrDAO plainAttrDAO;
@Autowired
private PlainSchemaDAO plainSchemaDAO;
@Autowired
private AnyTypeClassDAO anyTypeClassDAO;
@Tag("plainAttrTable")
@Test
public void findByKey() {
UPlainAttr attribute = findPlainAttr("01f22fbd-b672-40af-b528-686d9b27ebc4", UPlainAttr.class);
assertNotNull(attribute);
attribute = findPlainAttr("9d0d9e40-1b18-488e-9482-37dab82163c9", UPlainAttr.class);
assertNotNull(attribute);
}
@Tag("plainAttrTable")
@Test
public void read() {
UPlainAttr attribute = findPlainAttr("01f22fbd-b672-40af-b528-686d9b27ebc4", UPlainAttr.class);
assertNotNull(attribute);
assertTrue(attribute.getValues().isEmpty());
assertNotNull(attribute.getUniqueValue());
}
@Test
public void save() throws ClassNotFoundException {
User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
PlainSchema emailSchema = plainSchemaDAO.find("email");
assertNotNull(emailSchema);
UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
attr.setOwner(user);
attr.setSchema(emailSchema);
Exception thrown = null;
try {
attr.add("john.doe@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
attr.add("mario.rossi@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
} catch (ValidationException e) {
thrown = e;
}
assertNull(thrown);
try {
attr.add("http://www.apache.org", anyUtilsFactory.getInstance(AnyTypeKind.USER));
} catch (ValidationException e) {
thrown = e;
}
assertNotNull(thrown);
}
@Test
public void saveWithEnum() throws ClassNotFoundException {
User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
assertNotNull(user);
PlainSchema gender = plainSchemaDAO.find("gender");
assertNotNull(gender);
assertNotNull(gender.getType());
assertNotNull(gender.getEnumerationValues());
UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
attribute.setOwner(user);
attribute.setSchema(gender);
user.add(attribute);
Exception thrown = null;
try {
attribute.add("A", anyUtilsFactory.getInstance(AnyTypeKind.USER));
} catch (ValidationException e) {
thrown = e;
}
assertNotNull(thrown);
attribute.add("M", anyUtilsFactory.getInstance(AnyTypeKind.USER));
InvalidEntityException iee = null;
try {
userDAO.save(user);
} catch (InvalidEntityException e) {
iee = e;
}
assertNull(iee);
}
@Test
public void invalidValueList() {
User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
PlainSchema emailSchema = plainSchemaDAO.find("email");
assertNotNull(emailSchema);
PlainSchema fullnameSchema = plainSchemaDAO.find("fullname");
assertNotNull(fullnameSchema);
UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
attr.setOwner(user);
attr.setSchema(emailSchema);
user.add(attr);
InvalidEntityException iee = null;
try {
userDAO.save(user);
fail("This should not happen");
} catch (InvalidEntityException e) {
iee = e;
}
assertNotNull(iee);
// for attr because no values are set
assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList));
}
@Tag("plainAttrTable")
@Test
public void invalidPlainAttr() {
User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
PlainSchema emailSchema = plainSchemaDAO.find("email");
assertNotNull(emailSchema);
PlainSchema fullnameSchema = plainSchemaDAO.find("fullname");
assertNotNull(fullnameSchema);
UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
attr.setOwner(user);
attr.setSchema(emailSchema);
UPlainAttrUniqueValue uauv = entityFactory.newEntity(UPlainAttrUniqueValue.class);
uauv.setAttr(attr);
uauv.setSchema(fullnameSchema);
uauv.setStringValue("a value");
attr.setUniqueValue(uauv);
user.add(attr);
InvalidEntityException iee = null;
try {
userDAO.save(user);
fail("This should not happen");
} catch (InvalidEntityException e) {
iee = e;
}
assertNotNull(iee);
// for attr because no values are set
assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList));
// for uauv because uauv.schema and uauv.attr.schema are different
assertTrue(iee.hasViolation(EntityViolationType.InvalidPlainAttr));
}
@Test
public void saveWithEncrypted() throws Exception {
User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
PlainSchema obscureSchema = plainSchemaDAO.find("obscure");
assertNotNull(obscureSchema);
assertNotNull(obscureSchema.getSecretKey());
assertNotNull(obscureSchema.getCipherAlgorithm());
UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
attr.setOwner(user);
attr.setSchema(obscureSchema);
attr.add("testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER));
user.add(attr);
userDAO.save(user);
UPlainAttr obscure = user.getPlainAttr("obscure").get();
assertNotNull(obscure);
assertEquals(1, obscure.getValues().size());
assertEquals(Encryptor.getInstance(obscureSchema.getSecretKey()).
encode("testvalue", obscureSchema.getCipherAlgorithm()), obscure.getValues().get(0).getStringValue());
}
@Test
public void encryptedWithKeyAsSysProp() throws Exception {
PlainSchema obscureSchema = plainSchemaDAO.find("obscure");
assertNotNull(obscureSchema);
PlainSchema obscureWithKeyAsSysprop = entityFactory.newEntity(PlainSchema.class);
obscureWithKeyAsSysprop.setKey("obscureWithKeyAsSysprop");
obscureWithKeyAsSysprop.setAnyTypeClass(obscureSchema.getAnyTypeClass());
obscureWithKeyAsSysprop.setType(AttrSchemaType.Encrypted);
obscureWithKeyAsSysprop.setCipherAlgorithm(obscureSchema.getCipherAlgorithm());
obscureWithKeyAsSysprop.setSecretKey("${obscureSecretKey}");
obscureWithKeyAsSysprop = plainSchemaDAO.save(obscureWithKeyAsSysprop);
System.setProperty("obscureSecretKey", obscureSchema.getSecretKey());
UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
attr.setSchema(obscureWithKeyAsSysprop);
attr.add("testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER));
assertEquals(Encryptor.getInstance(obscureSchema.getSecretKey()).
encode("testvalue", obscureSchema.getCipherAlgorithm()), attr.getValues().get(0).getStringValue());
}
@Test
public void encryptedWithDecodeConversionPattern() throws Exception {
PlainSchema obscureWithDecodeConversionPattern = entityFactory.newEntity(PlainSchema.class);
obscureWithDecodeConversionPattern.setKey("obscureWithDecodeConversionPattern");
obscureWithDecodeConversionPattern.setAnyTypeClass(anyTypeClassDAO.find("other"));
obscureWithDecodeConversionPattern.setType(AttrSchemaType.Encrypted);
obscureWithDecodeConversionPattern.setCipherAlgorithm(CipherAlgorithm.AES);
obscureWithDecodeConversionPattern.setSecretKey(SecureRandomUtils.generateRandomUUID().toString());
obscureWithDecodeConversionPattern = plainSchemaDAO.save(obscureWithDecodeConversionPattern);
UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
attr.setSchema(obscureWithDecodeConversionPattern);
attr.add("testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER));
assertEquals(Encryptor.getInstance(obscureWithDecodeConversionPattern.getSecretKey()).
encode("testvalue", obscureWithDecodeConversionPattern.getCipherAlgorithm()),
attr.getValues().get(0).getStringValue());
obscureWithDecodeConversionPattern.setConversionPattern(SyncopeConstants.ENCRYPTED_DECODE_CONVERSION_PATTERN);
plainSchemaDAO.save(obscureWithDecodeConversionPattern);
assertNotEquals("testvalue", attr.getValues().get(0).getStringValue());
assertEquals("testvalue", attr.getValuesAsStrings().get(0));
}
@Test
public void saveWithBinary() throws UnsupportedEncodingException {
User user = userDAO.find("1417acbe-cbf6-4277-9372-e75e04f97000");
PlainSchema photoSchema = plainSchemaDAO.find("photo");
assertNotNull(photoSchema);
assertNotNull(photoSchema.getMimeType());
byte[] bytes = new byte[20];
new Random().nextBytes(bytes);
String photoB64Value = Base64.getEncoder().encodeToString(bytes);
UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
attr.setOwner(user);
attr.setSchema(photoSchema);
attr.add(photoB64Value, anyUtilsFactory.getInstance(AnyTypeKind.USER));
user.add(attr);
userDAO.save(user);
UPlainAttr photo = user.getPlainAttr("photo").get();
assertNotNull(photo);
assertEquals(1, photo.getValues().size());
assertTrue(Arrays.equals(bytes, photo.getValues().get(0).getBinaryValue()));
}
@Tag("plainAttrTable")
@Test
public void delete() {
UPlainAttr attribute = findPlainAttr("9d0d9e40-1b18-488e-9482-37dab82163c9", UPlainAttr.class);
String attrSchemaName = attribute.getSchema().getKey();
plainAttrDAO.delete(attribute);
PlainSchema schema = plainSchemaDAO.find(attrSchemaName);
assertNotNull(schema);
}
}