/*
* PermissionsDialogHandler.java
*
* This work is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This work 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* Copyright (c) 2004 Per Cederberg. All rights reserved.
*/
package org.liquidsite.app.admin;
import java.util.ArrayList;
import org.liquidsite.app.admin.view.AdminView;
import org.liquidsite.core.content.Content;
import org.liquidsite.core.content.ContentException;
import org.liquidsite.core.content.ContentManager;
import org.liquidsite.core.content.ContentSecurityException;
import org.liquidsite.core.content.Domain;
import org.liquidsite.core.content.Permission;
import org.liquidsite.core.content.PermissionList;
import org.liquidsite.core.content.PersistentObject;
import org.liquidsite.core.content.User;
import org.liquidsite.core.content.Group;
import org.liquidsite.core.web.FormValidationException;
import org.liquidsite.core.web.Request;
/**
* The permission editing request handler. This class handles the
* permissions dialog workflow for domain and content objects.
*
* @author Per Cederberg, <per at percederberg dot net>
* @version 1.0
*/
public class PermissionsDialogHandler extends AdminDialogHandler {
/**
* Creates a new permissions dialog handler.
*/
public PermissionsDialogHandler() {
super("index.html", "permissions.html", false);
}
/**
* Displays a form for the specified workflow step. This method
* will NOT be called when returning to the start page.
*
* @param request the request object
* @param step the workflow step
*
* @throws ContentException if the database couldn't be accessed
* properly
* @throws ContentSecurityException if the user didn't have the
* required permissions
*/
protected void displayStep(Request request, int step)
throws ContentException, ContentSecurityException {
PersistentObject obj = AdminUtils.getReference(request);
AdminView.DIALOG.viewPermissions(request, obj);
}
/**
* Validates a form for the specified workflow step. If the form
* validation fails in this step, the form page for the workflow
* step will be displayed again with an 'error' attribute
* containing the message in the validation exception.
*
* @param request the request object
* @param step the workflow step
*
* @throws ContentException if the database couldn't be accessed
* properly
* @throws FormValidationException if the form request data
* validation failed
*/
protected void validateStep(Request request, int step)
throws ContentException, FormValidationException {
Permission[] permissions;
User user;
Group[] groups;
boolean read = false;
boolean write = false;
boolean publish = false;
boolean admin = false;
String str;
// Check for unexisting users or groups
try {
permissions = getPermissions(request);
} catch (ContentSecurityException e) {
throw new FormValidationException("", e.getMessage());
}
// Check permissions for sanity
user = request.getUser();
groups = user.getGroups();
for (int i = 0; i < permissions.length; i++) {
if (permissions[i].isMatch(null, null)
&& permissions[i].getAdmin()) {
str = "Cannot set admin permission for anonymous user";
throw new FormValidationException("", str);
}
if (permissions[i].isMatch(user, groups)) {
if (permissions[i].getRead()) {
read = true;
}
if (permissions[i].getWrite()) {
write = true;
}
if (permissions[i].getPublish()) {
publish = true;
}
if (permissions[i].getAdmin()) {
admin = true;
}
}
}
if (!user.isSuperUser() && !read) {
str = "Cannot remove read permission for current user";
throw new FormValidationException("", str);
}
if (!user.isSuperUser() && !write) {
str = "Cannot remove write permission for current user";
throw new FormValidationException("", str);
}
if (!user.isSuperUser() && !publish) {
str = "Cannot remove publish permission for current user";
throw new FormValidationException("", str);
}
if (!user.isSuperUser() && !admin) {
str = "Cannot remove admin permission for current user";
throw new FormValidationException("", str);
}
}
/**
* Handles a validated form for the specified workflow step. This
* method returns the next workflow step, i.e. the step used when
* calling the display method. If the special zero (0) workflow
* step is returned, the workflow is assumed to have terminated.
* Note that this method also allows additional validation to
* occur. By returning the incoming workflow step number and
* setting the appropriate request attributes the same results as
* in the normal validate method can be achieved. For recoverable
* errors, this is the recommended course of action.
*
* @param request the request object
* @param step the workflow step
*
* @return the next workflow step, or
* zero (0) if the workflow has finished
*
* @throws ContentException if the database couldn't be accessed
* properly
* @throws ContentSecurityException if the user didn't have the
* required permissions
*/
protected int handleStep(Request request, int step)
throws ContentException, ContentSecurityException {
Object ref = AdminUtils.getReference(request);
PermissionList permissions;
Permission[] perms;
perms = getPermissions(request);
if (ref instanceof Domain) {
permissions = ((Domain) ref).getPermissions();
} else {
permissions = ((Content) ref).getPermissions(false);
}
permissions.setPermissions(perms);
permissions.save(request.getUser());
return 0;
}
/**
* Returns the permissions from the request object. If the
* inherited flag is set in the request, an empty array will be
* returned.
*
* @param request the request
*
* @return an array of permissions found in the request
*
* @throws ContentException if the database couldn't be accessed
* properly
* @throws ContentSecurityException if a permission user or
* group didn't exist in the database
*/
private Permission[] getPermissions(Request request)
throws ContentException, ContentSecurityException {
Object ref = AdminUtils.getReference(request);
ArrayList list = new ArrayList();
Permission[] permissions;
int index = 0;
if (!request.getParameter("inherit", "").equals("true")) {
while (request.getParameter("perm_" + index + "_type") != null) {
list.add(getPermission(request, index, ref));
index++;
}
}
permissions = new Permission[list.size()];
list.toArray(permissions);
return permissions;
}
/**
* Returns a permission from the request object. The permission
* index and reference object must be supplied.
*
* @param request the request
* @param index the permission index (from 0)
* @param ref the permission reference object
*
* @return the permission found in the request
*
* @throws ContentException if the database couldn't be accessed
* properly
* @throws ContentSecurityException if the permission user or
* group didn't exist in the database
*/
private Permission getPermission(Request request, int index, Object ref)
throws ContentException, ContentSecurityException {
ContentManager manager = AdminUtils.getContentManager();
String prefix = "perm_" + index + "_";
Domain domain = null;
Content content = null;
User user = null;
Group group = null;
Permission perm;
String str;
if (ref instanceof Domain) {
domain = (Domain) ref;
} else {
content = (Content) ref;
domain = content.getDomain();
}
str = request.getParameter(prefix + "user");
if (str != null) {
user = manager.getUser(domain, str);
if (user == null) {
str = "Couldn't find user '" + str + "'";
throw new ContentSecurityException(str);
} else if (user.isSuperUser()) {
str = "Cannot set permissions for superuser '" + str + "'";
throw new ContentSecurityException(str);
}
}
str = request.getParameter(prefix + "group");
if (str != null) {
group = manager.getGroup(domain, str);
if (group == null) {
str = "Couldn't find group '" + str + "'";
throw new ContentSecurityException(str);
}
}
if (ref instanceof Domain) {
perm = new Permission(user, group);
} else {
perm = new Permission(user, group);
}
str = request.getParameter(prefix + "read");
if (str != null) {
perm.setRead(true);
}
str = request.getParameter(prefix + "write");
if (str != null) {
perm.setWrite(true);
}
str = request.getParameter(prefix + "publish");
if (str != null) {
perm.setPublish(true);
}
str = request.getParameter(prefix + "admin");
if (str != null) {
perm.setAdmin(true);
}
return perm;
}
}