X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=swt%2Forg.argeo.tool.devops.e4%2Fsrc%2Forg%2Fargeo%2Fcms%2Fe4%2Fusers%2FUserEditor.java;fp=swt%2Forg.argeo.tool.devops.e4%2Fsrc%2Forg%2Fargeo%2Fcms%2Fe4%2Fusers%2FUserEditor.java;h=bcc976675cd30d14d090fca906afae6243b0d1dd;hb=825d60c5348dbe3f5be25b0bccf7bdebfe694219;hp=0000000000000000000000000000000000000000;hpb=5e991fff5cba01858dcc5747a27e637325bc5c8e;p=gpl%2Fargeo-jcr.git diff --git a/swt/org.argeo.tool.devops.e4/src/org/argeo/cms/e4/users/UserEditor.java b/swt/org.argeo.tool.devops.e4/src/org/argeo/cms/e4/users/UserEditor.java new file mode 100644 index 0000000..bcc9766 --- /dev/null +++ b/swt/org.argeo.tool.devops.e4/src/org/argeo/cms/e4/users/UserEditor.java @@ -0,0 +1,535 @@ +package org.argeo.cms.e4.users; + +import static org.argeo.api.acr.ldap.LdapAttr.cn; +import static org.argeo.api.acr.ldap.LdapAttr.givenName; +import static org.argeo.api.acr.ldap.LdapAttr.mail; +import static org.argeo.api.acr.ldap.LdapAttr.sn; +import static org.argeo.api.acr.ldap.LdapAttr.uid; +import static org.argeo.cms.auth.UserAdminUtils.getProperty; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import jakarta.inject.Inject; + +import org.argeo.api.acr.ldap.LdapAttr; +import org.argeo.api.cms.CmsConstants; +import org.argeo.cms.CurrentUser; +import org.argeo.cms.auth.UserAdminUtils; +import org.argeo.cms.e4.users.providers.CommonNameLP; +import org.argeo.cms.e4.users.providers.DomainNameLP; +import org.argeo.cms.e4.users.providers.RoleIconLP; +import org.argeo.cms.e4.users.providers.UserFilter; +import org.argeo.cms.swt.CmsSwtUtils; +import org.argeo.cms.swt.useradmin.LdifUsersTable; +import org.argeo.cms.ui.eclipse.forms.AbstractFormPart; +//import org.argeo.cms.ui.eclipse.forms.FormToolkit; +import org.argeo.cms.ui.eclipse.forms.IManagedForm; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.TrayDialog; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +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.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolBar; +import org.osgi.service.useradmin.Group; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; +import org.osgi.service.useradmin.UserAdminEvent; + +/** Display/edit the properties of a given user */ +public class UserEditor extends AbstractRoleEditor { + // final static String ID = "UserEditor.mainPage"; + + @Inject + private EPartService partService; + + // private final UserEditor editor; + // private UserAdminWrapper userAdminWrapper; + + // Local configuration + // private final int PRE_TITLE_INDENT = 10; + + // public UserMainPage(FormEditor editor, UserAdminWrapper userAdminWrapper) { + // super(editor, ID, "Main"); + // this.editor = (UserEditor) editor; + // this.userAdminWrapper = userAdminWrapper; + // } + + // protected void createFormContent(final IManagedForm mf) { + // ScrolledForm form = mf.getForm(); + // Composite body = form.getBody(); + // GridLayout mainLayout = new GridLayout(); + // // mainLayout.marginRight = 10; + // body.setLayout(mainLayout); + // User user = editor.getDisplayedUser(); + // appendOverviewPart(body, user); + // // Remove to ability to force the password for his own user. The user + // // must then use the change pwd feature + // appendMemberOfPart(body, user); + // } + + @Override + protected void createUi(Composite body) { + // Composite body = new Composite(parent, SWT.BORDER); + GridLayout mainLayout = new GridLayout(); + // mainLayout.marginRight = 10; + body.setLayout(mainLayout); + // body.getParent().setLayout(new GridLayout()); + // body.setLayoutData(CmsUiUtils.fillAll()); + User user = getDisplayedUser(); + appendOverviewPart(body, user); + // Remove to ability to force the password for his own user. The user + // must then use the change pwd feature + appendMemberOfPart(body, user); + } + + /** Creates the general section */ + private void appendOverviewPart(final Composite parent, final User user) { + // FormToolkit tk = getManagedForm().getToolkit(); + + // Section section = tk.createSection(parent, SWT.NO_FOCUS); + // GridData gd = EclipseUiUtils.fillWidth(); + // // gd.verticalAlignment = PRE_TITLE_INDENT; + // section.setLayoutData(gd); + Composite body = new Composite(parent, SWT.NONE); + body.setLayoutData(EclipseUiUtils.fillWidth()); + // section.setClient(body); + // body.setLayout(new GridLayout(6, false)); + body.setLayout(new GridLayout(2, false)); + + Text commonName = createReadOnlyLT(body, "Name", getProperty(user, cn)); + Text distinguishedName = createReadOnlyLT(body, "Login", getProperty(user, uid)); + Text firstName = createLT(body, "First name", getProperty(user, givenName)); + Text lastName = createLT(body, "Last name", getProperty(user, sn)); + Text email = createLT(body, "Email", getProperty(user, mail)); + + Link resetPwdLk = new Link(body, SWT.NONE); + if (!UserAdminUtils.isCurrentUser(user)) { + resetPwdLk.setText("Reset password"); + } + resetPwdLk.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); + + // create form part (controller) + AbstractFormPart part = new AbstractFormPart() { + private MainInfoListener listener; + + @Override + public void initialize(IManagedForm form) { + super.initialize(form); + listener = new MainInfoListener(parent.getDisplay(), this); + userAdminWrapper.addListener(listener); + } + + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + @SuppressWarnings("unchecked") + public void commit(boolean onSave) { + // TODO Sanity checks (mail validity...) + user.getProperties().put(LdapAttr.givenName.name(), firstName.getText()); + user.getProperties().put(LdapAttr.sn.name(), lastName.getText()); + user.getProperties().put(LdapAttr.cn.name(), commonName.getText()); + user.getProperties().put(LdapAttr.mail.name(), email.getText()); + super.commit(onSave); + } + + @Override + public void refresh() { + distinguishedName.setText(UserAdminUtils.getProperty(user, LdapAttr.uid.name())); + commonName.setText(UserAdminUtils.getProperty(user, LdapAttr.cn.name())); + firstName.setText(UserAdminUtils.getProperty(user, LdapAttr.givenName.name())); + lastName.setText(UserAdminUtils.getProperty(user, LdapAttr.sn.name())); + email.setText(UserAdminUtils.getProperty(user, LdapAttr.mail.name())); + refreshFormTitle(user); + super.refresh(); + } + }; + + // Improve this: automatically generate CN when first or last name + // changes + ModifyListener cnML = new ModifyListener() { + private static final long serialVersionUID = 4298649222869835486L; + + @Override + public void modifyText(ModifyEvent event) { + String first = firstName.getText(); + String last = lastName.getText(); + String cn = first.trim() + " " + last.trim() + " "; + cn = cn.trim(); + commonName.setText(cn); + // getManagedForm().getForm().setText(cn); + updateEditorTitle(cn); + } + }; + firstName.addModifyListener(cnML); + lastName.addModifyListener(cnML); + + ModifyListener defaultListener = new FormPartML(part); + firstName.addModifyListener(defaultListener); + lastName.addModifyListener(defaultListener); + email.addModifyListener(defaultListener); + + if (!UserAdminUtils.isCurrentUser(user)) + resetPwdLk.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 5881800534589073787L; + + @Override + public void widgetSelected(SelectionEvent e) { + new ChangePasswordDialog(user, "Reset password").open(); + } + }); + + getManagedForm().addPart(part); + } + + private class ChangePasswordDialog extends TrayDialog { + private static final long serialVersionUID = 2843538207460082349L; + + private User user; + private Text password1; + private Text password2; + private String title; + // private FormToolkit tk; + + public ChangePasswordDialog(User user, String title) { + super(Display.getDefault().getActiveShell()); + // this.tk = tk; + this.user = user; + this.title = title; + } + + protected Control createDialogArea(Composite parent) { + Composite dialogarea = (Composite) super.createDialogArea(parent); + dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + Composite body = new Composite(dialogarea, SWT.NO_FOCUS); + body.setLayoutData(EclipseUiUtils.fillAll()); + GridLayout layout = new GridLayout(2, false); + body.setLayout(layout); + + password1 = createLP(body, "New password", ""); + password2 = createLP(body, "Repeat password", ""); + parent.pack(); + return body; + } + + @SuppressWarnings("unchecked") + @Override + protected void okPressed() { + String msg = null; + + if (password1.getText().equals("")) + msg = "Password cannot be empty"; + else if (password1.getText().equals(password2.getText())) { + char[] newPassword = password1.getText().toCharArray(); + // userAdminWrapper.beginTransactionIfNeeded(); + userAdminWrapper.beginTransactionIfNeeded(); + user.getCredentials().put(null, newPassword); + userAdminWrapper.commitOrNotifyTransactionStateChange(); + super.okPressed(); + } else { + msg = "Passwords are not equals"; + } + + if (EclipseUiUtils.notEmpty(msg)) + MessageDialog.openError(getParentShell(), "Cannot reset pasword", msg); + } + + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText(title); + } + } + + private LdifUsersTable appendMemberOfPart(final Composite parent, User user) { + // Section section = addSection(tk, parent, "Roles"); + // Composite body = (Composite) section.getClient(); + // Composite body= parent; + Composite body = new Composite(parent, SWT.BORDER); + body.setLayout(new GridLayout()); + body.setLayoutData(CmsSwtUtils.fillAll()); + + // boolean isAdmin = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN); + + // Displayed columns + List columnDefs = new ArrayList(); + columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24)); + columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Name", 150)); + columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 100)); + // Only show technical DN to administrators + // if (isAdmin) + // columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", + // 300)); + + // Create and configure the table + final LdifUsersTable userViewerCmp = new MyUserTableViewer(body, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, user); + + userViewerCmp.setColumnDefinitions(columnDefs); + // if (isAdmin) + // userViewerCmp.populateWithStaticFilters(false, false); + // else + userViewerCmp.populate(true, false); + GridData gd = EclipseUiUtils.fillAll(); + gd.heightHint = 500; + userViewerCmp.setLayoutData(gd); + + // Controllers + TableViewer userViewer = userViewerCmp.getTableViewer(); + userViewer.addDoubleClickListener(new UserTableDefaultDClickListener(partService)); + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; + GroupDropListener dropL = new GroupDropListener(userAdminWrapper, userViewer, user); + userViewer.addDropSupport(operations, tt, dropL); + + AbstractFormPart part = new AbstractFormPart() { + + private GroupChangeListener listener; + + @Override + public void initialize(IManagedForm form) { + super.initialize(form); + listener = new GroupChangeListener(parent.getDisplay(), this); + userAdminWrapper.addListener(listener); + } + + public void commit(boolean onSave) { + super.commit(onSave); + } + + @Override + public void dispose() { + userAdminWrapper.removeListener(listener); + super.dispose(); + } + + @Override + public void refresh() { + userViewerCmp.refresh(); + super.refresh(); + } + }; + getManagedForm().addPart(part); + // addRemoveAbitily(body, userViewer, user); + // userViewerCmp.refresh(); + String tooltip = "Remove " + UserAdminUtils.getUserLocalId(user.getName()) + " from the below selected groups"; + Action action = new RemoveMembershipAction(userViewer, user, tooltip, SecurityAdminImages.ICON_REMOVE_DESC); + ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); + ToolBar toolBar = toolBarManager.createControl(body); + toolBar.setLayoutData(CmsSwtUtils.fillWidth()); + toolBarManager.add(action); + toolBarManager.update(true); + return userViewerCmp; + } + + private class MyUserTableViewer extends LdifUsersTable { + private static final long serialVersionUID = 2653790051461237329L; + + private Button showSystemRoleBtn; + + private final User user; + private final UserFilter userFilter; + + public MyUserTableViewer(Composite parent, int style, User user) { + super(parent, style, true); + this.user = user; + userFilter = new UserFilter(); + } + + protected void populateStaticFilters(Composite staticFilterCmp) { + staticFilterCmp.setLayout(new GridLayout()); + showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK); + showSystemRoleBtn.setText("Show system roles"); + boolean showSysRole = CurrentUser.isInRole(CmsConstants.ROLE_ADMIN); + showSystemRoleBtn.setSelection(showSysRole); + userFilter.setShowSystemRole(showSysRole); + showSystemRoleBtn.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = -7033424592697691676L; + + @Override + public void widgetSelected(SelectionEvent e) { + userFilter.setShowSystemRole(showSystemRoleBtn.getSelection()); + refresh(); + } + }); + } + + @Override + protected List listFilteredElements(String filter) { + List users = (List) getFlatGroups(null); + List filteredUsers = new ArrayList(); + if (users.contains(user)) + users.remove(user); + userFilter.setSearchText(filter); + for (User user : users) + if (userFilter.select(null, null, user)) + filteredUsers.add(user); + return filteredUsers; + } + } + + // private void addRemoveAbility(Composite parent, TableViewer userViewer, User + // user) { + // // Section section = sectionPart.getSection(); + // ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); + // ToolBar toolbar = toolBarManager.createControl(parent); + // final Cursor handCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND); + // toolbar.setCursor(handCursor); + // toolbar.addDisposeListener(new DisposeListener() { + // private static final long serialVersionUID = 3882131405820522925L; + // + // public void widgetDisposed(DisposeEvent e) { + // if ((handCursor != null) && (handCursor.isDisposed() == false)) { + // handCursor.dispose(); + // } + // } + // }); + // + // String tooltip = "Remove " + UserAdminUtils.getUserLocalId(user.getName()) + + // " from the below selected groups"; + // Action action = new RemoveMembershipAction(userViewer, user, tooltip, + // SecurityAdminImages.ICON_REMOVE_DESC); + // toolBarManager.add(action); + // toolBarManager.update(true); + // // section.setTextClient(toolbar); + // } + + private class RemoveMembershipAction extends Action { + private static final long serialVersionUID = -1337713097184522588L; + + private final TableViewer userViewer; + private final User user; + + RemoveMembershipAction(TableViewer userViewer, User user, String name, ImageDescriptor img) { + super(name, img); + this.userViewer = userViewer; + this.user = user; + } + + @Override + public void run() { + ISelection selection = userViewer.getSelection(); + if (selection.isEmpty()) + return; + + @SuppressWarnings("unchecked") + Iterator it = ((IStructuredSelection) selection).iterator(); + List groups = new ArrayList(); + while (it.hasNext()) { + Group currGroup = it.next(); + groups.add(currGroup); + } + + userAdminWrapper.beginTransactionIfNeeded(); + for (Group group : groups) { + group.removeMember(user); + } + userAdminWrapper.commitOrNotifyTransactionStateChange(); + for (Group group : groups) { + userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, group)); + } + } + } + + /** + * Defines the table as being a potential target to add group memberships + * (roles) to this user + */ + private class GroupDropListener extends ViewerDropAdapter { + private static final long serialVersionUID = 2893468717831451621L; + + private final UserAdminWrapper myUserAdminWrapper; + private final User myUser; + + public GroupDropListener(UserAdminWrapper userAdminWrapper, Viewer userViewer, User user) { + super(userViewer); + this.myUserAdminWrapper = userAdminWrapper; + this.myUser = user; + } + + @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 name = (String) event.data; + UserAdmin myUserAdmin = myUserAdminWrapper.getUserAdmin(); + Role role = myUserAdmin.getRole(name); + // TODO this check should be done before. + if (role.getType() == Role.GROUP) { + // TODO check if the user is already member of this group + + myUserAdminWrapper.beginTransactionIfNeeded(); + Group group = (Group) role; + group.addMember(myUser); + userAdminWrapper.commitOrNotifyTransactionStateChange(); + myUserAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, group)); + } + super.drop(event); + } + + @Override + public boolean performDrop(Object data) { + // userTableViewerCmp.refresh(); + return true; + } + } + + // LOCAL HELPERS + private void refreshFormTitle(User group) { + // getManagedForm().getForm().setText(UserAdminUtils.getProperty(group, + // LdapAttrs.cn.name())); + } + + /** Appends a section with a title */ + // private Section addSection(FormToolkit tk, Composite parent, String title) { + // Section section = tk.createSection(parent, Section.TITLE_BAR); + // GridData gd = EclipseUiUtils.fillWidth(); + // gd.verticalAlignment = PRE_TITLE_INDENT; + // section.setLayoutData(gd); + // section.setText(title); + // // section.getMenu().setVisible(true); + // + // Composite body = tk.createComposite(section, SWT.WRAP); + // body.setLayoutData(EclipseUiUtils.fillAll()); + // section.setClient(body); + // + // return section; + // } + +}