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