Don't use embedded entity for email address in User class

Jens Pelzetter 2020-05-24 14:00:23 +02:00
parent 26c8ce9491
commit 87dea3cebd
16 changed files with 119 additions and 78 deletions

View File

@ -45,15 +45,22 @@ import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.persistence.Column;
import javax.persistence.ColumnResult;
import javax.persistence.Entity;
import javax.persistence.EntityResult;
import javax.persistence.FetchType;
import javax.persistence.FieldResult;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.NamedEntityGraphs;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.NamedSubgraph;
import javax.persistence.OneToMany;
import javax.persistence.SqlResultSetMapping;
import javax.persistence.SqlResultSetMappings;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ -84,16 +91,16 @@ import javax.xml.bind.annotation.XmlTransient;
),
@NamedQuery(name = "User.countByName",
query = "SELECT COUNT(u) FROM User u WHERE u.name = :name"),
// @NamedQuery(name = "User.findByEmailAddress",
// query = "SELECT u FROM User u WHERE "
// + "u.primaryEmailAddress.address = :emailAddress "
// + "ORDER BY u.name, "
// + " u.familyName, "
// + " u.givenName, "
// + " u.primaryEmailAddress.address"),
// @NamedQuery(name = "User.countByPrimaryEmailAddress",
// query = "SELECT COUNT(u) FROM User u "
// + "WHERE u.primaryEmailAddress.address = :emailAddress"),
@NamedQuery(name = "User.findByEmailAddress",
query = "SELECT u FROM User u WHERE "
+ "u.primaryEmailAddress = :emailAddress "
+ "ORDER BY u.name, "
+ " u.familyName, "
+ " u.givenName, "
+ " u.primaryEmailAddress"),
@NamedQuery(name = "User.countByPrimaryEmailAddress",
query = "SELECT COUNT(u) FROM User u "
+ "WHERE u.primaryEmailAddress.address = :emailAddress"),
@NamedQuery(
name = "User.filterByNameAndEmail",
query = "SELECT u FROM User u WHERE "
@ -104,12 +111,12 @@ import javax.xml.bind.annotation.XmlTransient;
+ "u.familyName, "
+ "u.givenName"
),
// @NamedQuery(
// name = "User.findAllOrderedByUsername",
// query = "SELECT u FROM User u ORDER BY u.name, "
// + " u.familyName, "
// + " u.givenName, "
// + " u.primaryEmailAddress.address"),
@NamedQuery(
name = "User.findAllOrderedByUsername",
query = "SELECT u FROM User u ORDER BY u.name, "
+ " u.familyName, "
+ " u.givenName, "
+ " u.primaryEmailAddress"),
@NamedQuery(name = "User.findByGroup",
query = "SELECT u FROM User u "
+ "JOIN u.groupMemberships m "
@ -168,16 +175,22 @@ public class User extends Party implements Serializable, Exportable {
* The primary email address of the user.
*/
@Column(name = "PRIMARY_EMAIL_ADDRESS")
@Type(type = "org.libreccm.core.EmailAddressType")
@NotNull
@XmlElement(name = "primary-email-address", namespace = CORE_XML_NS)
private EmailAddress primaryEmailAddress;
private String primaryEmailAddress;
@Column(name = "PRIMARY_EMAIL_ADDRESS_BOUNCING")
private boolean primaryEmailAddressBouncing;
@Column(name = "PRIMARY_EMAIL_ADDRESS_VERIFIED")
private boolean primaryEmailAddressVerified;
/**
* Additional email addresses of the user.
*/
@Column(name = "EMAIL_ADDRESSES")
@Type(type = "org.libreccm.core.EmailAddressListType")
@Deprecated
@XmlElementWrapper(name = "email-addresses", namespace = CORE_XML_NS)
@XmlElement(name = "email-address", namespace = CORE_XML_NS)
private List<EmailAddress> emailAddresses;
@ -238,14 +251,31 @@ public class User extends Party implements Serializable, Exportable {
this.familyName = familyName;
}
public EmailAddress getPrimaryEmailAddress() {
public String getPrimaryEmailAddress() {
return primaryEmailAddress;
}
public void setPrimaryEmailAddress(final EmailAddress primaryEmailAddress) {
public void setPrimaryEmailAddress(final String primaryEmailAddress) {
this.primaryEmailAddress = primaryEmailAddress;
}
public boolean isPrimaryEmailAddressBouncing() {
return primaryEmailAddressBouncing;
}
public void setPrimaryEmailAddressBouncing(final boolean bouncing) {
primaryEmailAddressBouncing = bouncing;
}
public boolean isPrimaryEmailAddressVerified() {
return primaryEmailAddressVerified;
}
public void setPrimaryEmailAddressVerified(final boolean verified) {
primaryEmailAddressVerified = verified;
}
@Deprecated
public List<EmailAddress> getEmailAddresses() {
if (emailAddresses == null) {
return null;
@ -254,6 +284,7 @@ public class User extends Party implements Serializable, Exportable {
}
}
@Deprecated
protected void setEmailAddresses(final List<EmailAddress> emailAddresses) {
this.emailAddresses = new ArrayList<>(emailAddresses);
}
@ -363,7 +394,9 @@ public class User extends Party implements Serializable, Exportable {
.buildJson()
.add("givenName", givenName)
.add("familyName", familyName)
.add("primaryEmailAddress", primaryEmailAddress.buildJson())
.add("primaryEmailAddress", primaryEmailAddress)
.add("primaryEmailAddressBouncing", primaryEmailAddressBouncing)
.add("primaryEmailAddressVerified", primaryEmailAddressVerified)
.add(
"emailAddresses",
emailAddresses

View File

@ -94,10 +94,9 @@ public class UserManager implements Serializable {
user.setGivenName(givenName);
user.setFamilyName(familyName);
user.setName(name);
final EmailAddress email = new EmailAddress();
email.setAddress(emailAddress);
user.setPrimaryEmailAddress(email);
email.setVerified(true);
user.setPrimaryEmailAddress(emailAddress);
user.setPrimaryEmailAddressBouncing(false);
user.setPrimaryEmailAddressVerified(true);
if (password == null) {
user.setPassword(null);
} else {
@ -131,7 +130,7 @@ public class UserManager implements Serializable {
final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class);
if (kernelConfig.emailIsPrimaryIdentifier()) {
userIdentifier = user.getPrimaryEmailAddress().getAddress();
userIdentifier = user.getPrimaryEmailAddress();
} else {
userIdentifier = user.getName();
}

View File

@ -18,8 +18,11 @@
*/
package org.libreccm.security;
import org.hibernate.Session;
import org.libreccm.core.AbstractEntityRepository;
import org.libreccm.core.CoreConstants;
import org.libreccm.core.EmailAddressListType;
import org.libreccm.core.EmailAddressType;
import javax.enterprise.context.RequestScoped;
import javax.persistence.EntityGraph;
@ -30,6 +33,9 @@ import java.util.List;
import java.util.Optional;
import java.util.UUID;
import javax.persistence.NoResultException;
import javax.persistence.Query;
/**
* Repository for user objects.
*
@ -138,11 +144,16 @@ public class UserRepository extends AbstractEntityRepository<Long, User> {
* is no matching user {@code null} is returned.
*/
public Optional<User> findByEmailAddress(final String emailAddress) {
final TypedQuery<User> query = getEntityManager().createNamedQuery(
"User.findByEmailAddress", User.class);
query.setParameter("emailAddress", emailAddress);
return getSingleResult(query);
try {
return Optional.of(
getEntityManager()
.createNamedQuery("User.findByEmailAddress", User.class)
.setParameter("emailAddress", emailAddress)
.getSingleResult()
);
} catch (NoResultException ex) {
return Optional.empty();
}
}
public Optional<User> findByEmailAddress(final String emailAddress,
@ -210,8 +221,6 @@ public class UserRepository extends AbstractEntityRepository<Long, User> {
entity.setUuid(UUID.randomUUID().toString());
}
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)

View File

@ -154,6 +154,9 @@ public class CategoryManagerTest {
org.libreccm.testutils.dbunit.PgSqlJsonbType.class
)
.addClass(org.libreccm.hibernate.AbstractCcmJsonUserType.class)
.addClass(
org.libreccm.hibernate.dialects.LibreCcmPgSql9Dialect.class
)
.addAsLibraries(getModuleDependencies())
.addAsResource("configs/shiro.ini", "shiro.ini")
.addAsResource("test-persistence.xml",

View File

@ -65,25 +65,19 @@ public class ListContainsTest {
user1.setName("user1");
user1.setGivenName("User");
user1.setFamilyName("One");
final EmailAddress user1mail = new EmailAddress();
user1mail.setAddress("user.one@example.org");
user1.setPrimaryEmailAddress(user1mail);
user1.setPrimaryEmailAddress("user.one@example.org");
final User user2 = new User();
user2.setName("user2");
user2.setGivenName("User");
user2.setFamilyName("Two");
final EmailAddress user2mail = new EmailAddress();
user2mail.setAddress("user.two@example.org");
user2.setPrimaryEmailAddress(user1mail);
user2.setPrimaryEmailAddress("user.two@example.org");
final User user3 = new User();
user3.setName("user3");
user3.setGivenName("User");
user3.setFamilyName("Three");
final EmailAddress user3mail = new EmailAddress();
user3mail.setAddress("user.three@example.org");
user3.setPrimaryEmailAddress(user1mail);
user3.setPrimaryEmailAddress("user.three@example.org");
final List<User> users = new ArrayList<>();
users.add(user1);

View File

@ -218,15 +218,12 @@ public class PartyRepositoryTest {
public void saveNewParty() {
final User mmuster = new User();
final EmailAddress emailAddress = new EmailAddress();
emailAddress.setAddress("max.mustermann@example.org");
emailAddress.setBouncing(false);
emailAddress.setVerified(true);
mmuster.setName("mmuster");
mmuster.setGivenName("Max");
mmuster.setFamilyName("Mustermann");
mmuster.setPrimaryEmailAddress(emailAddress);
mmuster.setPrimaryEmailAddress("max.mustermann@example.org");
mmuster.setPrimaryEmailAddressBouncing(false);
mmuster.setPrimaryEmailAddressVerified(true);
mmuster.setPassword(
"$shiro1$SHA-512$500000$Y7CnccN1h25sR7KCElMOXg==$CVLWBhetodaEzzhDfGjRcCFZtSW02xOnjH7xhBx0lbxO66grKIt6LWmXoUhLEydce1JZ7cbzNLYOxIwwTeqi5Q==");
mmuster.setPasswordResetRequired(false);

View File

@ -260,15 +260,12 @@ public class UserRepositoryTest {
public void saveNewUser() {
final User user = new User();
final EmailAddress emailAddress = new EmailAddress();
emailAddress.setAddress("jane.doe@example.org");
emailAddress.setBouncing(false);
emailAddress.setVerified(false);
user.setName("jane");
user.setGivenName("Jane");
user.setFamilyName("Doe");
user.setPrimaryEmailAddress(emailAddress);
user.setPrimaryEmailAddress("jane.doe@example.org");
user.setPrimaryEmailAddressBouncing(false);
user.setPrimaryEmailAddressVerified(false);
user.setPassword(
"$shiro1$SHA-512$500000$24lA090z7GKYr4VFlZ6t4A==$/heoTHPA5huT1UfJ8Q+waXEG6AjUKhFYLFrj7KW/l0/z9O+QkiZTtfPfbcPblgjcEvrROMEIoQY4Z65S7rFLQg==");
user.setPasswordResetRequired(false);
@ -289,11 +286,9 @@ public class UserRepositoryTest {
user.setPassword(
"$shiro1$SHA-512$500000$AH1llRaMHE8W31Q7VG6jsA==$XXgKeyDCsrN23NvszQ5wt+uViQUlVqTAM+05LrE7Bd9sc0eaJT8HlAGvSdY+rqTLbiGm9YS4pohzoUt1x3kmKg==");
final EmailAddress emailAddress = new EmailAddress();
emailAddress.setAddress("jd@example.com");
emailAddress.setBouncing(false);
emailAddress.setVerified(true);
user.setPrimaryEmailAddress(emailAddress);
user.setPrimaryEmailAddress("jd@example.com");
user.setPrimaryEmailAddressBouncing(false);
user.setPrimaryEmailAddressVerified(true);
shiro.getSystemUser().execute(() -> userRepository.save(user));
}

View File

@ -26,6 +26,11 @@
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.id.new_generator_mappings" value="true"/>
<property name="hibernate.connection.autocommit" value="false" />
<property
name="hibernate.dialect"
value="org.libreccm.hibernate.dialects.LibreCcmPgSql9Dialect"
/>
<!--
Properties for Hibernate Envers

View File

@ -31,7 +31,7 @@
<ccm_core.users party_id="-10"
family_name="Doe"
given_name="John"
primary_email_address='{\"address\": \"john.doe@example.com\", \"bouncing\": false, \"verified\": true}'
primary_email_address='{"address": "john.doe@example.com", "bouncing": false, "verified": true}'
password="$shiro1$SHA-512$500000$7xkDcZUN0/whJInHIvGsDw==$WhelBVmJU/cLV7lAkMOrE5B/mqCW0bUuid1WX+xBwzzAaekC5bYn9eeOFGJWhiDgmaC50ZCUmM96/iGsRoc4uA=="
banned="false"
password_reset_required="false"
@ -39,7 +39,7 @@
<ccm_core.users party_id="-20"
family_name="Mustermann"
given_name="Max"
primary_email_address='{\"address\": \"max.muster@example.org\", \"bouncing\": false, \"verified\": true}'
primary_email_address='{"address": "max.muster@example.org", "bouncing": false, "verified": true}'
password="$shiro1$SHA-512$500000$Y7CnccN1h25sR7KCElMOXg==$CVLWBhetodaEzzhDfGjRcCFZtSW02xOnjH7xhBx0lbxO66grKIt6LWmXoUhLEydce1JZ7cbzNLYOxIwwTeqi5Q=="
banned="false"
password_reset_required="false"

View File

@ -31,7 +31,7 @@
<ccm_core.users party_id="-10"
family_name="Doe"
given_name="John"
primary_email_address='{\"address\": \"john.doe@example.com\", \"bouncing\": false, \"verified\": true}'
primary_email_address='{"address": "john.doe@example.com", "bouncing": false, "verified": true}'
password="$shiro1$SHA-512$500000$7xkDcZUN0/whJInHIvGsDw==$WhelBVmJU/cLV7lAkMOrE5B/mqCW0bUuid1WX+xBwzzAaekC5bYn9eeOFGJWhiDgmaC50ZCUmM96/iGsRoc4uA=="
banned="false"
password_reset_required="false"
@ -39,7 +39,7 @@
<ccm_core.users party_id="-20"
family_name="Mustermann"
given_name="Max"
primary_email_address='{\"address\": \"max.muster@example.org\", \"bouncing\": false, \"verified\": true}'
primary_email_address='{"address": "max.muster@example.org", "bouncing": false, "verified": true}'
password="$shiro1$SHA-512$500000$Y7CnccN1h25sR7KCElMOXg==$CVLWBhetodaEzzhDfGjRcCFZtSW02xOnjH7xhBx0lbxO66grKIt6LWmXoUhLEydce1JZ7cbzNLYOxIwwTeqi5Q=="
banned="false"
password_reset_required="false"

View File

@ -31,7 +31,7 @@
<ccm_core.users party_id="-10"
family_name="Doe"
given_name="John"
primary_email_address='{\"address\": \"john.doe@example.com\", \"bouncing\": false, \"verified\": true}'
primary_email_address='{"address": "john.doe@example.com", "bouncing": false, "verified": true}'
password="$shiro1$SHA-512$500000$7xkDcZUN0/whJInHIvGsDw==$WhelBVmJU/cLV7lAkMOrE5B/mqCW0bUuid1WX+xBwzzAaekC5bYn9eeOFGJWhiDgmaC50ZCUmM96/iGsRoc4uA=="
banned="false"
password_reset_required="false"
@ -39,7 +39,7 @@
<ccm_core.users party_id="-20"
family_name="Mustermann"
given_name="Max"
primary_email_address='{\"address\": \"max.muster@example.org\", \"bouncing\": false, \"verified\": true}'
primary_email_address='{"address": "max.muster@example.org", "bouncing": false, "verified": true}'
password="$shiro1$SHA-512$500000$Y7CnccN1h25sR7KCElMOXg==$CVLWBhetodaEzzhDfGjRcCFZtSW02xOnjH7xhBx0lbxO66grKIt6LWmXoUhLEydce1JZ7cbzNLYOxIwwTeqi5Q=="
banned="false"
password_reset_required="false"

View File

@ -44,7 +44,7 @@ ccm_core.users:
password_reset_required: false
# Joe Public
- banned: false
primary_email_address: "{\"address\": \"joe.public@example.com\", \"bouncing\": false, \"verified\": true}}"
primary_email_address: "{\"address\": \"joe.public@example.com\", \"bouncing\": false, \"verified\": true}"
family_name: Public
given_name: Joe
party_id: 30

View File

@ -44,7 +44,7 @@ ccm_core.users:
password_reset_required: false
# Joe Public
- banned: false
primary_email_address: "{\"address\": \"joe.public@example.com\", \"bouncing\": false, \"verified\": true}}"
primary_email_address: "{\"address\": \"joe.public@example.com\", \"bouncing\": false, \"verified\": true}"
family_name: Public
given_name: Joe
party_id: 30

View File

@ -44,7 +44,7 @@ ccm_core.users:
password_reset_required: false
# Joe Public
- banned: false
primary_email_address: "{\"address\": \"joe.public@example.com\", \"bouncing\": false, \"verified\": true}}"
primary_email_address: "{\"address\": \"joe.public@example.com\", \"bouncing\": false, \"verified\": true}"
family_name: Public
given_name: Joe
party_id: 30

View File

@ -37,7 +37,7 @@ ccm_core.users:
# Joe Public
- party_id: 30
banned: false
primary_email_address: "{\"address\": \"joe.public@example.com\", \"bouncing\": false, \"verified\": true}}"
primary_email_address: "{\"address\": \"joe.public@example.com\", \"bouncing\": false, \"verified\": true}"
family_name: Public
given_name: Joe
password: $shiro1$SHA-512$500000$RUCYXAQt+XzUmj3x8oG5gw==$qU+lX160Jc6sNUOI9X85wlf2lzn4/hLJNURtjmw9LOYJ7vAqUFFmhyNCMxpzuHIpzeMELr+A0XReoSmtcZnOOw==

View File

@ -14,7 +14,9 @@ ccm_core.parties:
ccm_core.users:
# John Doe
- banned: false
primary_email_address: "{\"address\": \"john.doe@example.com\", \"bouncing\": false, \"verified\": true}"
primary_email_address: john.doe@example.com
primary_email_address_bouncing: false
primary_email_address_verfified: true
family_name: Doe
given_name: John
party_id: 10
@ -23,7 +25,9 @@ ccm_core.users:
password_reset_required: false
# Max Mustermann
- banned: false
primary_email_address: "{\"address\": \"max.mustermann@example.org\", \"bouncing\": false, \"verified\": true}"
primary_email_address: max.mustermann@example.org
primary_email_address_bouncing: false
primary_email_address_verified: true
family_name: Mustermann
given_name: Max
party_id: 20
@ -32,7 +36,9 @@ ccm_core.users:
password_reset_required: false
# Joe Public
- banned: false
primary_email_address: "{\"address\": \"joe.public@example.com\", \"bouncing\": false, \"verified\": true}}"
primary_email_address: joe.public@example.com
primary_email_address_bouncing: false
primary_email_address_verified: true
family_name: Public
given_name: Joe
party_id: 30