/** * Copyright (C) 2010-2017 Structr GmbH * * This file is part of Structr <http://structr.org>. * * Structr is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * Structr 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 for more details. * * You should have received a copy of the GNU Affero General Public License * along with Structr. If not, see <http://www.gnu.org/licenses/>. */ package org.structr.console.shell; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.commons.lang.StringUtils; import org.structr.common.SecurityContext; import org.structr.common.error.FrameworkException; import org.structr.core.app.App; import org.structr.core.app.StructrApp; import org.structr.core.entity.AbstractNode; import org.structr.core.entity.Principal; import org.structr.core.graph.NodeAttribute; import org.structr.core.graph.NodeInterface; import org.structr.core.graph.Tx; import org.structr.core.property.PropertyMap; import org.structr.util.Writable; /** * A console command for user management. */ public class UserConsoleCommand extends AdminConsoleCommand { static { AdminConsoleCommand.registerCommand("user", UserConsoleCommand.class); } @Override public void run(final SecurityContext securityContext, final List<String> parameters, final Writable writable) throws FrameworkException, IOException { final String command = getParameter(parameters, 1); if (command != null) { final Principal user = securityContext.getUser(false); if (user != null && user.isAdmin()) { switch (command) { case "list": handleList(securityContext, writable); break; case "add": handleAdd(securityContext, writable, getParameter(parameters, 2), getParameter(parameters, 3), getParameter(parameters, 4)); break; case "delete": handleDelete(securityContext, writable, getParameter(parameters, 2), getParameter(parameters, 3)); break; case "password": handlePwd(securityContext, writable, getParameter(parameters, 2), getParameter(parameters, 3)); break; } } else { writable.println("You must be admin user to use this command."); } } else { writable.println("Missing command, must be one of 'list', 'add', 'delete' or 'password'."); } } @Override public void commandHelp(final Writable writable) throws IOException { writable.println("Creates and deletes users, sets passwords."); } @Override public void detailHelp(final Writable writable) throws IOException { writable.println("user list - lists all user in the database"); writable.println("user add <name> [<e-mail>|isAdmin] - adds a new user with the given name and optional e-mail address"); writable.println("user delete <name> - deletes the user with the given name"); writable.println("user password <name> <password> - sets the password for the given user"); } // ----- private methods ----- private void handleList(final SecurityContext securityContext, final Writable writable) throws FrameworkException, IOException{ final Class<NodeInterface> type = StructrApp.getConfiguration().getNodeEntityClass("User"); final App app = StructrApp.getInstance(securityContext); if (type != null) { try (final Tx tx = app.tx()) { final List<NodeInterface> users = app.nodeQuery(type).getAsList(); for (final Iterator<NodeInterface> it = users.iterator(); it.hasNext();) { final NodeInterface user = it.next(); final String name = user.getProperty(AbstractNode.name); if (name != null) { writable.print(name); } else { writable.print(user.getUuid()); } if (it.hasNext()) { writable.print(", "); } } writable.println(); tx.success(); } } else { throw new FrameworkException(422, "Cannot list users, no User class found."); } } private void handleAdd(final SecurityContext securityContext, final Writable writable, final String name, final String eMail, final String isAdmin) throws FrameworkException, IOException { if (StringUtils.isEmpty(name)) { throw new FrameworkException(422, "Missing user name for add command."); } final App app = StructrApp.getInstance(securityContext); final Class type = StructrApp.getConfiguration().getNodeEntityClass("User"); if (type != null) { try (final Tx tx = app.tx()) { final NodeInterface user = app.create(type, new NodeAttribute<>(AbstractNode.name, name)); // set e-mail address if (eMail != null && !"isAdmin".equals(eMail)) { user.setProperties(securityContext, new PropertyMap(Principal.eMail, eMail)); } // set isAdmin flag if ("isAdmin".equals(eMail) || "isAdmin".equals(isAdmin)) { user.setProperties(securityContext, new PropertyMap(Principal.isAdmin, true)); } writable.println("User created."); tx.success(); } } else { throw new FrameworkException(422, "Cannot create user, no User class found."); } } private void handleDelete(final SecurityContext securityContext, final Writable writable, final String name, final String confirm) throws FrameworkException, IOException { if (StringUtils.isEmpty(name)) { throw new FrameworkException(422, "Missing user name for delete command."); } final Class<? extends NodeInterface> type = StructrApp.getConfiguration().getNodeEntityClass("User"); final App app = StructrApp.getInstance(securityContext); if (type != null) { try (final Tx tx = app.tx()) { NodeInterface user = app.nodeQuery(type).andName(name).getFirst(); if (user == null) { user = app.get(type, name); } if (user != null) { if (user.getProperty(Principal.ownedNodes).isEmpty()) { app.delete(user); writable.println("User deleted."); } else { final String hash = user.getUuid().substring(7, 11); if (confirm == null || !confirm.equals(hash)) { writable.print("User '"); writable.print(name); writable.print("' has owned nodes, please confirm deletion with 'user delete "); writable.print(name); writable.print(" "); writable.print(hash); writable.println("'."); } else { app.delete(user); writable.println("User deleted."); } } } else { throw new FrameworkException(422, "User " + name + " not found."); } tx.success(); } } else { throw new FrameworkException(422, "Cannot delete user, no User class found."); } } private void handlePwd(final SecurityContext securityContext, final Writable writable, final String name, final String password) throws FrameworkException, IOException { if (StringUtils.isEmpty(name)) { throw new FrameworkException(422, "Missing user name for password command."); } final Class<? extends NodeInterface> type = StructrApp.getConfiguration().getNodeEntityClass("User"); final App app = StructrApp.getInstance(securityContext); if (type != null) { try (final Tx tx = app.tx()) { final NodeInterface user = app.nodeQuery(type).andName(name).getFirst(); if (user != null) { if (StringUtils.isNotBlank(password)) { user.setProperties(securityContext, new PropertyMap(Principal.password, password)); writable.println("Password changed."); } else { throw new FrameworkException(422, "Will not set empty password"); } } else { throw new FrameworkException(422, "User " + name + " not found."); } tx.success(); } } else { throw new FrameworkException(422, "Cannot change password, no User class found."); } } }