diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/AuthSurveyDriver.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/AuthSurveyDriver.java new file mode 100644 index 00000000000..8481be9f766 --- /dev/null +++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/AuthSurveyDriver.java @@ -0,0 +1,94 @@ +package org.unicode.cldr.web; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.unicode.cldr.util.CLDRConfig; +import org.unicode.cldr.util.Organization; +import org.unicode.cldr.util.StandardCodes; +import org.unicode.cldr.web.UserRegistry.User; + +public class AuthSurveyDriver { + + /** + * Fictitious domain identifying fictitious email addresses for simulated users like + * "driver-123@cldr-apps-webdriver.org" + */ + public static final String EMAIL_AT_DOMAIN = "@cldr-apps-webdriver.org"; + + private static final String EMAIL_PREFIX = "driver-"; + + private static final int INVALID_USER_INDEX = -1; + private static final int FIRST_VALID_USER_INDEX = 0; + + private static boolean isInitialized = false; + private static boolean isEnabled = false; + private static String realPassword = null; + + /** + * If webdriver users are enabled, and the given password and email are correct for such users, + * create a new user. + * + * @param password the password + * @param email the (pseudo) email address + * @return the new user, or null + */ + public static User createTestUser(String password, String email) { + if (!isInitialized) { + initialize(); + } + if (isEnabled && realPassword.equals(password) && email.contains(EMAIL_AT_DOMAIN)) { + int userIndex = getUserIndexFromEmail(email); + if (userIndex >= FIRST_VALID_USER_INDEX) { + return addTestUser(password, email, userIndex); + } + } + return null; + } + + private static void initialize() { + if (SurveyMain.isUnofficial()) { + realPassword = CLDRConfig.getInstance().getProperty("CLDR_WEBDRIVER_PASSWORD", ""); + if (realPassword != null && !realPassword.isBlank()) { + isEnabled = true; + } + } + isInitialized = true; + } + + /** + * Get a number like 123 given an email address like "driver-123@cldr-apps-webdriver.org" + * + * @param email the address + * @return the nonnegative number if the address matches the pattern, else INVALID_USER_INDEX + */ + private static int getUserIndexFromEmail(String email) { + Matcher m = Pattern.compile("\\d+").matcher(email); + if (m.find()) { + int userIndex = Integer.parseInt(m.group()); + String properEmail = EMAIL_PREFIX + userIndex + EMAIL_AT_DOMAIN; + if (properEmail.equals(email)) { + return userIndex; + } + } + return INVALID_USER_INDEX; + } + + private static User addTestUser(String password, String email, int userIndex) { + UserRegistry reg = CookieSession.sm.reg; + User u = reg.new User(UserRegistry.NO_USER); + u.email = email; + // Make user level TC, since even with ALL_LOCALES (*), a VETTER might + // not have permission to vote in all locales, depending on the organization. + u.userlevel = UserRegistry.TC; + u.locales = StandardCodes.ALL_LOCALES; + u.name = EMAIL_PREFIX + userIndex; + Organization[] orgArray = Organization.values(); + u.org = orgArray[userIndex % orgArray.length].name(); + u.setPassword(password); + User registeredUser = reg.newUser(null, u); + if (registeredUser == null || registeredUser.id <= 0) { + return null; + } + return registeredUser; + } +} diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/Auth.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/Auth.java index b6ba90fadd7..a7480c98dfa 100644 --- a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/Auth.java +++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/Auth.java @@ -18,6 +18,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.web.AuthSurveyDriver; import org.unicode.cldr.web.CookieSession; import org.unicode.cldr.web.SurveyLog; import org.unicode.cldr.web.SurveyMain; @@ -82,10 +83,17 @@ public Response login( String userIP = WebContext.userIP(hreq); CookieSession session = null; if (!request.isEmpty()) { - UserRegistry.User user = - CookieSession.sm.reg.get(request.password, request.email, userIP); + UserRegistry.User user; + try { + user = CookieSession.sm.reg.get(request.password, request.email, userIP); + } catch (LogoutException e) { + user = null; + } + if (user == null) { + user = AuthSurveyDriver.createTestUser(request.password, request.email); + } if (user == null) { - return Response.status(403, "Login failed").build(); + throw new LogoutException(); } session = CookieSession.retrieveUser(user); if (session == null) {