// -*- mode: java; c-basic-offset: 2; -*- // Copyright 2009-2011 Google, All Rights reserved // Copyright 2011-2012 MIT, All rights reserved // Released under the Apache License, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0 // Note: This code is no longer used but is kept here as an example and in case we // wish to switch back to a internal file based version of a whitelist package com.google.appinventor.server; import com.google.appinventor.server.flags.Flag; import com.google.appinventor.server.util.CsvParser; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Implementation of a whitelist. Note that it uses email addresses * (which can change), and not user ids (which are unique), because we * do not expect that the people creating the whitelist have access to * the user ids of users. * * @author kerr@google.com (Debby Wallach) */ public class Whitelist { /** * Class representing a case-insensitive email address. */ private static class EmailAddress { private final String email; EmailAddress(String email) { Preconditions.checkNotNull(email); this.email = email; } @Override public String toString() { return email; } @Override public boolean equals(Object other) { boolean result = (other instanceof EmailAddress) && ((EmailAddress) other).email.equalsIgnoreCase(email); return result; } @Override public int hashCode() { return email.toLowerCase().hashCode(); } } private static final Logger LOG = Logger.getLogger(Whitelist.class.getName()); private static final boolean DEBUG = false; // When running on appengine, the application is running in a way that // the rootPath should not be set to anything. This flag needs to be // set for testing. @VisibleForTesting public static final Flag<String> rootPath = Flag.createFlag("root.path", ""); private String pathToWhitelist = rootPath.get() + "WEB-INF/whitelist"; private boolean validWhitelist; private final Set<EmailAddress> addresses = new HashSet<EmailAddress>(); Whitelist() { validWhitelist = false; try { parseToAddresses(new CsvParser(new FileInputStream(pathToWhitelist))); if (addresses.size() == 0) { LOG.severe("Whitelist file contained no entries."); } else { if (DEBUG) { logWhitelistContents(); } validWhitelist = true; } } catch (FileNotFoundException e) { LOG.severe("No whitelist found."); } catch (SecurityException e) { LOG.severe("Whitelist found, but wrong permission."); } catch (IOException e) { LOG.log(Level.SEVERE, "Unexpected whitelist error", e); } } // should throw something if not valid whitelist? public boolean isInWhitelist(LocalUser user) { if (! validWhitelist) { // If we have not loaded a valid whitelist, reject everyone. return false; } boolean found = addresses.contains(new EmailAddress(user.getUserEmail())); if (!found) { LOG.info("User with email address " + user.getUserEmail() + " was not found in the whitelist"); } return found; } private void logWhitelistContents() { LOG.info("Whitelist contains " + addresses.size() + " addresses."); StringBuilder sb = new StringBuilder(); String delimiter = ""; for (EmailAddress address : addresses) { sb.append(delimiter).append(address); if (sb.length() > 70) { LOG.info("On whitelist: " + sb); sb = new StringBuilder(); delimiter = ""; } else { delimiter = ","; } } if (sb.length() > 0) { LOG.info("On whitelist: " + sb); } } private void parseToAddresses(CsvParser parser) { /* * expected file format: * "emailaddress1" * "emailaddress2" * */ Pattern patternPlus = Pattern.compile("([^+]*)(\\+[^@]*)(@.*)"); while (parser.hasNext()) { List<String> line = parser.next(); String address = line.get(0).trim(); // Change foo+bar@gmail.com to foo@gmail.com Matcher matcher = patternPlus.matcher(address); if (matcher.matches()) { address = matcher.group(1) + matcher.group(3); } addresses.add(new EmailAddress(address)); } } }