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
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.jetbrains.annotations.Nullable;
import org.json.JSONObject;
import org.labkey.announcements.model.AnnouncementDigestProvider;
import org.labkey.announcements.model.AnnouncementFullModel;
import org.labkey.announcements.model.AnnouncementManager;
import org.labkey.announcements.model.AnnouncementModel;
import org.labkey.announcements.model.DailyDigestEmailPrefsSelector;
Expand Down Expand Up @@ -107,11 +108,11 @@
import org.labkey.api.util.DateUtil;
import org.labkey.api.util.GUID;
import org.labkey.api.util.HtmlString;
import org.labkey.api.util.OptionBuilder;
import org.labkey.api.util.PageFlowUtil;
import org.labkey.api.util.Pair;
import org.labkey.api.util.URLHelper;
import org.labkey.api.util.OptionBuilder;
import org.labkey.api.util.SelectBuilder;
import org.labkey.api.util.URLHelper;
import org.labkey.api.view.ActionURL;
import org.labkey.api.view.AjaxCompletion;
import org.labkey.api.view.AlwaysAvailableWebPartFactory;
Expand All @@ -137,7 +138,6 @@
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
Expand Down Expand Up @@ -218,7 +218,6 @@ public static ActionURL getBeginURL(Container c)

public static AnnouncementModel copyEditableProps(AnnouncementModel target, AnnouncementModel source, boolean isInsert)
{
if (source.getApproved() != null) target.setApproved(source.getApproved());
if (source.getAssignedTo() != null) target.setAssignedTo(source.getAssignedTo());
if (source.getBody() != null) target.setBody(source.getBody());
if (source.getExpires() != null) target.setExpires(source.getExpires());
Expand Down Expand Up @@ -940,7 +939,7 @@ public BindException bindParameters(PropertyValues m) throws Exception
public ModelAndView getInsertUpdateView(AnnouncementForm form, boolean reshow, BindException errors)
{
Permissions perm = getPermissions();
AnnouncementModel parent = null;
AnnouncementFullModel parent = null;
Container c = getContainer();

if (null != form.getParentId())
Expand Down Expand Up @@ -2308,7 +2307,7 @@ protected DataRegion getDataRegion(Permissions perm, Settings settings)

public static class ThreadViewBean
{
public AnnouncementModel announcementModel;
public AnnouncementFullModel announcementModel;
public String message = "";
public Permissions perm = null;
public boolean isResponse = false;
Expand Down Expand Up @@ -2336,7 +2335,7 @@ public ThreadView(Container c, URLHelper currentURL, User user, String rowId, St
init(c, findThread(c, rowId, entityId), currentURL, getPermissions(c, user, getSettings(c)), false, false);
}

public ThreadView(Container c, ActionURL url, AnnouncementModel ann, Permissions perm)
public ThreadView(Container c, ActionURL url, AnnouncementFullModel ann, Permissions perm)
{
this();
init(c, ann, url, perm, true, false);
Expand All @@ -2345,11 +2344,11 @@ public ThreadView(Container c, ActionURL url, AnnouncementModel ann, Permissions
public ThreadView(AnnouncementForm form, Container c, ActionURL url, Permissions perm, boolean print)
{
this();
AnnouncementModel ann = findThread(c, form.get("rowId"), form.get("entityId"));
AnnouncementFullModel ann = findThread(c, form.get("rowId"), form.get("entityId"));
init(c, ann, url, perm, false, print);
}

protected void init(Container c, AnnouncementModel ann, URLHelper currentURL, Permissions perm, boolean isResponse, boolean print)
protected void init(Container c, AnnouncementFullModel ann, URLHelper currentURL, Permissions perm, boolean isResponse, boolean print)
{
if (null == c || !perm.allowRead(ann))
{
Expand Down Expand Up @@ -2454,7 +2453,7 @@ public AnnouncementModel getAnnouncement()
}


private static @Nullable AnnouncementModel findThread(Container c, String rowIdVal, String entityId)
private static @Nullable AnnouncementFullModel findThread(Container c, String rowIdVal, String entityId)
{
int rowId = 0;
if (rowIdVal != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<%@ page import="org.labkey.announcements.AnnouncementsController.RespondAction" %>
<%@ page import="org.labkey.announcements.AnnouncementsController.ThreadView" %>
<%@ page import="org.labkey.announcements.AnnouncementsController.ThreadViewBean" %>
<%@ page import="org.labkey.announcements.model.AnnouncementFullModel" %>
<%@ page import="org.labkey.announcements.model.AnnouncementManager" %>
<%@ page import="org.labkey.announcements.model.AnnouncementModel" %>
<%@ page import="org.labkey.announcements.model.DiscussionServiceImpl" %>
Expand All @@ -40,7 +41,7 @@
Container c = getContainer();
User user = getUser();
ThreadViewBean bean = me.getModelBean();
AnnouncementModel announcementModel = bean.announcementModel;
AnnouncementFullModel announcementModel = bean.announcementModel;
DiscussionService.Settings settings = bean.settings;

if (null == announcementModel)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.labkey.announcements.model;

import java.util.Date;

public class AnnouncementFullModel extends AnnouncementModel
{
private Date _approved = null;

public Date getApproved()
{
return _approved;
}

public void setApproved(Date approved)
{
_approved = approved;
}

public boolean isSpam()
{
return AnnouncementManager.SPAM_MAGIC_DATE.equals(getApproved());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,20 +124,20 @@ private AnnouncementManager()
{
}

private static @Nullable AnnouncementModel getAnnouncement(@Nullable Container c, @NotNull SimpleFilter filter)
private static @Nullable AnnouncementFullModel getAnnouncement(@Nullable Container c, @NotNull SimpleFilter filter)
{
if (c != null)
filter.addCondition(FieldKey.fromParts("Container"), c);

return new TableSelector(_comm.getTableInfoAnnouncements(), filter, null).getObject(AnnouncementModel.class);
return new TableSelector(_comm.getTableInfoAnnouncements(), filter, null).getObject(AnnouncementFullModel.class);
}

public static @Nullable AnnouncementModel getAnnouncement(@Nullable Container c, int rowId)
public static @Nullable AnnouncementFullModel getAnnouncement(@Nullable Container c, int rowId)
{
return getAnnouncement(c, new SimpleFilter(FieldKey.fromParts("RowId"), rowId));
}

public static @Nullable AnnouncementModel getAnnouncement(@Nullable Container c, String entityId)
public static @Nullable AnnouncementFullModel getAnnouncement(@Nullable Container c, String entityId)
{
try
{
Expand Down Expand Up @@ -531,7 +531,7 @@ private static AnnouncementModel validateModelWithSideEffects(AnnouncementModel
}

// Magic date value used to mark an announcement that a moderator has reviewed and marked as spam
private static final Date SPAM_MAGIC_DATE = new Date(0);
static final Date SPAM_MAGIC_DATE = new Date(0);

// Standard filters for retrieving specific classes of messages (approved, spam, needs review)
public static final SimpleFilter IS_APPROVED_FILTER = new SimpleFilter(FieldKey.fromParts("Approved"), AnnouncementManager.SPAM_MAGIC_DATE, CompareType.GT);
Expand All @@ -543,11 +543,6 @@ public static void markAsSpam(Container c, AnnouncementModel ann)
updateApproved(c, ann, SPAM_MAGIC_DATE);
}

public static boolean isSpam(AnnouncementModel ann)
{
return SPAM_MAGIC_DATE.equals(ann.getApproved());
}

// Execute direct SQL (not Table.update())... I don't think we want to change Modified or ModifiedBy. Could consider adding column for Moderator, though.
// Returns true if an update was made, false if not (e.g., message was already reviewed).
private static boolean updateApproved(Container c, AnnouncementModel ann, Date date)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ public class AnnouncementModel extends Entity implements Serializable

private Collection<AnnouncementModel> _responses = null;
private Set<User> _authors;
private Date _approved = null;

/**
* Standard constructor.
Expand Down Expand Up @@ -429,21 +428,5 @@ public AttachmentParent getAttachmentParent()
{
return new AnnouncementAttachmentParent(this);
}

public Date getApproved()
{
return _approved;
}

public void setApproved(Date approved)
{
_approved = approved;
}

@JsonIgnore
public boolean isSpam()
{
return AnnouncementManager.isSpam(this);
}
}

3 changes: 2 additions & 1 deletion api/src/org/labkey/api/action/ApiJsonWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,8 @@ public void testExceptionNotCommitted() throws IOException
var responseText = ((MockHttpServletResponse)writer.getResponse()).getContentAsString();
var json = new JSONObject(responseText);
assertEquals("throwing up", json.getString("exception"));
assertTrue(json.has("stackTrace"));
assertFalse(json.getBoolean("success"));
assertEquals("java.lang.IllegalStateException", json.get("exceptionClass"));
assertFalse(json.has("schemaName"));
}

Expand Down
1 change: 0 additions & 1 deletion api/src/org/labkey/api/action/ApiResponseWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,6 @@ public JSONObject toJSON(Throwable e)
JSONObject json = new JSONObject();
json.put("exception", e.getMessage() != null ? e.getMessage() : e.getClass().getName());
json.put("exceptionClass", e.getClass().getName());
json.put("stackTrace", e.getStackTrace());
return json;
}

Expand Down
2 changes: 1 addition & 1 deletion api/src/org/labkey/api/defaults/DefaultValuesAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public DefaultValuesAction(Class formClass)
protected Domain getDomain(FormType domainIdForm)
{
Domain domain = PropertyService.get().getDomain(domainIdForm.getDomainId());
if (domain == null)
if (domain == null || !domain.getContainer().equals(getContainer()))
{
throw new NotFoundException();
}
Expand Down
84 changes: 38 additions & 46 deletions core/src/org/labkey/core/CoreController.java
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,6 @@

import static org.labkey.api.view.template.WarningService.SESSION_WARNINGS_BANNER_KEY;

/**
* User: jeckels
* Date: Jan 4, 2007
*/
public class CoreController extends SpringActionController
{
private static final Map<Container, Content> _customStylesheetCache = new ConcurrentHashMap<>();
Expand Down Expand Up @@ -863,36 +859,11 @@ public static class MoveContainerAction extends MutatingApiAction<SimpleApiJsonF
@Override
public void validateForm(SimpleApiJsonForm form, Errors errors)
{
JSONObject object = form.getJsonObject();
String targetIdentifier = object.optString("container", null);

if (null == targetIdentifier)
{
errors.reject(ERROR_MSG, "A target container must be specified for move operation.");
return;
}

String parentIdentifier = object.optString("parent", null);
JSONObject json = form.getJsonObject();
target = validateContainer(json, "container", "Target", errors);

if (null == parentIdentifier)
{
errors.reject(ERROR_MSG, "A parent container must be specified for move operation.");
if (target == null)
return;
}

// Worry about escaping
Path path = Path.parse(targetIdentifier);
target = ContainerManager.getForPath(path);

if (null == target)
{
target = ContainerManager.getForId(targetIdentifier);
if (null == target)
{
errors.reject(ERROR_MSG, "Container '" + targetIdentifier + "' does not exist.");
return;
}
}

// This covers /home and /shared
if (target.isProject() || target.isRoot())
Expand All @@ -901,18 +872,14 @@ public void validateForm(SimpleApiJsonForm form, Errors errors)
return;
}

Path parentPath = Path.parse(parentIdentifier);
parent = ContainerManager.getForPath(parentPath);
// User has admin in target, but not in target's parent. It's okay to provide details here.
if (!target.getParent().hasPermission(getUser(), AdminPermission.class))
throw new UnauthorizedException("Insufficient permissions in target's current parent.");

if (null == parent)
{
parent = ContainerManager.getForId(parentIdentifier);
if (null == parent)
{
errors.reject(ERROR_MSG, "Parent container '" + parentIdentifier + "' does not exist.");
return;
}
}
parent = validateContainer(json, "parent", "Parent", errors);

if (parent == null)
return;

// Check children
if (parent.hasChildren())
Expand All @@ -933,9 +900,34 @@ public void validateForm(SimpleApiJsonForm form, Errors errors)
List<Container> children = ContainerManager.getAllChildren(target, getUser()); // assumes read permission
if (children.contains(parent))
{
errors.reject(ERROR_MSG, "The container '" + parentIdentifier + "' is not a valid parent folder.");
return;
errors.reject(ERROR_MSG, "The container '" + json.get("parent") + "' is not a valid parent folder.");
}
}

private @Nullable Container validateContainer(JSONObject json, String key, String description, Errors errors)
{
String identifier = json.optString(key, null);

if (null == identifier)
{
errors.reject(ERROR_MSG, description + " container must be specified for move operation.");
return null;
}

Path path = Path.parse(identifier);
Container c = ContainerManager.getForPath(path);

if (null == c)
{
c = ContainerManager.getForId(identifier);
// Treat non-existent and bad permissions equivalently to not leak any info
if (null == c || !c.hasPermission(getUser(), AdminPermission.class))
{
throw new NotFoundException(description + " not found");
}
}

return c;
}

@Override
Expand All @@ -949,7 +941,7 @@ public ApiResponse execute(SimpleApiJsonForm form, BindException errors) throws

// Prepare aliases
JSONObject object = form.getJsonObject();
Boolean addAlias = (Boolean) object.get("addAlias");
boolean addAlias = object.optBoolean("addAlias"); // optional, false by default

List<String> aliasList = new ArrayList<>(ContainerManager.getAliasesForContainer(target));
aliasList.add(target.getPath());
Expand Down
Loading