Skip to content

Commit

Permalink
New PersistenceUnit property - eclipselink.login.encryptor - backport…
Browse files Browse the repository at this point in the history
… from master (#1993)

* New PersistenceUnit property - eclipselink.login.encryptor

This is implementation of new PersistenceUnit property eclipselink.login.encryptor.
Same property (by meaning) encryption-class is available in sessions.xml file.
Usage of this avoid limit of Session customizer which called when all
other properties have been processed (too late when database login is configured).

Signed-off-by: Radek Felcman <[email protected]>
  • Loading branch information
rfelcman authored Nov 8, 2023
1 parent 9117bb2 commit 6cfd9eb
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -14,7 +14,7 @@
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.sessionsxml;

import org.eclipse.persistence.internal.security.Securable;
import org.eclipse.persistence.security.Securable;


public class CustomEncryption implements Securable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4167,6 +4167,24 @@ public class PersistenceUnitProperties {
*/
public static final String QUERY_RESULTS_CACHE_VALIDATION = "eclipselink.query-results-cache.validation";

/**
* The "<code>eclipselink.login.encryptor</code>" property configures a custom implementation of
* {@link org.eclipse.persistence.security.Securable} class used to encrypt and decrypt database password
* loaded from "<code>jakarta.persistence.jdbc.password</code>" property.
* Usage of this property avoids limitation of {@link SessionCustomizer} which is called when all other
* properties have been processed (too late when database login needs to be configured).
* If this property is not specified {@link org.eclipse.persistence.internal.security.JCEEncryptor} as a default encryptor is used.
* <p>
* <b>Allowed Values:</b>
* <ul>
* <li>the fully qualified name for a class that implements {@link org.eclipse.persistence.security.Securable} interface
* </ul>
*
* @see org.eclipse.persistence.security.Securable
* @see org.eclipse.persistence.internal.security.JCEEncryptor
*/
public static final String LOGIN_ENCRYPTOR = "eclipselink.login.encryptor";

/**
* INTERNAL: The following properties will not be displayed through logging
* but instead have an alternate value shown in the log.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -36,7 +36,7 @@
*
* @author Guy Pelletier
*/
public class JCEEncryptor implements Securable {
public class JCEEncryptor implements org.eclipse.persistence.security.Securable {

// Legacy DES ECB cipher used for backwards compatibility decryption only.
private static final String DES_ECB = "DES/ECB/PKCS5Padding";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private void initSecurableObject() {
* At runtime, no encryption will be made and the passwords will be assummed to
* be clear text.
*/
private static final class PassThroughEncryptor implements Securable {
private static final class PassThroughEncryptor implements org.eclipse.persistence.security.Securable {
public String encryptPassword(String pswd) {
return pswd;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.security;

/**
* EclipseLink encryption interface
*/
public interface Securable extends org.eclipse.persistence.internal.security.Securable {

@Override
String encryptPassword(String pswd);

@Override
String decryptPassword(String encryptedPswd);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!--
Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2018, 2023 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -21,6 +21,7 @@
<property name="eclipselink.session-name" value="JPASessionXML"/>
<property name="eclipselink.exception-handler" value="org.eclipse.persistence.testing.tests.jpa.jpaadvancedproperties.CustomizedExceptionHandler"/>
<property name="eclipselink.session-event-listener" value="org.eclipse.persistence.testing.tests.jpa.jpaadvancedproperties.CustomizedSessionEventListener"/>
<property name="eclipselink.login.encryptor" value="org.eclipse.persistence.testing.tests.jpa.jpaadvancedproperties.CustomizedEncryptor"/>
<property name="eclipselink.jdbc.batch-writing" value="BUFFERED"/>
<property name="eclipselink.jdbc.native-sql" value="true"/>
<property name="eclipselink.jdbc.cache-statements.size" value="100"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!--
Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2018, 2023 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -24,7 +24,7 @@
<property name="eclipselink.session-name" value="JPASessionXML"/>
<property name="eclipselink.exception-handler" value="org.eclipse.persistence.testing.tests.jpa.jpaadvancedproperties.CustomizedExceptionHandler"/>
<property name="eclipselink.session-event-listener" value="org.eclipse.persistence.testing.tests.jpa.jpaadvancedproperties.CustomizedSessionEventListener"/>

<property name="eclipselink.login.encryptor" value="org.eclipse.persistence.testing.tests.jpa.jpaadvancedproperties.CustomizedEncryptor"/>
<property name="eclipselink.jdbc.batch-writing" value="BUFFERED"/>
<property name="eclipselink.jdbc.native-sql" value="true"/>
<property name="eclipselink.jdbc.cache-statements.size" value="100"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.jpa.jpaadvancedproperties;

import org.eclipse.persistence.security.Securable;

public class CustomizedEncryptor implements Securable {

public static int encryptPasswordCounter = 0;
public static int decryptPasswordCounter = 0;

@Override
public String encryptPassword(String pswd) {
encryptPasswordCounter++;
return pswd;
}

@Override
public String decryptPassword(String encryptedPswd) {
decryptPasswordCounter++;
return encryptedPswd;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public static Test suite() {
suite.addTest(new JPAAdvPropertiesJUnitTestCase("testCopyDescriptorNamedQueryToSessionProperty"));
suite.addTest(new JPAAdvPropertiesJUnitTestCase("testLoggingTyperProperty"));
suite.addTest(new JPAAdvPropertiesJUnitTestCase("testProfilerTyperProperty"));
suite.addTest(new JPAAdvPropertiesJUnitTestCase("testLoginEncryptorProperty"));

return suite;
}
Expand Down Expand Up @@ -360,4 +361,29 @@ public void testSessionXMLProperty() {
assertTrue("Error deleting Customer", em.find(org.eclipse.persistence.testing.models.jpa.jpaadvancedproperties.Customer.class, customerId) == null);

}

public void testLoginEncryptorProperty() {
EntityManager em = createEntityManager(persistenceUnitName);
try {
//Create new customer
beginTransaction(em);
Customer customer = ModelExamples.customerExample1();
em.persist(customer);
em.flush();
Integer customerId = customer.getCustomerId();
commitTransaction(em);

customer = em.find(org.eclipse.persistence.testing.models.jpa.jpaadvancedproperties.Customer.class, customerId);
//Purge it
beginTransaction(em);
em.remove(customer);
commitTransaction(em);

assertNotNull(customer);
assertTrue("CustomizedEncryptor.encryptPassword() method wasn't called.", CustomizedEncryptor.encryptPasswordCounter > 0);
assertTrue("CustomizedEncryptor.decryptPassword() method wasn't called.", CustomizedEncryptor.decryptPasswordCounter > 0);
} finally {
closeEntityManager(em);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2465,6 +2465,11 @@ protected void updateLogins(Map m){
login.setProperty(property, value);
}

String encryptionClassName = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.LOGIN_ENCRYPTOR, m, this.session);
if (encryptionClassName != null) {
this.securableObjectHolder.setEncryptionClassName(encryptionClassName);
login.setEncryptionClassName(encryptionClassName);
}
// Note: This call does not checked the stored persistenceUnitInfo or extended properties because
// the map passed into this method should represent the full set of properties we expect to process

Expand Down

0 comments on commit 6cfd9eb

Please sign in to comment.