Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/src/org/labkey/api/view/ViewServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,12 @@ public String getParameter(@NotNull String name)
{
return _actionURL.getParameterNames();
}

@Override
public @Nullable String getQueryString()
{
return null == _actionURL || _actionURL.getParameters().isEmpty() ? null : _actionURL.getQueryString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this makes sense, but does this intentionally change the previous behavior where getQueryString() always returned null? (the parent method returned this.queryString, which was never set)

}
}


Expand Down
2 changes: 1 addition & 1 deletion api/src/org/labkey/api/view/WebPartFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public interface WebPartFactory

void setModule(Module module);

/** For backwards compatibility, names that this web part might have been previously called and should still match it for existing portal configurations */
/** For backwards compatibility, names that this web part might have been previously called and should still match for existing portal configurations */
List<String> getLegacyNames();

boolean isAvailable(Container c, String scope, String location);
Expand Down
5 changes: 5 additions & 0 deletions wiki/src/org/labkey/wiki/WikiManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,11 @@ public AttachmentParentType getAttachmentType()
return WikiType.get();
}

public HtmlString getNoPermissionsMessage(User user)
{
return HtmlString.of(user.isGuest() ? "Please log in to see this data." : "You do not have permission to see this data.");
}

public static class TestCase extends Assert
{
WikiManager _m = null;
Expand Down
3 changes: 2 additions & 1 deletion wiki/src/org/labkey/wiki/WikiModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ private void loadWikiContent(@Nullable Container c, User user, String name, Stri
return Set.of(
WikiManager.TestCase.class,
WikiController.CopyWikiContainerScopingTestCase.class,
WikiController.PermissionTestCase.class
WikiController.PermissionTestCase.class,
WikiTOC.TestCase.class
);
}

Expand Down
98 changes: 94 additions & 4 deletions wiki/src/org/labkey/wiki/WikiTOC.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,26 @@

package org.labkey.wiki;

import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.labkey.api.data.Container;
import org.labkey.api.data.ContainerManager;
import org.labkey.api.security.Group;
import org.labkey.api.security.MutableSecurityPolicy;
import org.labkey.api.security.SecurityManager;
import org.labkey.api.security.SecurityPolicyManager;
import org.labkey.api.security.User;
import org.labkey.api.security.permissions.AbstractContainerScopingTest;
import org.labkey.api.security.permissions.AdminPermission;
import org.labkey.api.security.permissions.InsertPermission;
import org.labkey.api.security.permissions.ReadPermission;
import org.labkey.api.security.permissions.UpdatePermission;
import org.labkey.api.security.roles.ReaderRole;
import org.labkey.api.security.roles.SubmitterRole;
import org.labkey.api.util.DOM;
import org.labkey.api.util.HtmlString;
import org.labkey.api.util.LinkBuilder;
Expand All @@ -36,8 +48,10 @@
import org.labkey.api.view.ViewContext;
import org.labkey.api.view.menu.NavTreeMenu;
import org.labkey.api.view.template.ClientDependency;
import org.labkey.api.wiki.WikiRendererType;
import org.labkey.api.writer.HtmlWriter;
import org.labkey.wiki.model.Wiki;
import org.springframework.mock.web.MockHttpServletResponse;

import java.util.LinkedHashSet;
import java.util.List;
Expand All @@ -55,6 +69,7 @@ public class WikiTOC extends NavTreeMenu
{
private String _selectedLink;
private final Container _cToc;
private final boolean _canRead;

public WikiTOC(ViewContext context)
{
Expand Down Expand Up @@ -90,10 +105,16 @@ public WikiTOC(ViewContext context, @Nullable Portal.WebPart part)
if (null == _cToc)
throw new NotFoundException("Could not find container for id: \"" + id + "\"");

setId(getNavTreeId(_cToc));
setElements(context, getNavTree());
setCollapsible(false);
setNavMenu(createNavMenu());
// Render the no-permission message in renderView() rather than throwing, to match wiki webpart
_canRead = _cToc.hasPermission(context.getUser(), ReadPermission.class);

if (_canRead)
{
setId(getNavTreeId(_cToc));
setElements(context, getNavTree());
setCollapsible(false);
setNavMenu(createNavMenu());
}
}

private NavTree createNavMenu()
Expand Down Expand Up @@ -185,6 +206,14 @@ public LinkedHashSet<ClientDependency> getClientDependencies()
protected void renderView(Object model, HtmlWriter out)
{
ViewContext context = getViewContext();
User user = context.getUser();

// Check read permission in target container before rendering anything, GH Issue 1445
if (!_canRead)
{
out.write(WikiManager.get().getNoPermissionsMessage(user));
return;
}

boolean isInWebPart = isInWebPart(context);

Expand Down Expand Up @@ -316,4 +345,65 @@ private boolean isInWebPart(ViewContext context)
//is page being rendered in web part or in module?
return context.getActionURL().getController().equalsIgnoreCase("Project");
}

public static class TestCase extends AbstractContainerScopingTest
{
private static final String PAGE_TITLE = "WikiTocTargetPage";
private static final String NEW_MENU_ITEM = ">New</a>";

private Container _host;
private Container _target;

@Before
public void createFolders()
{
_host = createContainer("Host");
_target = createContainer("Target");
WikiManager.get().insertWiki(getAdmin(), _target, "tocPage", "body", WikiRendererType.HTML, PAGE_TITLE);
}

@Test
public void testTocRequiresReadInTargetFolder() throws Exception
{
User user = createUserInRole(_host, ReaderRole.class);
String html = renderToc(user);
assertTrue("Expected no-permission message, html was: " + html, html.contains(WikiManager.get().getNoPermissionsMessage(user).toString()));
assertFalse("Target folder's page leaked into the TOC", html.contains(PAGE_TITLE));

grantRole(user, _target, ReaderRole.class);
html = renderToc(user);
assertTrue("Reader in the target folder should see its pages, html was: " + html, html.contains(PAGE_TITLE));

MutableSecurityPolicy policy = new MutableSecurityPolicy(_host.getPolicy());
policy.addRoleAssignment(SecurityManager.getGroup(Group.groupGuests), ReaderRole.class);
SecurityPolicyManager.savePolicyForTests(policy, getAdmin());
html = renderToc(User.guest);
assertTrue("Expected guest login prompt, html was: " + html, html.contains("Please log in to see this data."));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this use WikiManager.get().getNoPermissionsMessage(..) like above, instead of the hard-coded text?

assertFalse("Target folder's page leaked into the guest TOC", html.contains(PAGE_TITLE));
}

@Test
public void testTocHidesMenuWithoutReadInTargetFolder() throws Exception
{
// Submitter has Insert but not Read, so it would otherwise get the "New" menu item
User user = createUserInRole(_host, ReaderRole.class);
grantRole(user, _target, SubmitterRole.class);
String html = renderToc(user);
assertFalse("Menu should be suppressed without read, html was: " + html, html.contains(NEW_MENU_ITEM));

grantRole(user, _target, ReaderRole.class);
html = renderToc(user);
assertTrue("Insert + read in the target folder should show the \"New\" menu item, html was: " + html, html.contains(NEW_MENU_ITEM));
}

private String renderToc(User user) throws Exception
{
ActionURL url = new ActionURL("project", "getWebPart", _host)
.addParameter("webpart.name", "Wiki Table of Contents")
.addParameter("webPartContainer", _target.getId());
MockHttpServletResponse response = get(url, user);
assertStatus(HttpServletResponse.SC_OK, response);
return new JSONObject(response.getContentAsString()).getString("html");
}
}
}
5 changes: 0 additions & 5 deletions wiki/src/org/labkey/wiki/WikiTOCFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,6 @@
import java.util.HashMap;
import java.util.Map;

/**
* User: adam
* Date: Nov 5, 2008
* Time: 10:51:27 AM
*/
public class WikiTOCFactory extends BaseWebPartFactory
{
public WikiTOCFactory()
Expand Down
4 changes: 3 additions & 1 deletion wiki/src/org/labkey/wiki/model/BaseWikiView.java
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,9 @@ else if (folderHasWikis)
}

setTitle(title);
setNavMenu(initNavMenu());
// No nav menu if you can't read. This suppresses "New" and "Print" menu options.
if (perms.allowRead(wiki))
setNavMenu(initNavMenu());
}


