From b32a7ed960be8dbaa50e605a409c14402db5b489 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Wed, 21 Sep 2022 07:52:25 +0200 Subject: [PATCH] Create new user as a POSIX account --- .../src/org/argeo/app/api/IdRange.java | 60 +++++++ .../src/org/argeo/app/core/SuiteUtils.java | 38 +++- .../OSGI-INF/l10n/bundle.properties | 3 + .../OSGI-INF/l10n/bundle_fr.properties | 3 + org.argeo.app.ui/OSGI-INF/peopleLayer.xml | 2 +- .../org/argeo/app/ui/DefaultEditionLayer.java | 10 ++ .../src/org/argeo/app/ui/SuiteApp.java | 51 +++--- .../src/org/argeo/app/ui/SuiteLayer.java | 4 +- .../src/org/argeo/app/ui/SuiteMsg.java | 6 +- .../src/org/argeo/app/ui/SuiteUi.java | 3 +- .../argeo/app/ui/dialogs/NewUserWizard.java | 150 ---------------- .../org/argeo/app/ui/people/NewUserForm.java | 162 ++++++++++++++++++ .../argeo/app/ui/people/PeopleEntryArea.java | 8 +- 13 files changed, 316 insertions(+), 184 deletions(-) create mode 100644 org.argeo.app.api/src/org/argeo/app/api/IdRange.java delete mode 100644 org.argeo.app.ui/src/org/argeo/app/ui/dialogs/NewUserWizard.java create mode 100644 org.argeo.app.ui/src/org/argeo/app/ui/people/NewUserForm.java diff --git a/org.argeo.app.api/src/org/argeo/app/api/IdRange.java b/org.argeo.app.api/src/org/argeo/app/api/IdRange.java new file mode 100644 index 0000000..d96c789 --- /dev/null +++ b/org.argeo.app.api/src/org/argeo/app/api/IdRange.java @@ -0,0 +1,60 @@ +package org.argeo.app.api; + +/** A range of numerical IDs (typically numerical uid or gid). */ +public class IdRange { + + private final long min; + private final long max; + + public IdRange(long min, long max) { + this.min = min; + this.max = max; + } + + public IdRange(long minPow10) { + this(minPow10, maxFromMinPow10(minPow10)); + } + + public long getMin() { + return min; + } + + public long getMax() { + return max; + } + + private static long maxFromMinPow10(long minPow10) { + if ((minPow10 % 100) != 0) { + throw new IllegalArgumentException(minPow10 + " must at least ends with two zeroes"); + } + int exp = 2; + exp: for (int i = exp + 1; i < 10; i++) { + if ((minPow10 % pow10(i)) != 0) + break exp; + exp++; + } + System.out.println(exp); + + long max = minPow10 + pow10(exp) - 1; + return max; + } + + /** Power of 10. */ + private static long pow10(int exp) { + if (exp == 0) + return 1; + else + return 10 * pow10(exp - 1); + } + + public static void main(String... args) { + System.out.println(maxFromMinPow10(100)); + System.out.println(maxFromMinPow10(78500)); + System.out.println(maxFromMinPow10(716850000)); + +// System.out.println(pow10(6)); +// System.out.println(maxFromMinPow10(12)); +// System.out.println(maxFromMinPow10(124)); +// System.out.println(maxFromMinPow10(99814565)); + } +} diff --git a/org.argeo.app.core/src/org/argeo/app/core/SuiteUtils.java b/org.argeo.app.core/src/org/argeo/app/core/SuiteUtils.java index 6b63cdb..531d3a3 100644 --- a/org.argeo.app.core/src/org/argeo/app/core/SuiteUtils.java +++ b/org.argeo.app.core/src/org/argeo/app/core/SuiteUtils.java @@ -1,6 +1,7 @@ package org.argeo.app.core; import java.util.HashSet; +import java.util.Optional; import java.util.Set; import javax.jcr.Node; @@ -9,7 +10,9 @@ import javax.jcr.Session; import javax.jcr.nodetype.NodeType; import javax.jcr.security.Privilege; import javax.security.auth.x500.X500Principal; +import javax.xml.namespace.QName; +import org.argeo.api.acr.Content; import org.argeo.api.cms.CmsConstants; import org.argeo.api.cms.CmsSession; import org.argeo.app.api.EntityType; @@ -17,6 +20,7 @@ import org.argeo.cms.auth.RoleNameUtils; import org.argeo.jcr.JcrException; import org.argeo.jcr.JcrUtils; import org.argeo.util.naming.LdapAttrs; +import org.argeo.util.naming.LdapObjs; /** Utilities around the Argeo Suite APIs. */ public class SuiteUtils { @@ -96,11 +100,6 @@ public class SuiteUtils { } } - /** Singleton. */ - private SuiteUtils() { - - } - public static Set extractRoles(String[] semiColArr) { Set res = new HashSet<>(); // TODO factorize and make it more robust @@ -121,4 +120,33 @@ public class SuiteUtils { return res; } + synchronized static public long findNextId(Content hierarchyUnit, QName cclass) { + if (!hierarchyUnit.hasContentClass(LdapObjs.posixGroup.qName())) + throw new IllegalArgumentException(hierarchyUnit + " is not a POSIX group"); + + long min = hierarchyUnit.get(LdapAttrs.gidNumber.qName(), Long.class).orElseThrow(); + long currentMax = 0l; + for (Content childHu : hierarchyUnit) { + if (!childHu.hasContentClass(LdapObjs.organizationalUnit.qName())) + continue; + // FIXME filter out functional hierarchy unit + for (Content role : childHu) { + if (role.hasContentClass(cclass)) { + + if (LdapObjs.posixAccount.qName().equals(cclass)) { + Long id = role.get(LdapAttrs.uidNumber.qName(), Long.class).orElseThrow(); + if (id > currentMax) + currentMax = id; + } + } + } + } + if (currentMax == 0l) + return min; + return currentMax + 1; + } + + /** Singleton. */ + private SuiteUtils() { + } } diff --git a/org.argeo.app.ui/OSGI-INF/l10n/bundle.properties b/org.argeo.app.ui/OSGI-INF/l10n/bundle.properties index 8b76a47..0dd3532 100644 --- a/org.argeo.app.ui/OSGI-INF/l10n/bundle.properties +++ b/org.argeo.app.ui/OSGI-INF/l10n/bundle.properties @@ -106,3 +106,6 @@ content=content # Geo map=map +# Feedback messages +allFieldsMustBeSet=All fields must be set + diff --git a/org.argeo.app.ui/OSGI-INF/l10n/bundle_fr.properties b/org.argeo.app.ui/OSGI-INF/l10n/bundle_fr.properties index 225e5fd..3a9ad4d 100644 --- a/org.argeo.app.ui/OSGI-INF/l10n/bundle_fr.properties +++ b/org.argeo.app.ui/OSGI-INF/l10n/bundle_fr.properties @@ -100,3 +100,6 @@ pickUp=Choisir # Tags confirmNewTag=Le tag #{0} n'existe pas encore. Voulez-vous le créer? cannotCreateTag=Le tag #{0} n'existe pas encore et vous n'avez pas les droits pour le créer. + +# Feedback messages +allFieldsMustBeSet=Toutes les données doivent être renseignées diff --git a/org.argeo.app.ui/OSGI-INF/peopleLayer.xml b/org.argeo.app.ui/OSGI-INF/peopleLayer.xml index 159da12..4715f1c 100644 --- a/org.argeo.app.ui/OSGI-INF/peopleLayer.xml +++ b/org.argeo.app.ui/OSGI-INF/peopleLayer.xml @@ -5,5 +5,5 @@ - + diff --git a/org.argeo.app.ui/src/org/argeo/app/ui/DefaultEditionLayer.java b/org.argeo.app.ui/src/org/argeo/app/ui/DefaultEditionLayer.java index 97bede2..9e399f0 100644 --- a/org.argeo.app.ui/src/org/argeo/app/ui/DefaultEditionLayer.java +++ b/org.argeo.app.ui/src/org/argeo/app/ui/DefaultEditionLayer.java @@ -17,10 +17,12 @@ import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; import org.osgi.framework.wiring.BundleWiring; /** An app layer based on an entry area and an editor area. */ public class DefaultEditionLayer implements SuiteLayer { + private String id; private SwtUiProvider entryArea; private SwtUiProvider defaultView; private SwtUiProvider workArea; @@ -117,7 +119,15 @@ public class DefaultEditionLayer implements SuiteLayer { return title; } + @Override + public String getId() { + return id; + } + public void init(BundleContext bundleContext, Map properties) { + String pid = (String) properties.get(Constants.SERVICE_PID); + id = pid; + weights = LangUtils.toStringList(properties.get(Property.weights.name())); startMaximized = properties.containsKey(Property.startMaximized.name()) && "true".equals(properties.get(Property.startMaximized.name())); diff --git a/org.argeo.app.ui/src/org/argeo/app/ui/SuiteApp.java b/org.argeo.app.ui/src/org/argeo/app/ui/SuiteApp.java index 9ad2673..ef4aaff 100644 --- a/org.argeo.app.ui/src/org/argeo/app/ui/SuiteApp.java +++ b/org.argeo.app.ui/src/org/argeo/app/ui/SuiteApp.java @@ -2,7 +2,6 @@ package org.argeo.app.ui; import static org.argeo.api.cms.ux.CmsView.CMS_VIEW_UID_PROPERTY; -import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -659,27 +658,39 @@ public class SuiteApp extends AbstractCmsApp implements CmsEventSubscriber { } } +// public void addLayer(SuiteLayer layer, Map properties) { +// if (!properties.containsKey(Constants.SERVICE_PID)) +// throw new IllegalArgumentException("A layer must have an ID"); +// String pid = (String) properties.get(Constants.SERVICE_PID); +// List types = properties.containsKey(EntityConstants.TYPE) +// ? LangUtils.toStringList(properties.get(EntityConstants.TYPE)) +// : new ArrayList<>(); +// if (types.isEmpty()) { +// RankedObject.putIfHigherRank(layersByPid, pid, layer, properties); +// } else { +// if (layersByPid.containsKey(pid)) { +// RankedObject current = layersByPid.get(pid); +// List currentTypes = current.getProperties().containsKey(EntityConstants.TYPE) +// ? LangUtils.toStringList(current.getProperties().get(EntityConstants.TYPE)) +// : new ArrayList<>(); +// if (!types.containsAll(currentTypes)) { +// throw new IllegalArgumentException("Higher-ranked layer " + pid + " contains only types " + types +// + ", while it must override all " + currentTypes); +// } +// } +// RankedObject.putIfHigherRank(layersByPid, pid, layer, properties); +// for (String type : types) +// RankedObject.putIfHigherRank(layersByType, type, layer, properties); +// } +// } + public void addLayer(SuiteLayer layer, Map properties) { - if (!properties.containsKey(Constants.SERVICE_PID)) - throw new IllegalArgumentException("A layer must have an ID"); - String pid = (String) properties.get(Constants.SERVICE_PID); - List types = properties.containsKey(EntityConstants.TYPE) - ? LangUtils.toStringList(properties.get(EntityConstants.TYPE)) - : new ArrayList<>(); - if (types.isEmpty()) { - RankedObject.putIfHigherRank(layersByPid, pid, layer, properties); - } else { - if (layersByPid.containsKey(pid)) { - RankedObject current = layersByPid.get(pid); - List currentTypes = current.getProperties().containsKey(EntityConstants.TYPE) - ? LangUtils.toStringList(current.getProperties().get(EntityConstants.TYPE)) - : new ArrayList<>(); - if (!types.containsAll(currentTypes)) { - throw new IllegalArgumentException("Higher-ranked layer " + pid + " contains only types " + types - + ", while it must override all " + currentTypes); - } - } + if (properties.containsKey(Constants.SERVICE_PID)) { + String pid = (String) properties.get(Constants.SERVICE_PID); RankedObject.putIfHigherRank(layersByPid, pid, layer, properties); + } + if (properties.containsKey(EntityConstants.TYPE)) { + List types = LangUtils.toStringList(properties.get(EntityConstants.TYPE)); for (String type : types) RankedObject.putIfHigherRank(layersByType, type, layer, properties); } diff --git a/org.argeo.app.ui/src/org/argeo/app/ui/SuiteLayer.java b/org.argeo.app.ui/src/org/argeo/app/ui/SuiteLayer.java index 1618563..b97230d 100644 --- a/org.argeo.app.ui/src/org/argeo/app/ui/SuiteLayer.java +++ b/org.argeo.app.ui/src/org/argeo/app/ui/SuiteLayer.java @@ -11,8 +11,10 @@ public interface SuiteLayer extends SwtUiProvider { title, icon, weights, startMaximized, singleTab, fixedEntryArea; } + String getId(); + void view(SwtUiProvider uiProvider, Composite workArea, Content context); - + Content getCurrentContext(Composite workArea); default void open(SwtUiProvider uiProvider, Composite workArea, Content context) { diff --git a/org.argeo.app.ui/src/org/argeo/app/ui/SuiteMsg.java b/org.argeo.app.ui/src/org/argeo/app/ui/SuiteMsg.java index fae15df..1162144 100644 --- a/org.argeo.app.ui/src/org/argeo/app/ui/SuiteMsg.java +++ b/org.argeo.app.ui/src/org/argeo/app/ui/SuiteMsg.java @@ -30,5 +30,9 @@ public enum SuiteMsg implements Localized { // Generic label, aCustomLabel, description, value, name, primary, add, save, pickup, // Tag - confirmNewTag, cannotCreateTag; + confirmNewTag, cannotCreateTag, + // Feddback messages + allFieldsMustBeSet, + // + ; } diff --git a/org.argeo.app.ui/src/org/argeo/app/ui/SuiteUi.java b/org.argeo.app.ui/src/org/argeo/app/ui/SuiteUi.java index 2e27d6a..de060df 100644 --- a/org.argeo.app.ui/src/org/argeo/app/ui/SuiteUi.java +++ b/org.argeo.app.ui/src/org/argeo/app/ui/SuiteUi.java @@ -144,8 +144,9 @@ class SuiteUi extends Composite implements CmsUi { // TODO make it more robust for (String layerId : layers.keySet()) { SuiteLayer l = layers.get(layerId); - if (layer == l) { + if (layer.getId().equals(l.getId())) { switchToLayer(layerId, context); + return; } } throw new IllegalArgumentException("Layer is not registered."); diff --git a/org.argeo.app.ui/src/org/argeo/app/ui/dialogs/NewUserWizard.java b/org.argeo.app.ui/src/org/argeo/app/ui/dialogs/NewUserWizard.java deleted file mode 100644 index 5c7a6d2..0000000 --- a/org.argeo.app.ui/src/org/argeo/app/ui/dialogs/NewUserWizard.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.argeo.app.ui.dialogs; - -import static org.argeo.eclipse.ui.EclipseUiUtils.isEmpty; - -import org.argeo.app.ui.SuiteMsg; -import org.argeo.app.ui.SuiteUiUtils; -import org.argeo.cms.swt.dialogs.CmsFeedback; -import org.argeo.cms.swt.widgets.SwtGuidedFormPage; -import org.argeo.cms.ux.widgets.AbstractGuidedForm; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.util.directory.HierarchyUnit; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; - -/** Ask first & last name. Update the passed node on finish */ -public class NewUserWizard extends AbstractGuidedForm { - // private final static Log log = LogFactory.getLog(NewPersonWizard.class); - - // Context -// private Node person; - private HierarchyUnit hierarchyUnit; - // This page widgets - protected Text lastNameTxt; - protected Text firstNameTxt; - // private Button useDistinctDisplayNameBtn; - // private Text displayNameTxt; - - public NewUserWizard(HierarchyUnit hierarchyUnit) { - this.hierarchyUnit = hierarchyUnit; - } - - @Override - public void addPages() { - try { - MainInfoPage page = new MainInfoPage("Main page"); - addPage(page); - } catch (Exception e) { - throw new RuntimeException("Cannot add page to wizard", e); - } - setFormTitle(SuiteMsg.personWizardWindowTitle.lead()); - } - - /** - * Called when the user click on 'Finish' in the wizard. The task is then - * created and the corresponding session saved. - */ - @Override - public boolean performFinish() { - String lastName = lastNameTxt.getText(); - String firstName = firstNameTxt.getText(); - // String displayName = displayNameTxt.getText(); - // boolean useDistinct = useDistinctDisplayNameBtn.getSelection(); - if (EclipseUiUtils.isEmpty(lastName) && EclipseUiUtils.isEmpty(firstName)) { -// MessageDialog.openError(getShell(), "Non-valid information", -// "Please enter at least a name that is not empty."); - CmsFeedback.show("Please enter at least a name that is not empty."); - return false; - } else { -// ConnectJcrUtils.setJcrProperty(person, PEOPLE_LAST_NAME, PropertyType.STRING, lastName); -// ConnectJcrUtils.setJcrProperty(person, PEOPLE_FIRST_NAME, PropertyType.STRING, firstName); -// String fullName = firstName + " " + lastName; -// ConnectJcrUtils.setJcrProperty(person, PEOPLE_DISPLAY_NAME, PropertyType.STRING, fullName); - return true; - } - } - - @Override - public boolean performCancel() { - return true; - } - - @Override - public boolean canFinish() { - String lastName = lastNameTxt.getText(); - String firstName = firstNameTxt.getText(); - if (isEmpty(lastName) && isEmpty(firstName)) { - return false; - } else - return true; - } - - protected class MainInfoPage extends SwtGuidedFormPage { - - public MainInfoPage(String pageName) { - super(pageName); - setTitle(SuiteMsg.personWizardPageTitle.lead()); - // setMessage("Please enter a last name and/or a first name."); - } - - public void createControl(Composite parent) { - parent.setLayout(new GridLayout(2, false)); - - // FirstName - SuiteUiUtils.createBoldLabel(parent, SuiteMsg.firstName); - firstNameTxt = new Text(parent, SWT.BORDER); - // firstNameTxt.setMessage("a first name"); - firstNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - // LastName - SuiteUiUtils.createBoldLabel(parent, SuiteMsg.lastName); - lastNameTxt = new Text(parent, SWT.BORDER); - // lastNameTxt.setMessage("a last name"); - lastNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - // Display Name - // useDistinctDisplayNameBtn = new Button(parent, SWT.CHECK); - // useDistinctDisplayNameBtn.setText("Define a disting display name"); - // useDistinctDisplayNameBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, - // true, false, 2, 1)); - // - // ConnectWorkbenchUtils.createBoldLabel(parent, "Display Name"); - // displayNameTxt = new Text(parent, SWT.BORDER); - // displayNameTxt.setMessage("an optional display name"); - // displayNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, - // false)); - // displayNameTxt.setEnabled(false); - // - // useDistinctDisplayNameBtn.addSelectionListener(new SelectionAdapter() { - // private static final long serialVersionUID = 1L; - // - // @Override - // public void widgetSelected(SelectionEvent e) { - // displayNameTxt.setEnabled(useDistinctDisplayNameBtn.getSelection()); - // } - // }); - - ModifyListener ml = new ModifyListener() { - private static final long serialVersionUID = -1628130380128946886L; - - @Override - public void modifyText(ModifyEvent event) { - getView().updateButtons(); - } - }; - - firstNameTxt.addModifyListener(ml); - lastNameTxt.addModifyListener(ml); - // displayNameTxt.addModifyListener(ml); - - // Don't forget this. - // setControl(firstNameTxt); - firstNameTxt.setFocus(); - } - } -} diff --git a/org.argeo.app.ui/src/org/argeo/app/ui/people/NewUserForm.java b/org.argeo.app.ui/src/org/argeo/app/ui/people/NewUserForm.java new file mode 100644 index 0000000..ed9c4f4 --- /dev/null +++ b/org.argeo.app.ui/src/org/argeo/app/ui/people/NewUserForm.java @@ -0,0 +1,162 @@ +package org.argeo.app.ui.people; + +import static org.argeo.eclipse.ui.EclipseUiUtils.isEmpty; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.argeo.api.acr.Content; +import org.argeo.app.core.SuiteUtils; +import org.argeo.app.ui.SuiteMsg; +import org.argeo.app.ui.SuiteUiUtils; +import org.argeo.cms.CmsUserManager; +import org.argeo.cms.acr.ContentUtils; +import org.argeo.cms.swt.dialogs.CmsFeedback; +import org.argeo.cms.swt.widgets.SwtGuidedFormPage; +import org.argeo.cms.ux.widgets.AbstractGuidedForm; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.util.directory.HierarchyUnit; +import org.argeo.util.naming.LdapAttrs; +import org.argeo.util.naming.LdapObjs; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.osgi.service.useradmin.User; + +/** Ask first & last name. Update the passed node on finish */ +public class NewUserForm extends AbstractGuidedForm { + private Content hierarchyUnit; + private CmsUserManager cmsUserManager; + + protected Text lastNameT; + protected Text firstNameT; + protected Text emailT; + + public NewUserForm(CmsUserManager cmsUserManager, Content hierarchyUnit) { + this.hierarchyUnit = hierarchyUnit; + if (!hierarchyUnit.hasContentClass(LdapObjs.posixGroup.qName())) + throw new IllegalArgumentException(hierarchyUnit + " is not a POSIX group"); + this.cmsUserManager = cmsUserManager; + } + + @Override + public void addPages() { + try { + MainInfoPage page = new MainInfoPage("Main page"); + addPage(page); + } catch (Exception e) { + throw new RuntimeException("Cannot add page to wizard", e); + } + setFormTitle(SuiteMsg.personWizardWindowTitle.lead()); + } + + /** + * Called when the user click on 'Finish' in the wizard. The task is then + * created and the corresponding session saved. + */ + @Override + public boolean performFinish() { + String lastName = lastNameT.getText(); + String firstName = firstNameT.getText(); + String email = emailT.getText(); + if (EclipseUiUtils.isEmpty(lastName) || EclipseUiUtils.isEmpty(firstName) || EclipseUiUtils.isEmpty(email)) { + CmsFeedback.show(SuiteMsg.allFieldsMustBeSet.lead()); + return false; + } else { + UUID uuid = UUID.randomUUID(); + String shortId = uuid.toString().split("-")[0]; + String uid = "u" + shortId; + HierarchyUnit hu = hierarchyUnit.adapt(HierarchyUnit.class); + String username = "uid=" + uid + ",ou=People," + hu.getBase(); + + Map properties = new HashMap<>(); + properties.put(LdapAttrs.givenName.name(), firstName); + properties.put(LdapAttrs.sn.name(), lastName); + properties.put(LdapAttrs.mail.name(), email); + properties.put(LdapAttrs.cn.name(), firstName + " " + lastName); + properties.put(LdapAttrs.employeeNumber.name(), uuid.toString()); + + Map credentials = new HashMap<>(); + User user = cmsUserManager.createUser(username, properties, credentials); + + Long huGidNumber = hierarchyUnit.get(LdapAttrs.gidNumber.qName(), Long.class).orElseThrow(); + Long nextUserId = SuiteUtils.findNextId(hierarchyUnit, LdapObjs.posixAccount.qName()); + String homeDirectory = "/home/" + uid; + Map additionalProperties = new HashMap<>(); + additionalProperties.put(LdapAttrs.uidNumber.name(), nextUserId.toString()); + additionalProperties.put(LdapAttrs.gidNumber.name(), huGidNumber.toString()); + additionalProperties.put(LdapAttrs.homeDirectory.name(), homeDirectory); + + Set objectClasses = new HashSet<>(); + objectClasses.add(LdapObjs.posixAccount.name()); + cmsUserManager.addObjectClasses(user, objectClasses, additionalProperties); + return true; + } + } + + @Override + public boolean performCancel() { + return true; + } + + @Override + public boolean canFinish() { + String lastName = lastNameT.getText(); + String firstName = firstNameT.getText(); + String email = emailT.getText(); + if (isEmpty(lastName) || isEmpty(firstName) || isEmpty(email)) { + return false; + } else + return true; + } + + protected class MainInfoPage extends SwtGuidedFormPage { + + public MainInfoPage(String pageName) { + super(pageName); + setTitle(SuiteMsg.personWizardPageTitle.lead()); + } + + public void createControl(Composite parent) { + parent.setLayout(new GridLayout(2, false)); + + // FirstName + SuiteUiUtils.createBoldLabel(parent, SuiteMsg.firstName); + firstNameT = new Text(parent, SWT.BORDER); + // firstNameTxt.setMessage("a first name"); + firstNameT.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + // LastName + SuiteUiUtils.createBoldLabel(parent, SuiteMsg.lastName); + lastNameT = new Text(parent, SWT.BORDER); + // lastNameTxt.setMessage("a last name"); + lastNameT.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + SuiteUiUtils.createBoldLabel(parent, SuiteMsg.email); + emailT = new Text(parent, SWT.BORDER); + emailT.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + ModifyListener ml = new ModifyListener() { + private static final long serialVersionUID = 1939491923843870844L; + + @Override + public void modifyText(ModifyEvent event) { + getView().updateButtons(); + } + }; + + firstNameT.addModifyListener(ml); + lastNameT.addModifyListener(ml); + emailT.addModifyListener(ml); + + firstNameT.setFocus(); + } + } +} diff --git a/org.argeo.app.ui/src/org/argeo/app/ui/people/PeopleEntryArea.java b/org.argeo.app.ui/src/org/argeo/app/ui/people/PeopleEntryArea.java index 8ee656a..4a92c20 100644 --- a/org.argeo.app.ui/src/org/argeo/app/ui/people/PeopleEntryArea.java +++ b/org.argeo.app.ui/src/org/argeo/app/ui/people/PeopleEntryArea.java @@ -13,14 +13,12 @@ import org.argeo.api.cms.ux.CmsIcon; import org.argeo.api.cms.ux.CmsView; import org.argeo.app.ui.SuiteEvent; import org.argeo.app.ui.SuiteIcon; -import org.argeo.app.ui.dialogs.NewUserWizard; import org.argeo.cms.CmsUserManager; import org.argeo.cms.acr.ContentUtils; import org.argeo.cms.auth.CmsRole; import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.auth.UserAdminUtils; import org.argeo.cms.jcr.acr.JcrContent; -import org.argeo.cms.jface.dialog.CmsWizardDialog; import org.argeo.cms.swt.CmsSwtTheme; import org.argeo.cms.swt.CmsSwtUtils; import org.argeo.cms.swt.Selected; @@ -40,7 +38,6 @@ import org.argeo.util.directory.ldap.IpaUtils; import org.argeo.util.naming.LdapAttrs; import org.argeo.util.naming.LdapObjs; import org.eclipse.jface.window.Window; -import org.eclipse.jface.wizard.Wizard; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.layout.GridData; @@ -240,8 +237,9 @@ public class PeopleEntryArea implements SwtUiProvider, CmsUiProvider { }); addItem.addSelectionListener((Selected) (e) -> { - // SuiteUtils.getOrCreateUserNode(adminSession, userDn); - GuidedForm wizard = new NewUserWizard(null); + HierarchyUnit hierarchyUnit = usersPart.getInput(); + Content huContent = ContentUtils.hierarchyUnitToContent(contentSession, hierarchyUnit); + GuidedForm wizard = new NewUserForm(cmsUserManager, huContent); SwtGuidedFormDialog dialog = new SwtGuidedFormDialog(parent.getShell(), wizard); // WizardDialog dialog = new WizardDialog(shell, wizard); if (dialog.open() == Window.OK) { -- 2.30.2