From a3b52a20e13996d08f6f10a398c6b2a6824b2dca Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Tue, 2 Jul 2024 12:57:16 -0500 Subject: [PATCH 1/3] CLDR-17776 disallow reports if vetting closed Back end side: - Change CheckCLDR.Phase.getShowRowAction() to allow pathValueInfo and pathHeader to be optional (null) - add convenience functions on StatusAction - Report API returns 403 forbidden if NOT in phase where voting is allowed. --- .../org/unicode/cldr/web/api/ReportAPI.java | 31 +++++++++--- .../java/org/unicode/cldr/test/CheckCLDR.java | 50 +++++++++++++------ 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/ReportAPI.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/ReportAPI.java index 7973d09ecc0..d91c5d91d07 100644 --- a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/ReportAPI.java +++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/ReportAPI.java @@ -7,6 +7,7 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.logging.Logger; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; @@ -25,6 +26,7 @@ import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; import org.eclipse.microprofile.openapi.annotations.tags.Tag; +import org.unicode.cldr.test.CheckCLDR; import org.unicode.cldr.tool.Chart; import org.unicode.cldr.util.CLDRLocale; import org.unicode.cldr.util.VoteResolver; @@ -38,12 +40,15 @@ import org.unicode.cldr.web.STFactory; import org.unicode.cldr.web.SubtypeToURLMap; import org.unicode.cldr.web.SurveyAjax; +import org.unicode.cldr.web.SurveyLog; import org.unicode.cldr.web.SurveyMain; import org.unicode.cldr.web.UserRegistry; @Path("/voting/reports") @Tag(name = "voting", description = "APIs for voting and retrieving vote and row data") public class ReportAPI { + static final Logger logger = SurveyLog.forClass(ReportAPI.class); + @GET @Path("/users/{user}") @Produces(MediaType.APPLICATION_JSON) @@ -327,13 +332,27 @@ public Response updateReport( if (!report.isAvailable()) { return Response.status(Status.FORBIDDEN).build(); } + final CLDRLocale loc = CLDRLocale.getInstance(locale); + // apply the same standard as for vetting. + // First check whether they even have permission. + if (!UserRegistry.userCanModifyLocale(mySession.user, loc)) { + return Response.status(Status.FORBIDDEN).build(); + } + CheckCLDR.StatusAction showRowAction = + SurveyMain.checkCLDRPhase(loc) + .getShowRowAction( + null /* not path based */, + CheckCLDR.InputMethod.DIRECT, + null /* Not path based */, + mySession.user); + + logger.info(() -> "ShowRowAction = " + showRowAction); + if (!showRowAction.canVote()) { + return Response.status(Status.FORBIDDEN).build(); + } + ReportsDB.getInstance() - .markReportComplete( - user, - CLDRLocale.getInstance(locale), - report, - update.completed, - update.acceptable); + .markReportComplete(user, loc, report, update.completed, update.acceptable); return Response.status(Status.NO_CONTENT).build(); } diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/test/CheckCLDR.java b/tools/cldr-code/src/main/java/org/unicode/cldr/test/CheckCLDR.java index b5591694798..2c8fd1540ad 100644 --- a/tools/cldr-code/src/main/java/org/unicode/cldr/test/CheckCLDR.java +++ b/tools/cldr-code/src/main/java/org/unicode/cldr/test/CheckCLDR.java @@ -162,6 +162,16 @@ public boolean isForbidden() { public boolean canShow() { return !isForbidden; } + + public boolean canVote() { + // the one non-voting case + if (this == ALLOW_TICKET_ONLY) return false; + return !isForbidden(); + } + + public boolean canSubmit() { + return (this == ALLOW); + } } private static final HashMap PHASE_NAMES = new HashMap<>(); @@ -195,9 +205,9 @@ public boolean isUnitTest() { /** * Return whether or not to show a row, and if so, how. * - * @param pathValueInfo + * @param pathValueInfo - may be null for a non-path entry. * @param inputMethod - * @param ph the path header + * @param ph the path header - may be null if it is a non-path entry * @param userInfo null if there is no userInfo (nobody logged in). * @return */ @@ -208,7 +218,14 @@ public StatusAction getShowRowAction( UserInfo userInfo // can get voterInfo from this. ) { - PathHeader.SurveyToolStatus status = ph.getSurveyToolStatus(); + // default to read/write + PathHeader.SurveyToolStatus status = PathHeader.SurveyToolStatus.READ_WRITE; + boolean canReadAndWrite = true; + + if (ph != null) { + status = ph.getSurveyToolStatus(); + canReadAndWrite = ph.canReadAndWrite(); + } /* * Always forbid DEPRECATED items - don't show. * @@ -239,23 +256,26 @@ public StatusAction getShowRowAction( return StatusAction.FORBID_READONLY; } - CandidateInfo winner = pathValueInfo.getCurrentItem(); - ValueStatus valueStatus = getValueStatus(winner, ValueStatus.NONE, null); + ValueStatus valueStatus = ValueStatus.NONE; + if (pathValueInfo != null) { + CandidateInfo winner = pathValueInfo.getCurrentItem(); + valueStatus = getValueStatus(winner, ValueStatus.NONE, null); - // if limited submission, and winner doesn't have an error, limit the values + // if limited submission, and winner doesn't have an error, limit the values - if (LIMITED_SUBMISSION) { - if (!SubmissionLocales.allowEvenIfLimited( - pathValueInfo.getLocale().toString(), - pathValueInfo.getXpath(), - valueStatus == ValueStatus.ERROR, - pathValueInfo.getBaselineStatus() == Status.missing)) { - return StatusAction.FORBID_READONLY; + if (LIMITED_SUBMISSION) { + if (!SubmissionLocales.allowEvenIfLimited( + pathValueInfo.getLocale().toString(), + pathValueInfo.getXpath(), + valueStatus == ValueStatus.ERROR, + pathValueInfo.getBaselineStatus() == Status.missing)) { + return StatusAction.FORBID_READONLY; + } } } if (this == Phase.SUBMISSION || isUnitTest()) { - return (ph.canReadAndWrite()) + return (canReadAndWrite) ? StatusAction.ALLOW : StatusAction.ALLOW_VOTING_AND_TICKET; } @@ -265,7 +285,7 @@ public StatusAction getShowRowAction( // Only allow ADD if we have an error or warning // Only check winning value for errors/warnings per ticket #8677 if (valueStatus != ValueStatus.NONE) { - return (ph.canReadAndWrite()) + return (canReadAndWrite) ? StatusAction.ALLOW : StatusAction.ALLOW_VOTING_AND_TICKET; } From c62a1d0c359d3d61b7a1aede9c1e19ece38de9a4 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Tue, 2 Jul 2024 14:32:08 -0500 Subject: [PATCH 2/3] CLDR-17776 st: report page should pop up error - pop up error on voting or read error --- tools/cldr-apps/js/src/views/ReportResponse.vue | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tools/cldr-apps/js/src/views/ReportResponse.vue b/tools/cldr-apps/js/src/views/ReportResponse.vue index ebde8d50fa7..2ca780ed086 100644 --- a/tools/cldr-apps/js/src/views/ReportResponse.vue +++ b/tools/cldr-apps/js/src/views/ReportResponse.vue @@ -44,6 +44,7 @@