001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2008-2009 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2016 ForgeRock AS.
016 */
017package org.opends.guitools.controlpanel.ui;
018
019import static org.opends.messages.AdminToolMessages.*;
020
021import java.awt.Component;
022import java.awt.GridBagConstraints;
023import java.awt.event.ActionEvent;
024import java.awt.event.ActionListener;
025import java.io.IOException;
026import java.util.ArrayList;
027import java.util.Arrays;
028
029import javax.swing.DefaultComboBoxModel;
030import javax.swing.JComboBox;
031import javax.swing.JLabel;
032import javax.swing.JPasswordField;
033import javax.swing.JTextField;
034import javax.swing.event.DocumentEvent;
035import javax.swing.event.DocumentListener;
036
037import org.forgerock.i18n.LocalizableMessage;
038import org.opends.guitools.controlpanel.browser.BrowserController;
039import org.opends.guitools.controlpanel.ui.nodes.BasicNode;
040import org.opends.guitools.controlpanel.util.Utilities;
041import org.opends.server.types.OpenDsException;
042
043/** The panel used to create a new user. */
044public class NewUserPanel extends AbstractNewEntryPanel
045{
046  private static final long serialVersionUID = -2450090053404111892L;
047  private JLabel lFirstName = Utilities.createPrimaryLabel(
048      INFO_CTRL_PANEL_NEW_USER_FIRST_NAME_LABEL.get());
049  private JLabel lLastName = Utilities.createPrimaryLabel(
050      INFO_CTRL_PANEL_NEW_USER_LAST_NAME_LABEL.get());
051  private JLabel lCommonNames = Utilities.createPrimaryLabel(
052      INFO_CTRL_PANEL_NEW_USER_COMMON_NAMES_LABEL.get());
053  private JLabel lUserID = Utilities.createPrimaryLabel(
054      INFO_CTRL_PANEL_NEW_USER_UID_LABEL.get());
055  private JLabel lPassword = Utilities.createPrimaryLabel(
056      INFO_CTRL_PANEL_NEW_USER_PASSWORD_LABEL.get());
057  private JLabel lConfirmPassword = Utilities.createPrimaryLabel(
058      INFO_CTRL_PANEL_NEW_USER_CONFIRM_PASSWORD_LABEL.get());
059  private JLabel lEmail = Utilities.createPrimaryLabel(
060      INFO_CTRL_PANEL_NEW_USER_EMAIL_LABEL.get());
061  private JLabel lTelephoneNumber = Utilities.createPrimaryLabel(
062      INFO_CTRL_PANEL_NEW_USER_TELEPHONE_NUMBER_LABEL.get());
063  private JLabel lFaxNumber = Utilities.createPrimaryLabel(
064      INFO_CTRL_PANEL_NEW_USER_FAX_NUMBER_LABEL.get());
065  private JLabel lNamingAttribute = Utilities.createPrimaryLabel(
066      INFO_CTRL_PANEL_NEW_USER_NAMING_ATTRIBUTE_LABEL.get());
067  private JLabel lEntryDN = Utilities.createPrimaryLabel(
068      INFO_CTRL_PANEL_NEW_USER_ENTRY_DN_LABEL.get());
069
070  private JLabel[] labels = {lFirstName, lLastName, lCommonNames, lUserID,
071      lPassword, lConfirmPassword, lEmail, lTelephoneNumber, lFaxNumber,
072      lNamingAttribute, lEntryDN
073  };
074
075  private JTextField firstName = Utilities.createLongTextField();
076  private JTextField lastName = Utilities.createLongTextField();
077  private JTextField commonName = Utilities.createLongTextField();
078  private JTextField userID = Utilities.createLongTextField();
079  private JPasswordField password = Utilities.createPasswordField();
080  private JPasswordField confirmPassword = Utilities.createPasswordField(30);
081  private JTextField eMail = Utilities.createLongTextField();
082  private JTextField telephoneNumber = Utilities.createLongTextField();
083  private JTextField faxNumber = Utilities.createLongTextField();
084  private JComboBox<String> namingAttribute = Utilities.createComboBox();
085  private JLabel dn = Utilities.createDefaultLabel();
086
087  private Component[] comps = { firstName, lastName, commonName, userID,
088      password, confirmPassword, eMail, telephoneNumber, faxNumber,
089      namingAttribute, dn};
090
091  private final JTextField[] NAMING_ATTRIBUTE_TEXTFIELDS =
092  {commonName, firstName, lastName, userID};
093  private final String[] NAMING_ATTRIBUTES = {"cn", "givenName", "sn", "uid"};
094
095  /** Default constructor. */
096  public NewUserPanel()
097  {
098    super();
099    createLayout();
100  }
101
102  @Override
103  public void setParent(BasicNode parentNode, BrowserController controller)
104  {
105    super.setParent(parentNode, controller);
106    dn.setText(namingAttribute.getSelectedItem()+"=,"+parentNode.getDN());
107    for (Component comp : comps)
108    {
109      if (comp instanceof JTextField)
110      {
111        ((JTextField)comp).setText("");
112      }
113    }
114  }
115
116  @Override
117  public LocalizableMessage getTitle()
118  {
119    return INFO_CTRL_PANEL_NEW_USER_PANEL_TITLE.get();
120  }
121
122  @Override
123  public Component getPreferredFocusComponent()
124  {
125    return firstName;
126  }
127
128  @Override
129  protected LocalizableMessage getProgressDialogTitle()
130  {
131    return INFO_CTRL_PANEL_NEW_USER_PANEL_TITLE.get();
132  }
133
134  @Override
135  protected void checkSyntax(ArrayList<LocalizableMessage> errors)
136  {
137    for (JLabel label : labels)
138    {
139      setPrimaryValid(label);
140    }
141
142    JTextField[] requiredFields = {lastName, commonName};
143    LocalizableMessage[] msgs = {ERR_CTRL_PANEL_USER_LAST_NAME_REQUIRED.get(),
144        ERR_CTRL_PANEL_USER_COMMON_NAME_REQUIRED.get()
145    };
146    for (int i=0; i<requiredFields.length; i++)
147    {
148      String v = requiredFields[i].getText().trim();
149      if (v.length() == 0)
150      {
151        errors.add(msgs[i]);
152      }
153    }
154
155    String attr = (String)namingAttribute.getSelectedItem();
156    for (int i=0 ; i<NAMING_ATTRIBUTE_TEXTFIELDS.length; i++)
157    {
158      JTextField namingAttrTextField = NAMING_ATTRIBUTE_TEXTFIELDS[i];
159      boolean isRequired = contains(requiredFields, namingAttrTextField);
160      if (!isRequired && attr.equalsIgnoreCase(NAMING_ATTRIBUTES[i]))
161      {
162        String value = namingAttrTextField.getText().trim();
163        if (value.length() == 0)
164        {
165          errors.add(ERR_CTRL_PANEL_USER_NAMING_ATTRIBUTE_REQUIRED.get(attr));
166        }
167        break;
168      }
169    }
170
171    char[] pwd1 = password.getPassword();
172    char[] pwd2 = confirmPassword.getPassword();
173    if (!Arrays.equals(pwd1, pwd2))
174    {
175      errors.add(ERR_CTRL_PANEL_PASSWORD_DO_NOT_MATCH.get());
176    }
177
178    if (errors.isEmpty())
179    {
180      try
181      {
182        getEntry();
183      }
184      catch (OpenDsException ode)
185      {
186        errors.add(ode.getMessageObject());
187      }
188      catch (IOException ioe)
189      {
190        // This should not occur
191        throw new RuntimeException("Unexpected error: "+ioe, ioe);
192      }
193    }
194  }
195
196  private boolean contains(JTextField[] requiredFields, JTextField toFind)
197  {
198    for (JTextField tf : requiredFields)
199    {
200      if (tf == toFind)
201      {
202        return true;
203      }
204    }
205    return false;
206  }
207
208  /** Creates the layout of the panel (but the contents are not populated here). */
209  private void createLayout()
210  {
211    GridBagConstraints gbc = new GridBagConstraints();
212    Utilities.setRequiredIcon(lLastName);
213    Utilities.setRequiredIcon(lCommonNames);
214
215    gbc.gridwidth = 2;
216    gbc.gridy = 0;
217    addErrorPane(gbc);
218
219    gbc.gridy ++;
220    gbc.gridwidth = 1;
221    gbc.weighty = 0.0;
222    gbc.gridx = 1;
223    gbc.anchor = GridBagConstraints.EAST;
224    gbc.fill = GridBagConstraints.NONE;
225    JLabel requiredLabel = createRequiredLabel();
226    gbc.insets.bottom = 10;
227    add(requiredLabel, gbc);
228
229    gbc.gridy ++;
230    gbc.fill = GridBagConstraints.HORIZONTAL;
231    gbc.anchor = GridBagConstraints.WEST;
232    gbc.insets.bottom = 0;
233
234    Component[] inlineHelp = {null, null, null, null, null,
235        null, null, null, null, null, null};
236
237    for (int i=0 ; i< labels.length; i++)
238    {
239      gbc.insets.left = 0;
240      gbc.weightx = 0.0;
241      gbc.gridx = 0;
242      add(labels[i], gbc);
243      gbc.insets.left = 10;
244      gbc.gridx = 1;
245      if (comps[i] instanceof JComboBox)
246      {
247        gbc.weightx = 0.0;
248        gbc.fill = GridBagConstraints.NONE;
249      }
250      else
251      {
252        gbc.weightx = 1.0;
253        gbc.fill = GridBagConstraints.HORIZONTAL;
254      }
255      add(comps[i], gbc);
256      if (inlineHelp[i] != null)
257      {
258        gbc.insets.top = 3;
259        gbc.gridy ++;
260        add(inlineHelp[i], gbc);
261      }
262      gbc.insets.top = 10;
263      gbc.gridy ++;
264    }
265    addBottomGlue(gbc);
266
267    DocumentListener listener = new DocumentListener()
268    {
269      @Override
270      public void insertUpdate(DocumentEvent ev)
271      {
272        updateDNValue();
273      }
274
275      @Override
276      public void changedUpdate(DocumentEvent ev)
277      {
278        insertUpdate(ev);
279      }
280
281      @Override
282      public void removeUpdate(DocumentEvent ev)
283      {
284        insertUpdate(ev);
285      }
286    };
287    JTextField[] toAddListener = {firstName, lastName, commonName, userID};
288    for (JTextField tf : toAddListener)
289    {
290      tf.getDocument().addDocumentListener(listener);
291    }
292
293    DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(NAMING_ATTRIBUTES);
294    namingAttribute.setModel(model);
295    namingAttribute.setSelectedItem(NAMING_ATTRIBUTES[0]);
296    namingAttribute.addActionListener(new ActionListener()
297    {
298      @Override
299      public void actionPerformed(ActionEvent ev)
300      {
301        updateDNValue();
302      }
303    });
304  }
305
306  /** Updates the contents of DN value to reflect the data that the user is providing. */
307  private void updateDNValue()
308  {
309    String attr = (String)namingAttribute.getSelectedItem();
310    for (int i=0 ; i<NAMING_ATTRIBUTE_TEXTFIELDS.length; i++)
311    {
312      if (attr.equalsIgnoreCase(NAMING_ATTRIBUTES[i]))
313      {
314        String value = NAMING_ATTRIBUTE_TEXTFIELDS[i].getText().trim();
315        dn.setText(attr + "=" + value + "," + parentNode.getDN());
316        break;
317      }
318    }
319  }
320
321  @Override
322  protected String getLDIF()
323  {
324    StringBuilder sb = new StringBuilder();
325    sb.append("dn: ").append(dn.getText()).append("\n");
326    String[] attrNames = {"givenName", "sn", "cn", "uid", "userPassword",
327        "mail", "telephoneNumber", "facsimileTelephoneNumber"};
328    JTextField[] textFields = {firstName, lastName, commonName, userID,
329        password, eMail, telephoneNumber, faxNumber};
330    sb.append("objectclass: top\n");
331    sb.append("objectclass: person\n");
332    sb.append("objectclass: inetOrgPerson\n");
333    for (int i=0; i<attrNames.length; i++)
334    {
335      String value = textFields[i].getText().trim();
336      if (value.length() > 0)
337      {
338        sb.append(attrNames[i]).append(": ").append(value).append("\n");
339      }
340    }
341    return sb.toString();
342  }
343}