/* * Copyright (C) 2015 Stichting Akvo (Akvo Foundation) * * This file is part of Akvo FLOW. * * Akvo FLOW is free software: you can redistribute it and modify it under the terms of * the GNU Affero General Public License (AGPL) as published by the Free Software Foundation, * either version 3 of the License or any later version. * * Akvo FLOW is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License included below for more details. * * The full license text can also be seen at <http://www.gnu.org/licenses/agpl.html>. */ package org.akvo.gae.remoteapi; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import com.google.appengine.api.datastore.DatastoreService; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.FetchOptions; import com.google.appengine.api.datastore.Query; import com.google.appengine.api.datastore.Query.Filter; import com.google.appengine.api.datastore.Query.FilterOperator; import com.google.appengine.repackaged.org.apache.commons.io.FileUtils; import static org.akvo.gae.remoteapi.DataUtils.*; /** * Add new users to the datastore configuration. Takes in the path of a CSV file containing a list * of users to be added to the relevant instance. The CSV file format is * emailAddress,permissionList,superAdmin e.g. test@example.com,10,False */ public class AddUsers implements Process { @Override public void execute(DatastoreService ds, String[] args) throws Exception { if (args.length == 0 || args[0].length() == 0) { System.err.println("Usage: " + RemoteAPI.class.getName() + "AddUsers <appid> <username> <password> <users file path>"); System.exit(1); } final File f = new File(args[0]); List<String> userLines = FileUtils.readLines(f); if (userLines.isEmpty()) { System.err.println("Empty file"); return; } Map<String, Entity> users = createUserEntites(userLines); Map<String, Entity> existingUsers = retrieveExistingUsers(ds, users.keySet()); mergeUserProperties(users, existingUsers); System.out.println("Upserting " + users.size() + " users"); ds.put(users.values()); } private Map<String, Entity> createUserEntites(List<String> userLines) { Map<String, Entity> users = new HashMap<String, Entity>(); for (String line : userLines) { String[] userParts = line.split(",", 3); if (userParts.length < 3 || userParts[0].trim().length() == 0) { System.out.println("Skipping user: " + line); continue; } Entity user = new Entity(USER_KIND); user.setProperty(USER_EMAIL_FIELD, userParts[0].trim()); user.setProperty(USER_PERMISSION_FIELD, userParts[1].trim()); user.setProperty(USER_ROLE_FIELD, Boolean.valueOf(userParts[2].trim())); users.put(userParts[0].trim(), user); } return users; } private Map<String, Entity> retrieveExistingUsers(DatastoreService ds, Set<String> emailAddresses) { Map<String, Entity> existingUsers = new HashMap<String, Entity>(); Filter emailAddressFilter = new Query.FilterPredicate(USER_EMAIL_FIELD, FilterOperator.IN, new ArrayList<String>(emailAddresses)); Query userQuery = new Query(USER_KIND).setFilter(emailAddressFilter); for (Entity user : ds.prepare(userQuery).asList(FetchOptions.Builder.withDefaults())) { String email = (String) user.getProperty(USER_EMAIL_FIELD); existingUsers.put(email, user); } return existingUsers; } private void mergeUserProperties(Map<String, Entity> users, Map<String, Entity> existingUsers) { for (String email : users.keySet()) { if (existingUsers.containsKey(email)) { Entity existingUser = existingUsers.get(email); Entity newUser = users.get(email); existingUser.setProperty(USER_PERMISSION_FIELD, newUser.getProperty(USER_PERMISSION_FIELD)); existingUser.setProperty(USER_ROLE_FIELD, newUser.getProperty(USER_ROLE_FIELD)); users.put(email, existingUser); } } } }