Skip to content

Commit

Permalink
fix(PageResource) set tm_date as a request attribute when no session …
Browse files Browse the repository at this point in the history
…exist Refs: #30552 (#30777)

Pull Request Summary:

Historically, the tm_date (time machine date) has been passed as a
session attribute. Many components of the PageResource rely heavily on
session data. However, with the transition of timeMachineDate to a
request parameter, and considering that the endpoint can now be consumed
via curl using a Bearer token—where there is insufficient information to
construct or restore a session—we needed to ensure that this data could
be propagated to the internal layers of the API.

These changes introduce support for handling the timeMachineDate as a
request parameter, enabling its use even when no session exists.
Additionally, this update lays the groundwork for supporting a broader
range of dates for capturing the publishDate.
  • Loading branch information
fabrizzio-dotCMS authored Nov 28, 2024
1 parent 0c95091 commit 03141ce
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -356,25 +356,30 @@ private Optional<Date> timeMachineDate(final HttpServletRequest request) {
return Optional.empty();
}

Optional<String> millis = Optional.empty();
final HttpSession session = request.getSession(false);
if (session == null) {
return Optional.empty();
if (session != null) {
millis = Optional.ofNullable ((String)session.getAttribute(PageResource.TM_DATE));
}

if (millis.isEmpty()) {
millis = Optional.ofNullable((String)request.getAttribute(PageResource.TM_DATE));
}

final String millisAsString = (String) session.getAttribute(PageResource.TM_DATE);
if (!UtilMethods.isSet(millisAsString)) {
if (millis.isEmpty()) {
return Optional.empty();
}

try {
long milliseconds = Long.parseLong(millisAsString);
final long milliseconds = Long.parseLong(millis.get());
return milliseconds > 0
? Optional.of(Date.from(Instant.ofEpochMilli(milliseconds)))
: Optional.empty();
} catch (NumberFormatException e) {
Logger.error(this, "Invalid timestamp format: " + millisAsString, e);
Logger.error(this, "Invalid timestamp format: " + millis.get(), e);
return Optional.empty();
}

}

/**
Expand Down
40 changes: 29 additions & 11 deletions dotCMS/src/main/java/com/dotcms/rest/api/v1/page/PageResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import com.dotmarketing.portlets.languagesmanager.model.Language;
import com.dotmarketing.portlets.templates.model.Template;
import com.dotmarketing.portlets.workflows.model.WorkflowAction;
import com.dotmarketing.util.DateUtil;
import com.dotmarketing.util.Logger;
import com.dotmarketing.util.PageMode;
import com.dotmarketing.util.StringUtils;
Expand All @@ -87,6 +88,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
Expand Down Expand Up @@ -353,9 +355,18 @@ private PageRenderParams optionalRenderParams(final String modeParam,
if (null != deviceInode){
builder.deviceInode(deviceInode);
}
if(null != timeMachineDateAsISO8601){
final Instant date = Try.of(()->Instant.parse(timeMachineDateAsISO8601)).getOrElseThrow(e->new IllegalArgumentException("time machine date must be ISO-8601 compliant"));
builder.timeMachineDate(date);
if (null != timeMachineDateAsISO8601) {
final Date date;
try {
date = Try.of(() -> DateUtil.convertDate(timeMachineDateAsISO8601)).getOrElseThrow(
e -> new IllegalArgumentException(
String.format("Error Parsing date: %s", timeMachineDateAsISO8601),
e));
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
}
final Instant instant = date.toInstant();
builder.timeMachineDate(instant);
}
return builder.build();
}
Expand Down Expand Up @@ -416,7 +427,10 @@ private Response getPageRender(final PageRenderParams renderParams) throws DotDa
request.getSession()
.setAttribute(WebKeys.CURRENT_DEVICE,deviceInode.get());
} else {
request.getSession().removeAttribute(WebKeys.CURRENT_DEVICE);
final HttpSession session = request.getSession(false);
if (null != session) {
session.removeAttribute(WebKeys.CURRENT_DEVICE);
}
}
final PageView pageRendered;
final PageContextBuilder pageContextBuilder = PageContextBuilder.builder()
Expand Down Expand Up @@ -458,18 +472,22 @@ private Response getPageRender(final PageRenderParams renderParams) throws DotDa
private void setUpTimeMachineIfPresent(final PageRenderParams renderParams) {
final Optional<Instant> timeMachineDate = renderParams.timeMachineDate();
if(timeMachineDate.isPresent()){
final String timeMachineEpochMillis = String.valueOf(timeMachineDate.get().toEpochMilli());
final Optional<Host> host = currentHost(renderParams);
if(host.isEmpty()){
throw new IllegalArgumentException("Unable to set a host for the Time Machine");
}
final HttpServletRequest request = renderParams.request();
final HttpSession session = request.getSession(false);
if (null != session) {
session.setAttribute(TM_DATE, String.valueOf(timeMachineDate.get().toEpochMilli()));
session.setAttribute(TM_DATE, timeMachineEpochMillis);
session.setAttribute(TM_LANG, renderParams.languageId());
session.setAttribute(DOT_CACHE, "refresh");
final Optional<Host> host = currentHost(renderParams);
if(host.isPresent()){
session.setAttribute(TM_HOST, host.get());
} else {
throw new IllegalArgumentException("Unable to set a host for the Time Machine");
}
} else {
request.setAttribute(TM_DATE, timeMachineEpochMillis);
request.setAttribute(TM_LANG, renderParams.languageId());
request.setAttribute(DOT_CACHE, "refresh");
request.setAttribute(TM_HOST, host.get());
}
}
}
Expand Down
13 changes: 10 additions & 3 deletions dotCMS/src/main/java/com/dotcms/util/TimeMachineUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.dotcms.api.web.HttpServletRequestThreadLocal;

import com.dotcms.rest.api.v1.page.PageResource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Optional;

Expand All @@ -14,11 +16,16 @@ private TimeMachineUtil(){}
* @return
*/
public static Optional<String> getTimeMachineDate() {
if (null == HttpServletRequestThreadLocal.INSTANCE.getRequest()) {
final HttpServletRequest request = HttpServletRequestThreadLocal.INSTANCE.getRequest();
if (null == request) {
return Optional.empty();
}
final HttpSession session = HttpServletRequestThreadLocal.INSTANCE.getRequest().getSession(false);
final Object timeMachineObject = session != null ? session.getAttribute("tm_date") : null;
final HttpSession session = request.getSession(false);
Object timeMachineObject = session != null ? session.getAttribute(PageResource.TM_DATE) : null;
if(null != timeMachineObject){
return Optional.of(timeMachineObject.toString());
}
timeMachineObject = request.getAttribute(PageResource.TM_DATE);
return Optional.ofNullable(timeMachineObject != null ? timeMachineObject.toString() : null);
}

Expand Down

0 comments on commit 03141ce

Please sign in to comment.