xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
- <!-- USERS -->
+ <!-- USERS & GROUPS CRUDS -->
<bean id="newUser" class="org.argeo.security.ui.admin.commands.NewUser"
scope="prototype">
<property name="userAdmin" ref="userAdmin" />
<property name="userAdmin" ref="userAdmin" />
<property name="userTransaction" ref="userTransaction" />
</bean>
+ <bean id="deleteUsers" class="org.argeo.security.ui.admin.commands.DeleteUsers"
+ scope="prototype">
+ <property name="userAdmin" ref="userAdmin" />
+ <property name="userTransaction" ref="userTransaction" />
+ </bean>
+ <bean id="deleteGroups" class="org.argeo.security.ui.admin.commands.DeleteGroups"
+ scope="prototype">
+ <property name="userAdmin" ref="userAdmin" />
+ <property name="userTransaction" ref="userTransaction" />
+ </bean>
<!-- <bean id="userBatchUpdate" class="org.argeo.security.ui.admin.commands.UserBatchUpdate"
scope="prototype"> <property name="repository" ref="nodeRepository" /> <property
</command>
<command
id="org.argeo.security.ui.admin.deleteUsers"
- defaultHandler="org.argeo.security.ui.admin.commands.DeleteUsers"
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
name="Delete User">
</command>
<!-- Group CRUD -->
</command>
<command
id="org.argeo.security.ui.admin.deleteGroups"
- defaultHandler="org.argeo.security.ui.admin.commands.DeleteGroups"
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
name="Delete Group">
</command>
<!-- Transaction -->
import java.util.Map;
import java.util.TreeMap;
+import javax.transaction.UserTransaction;
+
import org.argeo.security.ui.admin.SecurityAdminPlugin;
import org.argeo.security.ui.admin.internal.UiAdminUtils;
import org.argeo.security.ui.admin.internal.UserAdminConstants;
+import org.argeo.security.ui.admin.views.GroupsView;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.UserAdmin;
/** Deletes the selected groups */
public class DeleteGroups extends AbstractHandler {
- public final static String ID = SecurityAdminPlugin.PLUGIN_ID + ".deleteGroups";
+ public final static String ID = SecurityAdminPlugin.PLUGIN_ID
+ + ".deleteGroups";
+
+ /* DEPENDENCY INJECTION */
+ private UserAdmin userAdmin;
+ private UserTransaction userTransaction;
-
@SuppressWarnings("unchecked")
public Object execute(ExecutionEvent event) throws ExecutionException {
ISelection selection = HandlerUtil.getCurrentSelection(event);
if (selection.isEmpty())
return null;
- Map<String, Group> toDelete = new TreeMap<String, Group>();
+ Map<String, String> toDelete = new TreeMap<String, String>();
+ // List<String> names = new ArrayList<String>();
Iterator<Group> it = ((IStructuredSelection) selection).iterator();
- groups: while (it.hasNext()) {
+ while (it.hasNext()) {
Group currGroup = it.next();
String groupName = UiAdminUtils.getProperty(currGroup,
UserAdminConstants.KEY_CN);
-
// TODO add checks
- // if (userName.equals(profileNode.getSession().getUserID())) {
- // log.warn("Cannot delete its own user: " + userName);
- // continue groups;
- // }
- toDelete.put(groupName, currGroup);
+ toDelete.put(groupName, currGroup.getName());
}
if (!MessageDialog
+ "This might lead to inconsistencies in the application."))
return null;
- for (String groupName : toDelete.keySet()) {
- }
- MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
- "Unimplemented method",
- "The effective deletion is not yet implemented");
- // TODO refresh?
- // JcrUsersView view = (JcrUsersView) HandlerUtil
- // .getActiveWorkbenchWindow(event).getActivePage()
- // .findView(JcrUsersView.ID);
- // view.refresh();
+ UiAdminUtils.beginTransactionIfNeeded(userTransaction);
+ for (String name : toDelete.values())
+ userAdmin.removeRole(name);
+
+ // TODO rather notify the update listener
+ forceRefresh(event);
return null;
}
- // public void setUserAdmin(UserAdmin userAdmin) {
- // this.userAdmin = userAdmin;
- // }
+ private void forceRefresh(ExecutionEvent event) {
+ IWorkbenchWindow iww = HandlerUtil.getActiveWorkbenchWindow(event);
+ if (iww == null)
+ return;
+ IWorkbenchPage activePage = iww.getActivePage();
+ IWorkbenchPart part = activePage.getActivePart();
+ if (part instanceof GroupsView)
+ ((GroupsView) part).refresh();
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setUserAdmin(UserAdmin userAdmin) {
+ this.userAdmin = userAdmin;
+ }
+
+ public void setUserTransaction(UserTransaction userTransaction) {
+ this.userTransaction = userTransaction;
+ }
}
\ No newline at end of file
import java.util.Map;
import java.util.TreeMap;
+import javax.transaction.UserTransaction;
+
import org.argeo.security.ui.admin.SecurityAdminPlugin;
import org.argeo.security.ui.admin.internal.UiAdminUtils;
+import org.argeo.security.ui.admin.views.UsersView;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
/** Deletes the selected users */
public class DeleteUsers extends AbstractHandler {
- public final static String ID = SecurityAdminPlugin.PLUGIN_ID + ".deleteUsers";
+ public final static String ID = SecurityAdminPlugin.PLUGIN_ID
+ + ".deleteUsers";
+
+ /* DEPENDENCY INJECTION */
+ private UserAdmin userAdmin;
+ private UserTransaction userTransaction;
@SuppressWarnings("unchecked")
public Object execute(ExecutionEvent event) throws ExecutionException {
if (selection.isEmpty())
return null;
- Map<String, User> toDelete = new TreeMap<String, User>();
+ Map<String, String> toDelete = new TreeMap<String, String>();
+ // Map<String, User> toDelete = new TreeMap<String, User>();
Iterator<User> it = ((IStructuredSelection) selection).iterator();
users: while (it.hasNext()) {
User currUser = it.next();
String userName = UiAdminUtils.getUsername(currUser);
- // check not deleting own user
+ // TODO check not deleting own user
// if (userName.equals(profileNode.getSession().getUserID())) {
// log.warn("Cannot delete its own user: " + userName);
// continue nodes;
// }
- toDelete.put(userName, currUser);
+ toDelete.put(userName, currUser.getName());
}
if (!MessageDialog
+ "This might lead to inconsistencies in the application."))
return null;
- for (String username : toDelete.keySet()) {
- // TODO perform real deletion
+ UiAdminUtils.beginTransactionIfNeeded(userTransaction);
+ for (String name : toDelete.values()) {
+ userAdmin.removeRole(name);
}
- MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
- "Unimplemented method",
- "The effective deletion is not yet implemented");
- // TODO refresh?
- // JcrUsersView view = (JcrUsersView) HandlerUtil
- // .getActiveWorkbenchWindow(event).getActivePage()
- // .findView(JcrUsersView.ID);
- // view.refresh();
+
+ // TODO rather notify the update listener
+ forceRefresh(event);
return null;
}
+
+ private void forceRefresh(ExecutionEvent event) {
+ IWorkbenchWindow iww = HandlerUtil.getActiveWorkbenchWindow(event);
+ if (iww == null)
+ return;
+ IWorkbenchPage activePage = iww.getActivePage();
+ IWorkbenchPart part = activePage.getActivePart();
+ if (part instanceof UsersView)
+ ((UsersView) part).refresh();
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setUserAdmin(UserAdmin userAdmin) {
+ this.userAdmin = userAdmin;
+ }
+
+ public void setUserTransaction(UserTransaction userTransaction) {
+ this.userTransaction = userTransaction;
+ }
}
\ No newline at end of file
import java.util.Dictionary;
-import javax.transaction.Status;
import javax.transaction.UserTransaction;
-import org.argeo.ArgeoException;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.argeo.jcr.ArgeoNames;
if (!canFinish())
return false;
String commonName = commonNameTxt.getText();
-
- // Begin transaction if needed
- try {
- if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION)
- userTransaction.begin();
- } catch (Exception e) {
- throw new ArgeoException("Unable to start "
- + "transaction to create user " + commonName, e);
- }
-
try {
+ UiAdminUtils.beginTransactionIfNeeded(userTransaction);
Group user = (Group) userAdmin.createRole(getDn(commonName),
Role.GROUP);
Dictionary props = user.getProperties();
import java.util.Dictionary;
-import javax.transaction.Status;
import javax.transaction.UserTransaction;
-import org.argeo.ArgeoException;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.argeo.jcr.ArgeoNames;
if (!canFinish())
return false;
String username = mainUserInfo.getUsername();
-
- // Begin transaction if needed
- try {
- if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION)
- userTransaction.begin();
- } catch (Exception e) {
- throw new ArgeoException("Unable to start "
- + "transaction to create user " + username, e);
- }
-
try {
+ UiAdminUtils.beginTransactionIfNeeded(userTransaction);
char[] password = mainUserInfo.getPassword();
User user = (User) userAdmin.createRole(getDn(username),
Role.USER);
import org.argeo.security.ui.admin.internal.UserNameLP;
import org.argeo.security.ui.admin.internal.UserTableDefaultDClickListener;
import org.argeo.security.ui.admin.internal.UserTableViewer;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.AbstractFormPart;
import org.eclipse.ui.forms.IManagedForm;
private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
public void createMemberPart(Composite parent) {
- // parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
- // parent2.setLayoutData(EclipseUiUtils.fillAll());
- // Composite parent = new Composite(parent2, SWT.NO_FOCUS);
- // parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
- // parent.setLayoutData(EclipseUiUtils.fillAll());
-
parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
// Define the displayed columns
columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24));
userViewer.addDoubleClickListener(new UserTableDefaultDClickListener());
// Really?
userTableViewerCmp.refresh();
+
+ // Drag and drop
+ int operations = DND.DROP_COPY | DND.DROP_MOVE;
+ Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
+ userViewer.addDropSupport(operations, tt, new GroupDropListener(
+ userViewer, userAdmin, (Group) editor.getDisplayedUser()));
}
private class MyUserTableViewer extends UserTableViewer {
editor.getProperty(UserAdminConstants.KEY_CN));
}
+ /**
+ * Defines this table as being a potential target to add group membership
+ * (roles) to this user
+ */
+ private class GroupDropListener extends ViewerDropAdapter {
+ private static final long serialVersionUID = 2893468717831451621L;
+
+ private final UserAdmin myUserAdmin;
+ private final Group myGroup;
+
+ public GroupDropListener(Viewer viewer, UserAdmin userAdmin, Group group) {
+ super(viewer);
+ this.myUserAdmin = userAdmin;
+ this.myGroup = group;
+ }
+
+ @Override
+ public boolean validateDrop(Object target, int operation,
+ TransferData transferType) {
+ // Target is always OK in a list only view
+ // TODO check if not a string
+ boolean validDrop = true;
+ return validDrop;
+ }
+
+ @Override
+ public void drop(DropTargetEvent event) {
+ String newUserName = (String) event.data;
+ Role role = myUserAdmin.getRole(newUserName);
+ // TODO this check should be done before.
+ if (role.getType() == Role.USER) {
+ // TODO check if the user is already member of this group
+ // we expect here that there is already a begun transaction
+ // TODO implement the dirty state
+ editor.beginTransactionIfNeeded();
+ User user = (User) role;
+ myGroup.addMember(user);
+ } else if (role.getType() == Role.GROUP) {
+ Group newGroup = (Group) role;
+
+ Shell shell = getViewer().getControl().getShell();
+ // Sanity checks
+ if (myGroup == newGroup) { // Equality
+
+ MessageDialog.openError(shell, "Forbidden addition ",
+ "A group cannot be a member of itself.");
+ return;
+ }
+
+ // Cycle
+ String myName = myGroup.getName();
+ List<User> myMemberships = editor.getFlatGroups(myGroup);
+ if (myMemberships.contains(newGroup)) {
+ MessageDialog.openError(shell, "Forbidden addition: cycle",
+ "Cannot add " + newUserName + " to group " + myName
+ + ". This would create a cycle");
+ return;
+ }
+
+ // Already member
+ List<User> newGroupMemberships = editor.getFlatGroups(newGroup);
+ if (newGroupMemberships.contains(myGroup)) {
+ MessageDialog.openError(shell, "Forbidden addition",
+ "Cannot add " + newUserName + " to group " + myName
+ + ", this membership already exists");
+ return;
+ }
+
+ editor.beginTransactionIfNeeded();
+ // TODO implement the dirty state
+ myGroup.addMember(newGroup);
+ }
+ super.drop(event);
+ }
+
+ @Override
+ public boolean performDrop(Object data) {
+ userTableViewerCmp.refresh();
+ return true;
+ }
+ }
+
+ // LOCAL HELPERS
private Composite addSection(FormToolkit tk, Composite parent, String title) {
Section section = tk.createSection(parent, Section.TITLE_BAR);
GridData gd = EclipseUiUtils.fillWidth();
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
return text;
}
-
- // private class FormPartML implements ModifyListener {
- // private static final long serialVersionUID = 6299808129505381333L;
- // private AbstractFormPart formPart;
- //
- // public FormPartML(AbstractFormPart generalPart) {
- // this.formPart = generalPart;
- // }
- //
- // public void modifyText(ModifyEvent e) {
- // formPart.markDirty();
- // }
- // }
}
\ No newline at end of file
import javax.transaction.UserTransaction;
import org.argeo.ArgeoException;
-import org.argeo.security.ui.admin.SecurityAdminImages;
import org.argeo.security.ui.admin.SecurityAdminPlugin;
+import org.argeo.security.ui.admin.internal.UiAdminUtils;
import org.argeo.security.ui.admin.internal.UserAdminConstants;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.ui.IEditorInput;
user = (User) userAdmin.getRole(username);
String commonName = getProperty(KEY_CN);
- // this.setPartProperty("name", commonName != null ? commonName
- // : "username");
- // if (user.getType() == Role.GROUP) {
- // this.setPartProperty("icon", "icons/users.gif");
- // firePartPropertyChanged("icon", "icons/user.gif", "icons/users.gif");
- // }
setPartName(commonName != null ? commonName : "username");
- setTitleImage(user.getType() == Role.GROUP ? SecurityAdminImages.ICON_GROUP
- : SecurityAdminImages.ICON_USER);
+
+ // TODO: following has been disabled because it causes NPE after a
+ // login/logout on RAP
+ // Image titleIcon = user.getType() == Role.GROUP ?
+ // SecurityAdminImages.ICON_GROUP
+ // : SecurityAdminImages.ICON_USER;
+ // setTitleImage(titleIcon);
}
- protected List<User> getFlatGroups() {
- Authorization currAuth = userAdmin.getAuthorization(user);
+ /**
+ * returns the list of all authorisation for the given user or of the
+ * current displayed user if parameter is null
+ */
+ protected List<User> getFlatGroups(User aUser) {
+ Authorization currAuth;
+ if (aUser == null)
+ currAuth = userAdmin.getAuthorization(this.user);
+ else
+ currAuth = userAdmin.getAuthorization(aUser);
+
String[] roles = currAuth.getRoles();
List<User> groups = new ArrayList<User>();
return "";
}
- /** The property is directly updated!!! */
+ protected void beginTransactionIfNeeded() {
+ UiAdminUtils.beginTransactionIfNeeded(userTransaction);
+ }
+
+ /**
+ * Updates the property in the working copy. The transaction must be
+ * explicitly committed to persist the update.
+ */
@SuppressWarnings("unchecked")
protected void setProperty(String key, String value) {
user.getProperties().put(key, value);
// Drag and drop
int operations = DND.DROP_COPY | DND.DROP_MOVE;
Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
- userViewer.addDropSupport(operations, tt, new ItemDropListener(
+ userViewer.addDropSupport(operations, tt, new GroupDropListener(
userViewer, userAdmin, editor.getDisplayedUser()));
}
@Override
protected List<User> listFilteredElements(String filter) {
- return (List<User>) editor.getFlatGroups();
+ return (List<User>) editor.getFlatGroups(null);
}
}
- // DRAG & DROP MANAGEMENT
-
- private class ItemDropListener extends ViewerDropAdapter {
+ /**
+ * Defines this table as being a potential target to add group membership
+ * (roles) to this user
+ */
+ private class GroupDropListener extends ViewerDropAdapter {
private static final long serialVersionUID = 2893468717831451621L;
private final UserAdmin myUserAdmin;
private final User myUser;
- public ItemDropListener(Viewer viewer, UserAdmin userAdmin, User user) {
+ public GroupDropListener(Viewer viewer, UserAdmin userAdmin, User user) {
super(viewer);
this.myUserAdmin = userAdmin;
this.myUser = user;
// TODO check if the user is already member of this group
// we expect here that there is already a begun transaction
// TODO implement the dirty state
+ editor.beginTransactionIfNeeded();
Group group = (Group) role;
group.addMember(myUser);
}
import javax.security.auth.Subject;
import javax.security.auth.x500.X500Principal;
+import javax.transaction.Status;
+import javax.transaction.UserTransaction;
+import org.argeo.ArgeoException;
import org.osgi.service.useradmin.Role;
import org.osgi.service.useradmin.User;
return (firstName.trim() + " " + lastName.trim() + " ").trim();
}
+ public final static void beginTransactionIfNeeded(
+ UserTransaction userTransaction) {
+ try {
+ if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION)
+ userTransaction.begin();
+ } catch (Exception e) {
+ throw new ArgeoException("Unable to begin transaction", e);
+ }
+ }
+
/*
* INTERNAL METHODS: Below methods are meant to stay here and are not part
* of a potential generic backend to manage the useradmin
import org.argeo.ArgeoException;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.jcr.ArgeoNames;
+import org.argeo.security.ui.admin.SecurityAdminImages;
import org.argeo.security.ui.admin.SecurityAdminPlugin;
import org.argeo.security.ui.admin.internal.ColumnDefinition;
import org.argeo.security.ui.admin.internal.CommonNameLP;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
import org.osgi.framework.InvalidSyntaxException;
@Override
public void createPartControl(Composite parent) {
+
parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
// Define the displayed columns
columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name",
Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
userViewer.addDragSupport(operations, tt, new UserDragListener(
userViewer));
+
+ // FIXME insure the group and person icons are registered before calling
+ // the open editor
+ @SuppressWarnings("unused")
+ Image dummyImg = SecurityAdminImages.ICON_GROUP;
+ dummyImg = SecurityAdminImages.ICON_USER;
}
private class MyUserTableViewer extends UserTableViewer {