Skip to content

Commit

Permalink
chore: include hotfix-17613 (#26142)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsolistorres committed Sep 17, 2023
1 parent df4e9fc commit faca97f
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.dotmarketing.util.PageMode;
import com.liferay.portal.PortalException;
import com.liferay.portal.SystemException;
import com.liferay.portal.model.User;

import javax.servlet.http.HttpServletRequest;

Expand All @@ -28,7 +29,7 @@ public interface HostWebAPI extends HostAPI {

public Host getCurrentHost(HttpServletRequest req) throws DotDataException, DotSecurityException, PortalException, SystemException;

public Host getCurrentHost(final HttpServletRequest request, final PageMode mode) throws DotDataException, DotSecurityException, PortalException, SystemException;
public Host getCurrentHost(final HttpServletRequest request, final User userParam) throws DotDataException, DotSecurityException, PortalException, SystemException;

public Host getHost(HttpServletRequest request);

Expand Down
117 changes: 86 additions & 31 deletions dotCMS/src/main/java/com/dotmarketing/business/web/HostWebAPIImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
import com.dotcms.repackage.javax.portlet.ActionRequest;
import com.dotcms.repackage.javax.portlet.RenderRequest;
import com.dotmarketing.beans.Host;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.business.DotStateException;
import com.dotmarketing.business.PermissionAPI;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.exception.DotRuntimeException;
import com.dotmarketing.exception.DotSecurityException;
import com.dotmarketing.portlets.contentlet.business.HostAPIImpl;
import com.dotmarketing.util.Logger;
import com.dotmarketing.util.PageMode;
import com.dotmarketing.util.UtilMethods;
import com.dotmarketing.util.WebKeys;
Expand All @@ -23,6 +26,7 @@

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Optional;

/**
*
Expand All @@ -31,11 +35,11 @@
*/
public class HostWebAPIImpl extends HostAPIImpl implements HostWebAPI {

public Host getCurrentHost(RenderRequest req) throws DotDataException, DotSecurityException, PortalException, SystemException {
public Host getCurrentHost(RenderRequest req) throws DotDataException, DotSecurityException {
return getCurrentHost(((RenderRequestImpl)req).getHttpServletRequest());
}

public Host getCurrentHost(ActionRequest req) throws DotDataException, DotSecurityException, PortalException, SystemException {
public Host getCurrentHost(ActionRequest req) throws DotDataException, DotSecurityException {
return getCurrentHost(((ActionRequestImpl)req).getHttpServletRequest());
}

Expand All @@ -52,48 +56,99 @@ public Host getHost(HttpServletRequest request) {

@CloseDBIfOpened
public Host getCurrentHost(final HttpServletRequest request)
throws DotDataException, DotSecurityException, PortalException, SystemException {

final PageMode mode = PageMode.get(request);

return this.getCurrentHost(request, mode);
throws DotDataException, DotSecurityException {
return this.getCurrentHost(request, null);
}

@Override
@CloseDBIfOpened
public Host getCurrentHost(final HttpServletRequest request, final PageMode mode)
throws DotDataException, DotSecurityException, PortalException, SystemException {
public Host getCurrentHost(final HttpServletRequest request, final User userParam)
throws DotDataException, DotSecurityException {

Host host = null;
final HttpSession session = request.getSession(false);
final UserWebAPI userWebAPI = WebAPILocator.getUserWebAPI();
final User systemUser = userWebAPI.getSystemUser();
final boolean respectFrontendRoles = !userWebAPI.isLoggedToBackend(request);
final String pageHostId = request.getParameter("host_id");
final User user = userParam != null ? userParam : userWebAPI.getSystemUser();
final boolean respectAnonPerms;
try {
respectAnonPerms = !userWebAPI.isLoggedToBackend(request);
} catch (PortalException | SystemException e) {
throw new DotDataException(e);
}

Optional<Host> optionalHost = this.getCurrentHostFromRequest(request, user, respectAnonPerms);

if (!optionalHost.isPresent() && !respectAnonPerms){
optionalHost = this.getCurrentHostFromSession(request, user);
}

final Host host = optionalHost.isPresent() ? optionalHost.get() : resolveHostName(request.getServerName(),
user, respectAnonPerms);

checkHostPermission(user, respectAnonPerms, host);
storeCurrentHost(request, respectAnonPerms, host);

return host;
}

private void checkHostPermission(final User user, boolean respectAnonPerms, final Host host)
throws DotDataException, DotSecurityException {

if(!APILocator.getPermissionAPI().doesUserHavePermission(host, PermissionAPI.PERMISSION_READ, user, respectAnonPerms)){
final String userId = (user != null) ? user.getUserId() : null;

final String message = "User " + userId + " does not have permission to host:" + host.getHostname();
Logger.error(HostAPIImpl.class, message);
throw new DotSecurityException(message);
}
}

private Optional<Host> getCurrentHostFromSession(final HttpServletRequest request, final User user)
throws DotSecurityException, DotDataException {

if (pageHostId != null && mode.isAdmin) {
host = find(pageHostId, systemUser, respectFrontendRoles);
final HttpSession session = request.getSession(false);

if (session == null){
return Optional.empty();
}

Host host = null;
if (session.getAttribute(WebKeys.CURRENT_HOST) != null) {
final Host hostFromSession = (Host) session.getAttribute(WebKeys.CURRENT_HOST);
final Object hostId = session.getAttribute(WebKeys.CMS_SELECTED_HOST_ID);
host = hostFromSession.getIdentifier().equals(hostId) ? hostFromSession : null;
}

if (host == null && session.getAttribute(WebKeys.CMS_SELECTED_HOST_ID) != null) {
final String hostId = (String) session.getAttribute(WebKeys.CMS_SELECTED_HOST_ID);
host = find(hostId, user, false);
}

return Optional.ofNullable(host);
}

private Optional<Host> getCurrentHostFromRequest(final HttpServletRequest request, final User user, final boolean respectAnonPerms)
throws DotDataException, DotSecurityException {

final String hostId = request.getParameter("host_id");

if (hostId != null && !respectAnonPerms) {
return Optional.ofNullable(find(hostId, user, false));
} else if (request.getParameter(Host.HOST_VELOCITY_VAR_NAME) != null) {
final String hostName = request.getParameter(Host.HOST_VELOCITY_VAR_NAME);
return this.resolveHostNameWithoutDefault(hostName, user, respectAnonPerms);
} else if (request.getAttribute(WebKeys.CURRENT_HOST) != null) {
return Optional.of((Host) request.getAttribute(WebKeys.CURRENT_HOST));
} else {
if (session != null && mode.isAdmin && session.getAttribute(WebKeys.CURRENT_HOST) != null) {
host = (Host) session.getAttribute(WebKeys.CURRENT_HOST);
} else if (request.getAttribute(WebKeys.CURRENT_HOST) != null) {
host = (Host) request.getAttribute(WebKeys.CURRENT_HOST);
} else {

final String serverName = request.getServerName();
if (UtilMethods.isSet(serverName)) {
host = resolveHostName(serverName, systemUser, respectFrontendRoles);
}
}
return Optional.empty();
}
}

request.setAttribute(WebKeys.CURRENT_HOST, host);
if (session != null && mode.isAdmin) {
private void storeCurrentHost(final HttpServletRequest request, final boolean respectAnonPerms, final Host host) {
final HttpSession session = request.getSession(false);

request.setAttribute(WebKeys.CURRENT_HOST, host);
if (session != null && !respectAnonPerms) {
session.setAttribute(WebKeys.CURRENT_HOST, host);
}

return host;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,20 @@ public interface HostAPI {
*/
public Host resolveHostName(String serverName, User user, boolean respectFrontendRoles) throws DotDataException, DotSecurityException ;

/**
* This method takes a server name (from a web request) and maps it to a host.
* It is designed to do a lightweight cache lookup to get the mapping from server name -> host
* and to prevent unnecessary lucene lookups.
* If does not exists a host with that serverName then null is returned
* @param serverName
* @param user
* @param respectFrontendRoles
* @return
* @throws DotDataException
* @throws DotSecurityException
*/
public Optional<Host> resolveHostNameWithoutDefault(String serverName, User user, boolean respectFrontendRoles) throws DotDataException, DotSecurityException ;

/**
* Retrieves the subset of all hosts in the system
* that matches the current host name filter, offset and limit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ public Host findDefaultHost(User user, boolean respectFrontendRoles) throws DotS

APILocator.getPermissionAPI().checkPermission(host, PermissionLevel.READ, user);
return host;
} catch (DotSecurityException | DotDataException e) {
Logger.warn(HostAPIImpl.class, "Error trying to het default host:" + e.getMessage());
throw e;
} catch (Exception e) {

throw new DotRuntimeException(e.getMessage(), e);
Expand Down Expand Up @@ -112,7 +115,7 @@ public Host resolveHostName(String serverName, User user, boolean respectFronten

if(host == null){
try {
host = findByNameNotDefault(serverName, systemUser, respectFrontendRoles);
host = resolveHostNameWithoutDefault(serverName, systemUser, respectFrontendRoles).get();
} catch (Exception e) {
return findDefaultHost(systemUser, respectFrontendRoles);
}
Expand All @@ -130,13 +133,44 @@ public Host resolveHostName(String serverName, User user, boolean respectFronten
hostCache.addHostAlias(serverName, host);
}
}

if(APILocator.getPermissionAPI().doesUserHavePermission(host, PermissionAPI.PERMISSION_READ, user, respectFrontendRoles)){
return host;
} else {

checkHostPermission(user, respectFrontendRoles, host);
return host;

}

@Override
@CloseDBIfOpened
public Optional<Host> resolveHostNameWithoutDefault(String serverName, User user, boolean respectFrontendRoles) throws DotDataException, DotSecurityException {

Host host = hostCache.getHostByAlias(serverName);
User systemUser = APILocator.systemUser();

if(host == null){
host = findByNameNotDefault(serverName, systemUser, respectFrontendRoles);

if(host == null){
host = findByAlias(serverName, systemUser, respectFrontendRoles);
}

if(host != null){
hostCache.addHostAlias(serverName, host);
}
}

if (host != null) {
checkHostPermission(user, respectFrontendRoles, host);
}

return Optional.ofNullable(host);

}

private void checkHostPermission(User user, boolean respectFrontendRoles, Host host) throws DotDataException, DotSecurityException {
if (!APILocator.getPermissionAPI().doesUserHavePermission(host, PermissionAPI.PERMISSION_READ, user, respectFrontendRoles)) {
String u = (user != null) ? user.getUserId() : null;
String h = (host != null) ? host.getHostname() : null;
throw new DotSecurityException("User: " + u + " does not have read permissions to " + h );
throw new DotSecurityException("User: " + u + " does not have read permissions to " + h);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@
import com.dotmarketing.portlets.htmlpageasset.model.IHTMLPage;
import com.dotmarketing.portlets.languagesmanager.business.LanguageAPI;
import com.dotmarketing.portlets.languagesmanager.model.Language;
import com.dotmarketing.util.Logger;
import com.dotmarketing.util.PageMode;
import com.dotmarketing.util.UUIDUtil;
import com.dotmarketing.util.WebKeys;
import com.liferay.portal.PortalException;
import com.liferay.portal.SystemException;
import com.liferay.portal.model.User;

import java.util.Optional;
Expand Down Expand Up @@ -120,7 +123,7 @@ public PageView getPageMetadata(
final HttpServletResponse response)
throws DotSecurityException, DotDataException {

final Host host = resolveSite(context, request);
final Host host = getCurrentHost(request, context.getUser());
final IHTMLPage page = getHtmlPageAsset(context, host, request);

return new HTMLPageAssetRenderedBuilder()
Expand Down Expand Up @@ -162,7 +165,7 @@ public PageView getPageRendered(

PageMode.setPageMode(request, mode);

final Host host = resolveSite(context, request);
final Host host = getCurrentHost(request, context.getUser());
final HTMLPageAsset page = context.getPage() != null
? context.getPage()
: (HTMLPageAsset) getHtmlPageAsset(context, host, request);
Expand Down Expand Up @@ -202,12 +205,7 @@ public PageMode getDefaultEditPageMode(
try {
final User systemUser = userAPI.getSystemUser();

final Host host = this.resolveSite(
PageContextBuilder.builder()
.setUser(systemUser)
.setPageMode(PageMode.PREVIEW_MODE)
.build(),
request);
final Host host = getCurrentHost(request, systemUser);

final IHTMLPage htmlPageAsset = this.getHtmlPageAsset(
PageContextBuilder.builder()
Expand Down Expand Up @@ -235,7 +233,7 @@ public String getPageHtml(
final HttpServletResponse response)
throws DotSecurityException, DotDataException {

final Host host = resolveSite(context, request);
final Host host = getCurrentHost(request, context.getUser());
final IHTMLPage page = getHtmlPageAsset(context, host, request);

return new HTMLPageAssetRenderedBuilder()
Expand Down Expand Up @@ -354,26 +352,15 @@ private Language getCurrentLanguage(final HttpServletRequest request) {
return request != null ? this.languageWebAPI.getLanguage(request) : defaultLanguage;
}

private Host resolveSite(final PageContext context, final HttpServletRequest request)
private Host getCurrentHost(final HttpServletRequest request, final User user)
throws DotDataException, DotSecurityException {

final User user = context.getUser();
final PageMode mode = context.getPageMode();

final String hostId = request.getParameter("host_id");
if (null != hostId) {
return this.hostAPI.find(hostId, user, mode.respectAnonPerms);
}

Host site;
if(mode.isAdmin && request.getSession().getAttribute( com.dotmarketing.util.WebKeys.CMS_SELECTED_HOST_ID )!=null) {
site = this.hostAPI.find(request.getSession().getAttribute( com.dotmarketing.util.WebKeys.CMS_SELECTED_HOST_ID ).toString(), user, mode.respectAnonPerms);
} else {
final String siteName = (null == request.getParameter(Host.HOST_VELOCITY_VAR_NAME)) ?
request.getServerName() : request.getParameter(Host.HOST_VELOCITY_VAR_NAME);
site = this.hostWebAPI.resolveHostName(siteName, user, mode.respectAnonPerms);
try {
return this.hostWebAPI.getCurrentHost(request, user);
} catch (PortalException | SystemException e) {
Logger.error(this,"System error getting current host", e);
throw new DotDataException(e);
}
return site;

}
}
2 changes: 1 addition & 1 deletion dotCMS/src/main/java/com/dotmarketing/util/PageMode.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public static PageMode get(final HttpServletRequest req) {

if (null != user && APILocator.getUserAPI().getAnonymousUser().equals(user)) {

final Host host = WebAPILocator.getHostWebAPI().getCurrentHost(req, pageMode);
final Host host = WebAPILocator.getHostWebAPI().getCurrentHost(req, user);
if (null == host || !APILocator.getPermissionAPI().doesUserHavePermission
(host, PermissionLevel.READ.getType(), user)) {

Expand Down

0 comments on commit faca97f

Please sign in to comment.