Skip to content

Commit 273381a

Browse files
Merge 25.11 to 25.12
2 parents 19ff50c + e1da7bd commit 273381a

23 files changed

Lines changed: 195 additions & 72 deletions

File tree

api/src/org/labkey/api/action/PermissionCheckableAction.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.labkey.api.action;
1717

1818
import jakarta.servlet.http.HttpServletResponse;
19+
import org.apache.logging.log4j.Logger;
1920
import org.jetbrains.annotations.Nullable;
2021
import org.labkey.api.data.Container;
2122
import org.labkey.api.module.IgnoresForbiddenProjectCheck;
@@ -39,6 +40,7 @@
3940
import org.labkey.api.security.roles.RoleManager;
4041
import org.labkey.api.util.ConfigurationException;
4142
import org.labkey.api.util.HttpUtil;
43+
import org.labkey.api.util.logging.LogHelper;
4244
import org.labkey.api.view.BadRequestException;
4345
import org.labkey.api.view.NotFoundException;
4446
import org.labkey.api.view.RedirectException;
@@ -55,6 +57,7 @@
5557

5658
public abstract class PermissionCheckableAction implements Controller, PermissionCheckable, HasViewContext
5759
{
60+
private static final Logger LOG = LogHelper.getLogger(PermissionCheckableAction.class, "Permission checks for actions");
5861
private static final HttpUtil.Method[] arrayGetPost = new HttpUtil.Method[] {Method.GET, Method.POST};
5962
private ViewContext _context = null;
6063
UnauthorizedException.Type _unauthorizedType = UnauthorizedException.Type.redirectToLogin;
@@ -148,6 +151,8 @@ private void _checkActionPermissions(Set<Role> contextualRoles) throws Unauthori
148151
Container c = context.getContainer();
149152
User user = context.getUser();
150153
Class<? extends Controller> actionClass = getClass();
154+
if (LOG.isDebugEnabled())
155+
LOG.debug(actionClass.getName() + ": checking permissions for user " + (user == null ? "<null>" : user.getName() + " (impersonated=" + user.isImpersonated() + ")"));
151156

152157
if (!actionClass.isAnnotationPresent(IgnoresForbiddenProjectCheck.class))
153158
c.throwIfForbiddenProject(user);
@@ -159,18 +164,22 @@ private void _checkActionPermissions(Set<Role> contextualRoles) throws Unauthori
159164
methodsAllowed = methodsAllowedAnnotation.value();
160165
if (Arrays.stream(methodsAllowed).noneMatch(s -> s.equals(method)))
161166
{
162-
throw new BadRequestException("Method Not Allowed: " + method, null, HttpServletResponse.SC_METHOD_NOT_ALLOWED);
167+
String msg = "Method Not Allowed: " + method;
168+
LOG.debug(msg);
169+
throw new BadRequestException(msg, null, HttpServletResponse.SC_METHOD_NOT_ALLOWED);
163170
}
164171

165172
boolean requiresSiteAdmin = actionClass.isAnnotationPresent(RequiresSiteAdmin.class);
166173
if (requiresSiteAdmin && !user.hasSiteAdminPermission())
167174
{
175+
LOG.debug(actionClass.getName() + ": action requires site admin permissions");
168176
throw new UnauthorizedException();
169177
}
170178

171179
boolean requiresLogin = actionClass.isAnnotationPresent(RequiresLogin.class);
172180
if (requiresLogin && user.isGuest())
173181
{
182+
LOG.debug(actionClass.getName() + ": action requires login (non-guest)");
174183
throw new UnauthorizedException();
175184
}
176185

@@ -214,7 +223,10 @@ private void _checkActionPermissions(Set<Role> contextualRoles) throws Unauthori
214223
// Must have all permissions in permissionsRequired
215224
if (!SecurityManager.hasAllPermissions(this.getClass().getName()+"_checkActionPermissions",
216225
c, user, permissionsRequired, contextualRoles))
226+
{
227+
LOG.debug(actionClass.getName() + ": action requires all permissions: " + permissionsRequired);
217228
throw new UnauthorizedException();
229+
}
218230

219231
CSRF.Method csrfCheck = actionClass.isAnnotationPresent(CSRF.class) ? actionClass.getAnnotation(CSRF.class).value() : CSRF.Method.POST;
220232
csrfCheck.validate(context);
@@ -228,7 +240,10 @@ private void _checkActionPermissions(Set<Role> contextualRoles) throws Unauthori
228240
Collections.addAll(permissionsAnyOf, requiresAnyOf.value());
229241
if (!SecurityManager.hasAnyPermissions(this.getClass().getName() + "_checkActionPermissions",
230242
c, user, permissionsAnyOf, contextualRoles))
243+
{
244+
LOG.debug(actionClass.getName() + ": action requires any permissions: " + permissionsAnyOf);
231245
throw new UnauthorizedException();
246+
}
232247
}
233248

