| /* | |
| * Copyright 2012 gitblit.com. | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| package com.gitblit.authority; | |
| import java.awt.BorderLayout; | |
| import java.awt.FlowLayout; | |
| import java.awt.Frame; | |
| import java.awt.event.ActionEvent; | |
| import java.awt.event.ActionListener; | |
| import java.awt.event.MouseAdapter; | |
| import java.awt.event.MouseEvent; | |
| import java.io.IOException; | |
| import java.security.cert.X509Certificate; | |
| import java.text.MessageFormat; | |
| import java.util.Date; | |
| import javax.swing.ImageIcon; | |
| import javax.swing.JButton; | |
| import javax.swing.JOptionPane; | |
| import javax.swing.JPanel; | |
| import javax.swing.JScrollPane; | |
| import javax.swing.JTable; | |
| import javax.swing.event.ListSelectionEvent; | |
| import javax.swing.event.ListSelectionListener; | |
| import javax.swing.table.TableRowSorter; | |
| import com.gitblit.client.HeaderPanel; | |
| import com.gitblit.client.Translation; | |
| import com.gitblit.models.UserModel; | |
| import com.gitblit.utils.X509Utils.RevocationReason; | |
| import com.gitblit.utils.X509Utils.X509Metadata; | |
| public abstract class UserCertificatePanel extends JPanel { | |
| private static final long serialVersionUID = 1L; | |
| private Frame owner; | |
| private UserCertificateModel ucm; | |
| private UserOidsPanel oidsPanel; | |
| private CertificatesTableModel tableModel; | |
| private JButton saveUserButton; | |
| private JButton editUserButton; | |
| private JButton newCertificateButton; | |
| private JButton revokeCertificateButton; | |
| private JTable table; | |
| public UserCertificatePanel(Frame owner) { | |
| super(new BorderLayout()); | |
| this.owner = owner; | |
| oidsPanel = new UserOidsPanel(); | |
| JPanel fp = new JPanel(new BorderLayout(Utils.MARGIN, Utils.MARGIN)); | |
| fp.add(oidsPanel, BorderLayout.NORTH); | |
| JPanel fieldsPanel = new JPanel(new BorderLayout()); | |
| fieldsPanel.add(new HeaderPanel(Translation.get("gb.properties"), "vcard_16x16.png"), BorderLayout.NORTH); | |
| fieldsPanel.add(fp, BorderLayout.CENTER); | |
| saveUserButton = new JButton(Translation.get("gb.save")); | |
| saveUserButton.setEnabled(false); | |
| saveUserButton.addActionListener(new ActionListener() { | |
| public void actionPerformed(ActionEvent e) { | |
| setEditable(false); | |
| String username = ucm.user.username; | |
| oidsPanel.updateUser(ucm); | |
| saveUser(username, ucm); | |
| } | |
| }); | |
| editUserButton = new JButton(Translation.get("gb.edit")); | |
| editUserButton.setEnabled(false); | |
| editUserButton.addActionListener(new ActionListener() { | |
| public void actionPerformed(ActionEvent e) { | |
| setEditable(true); | |
| } | |
| }); | |
| JPanel userControls = new JPanel(new FlowLayout(FlowLayout.LEFT)); | |
| userControls.add(editUserButton); | |
| userControls.add(saveUserButton); | |
| fieldsPanel.add(userControls, BorderLayout.SOUTH); | |
| JPanel certificatesPanel = new JPanel(new BorderLayout()); | |
| certificatesPanel.add(new HeaderPanel(Translation.get("gb.certificates"), "rosette_16x16.png"), BorderLayout.NORTH); | |
| tableModel = new CertificatesTableModel(); | |
| table = Utils.newTable(tableModel, Utils.DATE_FORMAT); | |
| table.setRowSorter(new TableRowSorter<CertificatesTableModel>(tableModel)); | |
| table.setDefaultRenderer(CertificateStatus.class, new CertificateStatusRenderer()); | |
| table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { | |
| @Override | |
| public void valueChanged(ListSelectionEvent e) { | |
| if (e.getValueIsAdjusting()) { | |
| return; | |
| } | |
| boolean enable = false; | |
| int row = table.getSelectedRow(); | |
| if (row > -1) { | |
| int modelIndex = table.convertRowIndexToModel(row); | |
| X509Certificate cert = tableModel.get(modelIndex); | |
| enable = !ucm.isRevoked(cert.getSerialNumber()); | |
| } | |
| revokeCertificateButton.setEnabled(enable); | |
| } | |
| }); | |
| table.addMouseListener(new MouseAdapter() { | |
| public void mouseClicked(MouseEvent e) { | |
| if (e.getClickCount() == 2) { | |
| int row = table.rowAtPoint(e.getPoint()); | |
| int modelIndex = table.convertRowIndexToModel(row); | |
| X509Certificate cert = tableModel.get(modelIndex); | |
| X509CertificateViewer viewer = new X509CertificateViewer(UserCertificatePanel.this.owner, cert); | |
| viewer.setVisible(true); | |
| } | |
| } | |
| }); | |
| certificatesPanel.add(new JScrollPane(table), BorderLayout.CENTER); | |
| newCertificateButton = new JButton(Translation.get("gb.newCertificate")); | |
| newCertificateButton.setEnabled(false); | |
| newCertificateButton.addActionListener(new ActionListener() { | |
| public void actionPerformed(ActionEvent e) { | |
| try { | |
| if (saveUserButton.isEnabled()) { | |
| // save changes | |
| String username = ucm.user.username; | |
| setEditable(false); | |
| oidsPanel.updateUser(ucm); | |
| saveUser(username, ucm); | |
| } | |
| NewClientCertificateDialog dialog = new NewClientCertificateDialog(UserCertificatePanel.this.owner, | |
| ucm.user.getDisplayName(), getDefaultExpiration(), isAllowEmail()); | |
| dialog.setModal(true); | |
| dialog.setVisible(true); | |
| if (dialog.isCanceled()) { | |
| return; | |
| } | |
| final boolean sendEmail = dialog.sendEmail(); | |
| final UserModel user = ucm.user; | |
| final X509Metadata metadata = new X509Metadata(user.username, dialog.getPassword()); | |
| metadata.userDisplayname = user.getDisplayName(); | |
| metadata.emailAddress = user.emailAddress; | |
| metadata.passwordHint = dialog.getPasswordHint(); | |
| metadata.notAfter = dialog.getExpiration(); | |
| AuthorityWorker worker = new AuthorityWorker(UserCertificatePanel.this.owner) { | |
| @Override | |
| protected Boolean doRequest() throws IOException { | |
| return newCertificate(ucm, metadata, sendEmail); | |
| } | |
| @Override | |
| protected void onSuccess() { | |
| JOptionPane.showMessageDialog(UserCertificatePanel.this.owner, | |
| MessageFormat.format(Translation.get("gb.clientCertificateGenerated"), user.getDisplayName()), | |
| Translation.get("gb.newCertificate"), JOptionPane.INFORMATION_MESSAGE); | |
| } | |
| }; | |
| worker.execute(); | |
| } catch (Exception x) { | |
| Utils.showException(UserCertificatePanel.this, x); | |
| } | |
| } | |
| }); | |
| revokeCertificateButton = new JButton(Translation.get("gb.revokeCertificate")); | |
| revokeCertificateButton.setEnabled(false); | |
| revokeCertificateButton.addActionListener(new ActionListener() { | |
| public void actionPerformed(ActionEvent e) { | |
| try { | |
| int row = table.getSelectedRow(); | |
| if (row < 0) { | |
| return; | |
| } | |
| int modelIndex = table.convertRowIndexToModel(row); | |
| final X509Certificate cert = tableModel.get(modelIndex); | |
| String [] choices = new String[RevocationReason.reasons.length]; | |
| for (int i = 0; i < choices.length; i++) { | |
| choices[i] = Translation.get("gb." + RevocationReason.reasons[i].name()); | |
| } | |
| Object choice = JOptionPane.showInputDialog(UserCertificatePanel.this.owner, | |
| Translation.get("gb.revokeCertificateReason"), Translation.get("gb.revokeCertificate"), | |
| JOptionPane.PLAIN_MESSAGE, new ImageIcon(getClass().getResource("/rosette_32x32.png")), choices, Translation.get("gb.unspecified")); | |
| if (choice == null) { | |
| return; | |
| } | |
| RevocationReason selection = RevocationReason.unspecified; | |
| for (int i = 0 ; i < choices.length; i++) { | |
| if (choices[i].equals(choice)) { | |
| selection = RevocationReason.reasons[i]; | |
| break; | |
| } | |
| } | |
| final RevocationReason reason = selection; | |
| if (!ucm.isRevoked(cert.getSerialNumber())) { | |
| if (ucm.certs.size() == 1) { | |
| // no other certificates | |
| ucm.expires = null; | |
| } else { | |
| // determine new expires date for user | |
| Date newExpires = null; | |
| for (X509Certificate c : ucm.certs) { | |
| if (!c.equals(cert)) { | |
| if (!ucm.isRevoked(c.getSerialNumber())) { | |
| if (newExpires == null || c.getNotAfter().after(newExpires)) { | |
| newExpires = c.getNotAfter(); | |
| } | |
| } | |
| } | |
| } | |
| ucm.expires = newExpires; | |
| } | |
| AuthorityWorker worker = new AuthorityWorker(UserCertificatePanel.this.owner) { | |
| @Override | |
| protected Boolean doRequest() throws IOException { | |
| return revoke(ucm, cert, reason); | |
| } | |
| @Override | |
| protected void onSuccess() { | |
| JOptionPane.showMessageDialog(UserCertificatePanel.this.owner, | |
| MessageFormat.format(Translation.get("gb.certificateRevoked"), cert.getSerialNumber(), cert.getIssuerDN().getName()), | |
| Translation.get("gb.revokeCertificate"), JOptionPane.INFORMATION_MESSAGE); | |
| } | |
| }; | |
| worker.execute(); | |
| } | |
| } catch (Exception x) { | |
| Utils.showException(UserCertificatePanel.this, x); | |
| } | |
| } | |
| }); | |
| JPanel certificateControls = new JPanel(new FlowLayout(FlowLayout.LEFT)); | |
| certificateControls.add(newCertificateButton); | |
| certificateControls.add(revokeCertificateButton); | |
| certificatesPanel.add(certificateControls, BorderLayout.SOUTH); | |
| add(fieldsPanel, BorderLayout.NORTH); | |
| add(certificatesPanel, BorderLayout.CENTER); | |
| setEditable(false); | |
| } | |
| public void setUserCertificateModel(UserCertificateModel ucm) { | |
| this.ucm = ucm; | |
| setEditable(false); | |
| oidsPanel.setUserCertificateModel(ucm); | |
| tableModel.setUserCertificateModel(ucm); | |
| tableModel.fireTableDataChanged(); | |
| Utils.packColumns(table, Utils.MARGIN); | |
| } | |
| public void setEditable(boolean editable) { | |
| oidsPanel.setEditable(editable); | |
| editUserButton.setEnabled(!editable && ucm != null); | |
| saveUserButton.setEnabled(editable && ucm != null); | |
| newCertificateButton.setEnabled(ucm != null); | |
| revokeCertificateButton.setEnabled(false); | |
| } | |
| public abstract Date getDefaultExpiration(); | |
| public abstract boolean isAllowEmail(); | |
| public abstract boolean saveUser(String username, UserCertificateModel ucm); | |
| public abstract boolean newCertificate(UserCertificateModel ucm, X509Metadata metadata, boolean sendEmail); | |
| public abstract boolean revoke(UserCertificateModel ucm, X509Certificate cert, RevocationReason reason); | |
| } |