Add user and permissions lists.

This commit is contained in:
Michael Jumper
2013-01-30 13:23:16 -08:00
parent 9599d012a4
commit 192d0050bb
3 changed files with 438 additions and 0 deletions

View File

@@ -0,0 +1,206 @@
package net.sourceforge.guacamole.net.basic;
/*
* Guacamole - Clientless Remote Desktop
* Copyright (C) 2010 Michael Jumper
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.GuacamoleSecurityException;
import net.sourceforge.guacamole.net.auth.PermissionDirectory;
import net.sourceforge.guacamole.net.auth.UserContext;
import net.sourceforge.guacamole.net.auth.permission.GuacamoleConfigurationDirectoryPermission;
import net.sourceforge.guacamole.net.auth.permission.GuacamoleConfigurationPermission;
import net.sourceforge.guacamole.net.auth.permission.ObjectPermission;
import net.sourceforge.guacamole.net.auth.permission.Permission;
import net.sourceforge.guacamole.net.auth.permission.SystemPermission;
import net.sourceforge.guacamole.net.auth.permission.UserDirectoryPermission;
import net.sourceforge.guacamole.net.auth.permission.UserPermission;
/**
* Simple HttpServlet which outputs XML containing a list of all visible
* permissions of a given user.
*
* @author Michael Jumper
*/
public class PermissionList extends AuthenticatingHttpServlet {
/**
* Returns the XML attribute value representation of the given
* SystemPermission.Type.
*
* @param type The SystemPermission.Type to translate into a String.
* @return The XML attribute value representation of the given
* SystemPermission.Type.
*
* @throws GuacamoleException If the type given is not implemented.
*/
private String toString(SystemPermission.Type type)
throws GuacamoleException {
switch (type) {
case CREATE: return "read";
}
throw new GuacamoleException("Unknown permission type: " + type);
}
/**
* Returns the XML attribute value representation of the given
* ObjectPermission.Type.
*
* @param type The ObjectPermission.Type to translate into a String.
* @return The XML attribute value representation of the given
* ObjectPermission.Type.
*
* @throws GuacamoleException If the type given is not implemented.
*/
private String toString(ObjectPermission.Type type)
throws GuacamoleException {
switch (type) {
case READ: return "read";
case UPDATE: return "update";
case DELETE: return "delete";
case ADMINISTER: return "admin";
}
throw new GuacamoleException("Unknown permission type: " + type);
}
@Override
protected void authenticatedService(
UserContext context,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
// Do not cache
response.setHeader("Cache-Control", "no-cache");
// Write actual XML
try {
// Get permission directory
PermissionDirectory permissions = context.getPermissionDirectory();
// Get username
String username = request.getParameter("user");
if (username == null)
throw new ServletException("No user specified.");
// Write XML content type
response.setHeader("Content-Type", "text/xml");
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter xml = outputFactory.createXMLStreamWriter(response.getWriter());
// Begin document
xml.writeStartDocument();
xml.writeStartElement("permissions");
xml.writeAttribute("user", username);
// For each entry, write corresponding user element
for (Permission permission : permissions.getPermissions(username)) {
// Config directory permission
if (permission instanceof GuacamoleConfigurationDirectoryPermission) {
// Get permission
GuacamoleConfigurationDirectoryPermission gcdp =
(GuacamoleConfigurationDirectoryPermission) permission;
// Write permission
xml.writeEmptyElement("configs");
xml.writeAttribute("type", toString(gcdp.getType()));
}
// Config permission
else if (permission instanceof GuacamoleConfigurationPermission) {
// Get permission
GuacamoleConfigurationPermission gcp =
(GuacamoleConfigurationPermission) permission;
// Write permission
xml.writeEmptyElement("config");
xml.writeAttribute("type", toString(gcp.getType()));
xml.writeAttribute("name", gcp.getObjectIdentifier());
}
// User directory permission
else if (permission instanceof UserDirectoryPermission) {
// Get permission
UserDirectoryPermission udp =
(UserDirectoryPermission) permission;
// Write permission
xml.writeEmptyElement("users");
xml.writeAttribute("type", toString(udp.getType()));
}
// User permission
else if (permission instanceof UserPermission) {
// Get permission
UserPermission up = (UserPermission) permission;
// Write permission
xml.writeEmptyElement("users");
xml.writeAttribute("type", toString(up.getType()));
xml.writeAttribute("name", up.getObjectIdentifier());
}
else
throw new ServletException("Unsupported permission type.");
}
// End document
xml.writeEndElement();
xml.writeEndDocument();
}
catch (XMLStreamException e) {
throw new IOException("Unable to write permission list XML.", e);
}
catch (GuacamoleSecurityException e) {
// If cannot read permissions, return error
response.sendError(HttpServletResponse.SC_FORBIDDEN,
"Permission denied.");
}
catch (GuacamoleException e) {
throw new ServletException("Unable to read permissions.", e);
}
}
}

View File

