Skip to content

Commit

Permalink
Merge branch 'master' into issue-26900-pass-field-variables-binary-fi…
Browse files Browse the repository at this point in the history
…eld-monaco
  • Loading branch information
oidacra authored Feb 1, 2024
2 parents d329d26 + c4e5541 commit e31e996
Show file tree
Hide file tree
Showing 29 changed files with 1,039 additions and 404 deletions.
71 changes: 68 additions & 3 deletions dotCMS/src/curl-test/ApiToken_Resource.postman_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,45 @@
" pm.expect(jsonData.entity.token.userId).to.eql('dotcms.org.1');",
"});",
"",
"pm.collectionVariables.set(\"tokenid\", jsonData.entity.token.id);"
"pm.collectionVariables.set(\"tokenid\", jsonData.entity.token.id);",
"",
"pm.test(\"Token should expire after certain duration\", function () {",
" const currentTimestamp = Math.floor(Date.now() / 1000);",
" const expirationTime = jsonData.entity.token.expiresDate;",
" pm.expect(expirationTime).to.be.above(currentTimestamp);",
"});",
"",
"pm.test(\"Token ID should be unique\", function () {",
" const tokenID = jsonData.entity.token.id;",
" pm.collectionVariables.get(\"tokenIDs\") || pm.collectionVariables.set(\"tokenIDs\", []);",
" const tokenIDs = pm.collectionVariables.get(\"tokenIDs\");",
" pm.expect(tokenIDs).to.not.include(tokenID);",
" tokenIDs.push(tokenID);",
" pm.collectionVariables.set(\"tokenIDs\", tokenIDs);",
"});",
"",
"pm.test(\"Token should be securely generated\", function () {",
" const jwtToken = jsonData.entity.jwt;",
" // Add your custom logic to check the security of the JWT token",
" pm.expect(jwtToken.length).to.be.above(50); // Example: Check for a minimum length",
" pm.expect(jwtToken).to.match(/^[A-Za-z0-9-_=]+\\.[A-Za-z0-9-_=]+\\.[A-Za-z0-9-_.+/=]+$/); // Example: Check for a typical JWT format",
"});",
"",
"pm.test(\"Rate-limit shouldn't exceed\", function () {",
" // Adjust the expected status code and message based on your API's rate limiting response",
" const expectedRateLimitStatusCode = 429; // HTTP status code for Too Many Requests",
" const expectedRateLimitMessage = \"Rate Limit Exceeded\"; // Message indicating rate limit exceeded",
"",
" if (pm.response.code === expectedRateLimitStatusCode) {",
" // Rate limit exceeded, which is expected behavior",
" pm.expect(pm.response.text()).to.include(expectedRateLimitMessage);",
" } else {",
" ",
" pm.expect(pm.response.code).to.eql(200);",
" }",
"});",
"",
""
],
"type": "text/javascript"
}
Expand Down Expand Up @@ -654,7 +692,29 @@
" pm.expect(jsonData.entity.token.userId).to.eql('dotcms.org.1');",
"});",
"",
"pm.collectionVariables.set(\"tokenid\", jsonData.entity.token.id);"
"pm.collectionVariables.set(\"tokenid\", jsonData.entity.token.id);",
"",
"pm.test(\"Token should expire\", function () {",
" const currentTimestamp = Math.floor(Date.now() / 1000);",
" const expirationTime = jsonData.entity.token.expiresDate;",
" pm.expect(expirationTime).to.be.above(currentTimestamp);",
"});",
"",
"pm.test(\"Token ID should be unique\", function () {",
" const tokenID = jsonData.entity.token.id;",
" pm.collectionVariables.get(\"tokenIDs\") || pm.collectionVariables.set(\"tokenIDs\", []);",
" const tokenIDs = pm.collectionVariables.get(\"tokenIDs\");",
" pm.expect(tokenIDs).to.not.include(tokenID);",
" tokenIDs.push(tokenID);",
" pm.collectionVariables.set(\"tokenIDs\", tokenIDs);",
"});",
"",
"pm.test(\"Token should be securely generated\", function () {",
" const jwtToken = jsonData.entity.jwt;",
" // Add your custom logic to check the security of the JWT token",
" pm.expect(jwtToken.length).to.be.above(50); // Example: Check for a minimum length",
" pm.expect(jwtToken).to.match(/^[A-Za-z0-9-_=]+\\.[A-Za-z0-9-_=]+\\.[A-Za-z0-9-_.+/=]+$/); // Example: Check for a typical JWT format",
"});"
],
"type": "text/javascript"
}
Expand Down Expand Up @@ -759,7 +819,12 @@
"exec": [
"pm.test(\"Status code should be 200\", function() {",
" pm.response.to.have.status(200);",
"});"
"});",
"",
"pm.test(\"Response has a valid JWT\", function () {",
" pm.expect(pm.response.json().entity.jwt).to.match(/^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_.+/=]*$/);",
"});"

],
"type": "text/javascript"
}
Expand Down
7 changes: 6 additions & 1 deletion dotCMS/src/curl-test/TempAPI.postman_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
" ",
"});",
"",
"pm.test('File size exceeded', () => {",
" // Check if the response body contains the error message",
" pm.expect(pm.response.text()).to.include('Invalid Binary Part, Message: The maximum file size for this field is 1024.0 K.');",
"});",
"",
""
],
"type": "text/javascript"
Expand Down Expand Up @@ -242,4 +247,4 @@
"response": []
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,24 @@

