Skip to content

Commit a81500b

Browse files
committed
Updated MendixSSO version to 3.1.1
Update MendixSSO version to get rid of commons-text vulnerability in the repo.
1 parent 33b0de9 commit a81500b

74 files changed

Lines changed: 1400 additions & 1003 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
0 Bytes
Binary file not shown.

src/DeepLinkModule/javasource/mendixsso/actions/CalculateOpenIDFromUUID.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99

1010
package mendixsso.actions;
1111

12-
import org.apache.commons.lang3.StringUtils;
1312
import com.mendix.systemwideinterfaces.core.IContext;
1413
import com.mendix.webui.CustomJavaAction;
1514
import mendixsso.implementation.utils.OpenIDUtils;
15+
import org.apache.commons.lang3.StringUtils;
1616

1717
public class CalculateOpenIDFromUUID extends CustomJavaAction<java.lang.String>
1818
{

src/DeepLinkModule/javasource/mendixsso/actions/DecryptString.java

Lines changed: 88 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,28 @@ public DecryptString(IContext context, java.lang.String value, java.lang.String
3838
public java.lang.String executeAction() throws Exception
3939
{
4040
// BEGIN USER CODE
41-
if (this.value == null || !isStartsWithRightPrefix())
42-
return null;
43-
if (this.prefix == null || this.prefix.isEmpty())
44-
throw new MendixRuntimeException("Prefix should not be empty");
45-
if (this.key == null || this.key.isEmpty())
46-
throw new MendixRuntimeException("Key should not be empty");
47-
if (this.key.length() != 16)
48-
throw new MendixRuntimeException("Key length should be 16");
49-
50-
String decryptedText = null;
51-
52-
if (isEncryptedWithLegacyAlgorithm(this.value)) {
53-
decryptedText = decryptUsingLegacyAlgorithm();
54-
} else {
55-
decryptedText = decryptUsingGcm();
56-
}
57-
58-
return decryptedText;
41+
if (this.value == null || !isStartsWithRightPrefix()) {
42+
return null;
43+
}
44+
if (this.prefix == null || this.prefix.isEmpty()) {
45+
throw new MendixRuntimeException("Prefix should not be empty");
46+
}
47+
if (this.key == null || this.key.isEmpty()) {
48+
throw new MendixRuntimeException("Key should not be empty");
49+
}
50+
if (this.key.length() != getKeyLength()) {
51+
throw new MendixRuntimeException("Key length should be 16");
52+
}
53+
54+
String decryptedText = null;
55+
56+
if (isEncryptedWithLegacyAlgorithm(this.value)) {
57+
decryptedText = decryptUsingLegacyAlgorithm();
58+
} else {
59+
decryptedText = decryptUsingGcm();
60+
}
61+
62+
return decryptedText;
5963
// END USER CODE
6064
}
6165

@@ -69,67 +73,81 @@ public java.lang.String toString()
6973
}
7074

7175
// BEGIN EXTRA CODE
72-
private final int GCM_TAG_LENGTH = 16; // in bytes
73-
private final String LEGACY_PREFIX = "{AES}";
74-
private final String WRONG_KEY_ERROR_MESSAGE = "Cannot decrypt the text because it was either NOT encrypted with a key of length 16 or they key is different";
75-
76-
private String decryptUsingGcm() throws Exception {
77-
String[] s = this.value.substring(this.prefix.length()).split(";");
78-
79-
if (s.length < 2) //Not an encrypted string, just return the original value.
80-
return this.value;
81-
82-
Cipher c = Cipher.getInstance("AES/GCM/PKCS5PADDING");
83-
SecretKeySpec k = new SecretKeySpec(this.key.getBytes(), "AES");
84-
85-
byte[] iv = Base64.getDecoder().decode(s[0].getBytes());
86-
byte[] encryptedData = Base64.getDecoder().decode(s[1].getBytes());
87-
88-
try {
89-
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
90-
c.init(Cipher.DECRYPT_MODE, k, spec);
91-
return new String(c.doFinal(encryptedData));
92-
} catch (InvalidAlgorithmParameterException | BadPaddingException ex) {
93-
if (isEncryptedWithWrongKey(ex.getMessage()))
94-
throw new MendixRuntimeException(WRONG_KEY_ERROR_MESSAGE);
95-
else throw ex;
96-
}
97-
}
76+
private static final int GCM_TAG_LENGTH = 16; // in bytes
77+
private static final String LEGACY_PREFIX = "{AES}";
78+
private static final String WRONG_KEY_ERROR_MESSAGE =
79+
"Cannot decrypt the text because it was either NOT "
80+
+ "encrypted with a key of length 16 or they key is different";
9881

99-
private boolean isEncryptedWithWrongKey(String message) {
100-
return
101-
message.equals("Wrong IV length: must be 16 bytes long") ||
102-
message.equals("Given final block not properly padded");
103-
}
82+
private static final int KEY_LENGTH = 16;
83+
private static final int ENCRYPTED_STR_PART_NUMBER = 2;
10484

105-
private String decryptUsingLegacyAlgorithm() throws Exception {
106-
String[] s = this.value.substring(LEGACY_PREFIX.length()).split(";");
85+
private String decryptUsingGcm() throws Exception {
86+
String[] s = this.value.substring(this.prefix.length()).split(";");
10787

108-
if (s.length < 2) //Not an encrypted string, just return the original value.
109-
return this.value;
88+
// Not an encrypted string, just return the original value.
89+
if (s.length < ENCRYPTED_STR_PART_NUMBER) {
90+
return this.value;
91+
}
11092

111-
Cipher c = Cipher.getInstance("AES/CBC/PKCS5PADDING");
112-
SecretKeySpec k = new SecretKeySpec(this.key.getBytes(), "AES");
93+
Cipher c = Cipher.getInstance("AES/GCM/PKCS5PADDING");
94+
SecretKeySpec k = new SecretKeySpec(this.key.getBytes(), "AES");
95+
96+
try {
97+
GCMParameterSpec spec =
98+
new GCMParameterSpec(GCM_TAG_LENGTH * 8, Base64.getDecoder().decode(s[0]));
99+
c.init(Cipher.DECRYPT_MODE, k, spec);
100+
byte[] encryptedData = Base64.getDecoder().decode(s[1]);
101+
return new String(c.doFinal(encryptedData));
102+
} catch (InvalidAlgorithmParameterException | BadPaddingException ex) {
103+
if (isEncryptedWithWrongKey(ex.getMessage())) {
104+
throw new MendixRuntimeException(WRONG_KEY_ERROR_MESSAGE);
105+
} else {
106+
throw ex;
107+
}
108+
}
109+
}
113110

114-
byte[] iv = Base64.getDecoder().decode(s[0].getBytes());
115-
byte[] encryptedData = Base64.getDecoder().decode(s[1].getBytes());
111+
private boolean isEncryptedWithWrongKey(String message) {
112+
return "Wrong IV length: must be 16 bytes long".equals(message)
113+
|| "Given final block not properly padded".equals(message);
114+
}
116115

117-
try {
118-
c.init(Cipher.DECRYPT_MODE, k, new IvParameterSpec(iv));
119-
return new String(c.doFinal(encryptedData));
120-
} catch (InvalidAlgorithmParameterException | BadPaddingException ex) {
121-
if (isEncryptedWithWrongKey(ex.getMessage()))
122-
throw new MendixRuntimeException(WRONG_KEY_ERROR_MESSAGE);
123-
else throw ex;
124-
}
125-
}
116+
private String decryptUsingLegacyAlgorithm() throws Exception {
117+
String[] s = this.value.substring(LEGACY_PREFIX.length()).split(";");
126118

127-
private boolean isEncryptedWithLegacyAlgorithm(String text) {
128-
return text.startsWith(LEGACY_PREFIX);
119+
// Not an encrypted string, just return the original value.
120+
if (s.length < ENCRYPTED_STR_PART_NUMBER) {
121+
return this.value;
129122
}
130123

131-
private boolean isStartsWithRightPrefix() {
132-
return this.value.startsWith(this.value) || isEncryptedWithLegacyAlgorithm(this.value);
124+
Cipher c = Cipher.getInstance("AES/CBC/PKCS5PADDING");
125+
SecretKeySpec k = new SecretKeySpec(this.key.getBytes(), "AES");
126+
127+
try {
128+
c.init(Cipher.DECRYPT_MODE, k, new IvParameterSpec(Base64.getDecoder().decode(s[0])));
129+
byte[] encryptedData = Base64.getDecoder().decode(s[1]);
130+
return new String(c.doFinal(encryptedData));
131+
} catch (InvalidAlgorithmParameterException | BadPaddingException ex) {
132+
if (isEncryptedWithWrongKey(ex.getMessage())) {
133+
throw new MendixRuntimeException(WRONG_KEY_ERROR_MESSAGE);
134+
} else {
135+
throw ex;
136+
}
133137
}
138+
}
139+
140+
private boolean isEncryptedWithLegacyAlgorithm(String text) {
141+
return text.startsWith(LEGACY_PREFIX);
142+
}
143+
144+
private boolean isStartsWithRightPrefix() {
145+
return this.value.startsWith(this.value) || isEncryptedWithLegacyAlgorithm(this.value);
146+
}
147+
148+
private static int getKeyLength() {
149+
return KEY_LENGTH;
150+
}
151+
134152
// END EXTRA CODE
135153
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// This file was generated by Mendix Studio Pro.
2+
//
3+
// WARNING: Only the following code will be retained when actions are regenerated:
4+
// - the import list
5+
// - the code between BEGIN USER CODE and END USER CODE
6+
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
7+
// Other code you write will be lost the next time you deploy the project.
8+
// Special characters, e.g., é, ö, à, etc. are supported in comments.
9+
10+
package mendixsso.actions;
11+
12+
import com.mendix.core.Core;
13+
import com.mendix.logging.ILogNode;
14+
import com.mendix.systemwideinterfaces.core.IContext;
15+
import com.mendix.webui.CustomJavaAction;
16+
import mendixsso.implementation.utils.StaleDBObjectCleaner;
17+
import mendixsso.proxies.AuthRequest;
18+
import mendixsso.proxies.constants.Constants;
19+
import java.time.Instant;
20+
21+
public class DeleteExpiredAuthRequests extends CustomJavaAction<java.lang.Boolean>
22+
{
23+
private java.lang.Boolean removeAll;
24+
25+
public DeleteExpiredAuthRequests(IContext context, java.lang.Boolean removeAll)
26+
{
27+
super(context);
28+
this.removeAll = removeAll;
29+
}
30+
31+
@java.lang.Override
32+
public java.lang.Boolean executeAction() throws Exception
33+
{
34+
// BEGIN USER CODE
35+
final long olderThan = removeAll ? Instant.now().toEpochMilli() : Instant.now().toEpochMilli() - Constants.getAuthRequestExpiryDurationInMinutes()*60*60*1000;
36+
final long totalDeleted = StaleDBObjectCleaner.cleanupStaleObjects(AuthRequest.class, AuthRequest.entityName, "createdDate", olderThan, Constants.getBatchSize().intValue());
37+
LOG_NODE.info(String.format("Total %d auth requests are deleted", totalDeleted));
38+
return true;
39+
// END USER CODE
40+
}
41+
42+
/**
43+
* Returns a string representation of this action
44+
*/
45+
@java.lang.Override
46+
public java.lang.String toString()
47+
{
48+
return "DeleteExpiredAuthRequests";
49+
}
50+
51+
// BEGIN EXTRA CODE
52+
static final ILogNode LOG_NODE = Core.getLogger(Constants.getLogNode());
53+
// END EXTRA CODE
54+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// This file was generated by Mendix Studio Pro.
2+
//
3+
// WARNING: Only the following code will be retained when actions are regenerated:
4+
// - the import list
5+
// - the code between BEGIN USER CODE and END USER CODE
6+
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
7+
// Other code you write will be lost the next time you deploy the project.
8+
// Special characters, e.g., é, ö, à, etc. are supported in comments.
9+
10+
package mendixsso.actions;
11+
12+
import com.mendix.core.Core;
13+
import com.mendix.logging.ILogNode;
14+
import com.mendix.systemwideinterfaces.core.IContext;
15+
import com.mendix.webui.CustomJavaAction;
16+
import mendixsso.implementation.utils.StaleDBObjectCleaner;
17+
import mendixsso.proxies.Token;
18+
import mendixsso.proxies.constants.Constants;
19+
import java.time.Instant;
20+
21+
public class DeleteExpiredTokens extends CustomJavaAction<java.lang.Boolean>
22+
{
23+
private java.lang.Boolean removeAll;
24+
25+
public DeleteExpiredTokens(IContext context, java.lang.Boolean removeAll)
26+
{
27+
super(context);
28+
this.removeAll = removeAll;
29+
}
30+
31+
@java.lang.Override
32+
public java.lang.Boolean executeAction() throws Exception
33+
{
34+
// BEGIN USER CODE
35+
final String expiryFieldName = removeAll ? "createdDate" : "ExpiresAt";
36+
final long totalDeleted = StaleDBObjectCleaner.cleanupStaleObjects(Token.class, Token.entityName, expiryFieldName, Instant.now().toEpochMilli(), Constants.getBatchSize().intValue());
37+
LOG_NODE.info(String.format("Total %d tokens are deleted", totalDeleted));
38+
return true;
39+
// END USER CODE
40+
}
41+
42+
/**
43+
* Returns a string representation of this action
44+
*/
45+
@java.lang.Override
46+
public java.lang.String toString()
47+
{
48+
return "DeleteExpiredTokens";
49+
}
50+
51+
// BEGIN EXTRA CODE
52+
static final ILogNode LOG_NODE = Core.getLogger(Constants.getLogNode());
53+
// END EXTRA CODE
54+
}

src/DeepLinkModule/javasource/mendixsso/actions/EncryptString.java

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
import com.mendix.systemwideinterfaces.MendixRuntimeException;
1313
import com.mendix.systemwideinterfaces.core.IContext;
1414
import com.mendix.webui.CustomJavaAction;
15+
import java.nio.charset.StandardCharsets;
16+
import java.util.Base64;
1517
import javax.crypto.Cipher;
1618
import javax.crypto.spec.SecretKeySpec;
17-
import java.util.Base64;
1819

1920
public class EncryptString extends CustomJavaAction<java.lang.String>
2021
{
@@ -34,24 +35,30 @@ public EncryptString(IContext context, java.lang.String value, java.lang.String
3435
public java.lang.String executeAction() throws Exception
3536
{
3637
// BEGIN USER CODE
37-
if (this.value == null)
38-
return null;
39-
if (this.prefix == null || this.prefix.isEmpty())
40-
throw new MendixRuntimeException("Prefix should not be empty");
41-
if (this.key == null || this.key.isEmpty())
42-
throw new MendixRuntimeException("Key should not be empty");
43-
if (this.key.length() != 16)
44-
throw new MendixRuntimeException("Key length should be 16");
45-
Cipher c = Cipher.getInstance("AES/GCM/PKCS5PADDING");
46-
SecretKeySpec k = new SecretKeySpec(this.key.getBytes(), "AES");
47-
c.init(Cipher.ENCRYPT_MODE, k);
38+
if (this.value == null) {
39+
return null;
40+
}
41+
if (this.prefix == null || this.prefix.isEmpty()) {
42+
throw new MendixRuntimeException("Prefix should not be empty");
43+
}
44+
if (this.key == null || this.key.isEmpty()) {
45+
throw new MendixRuntimeException("Key should not be empty");
46+
}
47+
if (this.key.length() != getKeyLength()) {
48+
throw new MendixRuntimeException("Key length should be 16");
49+
}
50+
Cipher c = Cipher.getInstance("AES/GCM/PKCS5PADDING");
51+
SecretKeySpec k = new SecretKeySpec(this.key.getBytes(), "AES");
52+
c.init(Cipher.ENCRYPT_MODE, k);
4853

49-
byte[] encryptedData = c.doFinal(this.value.getBytes());
50-
byte[] iv = c.getIV();
54+
byte[] encryptedData = c.doFinal(this.value.getBytes());
55+
byte[] iv = c.getIV();
5156

52-
return new StringBuilder(this.prefix +
53-
new String(Base64.getEncoder().encode(iv))).append(";").append(
54-
new String(Base64.getEncoder().encode(encryptedData))).toString();
57+
return new StringBuilder(
58+
this.prefix + new String(Base64.getEncoder().encode(iv), StandardCharsets.UTF_8))
59+
.append(";")
60+
.append(new String(Base64.getEncoder().encode(encryptedData), StandardCharsets.UTF_8))
61+
.toString();
5562
// END USER CODE
5663
}
5764

@@ -65,5 +72,10 @@ public java.lang.String toString()
6572
}
6673

6774
// BEGIN EXTRA CODE
75+
private static final int KEY_LENGTH = 16;
76+
77+
private static int getKeyLength() {
78+
return KEY_LENGTH;
79+
}
6880
// END EXTRA CODE
6981
}

src/DeepLinkModule/javasource/mendixsso/actions/FindOrCreateUserWithUserInfo.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public IMendixObject executeAction() throws Exception
4949
user = UserManager.findOrCreateUser(userProfile).getMendixObject();
5050
} catch (Throwable e) {
5151
LOG.error("Something went wrong while provisioning the user with the provided user info", e);
52+
Thread.currentThread().interrupt();
5253
} finally {
5354
if (uuid != null) {
5455
ForeignIdentityUtils.unlockForeignIdentity(uuid);

0 commit comments

Comments
 (0)