234249
boolean requiresNoPermission = actionClass.isAnnotationPresent(RequiresNoPermission.class);

api/src/org/labkey/api/data/Container.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.labkey.api.query.QueryService;
4242
import org.labkey.api.security.HasPermission;
4343
import org.labkey.api.security.SecurableResource;
44+
import org.labkey.api.security.SecurityLogger;
4445
import org.labkey.api.security.SecurityManager;
4546
import org.labkey.api.security.SecurityPolicy;
4647
import org.labkey.api.security.SecurityPolicyManager;
@@ -550,7 +551,11 @@ private boolean handleForbiddenProject(User user, Set<Role> contextualRoles, boo
550551
if (null != impersonationProject && !impersonationProject.equals(currentProject))
551552
{
552553
if (shouldThrow)
553-
throw new ForbiddenProjectException("You are not allowed to access this folder while impersonating within a different project.");
554+
{
555+
String msg = "You are not allowed to access this folder while impersonating within a different project.";
556+
SecurityLogger.log(msg, user, null, null);
557+
throw new ForbiddenProjectException(msg);
558+
}
554559

555560
return true;
556561
}
@@ -563,7 +568,11 @@ private boolean handleForbiddenProject(User user, Set<Role> contextualRoles, boo
563568
if (lockState.isLocked() && ContainerManager.LOCKED_PROJECT_HANDLER.isForbidden(currentProject, user, contextualRoles, lockState))
564569
{
565570
if (shouldThrow)
566-
throw new ForbiddenProjectException("You are not allowed to access this folder; it is " + lockState.getDescription() + ".");
571+
{
572+
String msg = "You are not allowed to access this folder; it is " + lockState.getDescription() + ".";
573+
SecurityLogger.log(msg, user, null, null);
574+
throw new ForbiddenProjectException(msg);
575+
}
567576

568577
return true;
569578
}

api/src/org/labkey/api/data/URLDisplayColumn.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public Renderable createThumbnailImage()
182182
String thumbnailUrl = _fileIconUrl != null ? ensureAbsoluteUrl(_ctx, _fileIconUrl) : ensureAbsoluteUrl(_ctx, _url);
183183

184184
return IMG(at(
185-
style, "display:block; vertical-align:middle;" + (renderSize ? (_thumbnailWidth != null ? " width:" + _thumbnailWidth : " max-width:32px" + "; ") + (_thumbnailHeight != null ? " height:" + _thumbnailHeight : " height:auto" + ";") : ""),
185+
style, "display:block; vertical-align:middle;" + (renderSize ? (_thumbnailWidth != null ? " width:" + _thumbnailWidth : " max-width:32px") + "; " + (_thumbnailHeight != null ? " height:" + _thumbnailHeight : " height:auto") + ";" : ""),
186186
src, thumbnailUrl, title, _displayName
187187
));
188188
}

api/src/org/labkey/api/exp/list/ListImportProgress.java renamed to api/src/org/labkey/api/dataiterator/ImportProgress.java

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
1-
/*
2-
* Copyright (c) 2009-2014 LabKey Corporation
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*/
16-
package org.labkey.api.exp.list;
17-
18-
/*
19-
* User: adam
20-
* Date: Dec 23, 2009
21-
* Time: 3:05:51 PM
22-
*/
23-
public interface ListImportProgress
24-
{
25-
void setTotalRows(int rows);
26-
void setCurrentRow(int currentRow);
27-
}
1+
/*
2+
* Copyright (c) 2009-2014 LabKey Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.labkey.api.dataiterator;
17+
18+
public interface ImportProgress
19+
{
20+
void setTotalRows(int rows);
21+
void setCurrentRow(int currentRow);
22+
}

api/src/org/labkey/api/dataiterator/Pump.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import org.apache.logging.log4j.LogManager;
1919
import org.apache.logging.log4j.Logger;
20-
import org.labkey.api.exp.list.ListImportProgress;
2120
import org.labkey.api.query.BatchValidationException;
2221

2322
import java.io.IOException;
@@ -34,7 +33,7 @@ public class Pump implements Runnable
3433
final BatchValidationException _errors;
3534
int _errorLimit = Integer.MAX_VALUE;
3635
long _rowCount = 0;
37-
ListImportProgress _progress = null;
36+
ImportProgress _progress = null;
3837

3938
public Pump(DataIterator it, DataIteratorContext context)
4039
{
@@ -50,7 +49,7 @@ public Pump(DataIteratorBuilder builder, DataIteratorContext context)
5049
_errors = context.getErrors();
5150
}
5251

53-
public void setProgress(ListImportProgress progress)
52+
public void setProgress(ImportProgress progress)
5453
{
5554
_progress = progress;
5655
}

api/src/org/labkey/api/exp/list/ListDefinition.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.labkey.api.data.ContainerFilter;
2424
import org.labkey.api.data.LookupResolutionType;
2525
import org.labkey.api.data.TableInfo;
26+
import org.labkey.api.dataiterator.ImportProgress;
2627
import org.labkey.api.exp.DomainNotFoundException;
2728
import org.labkey.api.exp.PropertyType;
2829
import org.labkey.api.exp.property.Domain;
@@ -269,8 +270,8 @@ public static BodySetting getForValue(int value)
269270
ListItem getListItemForEntityId(String entityId, User user);
270271

271272
int insertListItems(User user, Container container, List<ListItem> listItems) throws IOException;
272-
int insertListItems(User user, Container container, DataLoader loader, @NotNull BatchValidationException errors, @Nullable VirtualFile attachmentDir, @Nullable ListImportProgress progress, boolean supportAutoIncrementKey, LookupResolutionType lookupResolutionType) throws IOException;
273-
int importListItems(User user, Container container, DataLoader loader, @NotNull BatchValidationException errors, @Nullable VirtualFile attachmentDir, @Nullable ListImportProgress progress, boolean supportAutoIncrementKey, LookupResolutionType lookupResolutionType, QueryUpdateService.InsertOption insertOption) throws IOException;
273+
int insertListItems(User user, Container container, DataLoader loader, @NotNull BatchValidationException errors, @Nullable VirtualFile attachmentDir, @Nullable ImportProgress progress, boolean supportAutoIncrementKey, LookupResolutionType lookupResolutionType) throws IOException;
274+
int importListItems(User user, Container container, DataLoader loader, @NotNull BatchValidationException errors, @Nullable VirtualFile attachmentDir, @Nullable ImportProgress progress, boolean supportAutoIncrementKey, LookupResolutionType lookupResolutionType, QueryUpdateService.InsertOption insertOption) throws IOException;
274275

275276
@Nullable TableInfo getTable(User user);
276277
@Nullable TableInfo getTable(User user, Container c);

api/src/org/labkey/api/migration/DatabaseMigrationConfiguration.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
import org.labkey.api.data.DbScope;
88
import org.labkey.api.data.TableInfo;
99
import org.labkey.api.data.TableSelector;
10+
import org.labkey.api.util.GUID;
11+
import org.labkey.api.util.Pair;
1012

13+
import java.io.PrintWriter;
1114
import java.util.Set;
1215
import java.util.function.Predicate;
1316

@@ -21,5 +24,8 @@ default void beforeMigration(){}
2124
Predicate<String> getColumnNameFilter();
2225
@Nullable TableSelector getTableSelector(DbSchemaType schemaType, TableInfo sourceTable, TableInfo targetTable, Set<String> selectColumnNames, MigrationSchemaHandler schemaHandler, @Nullable MigrationTableHandler tableHandler);
2326
default void copyAttachments(DbSchema sourceSchema, DbSchema targetSchema, MigrationSchemaHandler schemaHandler){}
24-
default void afterMigration(){}
27+
default @Nullable Pair<FilePathWriter, Set<GUID>> initializeFilePathWriter()
28+
{
29+
return null;
30+
}
2531
}

api/src/org/labkey/api/migration/DefaultMigrationSchemaHandler.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,15 +306,15 @@ public static void afterMigration() throws InterruptedException
306306
if (unseen.isEmpty())
307307
LOG.info("All AttachmentTypes have been seen");
308308
else
309-
throw new ConfigurationException("These AttachmentTypes have not been seen: " + unseen.stream().map(type -> type.getClass().getSimpleName()).collect(Collectors.joining(", ")));
309+
LOG.error("These AttachmentTypes have not been seen: {}", unseen.stream().map(type -> type.getClass().getSimpleName()).collect(Collectors.joining(", ")));
310310

311311
// Shut down the attachment JobRunner
312312
LOG.info("Waiting for attachments background transfer to complete");
313313
ATTACHMENT_JOB_RUNNER.shutdown();
314-
if (ATTACHMENT_JOB_RUNNER.awaitTermination(1, TimeUnit.HOURS))
314+
if (ATTACHMENT_JOB_RUNNER.awaitTermination(2, TimeUnit.HOURS))
315315
LOG.info("Attachments background transfer is complete");
316316
else
317-
LOG.error("Attachments background transfer did not complete after one hour! Giving up.");
317+
LOG.error("Attachments background transfer did not complete after two hours! Giving up.");
318318
}
319319

320320
@Override
@@ -332,4 +332,9 @@ public void afterSchema(DatabaseMigrationConfiguration configuration, DbSchema s
332332
public void afterMigration(DatabaseMigrationConfiguration configuration)
333333
{
334334
}
335+
336+
@Override
337+
public void writeFilePaths(FilePathWriter writer, Set<GUID> guids)
338+
{
339+
}
335340
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package org.labkey.api.migration;
2+
3+
import org.labkey.api.data.ContainerManager;
4+
import org.labkey.api.files.FileContentService;
5+
6+
import java.io.Closeable;
7+
import java.io.File;
8+
import java.io.PrintWriter;
9+
import java.nio.file.Path;
10+
11+
public class FilePathWriter implements Closeable
12+
{
13+
private final PrintWriter _out;
14+
private final Path _rootPath;
15+
16+
public FilePathWriter(PrintWriter out)
17+
{
18+
_out = out;
19+
_rootPath = FileContentService.get().getFileRoot(ContainerManager.getRoot()).toPath();
20+
}
21+
22+
public void write(File file)
23+
{
24+
_out.println(_rootPath.relativize(file.toPath()).normalize());
25+
}
26+
27+
public void println(String s)
28+
{
29+
_out.println(s);
30+
}
31+
32+
public void println()
33+
{
34+
_out.println();
35+
}
36+
37+
@Override
38+
public void close()
39+
{
40+
_out.close();
41+
}
42+
}

api/src/org/labkey/api/migration/MigrationSchemaHandler.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.labkey.api.query.FieldKey;
1313
import org.labkey.api.util.GUID;
1414

15+
import java.io.PrintWriter;
1516
import java.util.Collection;
1617
import java.util.List;
1718
import java.util.Set;
@@ -57,4 +58,6 @@ public interface MigrationSchemaHandler
5758
@NotNull Collection<AttachmentType> getAttachmentTypes();
5859

5960
void afterMigration(DatabaseMigrationConfiguration configuration);
61+
62+
void writeFilePaths(FilePathWriter writer, Set<GUID> guids);
6063
}

0 commit comments

Comments
 (0)