import java.io.IOException;

public class DotInvalidLicenseException extends Exception {
public class DotInvalidLicenseException extends RuntimeException {

private static final long serialVersionUID = 1L;

String message;

@Override
public String getMessage() {
// TODO Auto-generated method stub
return message;
}

public DotInvalidLicenseException(final String string) {
this.message = string;
}

public DotInvalidLicenseException(String string, IOException e) {
this.message = string;
initCause(e);
}

/**
*
*/
private static final long serialVersionUID = 1L;





}
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,6 @@

package com.dotcms.enterprise.license;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import com.dotcms.business.WrapInTransaction;
import com.dotcms.cluster.ClusterUtils;
import com.dotcms.enterprise.LicenseUtil;
Expand All @@ -68,6 +56,7 @@
import com.dotcms.enterprise.license.bouncycastle.crypto.params.KeyParameter;
import com.dotcms.enterprise.license.bouncycastle.util.encoders.Base64;
import com.dotcms.enterprise.license.bouncycastle.util.encoders.Hex;
import com.dotcms.exception.ExceptionUtil;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.business.CacheLocator;
import com.dotmarketing.business.ChainableCacheAdministratorImpl;
Expand All @@ -77,14 +66,26 @@
import com.dotmarketing.servlets.InitServlet;
import com.dotmarketing.util.ConfigUtils;
import com.dotmarketing.util.Logger;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.exception.ExceptionUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;

/**
* Provides access to licensing information for a dotCMS instance. This allows the system to perform
* validations a to limit or hide enterprise-only application features.
* validations and limit or hide enterprise-level application features.
*
* @author root
* @since 1.x
*
*/
public final class LicenseManager {

Expand Down Expand Up @@ -169,20 +170,20 @@ public void forceLicenseFromRepo(String serial) throws Exception {
* expiration days.
*/
private DotLicense readLicenseFile() {
File f = new File(getLicensePath());
try (InputStream is = Files.newInputStream(f.toPath())){
String licenseRaw = IOUtils.toString(is);
DotLicense dl = new LicenseTransformer(licenseRaw).dotLicense;
final File licenseFile = new File(getLicensePath());
try (final InputStream is = Files.newInputStream(licenseFile.toPath())) {
final String licenseRaw = IOUtils.toString(is, StandardCharsets.UTF_8);
final DotLicense dl = new LicenseTransformer(licenseRaw).dotLicense;
try {
LicenseRepoDAO.upsertLicenseToRepo( dl.serial, licenseRaw);
} catch (Exception e) {
} catch (final Exception e) {
Logger.warnEveryAndDebug(this.getClass(), "Cannot upsert License to db", e,120000);
}
return dl;
} catch (Throwable e) {
} catch (final Throwable e) {
// Eat Me
Logger.warn(System.class, "No Valid License Found : " + f.getAbsolutePath());

Logger.debug(System.class, String.format("No valid license was found: %s",
ExceptionUtil.getErrorMessage(e)), e);
}
return setupDefaultLicense(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.dotcms.business.CloseDB;
import com.dotcms.business.CloseDBIfOpened;
import com.dotcms.business.WrapInTransaction;
import com.dotcms.util.EnterpriseFeature;
import com.dotcms.util.LogTime;
import com.dotmarketing.util.Logger;
import net.bytebuddy.agent.ByteBuddyAgent;
Expand All @@ -23,7 +24,11 @@
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import static net.bytebuddy.matcher.ElementMatchers.*;
import static net.bytebuddy.matcher.ElementMatchers.declaresMethod;
import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isSynthetic;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;

/**
* Initializes ByteBuddy to handle transactional annotations. This replaces AspectJ functionality
Expand All @@ -39,7 +44,8 @@ public class ByteBuddyFactory {
WrapInTransaction.class, WrapInTransactionAdvice.class,
CloseDB.class, CloseDBAdvice.class,
CloseDBIfOpened.class, CloseDBIfOpenedAdvice.class,
LogTime.class, LogTimeAdvice.class
LogTime.class, LogTimeAdvice.class,
EnterpriseFeature.class, EnterpriseFeatureAdvice.class
);


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.dotcms.business.bytebuddy;

import com.dotcms.enterprise.LicenseUtil;
import com.dotcms.enterprise.license.DotInvalidLicenseException;
import com.dotcms.enterprise.license.LicenseLevel;
import com.dotcms.util.EnterpriseFeature;
import net.bytebuddy.asm.Advice;

import java.lang.reflect.Method;

/**
* This Advice class handles the behavior of the @{@link EnterpriseFeature} Annotation.
*
* @author Jose Castro
* @since Jan 23rd, 2024
*/
public class EnterpriseFeatureAdvice {

/**
* Checks that the specified Enterprise License level requirement is met. It allows for all
* License levels that are equal or greater than the one set in the Annotation.
*
* @param method The method that has been annotated with @{@link EnterpriseFeature}
*/
@Advice.OnMethodEnter
static void enter(final @Advice.Origin Method method) {
final LicenseLevel licenseLevel =
method.getAnnotation(EnterpriseFeature.class).licenseLevel();
final String errorMsg = method.getAnnotation(EnterpriseFeature.class).errorMsg();
final int currenLicenseLevel = LicenseUtil.getLevel();
if (currenLicenseLevel < licenseLevel.level) {
throw new DotInvalidLicenseException(errorMsg);
}
}

}
Loading

0 comments on commit e31e996

Please sign in to comment.