Expand Down
13 changes: 4 additions & 9 deletions wiki/src/org/labkey/wiki/view/wiki.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<%@ page import="org.labkey.wiki.WikiController" %>
<%@ page import="org.labkey.wiki.model.BaseWikiView" %>
<%@ page import="org.labkey.wiki.model.Wiki" %>
<%@ page import="org.labkey.wiki.WikiManager" %>
<%@ page extends="org.labkey.api.jsp.JspBase" %>
<!--wiki-->
<%
Expand All @@ -44,15 +45,9 @@

if (!c.hasPermission(user, ReadPermission.class))
{
%><table width="100%"><tr><td align=left><%
if (user.isGuest())
{
%>Please log in to see this data.<%
}
else
{
%>You do not have permission to see this data.<%
}%></td></tr></table><%
%><table width="100%">
<tr><td align=left><%=WikiManager.get().getNoPermissionsMessage(user)%></td></tr>
</table><%
return;
}

Expand Down
16 changes: 5 additions & 11 deletions wiki/src/org/labkey/wiki/view/wikiVersion.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,25 @@
<%@ page import="org.labkey.wiki.WikiController.VersionBean" %>
<%@ page import="org.labkey.wiki.WikiSelectManager" %>
<%@ page import="org.labkey.wiki.model.WikiVersion" %>
<%@ page import="org.labkey.wiki.WikiManager" %>
<%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib" %>
<%@ page extends="org.labkey.api.jsp.JspBase" %>
<%
JspView<VersionBean> me = HttpView.currentView();
VersionBean bean = me.getModelBean();
User user = getUser();
Container c = getContainer();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unused Container import can be removed since this line was deleted and there are no other Container usages.

%>
<!--wiki-->
<table width="100%">
<tr><td align=left colspan="2">
<%
if (!bean.hasReadPermission)
{
if (user.isGuest())
{
%>Please log in to see this data.<%
}
else
{
%>You do not have permission to see this data.<%
}%>
%>
<%=WikiManager.get().getNoPermissionsMessage(user)%>
</td></tr></table>

<%}
<%
}
else
{
HtmlString formattedHtml = bean.html;
Expand Down
Loading