Skip to content

Commit

Permalink
[master] New PersistenceUnit property - eclipselink.login.encryptor (#…
Browse files Browse the repository at this point in the history
…1983)

* New PersistenceUnit property - eclipselink.login.encryptor
New non-internal org.eclipse.persistence.security.Securable interface to implement custom password encryptor

Signed-off-by: Radek Felcman <[email protected]>
  • Loading branch information
rfelcman authored Nov 7, 2023
1 parent 04deabc commit c8f43af
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 9 deletions.
60 changes: 60 additions & 0 deletions docs/docs.jpa/src/main/asciidoc/persistenceproperties_ref.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ customizing descriptors and sessions:
* link:#metadatasourcepropertiesfile[`metadata-source.properties.file`]
* link:#metadatasourcesendrefreshcommand[`metadata-source.send-refresh-command`]
* link:#metadatasourcexmlurl[`metadata-source.xml.url`]
* link:#loginencryptor[`login.encryptor`]
[[CACJHFEC2]][[TLJPA1051]]
Expand Down Expand Up @@ -339,6 +340,7 @@ The following lists the EclipseLink persistence property
* link:#loggingsession[`logging.session`]
* link:#loggingthread[`logging.thread`]
* link:#loggingtimestamp[`logging.timestamp`]
* link:#login-encryptor[`login.encryptor`]
* link:#locking-timestamp-local[`locking.timestamp.local`]
* link:#metadatasource[`metadata-source`]
* link:#metadatasourcepropertiesfile[`metadata-source.properties.file`]
Expand Down Expand Up @@ -6456,6 +6458,64 @@ _Solutions Guide for EclispeLink_
'''''
=== login.encryptor
Use the `eclipselink.login.encryptor` property to specify a custom
implementation of class that implements the
`org.eclipse.persistence.security.Securable` interface. The class
must provide a default, no argument constructor.
*Values*
link:#CHDGBEFGA[Table 5-89] describes this persistence property's values.
[[CHDGBEFGA]]
*_Table 5-89 Valid Values for login.encryptor_*
|======================================================================
|*Value* |*Description*
|class name |Fully qualified class name of custom implementation `org.eclipse.persistence.security.Securable` class.
|======================================================================
*Usage*
It is used to encrypt and decrypt database password loaded from
`jakarta.persistence.jdbc.password` property.
Usage of this property avoids limitation of link:#sessioncustomizer[`session.customizer`] which is called when all other
properties have been processed (too late when database login needs to be configured).
*Examples*
link:#CHDFBIEIA[Example 5-109] shows how to use this property in the
`persistence.xml` file.
[[CHDFBIEIA]][[TLJPA1015]]
*_Example 5-109 Using login.encryptor in persistence.xml_*
[source,oac_no_warn]
----
<property name="eclipselink.login.encryptor"
value="acme.sessions.MyEncryptor"/>
----
link:#CHDJEDJGA[Example 5-110] shows how to use this property in a
property map.
[[CHDJEDJGA]][[TLJPA1016]]
*_Example 5-110 Using session.customizer in a Property Map_*
[source,oac_no_warn]
----
import org.eclipse.persistence.config.PersistenceUnitProperties;
propertiesMap.put(PersistenceUnitProperties.LOGIN_ENCRYPTOR,
"acme.sessions.MyEncryptor");
----
'''''
=== locking.timestamp.local
This property defines if locking policies should default to local time(true) or server time(false).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2021 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 @@ -4160,6 +4160,25 @@ 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
Expand Up @@ -35,7 +35,7 @@
*
* @author Guy Pelletier
*/
public class JCEEncryptor implements Securable {
public final 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
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019 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 @@ -20,7 +20,8 @@
*
* @author Guy Pelletier
*/
public interface Securable {
public sealed interface Securable
permits org.eclipse.persistence.security.Securable {
String encryptPassword(String pswd);

String decryptPassword(String encryptedPswd);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,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 {
@Override
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 non-sealed 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, 2022 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
@@ -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
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2022 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 @@ -63,6 +63,7 @@ public static Test suite() {
suite.addTest(new JPAAdvPropertiesTest("testBatchwritingProperty"));
suite.addTest(new JPAAdvPropertiesTest("testCopyDescriptorNamedQueryToSessionProperty"));
suite.addTest(new JPAAdvPropertiesTest("testLoggingTyperProperty"));
suite.addTest(new JPAAdvPropertiesTest("testLoginEncryptorProperty"));

return suite;
}
Expand Down Expand Up @@ -299,4 +300,29 @@ public void testSessionXMLProperty() {
assertNull("Error deleting Customer", em.find(Customer.class, customerId));

}

public void testLoginEncryptorProperty() {
EntityManager em = createEntityManager();
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 @@ -3052,7 +3052,6 @@ else if (expression.hasElseExpression() &&
}
}

//TODO RFELCMAN there or DefaultGrammarValidator?
@Override
public void visit(CastExpression expression) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2503,6 +2503,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 c8f43af

Please sign in to comment.