@@ -0,0 +1,210 @@
package net.sourceforge.guacamole.net.basic;
/*
* Guacamole - Clientless Remote Desktop
* Copyright (C) 2010 Michael Jumper
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.IOException;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.GuacamoleSecurityException;
import net.sourceforge.guacamole.net.auth.PermissionDirectory;
import net.sourceforge.guacamole.net.auth.User;
import net.sourceforge.guacamole.net.auth.UserContext;
import net.sourceforge.guacamole.net.auth.UserDirectory;
import net.sourceforge.guacamole.net.auth.permission.ObjectPermission;
import net.sourceforge.guacamole.net.auth.permission.Permission;
import net.sourceforge.guacamole.net.auth.permission.SystemPermission;
import net.sourceforge.guacamole.net.auth.permission.UserDirectoryPermission;
import net.sourceforge.guacamole.net.auth.permission.UserPermission;
/**
* Simple HttpServlet which outputs XML containing a list of all visible users.
*
* @author Michael Jumper
*/
public class UserList extends AuthenticatingHttpServlet {
/**
* Checks whether the given user has permission to perform the given
* system operation. Security exceptions are handled appropriately - only
* non-security exceptions pass through.
*
* @param permissions The PermissionsDirectory to check.
* @param user The user whose permissions should be verified.
* @param type The type of operation to check for permission for.
* @return true if permission is granted, false otherwise.
*
* @throws GuacamoleException If an error occurs while checking permissions.
*/
private boolean hasUserPermission(PermissionDirectory permissions,
String user, SystemPermission.Type type)
throws GuacamoleException {
// Build permission
Permission permission = new UserDirectoryPermission(type);
try {
// Return result of permission check, if possible
return permissions.hasPermission(user, permission);
}
catch (GuacamoleSecurityException e) {
// If cannot check due to security restrictions, no permission
return false;
}
}
/**
* Checks whether the given user has permission to perform the given
* object operation. Security exceptions are handled appropriately - only
* non-security exceptions pass through.
*
* @param permissions The PermissionsDirectory to check.
* @param user The user whose permissions should be verified.
* @param type The type of operation to check for permission for.
* @param identifier The identifier of the user the operation would be
* performed upon.
* @return true if permission is granted, false otherwise.
*
* @throws GuacamoleException If an error occurs while checking permissions.
*/
private boolean hasUserPermission(PermissionDirectory permissions,
String user, ObjectPermission.Type type, String identifier)
throws GuacamoleException {
// Build permission
Permission permission = new UserPermission(type, identifier);
try {
// Return result of permission check, if possible
return permissions.hasPermission(user, permission);
}
catch (GuacamoleSecurityException e) {
// If cannot check due to security restrictions, no permission
return false;
}
}
@Override
protected void authenticatedService(
UserContext context,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
// Do not cache
response.setHeader("Cache-Control", "no-cache");
// Write XML content type
response.setHeader("Content-Type", "text/xml");
// Try to get permission directory
PermissionDirectory permissions = null;
try {
permissions = context.getPermissionDirectory();
}
catch (GuacamoleSecurityException e) {
// Soft fail - can't check permissions ... assume have READ and
// nothing else
}
catch (GuacamoleException e) {
throw new ServletException("Unable to retrieve permissions.", e);
}
// Write actual XML
try {
// Get user directory
UserDirectory directory = context.getUserDirectory();
// Get users
Set<User> users = directory.getUsers();
// Get username
String username = context.self().getUsername();
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter xml = outputFactory.createXMLStreamWriter(response.getWriter());
// Begin document
xml.writeStartDocument();
xml.writeStartElement("users");
// Save user create permission attribute
if (hasUserPermission(permissions, username,
SystemPermission.Type.CREATE))
xml.writeAttribute("create", "yes");
// For each entry, write corresponding user element
for (User user : users) {
// Write user
xml.writeEmptyElement("user");
xml.writeAttribute("name", user.getUsername());
// Check permissions and set attributes appropriately
if (permissions != null) {
// Save update permission attribute
if (hasUserPermission(permissions, username,
ObjectPermission.Type.UPDATE, user.getUsername()))
xml.writeAttribute("update", "yes");
// Save admin permission attribute
if (hasUserPermission(permissions, username,
ObjectPermission.Type.ADMINISTER, user.getUsername()))
xml.writeAttribute("admin", "yes");
// Save delete permission attribute
if (hasUserPermission(permissions, username,
ObjectPermission.Type.DELETE, user.getUsername()))
xml.writeAttribute("delete", "yes");
}
}
// End document
xml.writeEndElement();
xml.writeEndDocument();
}
catch (XMLStreamException e) {
throw new IOException("Unable to write user list XML.", e);
}
catch (GuacamoleSecurityException e) {
// If cannot read permissions, return error
response.sendError(HttpServletResponse.SC_FORBIDDEN,
"Permission denied.");
}
catch (GuacamoleException e) {
throw new ServletException("Unable to read users.", e);
}
}
}

View File

@@ -66,6 +66,28 @@
<url-pattern>/configs</url-pattern>
</servlet-mapping>
<!-- User List Servlet -->
<servlet>
<description>User list servlet.</description>
<servlet-name>Users</servlet-name>
<servlet-class>net.sourceforge.guacamole.net.basic.UserList</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Users</servlet-name>
<url-pattern>/users</url-pattern>
</servlet-mapping>
<!-- Permission List Servlet -->
<servlet>
<description>Permission list servlet.</description>
<servlet-name>Permissions</servlet-name>
<servlet-class>net.sourceforge.guacamole.net.basic.PermissionList</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Permissions</servlet-name>
<url-pattern>/permissions</url-pattern>
</servlet-mapping>
<!-- Guacamole Tunnel Servlet -->
<servlet>
<description>Tunnel servlet.</description>