403 lines
15 KiB
Java
Executable File
403 lines
15 KiB
Java
Executable File
/*
|
|
* Copyright (C) 2001, 2002, 2003 Red Hat Inc. All Rights Reserved.
|
|
*
|
|
* The contents of this file are subject to the CCM Public
|
|
* License (the "License"); you may not use this file except in
|
|
* compliance with the License. You may obtain a copy of
|
|
* the License at http://www.redhat.com/licenses/ccmpl.html
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
*/
|
|
|
|
package com.arsdigita.portalworkspace.ui.admin;
|
|
|
|
import com.arsdigita.bebop.PageState;
|
|
import com.arsdigita.bebop.RequestLocal;
|
|
import com.arsdigita.bebop.Component;
|
|
import com.arsdigita.bebop.ControlLink;
|
|
import com.arsdigita.bebop.Label;
|
|
import com.arsdigita.bebop.Table;
|
|
import com.arsdigita.bebop.table.TableModel;
|
|
import com.arsdigita.bebop.table.AbstractTableModelBuilder;
|
|
import com.arsdigita.bebop.table.TableColumn;
|
|
import com.arsdigita.bebop.table.TableColumnModel;
|
|
import com.arsdigita.bebop.table.DefaultTableColumnModel;
|
|
import com.arsdigita.bebop.table.TableCellRenderer;
|
|
import com.arsdigita.bebop.table.TableHeader;
|
|
import com.arsdigita.kernel.Party;
|
|
import com.arsdigita.kernel.ACSObject;
|
|
import com.arsdigita.kernel.permissions.PermissionService;
|
|
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
|
|
import com.arsdigita.kernel.permissions.PermissionDescriptor;
|
|
import com.arsdigita.portalworkspace.ui.Icons;
|
|
import com.arsdigita.persistence.OID;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import org.apache.log4j.Category;
|
|
|
|
/**
|
|
* GrantsTable.
|
|
*
|
|
* Reimplementation using Ardigita portal server code.
|
|
* @author dennis (2003/08/15)
|
|
* @version $Id: com/arsdigita/portalserver/permissions/GrantsTable.java $
|
|
*/
|
|
abstract class GrantsTable extends Table {
|
|
|
|
private static Category s_log = Category.getInstance
|
|
(GrantsTable.class.getName());
|
|
|
|
private static final String REMOVE_EVENT = "_revoke_all_";
|
|
|
|
private static final String COLUMN_WIDTH = "12%";
|
|
|
|
// These RLs are used by all the control links to get their
|
|
// control event values. It's basically a communications
|
|
// chanel between getComponent and setControlEvent.
|
|
final static RequestLocal s_targetRL = new RequestLocal();
|
|
final static RequestLocal s_adjustCodeRL = new RequestLocal();
|
|
|
|
private static class EditPrivilegeCellRenderer
|
|
implements TableCellRenderer {
|
|
final PrivilegeDescriptor m_privilege;
|
|
final ControlLink m_link;
|
|
|
|
EditPrivilegeCellRenderer(PrivilegeDescriptor privilege) {
|
|
m_privilege = privilege;
|
|
|
|
final String eventName = privilege.getName();
|
|
|
|
m_link = new ControlLink(Icons.RADIO_EMPTY_16) {
|
|
@Override
|
|
public void setControlEvent(PageState ps) {
|
|
ps.setControlEvent((Component) s_targetRL.get(ps),
|
|
eventName,
|
|
(String) s_adjustCodeRL.get(ps));
|
|
}
|
|
};
|
|
}
|
|
|
|
public Component getComponent(Table table, PageState ps,
|
|
Object value, boolean isSelected,
|
|
Object key, int row, int column) {
|
|
Grant grant = (Grant) value;
|
|
|
|
if (grant.basePrivilege.equals(m_privilege)) {
|
|
// If the current privilege is equal to the privilege
|
|
// this component stands for, return the (*).
|
|
return Icons.RADIO_FULL_16;
|
|
} else {
|
|
// Otherwise set up the control event for the link.
|
|
s_targetRL.set(ps, table);
|
|
s_adjustCodeRL.set(ps, key);
|
|
return m_link;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static class ViewPrivilegeCellRenderer
|
|
implements TableCellRenderer {
|
|
final PrivilegeDescriptor m_privilege;
|
|
|
|
ViewPrivilegeCellRenderer(PrivilegeDescriptor privilege) {
|
|
m_privilege = privilege;
|
|
}
|
|
|
|
public Component getComponent(Table table, PageState ps,
|
|
Object value, boolean isSelected,
|
|
Object key, int row, int column) {
|
|
Grant grant = (Grant) value;
|
|
|
|
if (grant.basePrivilege.equals(m_privilege)) {
|
|
return Icons.RADIO_FULL_GRAYED_16;
|
|
} else {
|
|
return Icons.RADIO_EMPTY_GRAYED_16;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static TableCellRenderer[] s_editCellRenderers;
|
|
private static TableCellRenderer[] s_viewCellRenderers;
|
|
|
|
static {
|
|
s_log.debug("Static initalizer starting...");
|
|
int n = Grant.s_interestingPrivileges.length;
|
|
s_editCellRenderers = new TableCellRenderer[n];
|
|
s_viewCellRenderers = new TableCellRenderer[n];
|
|
for (int i = 0; i < n; i++) {
|
|
s_editCellRenderers[i] =
|
|
new EditPrivilegeCellRenderer(Grant.s_interestingPrivileges[i]);
|
|
s_viewCellRenderers[i] =
|
|
new ViewPrivilegeCellRenderer(Grant.s_interestingPrivileges[i]);
|
|
}
|
|
s_log.debug("Static initalizer finished.");
|
|
}
|
|
|
|
// Per-request label for renderer getComponent calls
|
|
private final static RequestLocal s_dynamicLabel = new RequestLocal() {
|
|
@Override
|
|
public Object initialValue(PageState ps) {
|
|
return new Label();
|
|
}
|
|
};
|
|
|
|
public GrantsTable(final RequestLocal grantsRL,
|
|
final RequestLocal typesRL,
|
|
final boolean isEditable) {
|
|
super();
|
|
|
|
setClassAttr("fancy");
|
|
|
|
setModelBuilder(new AbstractTableModelBuilder() {
|
|
public TableModel makeModel(Table t, PageState ps) {
|
|
final Iterator grants = (Iterator) grantsRL.get(ps);
|
|
|
|
return new TableModel() {
|
|
Grant m_currentGrant;
|
|
String m_currentKey;
|
|
|
|
public int getColumnCount() {
|
|
return 6;
|
|
}
|
|
|
|
public Object getElementAt(int index) {
|
|
return m_currentGrant;
|
|
}
|
|
|
|
public Object getKeyAt(int columnIndex) {
|
|
return m_currentKey;
|
|
}
|
|
|
|
public boolean nextRow() {
|
|
if (grants.hasNext()) {
|
|
m_currentGrant = (Grant) grants.next();
|
|
|
|
s_log.debug("Preparing to display Grant "
|
|
+ m_currentGrant);
|
|
|
|
m_currentKey = m_currentGrant.toString();
|
|
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
});
|
|
|
|
TableColumnModel columnModel = new DefaultTableColumnModel();
|
|
|
|
// We assume that whoever uses the GrantsTable will
|
|
// be adding a column of their own
|
|
|
|
// COLUMN 1: Type Name (may be hidden)
|
|
TableColumn typeColumn = new TableColumn(1, "On") {
|
|
public boolean isVisible(PageState ps) {
|
|
return (typesRL.get(ps) != null);
|
|
}
|
|
};
|
|
|
|
typeColumn.setCellRenderer(new TableCellRenderer() {
|
|
public Component getComponent(Table table,
|
|
PageState ps,
|
|
Object value,
|
|
boolean isSelected,
|
|
Object key,
|
|
int row,
|
|
int column) {
|
|
Grant grant = (Grant) value;
|
|
Label typeLabel = (Label) s_dynamicLabel.get(ps);
|
|
typeLabel.setLabel(grant.objectTypeDisplayName);
|
|
return typeLabel;
|
|
}
|
|
});
|
|
columnModel.add(typeColumn);
|
|
|
|
// COLUMNS 2 through N: Privilege entries
|
|
TableCellRenderer[] cellRenderers;
|
|
|
|
if (isEditable) {
|
|
cellRenderers = s_editCellRenderers;
|
|
} else {
|
|
cellRenderers = s_viewCellRenderers;
|
|
}
|
|
|
|
for (int i = 0; i < Grant.s_interestingPrivileges.length; i++) {
|
|
TableColumn privColumn = new TableColumn
|
|
(2 + i, Grant.s_privilegePrettyNames[i]);
|
|
|
|
privColumn.setCellRenderer(cellRenderers[i]);
|
|
privColumn.setClassAttr("icon");
|
|
privColumn.setHeadClassAttr("icon");
|
|
privColumn.setWidth(COLUMN_WIDTH);
|
|
|
|
columnModel.add(privColumn);
|
|
}
|
|
|
|
// COLUMN N + 1: Optional REMOVE column
|
|
if (isEditable) {
|
|
TableColumn removeColumn = new TableColumn(5, "Remove");
|
|
|
|
removeColumn.setAlign("center");
|
|
removeColumn.setCellRenderer(new TableCellRenderer() {
|
|
final ControlLink m_link = new ControlLink(Icons.TRASH_16) {
|
|
public void setControlEvent(PageState ps) {
|
|
ps.setControlEvent(GrantsTable.this,
|
|
REMOVE_EVENT,
|
|
(String) s_adjustCodeRL.get(ps));
|
|
}
|
|
};
|
|
|
|
public Component getComponent(Table table,
|
|
PageState ps,
|
|
Object value,
|
|
boolean isSelected,
|
|
Object key,
|
|
int row,
|
|
int column) {
|
|
Grant grant = (Grant) value;
|
|
|
|
s_adjustCodeRL.set(ps, key);
|
|
|
|
return m_link;
|
|
}
|
|
});
|
|
|
|
removeColumn.setClassAttr("icon");
|
|
removeColumn.setHeadClassAttr("icon");
|
|
removeColumn.setWidth(COLUMN_WIDTH);
|
|
|
|
columnModel.add(removeColumn);
|
|
}
|
|
|
|
setColumnModel(columnModel);
|
|
setHeader(new TableHeader(columnModel));
|
|
}
|
|
|
|
@Override
|
|
public void respond(PageState ps) {
|
|
String controlEventName = ps.getControlEventName();
|
|
String controlEventValue = ps.getControlEventValue();
|
|
|
|
s_log.debug("Responding to control event \"" + controlEventName +
|
|
" => " + controlEventValue + "\"");
|
|
|
|
PrivilegeDescriptor newPriv = null;
|
|
|
|
found: if (!REMOVE_EVENT.equals(controlEventName)) {
|
|
for (int i = 0; i < Grant.s_interestingPrivileges.length; i++) {
|
|
PrivilegeDescriptor priv = Grant.s_interestingPrivileges[i];
|
|
String privName = priv.getName();
|
|
|
|
if (privName.equals(controlEventName)) {
|
|
newPriv = priv;
|
|
break found;
|
|
}
|
|
}
|
|
|
|
throw new IllegalStateException("Unknown control event");
|
|
}
|
|
|
|
Grant grant = Grant.unmarshal(ps.getControlEventValue());
|
|
|
|
OID objectOID = new OID
|
|
(ACSObject.BASE_DATA_OBJECT_TYPE, grant.objectID);
|
|
|
|
OID partyOID = new OID
|
|
(Party.BASE_DATA_OBJECT_TYPE, grant.granteeID);
|
|
|
|
s_log.debug("Privilege requested is " + newPriv + ". " +
|
|
"Existing privilege is " + grant.basePrivilege + ".");
|
|
|
|
int oldLevel = Grant.getPrivilegeLevel(grant.basePrivilege);
|
|
|
|
if (oldLevel > 0 && newPriv == null) {
|
|
// REMOVE_EVENT case 1: There are existing privileges
|
|
// other than read.
|
|
|
|
s_log.debug("Revoking old privilege. Old privilege was " +
|
|
oldLevel + ".");
|
|
|
|
PermissionDescriptor createPD =
|
|
getPermissionDescriptorHelper(grant, Grant.CREATE,
|
|
objectOID, partyOID);
|
|
PermissionDescriptor oldPD =
|
|
getPermissionDescriptorHelper(grant, oldLevel,
|
|
objectOID, partyOID);
|
|
PermissionService.revokePermission(createPD);
|
|
PermissionService.revokePermission(oldPD);
|
|
} else if (oldLevel == 0 && newPriv == null) {
|
|
// REMOVE_EVENT case 2: Only existing privilege is read.
|
|
|
|
s_log.debug("Revoking old privilege. Old privilege was " +
|
|
oldLevel + ".");
|
|
|
|
PermissionDescriptor oldPD =
|
|
getPermissionDescriptorHelper(grant, oldLevel,
|
|
objectOID, partyOID);
|
|
PermissionService.revokePermission(oldPD);
|
|
} else {
|
|
// Add new privileges (but first revoke old ones).
|
|
|
|
s_log.debug("Adding new privilege, but first removing old ones.");
|
|
|
|
int newLevel = Grant.getPrivilegeLevel(newPriv);
|
|
|
|
// Revoke old privileges.
|
|
PermissionDescriptor oldPD =
|
|
getPermissionDescriptorHelper(grant, oldLevel,
|
|
objectOID, partyOID);
|
|
PermissionService.revokePermission(oldPD);
|
|
|
|
// Grant new privileges.
|
|
PermissionDescriptor newPD =
|
|
getPermissionDescriptorHelper(grant, newLevel,
|
|
objectOID, partyOID);
|
|
PermissionService.grantPermission(newPD);
|
|
|
|
// Handle create.
|
|
PermissionDescriptor createPD =
|
|
getPermissionDescriptorHelper(grant, Grant.CREATE,
|
|
objectOID, partyOID);
|
|
|
|
if (newLevel == Grant.EDIT || newLevel == Grant.ADMIN) {
|
|
s_log.debug("Implicitly granting create.");
|
|
|
|
PermissionService.grantPermission(createPD);
|
|
} else if (oldLevel == Grant.EDIT || oldLevel == Grant.ADMIN) {
|
|
// If the new permission grant is one that
|
|
// does not require create AND the old permission
|
|
// did have create, revoke it.
|
|
|
|
s_log.debug("Implicitly revoking create.");
|
|
|
|
PermissionService.revokePermission(createPD);
|
|
}
|
|
}
|
|
}
|
|
|
|
private PermissionDescriptor getPermissionDescriptorHelper(Grant grant,
|
|
int privLevel,
|
|
OID objectOID,
|
|
OID partyOID) {
|
|
PrivilegeDescriptor priv;
|
|
|
|
// if (grant.objectType != null) {
|
|
// priv = ParameterizedPrivilege.createPrivilege
|
|
// (Grant.s_privileges[privLevel],
|
|
// grant.objectType.getQualifiedName(),
|
|
// "");
|
|
// } else {
|
|
priv = Grant.s_privileges[privLevel];
|
|
// }
|
|
|
|
return new PermissionDescriptor(priv, objectOID, partyOID);
|
|
}
|
|
}
|