From a502d96a860456ec5e8c96761db70f7cabb74751 Mon Sep 17 00:00:00 2001 From: Paul Martin <paul@paulsputer.com> Date: Sat, 30 Apr 2016 04:19:14 -0400 Subject: [PATCH] Merge pull request #1073 from gitblit/1062-DocEditorUpdates --- src/main/java/com/gitblit/authority/GitblitAuthority.java | 219 ++++++++++++++++++++++++++---------------------------- 1 files changed, 105 insertions(+), 114 deletions(-) diff --git a/src/main/java/com/gitblit/authority/GitblitAuthority.java b/src/main/java/com/gitblit/authority/GitblitAuthority.java index 1a1f96d..5f4a7e7 100644 --- a/src/main/java/com/gitblit/authority/GitblitAuthority.java +++ b/src/main/java/com/gitblit/authority/GitblitAuthority.java @@ -50,12 +50,7 @@ import java.util.List; import java.util.Map; -import javax.activation.DataHandler; -import javax.activation.FileDataSource; import javax.mail.Message; -import javax.mail.Multipart; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMultipart; import javax.swing.ImageIcon; import javax.swing.InputVerifier; import javax.swing.JButton; @@ -90,10 +85,11 @@ import com.gitblit.IStoredSettings; import com.gitblit.IUserService; import com.gitblit.Keys; -import com.gitblit.MailExecutor; import com.gitblit.client.HeaderPanel; import com.gitblit.client.Translation; +import com.gitblit.models.Mailing; import com.gitblit.models.UserModel; +import com.gitblit.service.MailService; import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.FileUtils; import com.gitblit.utils.StringUtils; @@ -105,33 +101,33 @@ /** * Simple GUI tool for administering Gitblit client certificates. - * + * * @author James Moger * */ public class GitblitAuthority extends JFrame implements X509Log { private static final long serialVersionUID = 1L; - + private final UserCertificateTableModel tableModel; private UserCertificatePanel userCertificatePanel; - + private File folder; - + private IStoredSettings gitblitSettings; - + private IUserService userService; - + private String caKeystorePassword; private JTable table; - + private int defaultDuration; - + private TableRowSorter<UserCertificateTableModel> defaultSorter; - - private MailExecutor mail; + + private MailService mail; private JButton certificateDefaultsButton; @@ -146,7 +142,7 @@ if (i + 1 == args.length) { System.out.println("Invalid --baseFolder parameter!"); System.exit(-1); - } else if (args[i + 1] != ".") { + } else if (!".".equals(args[i + 1])) { folder = args[i+1]; } break; @@ -154,6 +150,7 @@ } final String baseFolder = folder; EventQueue.invokeLater(new Runnable() { + @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); @@ -172,7 +169,7 @@ tableModel = new UserCertificateTableModel(); defaultSorter = new TableRowSorter<UserCertificateTableModel>(tableModel); } - + public void initialize(String baseFolder) { setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage()); setTitle("Gitblit Certificate Authority v" + Constants.getVersion() + " (" + Constants.getBuildDate() + ")"); @@ -187,14 +184,14 @@ @Override public void windowOpened(WindowEvent event) { } - }); + }); File folder = new File(baseFolder).getAbsoluteFile(); load(folder); - + setSizeAndPosition(); } - + private void setSizeAndPosition() { String sz = null; String pos = null; @@ -243,30 +240,27 @@ Utils.showException(GitblitAuthority.this, t); } } - + private StoredConfig getConfig() throws IOException, ConfigInvalidException { File configFile = new File(folder, X509Utils.CA_CONFIG); FileBasedConfig config = new FileBasedConfig(configFile, FS.detect()); config.load(); return config; } - + private IUserService loadUsers(File folder) { File file = new File(folder, "gitblit.properties"); if (!file.exists()) { return null; } gitblitSettings = new FileSettings(file.getAbsolutePath()); - mail = new MailExecutor(gitblitSettings); + mail = new MailService(gitblitSettings); String us = gitblitSettings.getString(Keys.realm.userService, "${baseFolder}/users.conf"); String ext = us.substring(us.lastIndexOf(".") + 1).toLowerCase(); IUserService service = null; - if (!ext.equals("conf") && !ext.equals("properties")) { - if (us.equals("com.gitblit.LdapUserService")) { - us = gitblitSettings.getString(Keys.realm.ldap.backingUserService, "${baseFolder}/users.conf"); - } else if (us.equals("com.gitblit.LdapUserService")) { - us = gitblitSettings.getString(Keys.realm.redmine.backingUserService, "${baseFolder}/users.conf"); - } + if (!ext.equals("conf") && !ext.equals("properties") && ext.contains("userservice")) { + String realm = ext.substring(0, ext.indexOf("userservice")); + us = gitblitSettings.getString(MessageFormat.format("realm.{0}.backingUserService", realm), "${baseFolder}/users.conf"); } if (us.endsWith(".conf")) { @@ -274,11 +268,11 @@ } else { throw new RuntimeException("Unsupported user service: " + us); } - + service = new ConfigUserService(FileUtils.resolveParameter(Constants.baseFolder$, folder, us)); return service; } - + private void load(File folder) { this.folder = folder; this.userService = loadUsers(folder); @@ -290,7 +284,7 @@ Map<String, UserCertificateModel> map = new HashMap<String, UserCertificateModel>(); for (String user : userService.getAllUsernames()) { UserModel model = userService.getUserModel(user); - UserCertificateModel ucm = new UserCertificateModel(model); + UserCertificateModel ucm = new UserCertificateModel(model); map.put(user, ucm); } File certificatesConfigFile = new File(folder, X509Utils.CA_CONFIG); @@ -299,8 +293,8 @@ try { config.load(); // replace user certificate model with actual data - List<UserCertificateModel> list = UserCertificateConfig.KEY.parse(config).list; - for (UserCertificateModel ucm : list) { + List<UserCertificateModel> list = UserCertificateConfig.KEY.parse(config).list; + for (UserCertificateModel ucm : list) { ucm.user = userService.getUserModel(ucm.user.username); map.put(ucm.user.username, ucm); } @@ -310,15 +304,15 @@ e.printStackTrace(); } } - + tableModel.list = new ArrayList<UserCertificateModel>(map.values()); Collections.sort(tableModel.list); tableModel.fireTableDataChanged(); Utils.packColumns(table, Utils.MARGIN); - + File caKeystore = new File(folder, X509Utils.CA_KEY_STORE); if (!caKeystore.exists()) { - + if (!X509Utils.unlimitedStrength) { // prompt to confirm user understands JCE Standard Strength encryption int res = JOptionPane.showConfirmDialog(GitblitAuthority.this, Translation.get("gb.jceWarning"), @@ -335,16 +329,16 @@ System.exit(1); } } - - // show certificate defaults dialog + + // show certificate defaults dialog certificateDefaultsButton.doClick(); - + // create "localhost" ssl certificate prepareX509Infrastructure(); } } } - + private boolean prepareX509Infrastructure() { if (caKeystorePassword == null) { JPasswordField pass = new JPasswordField(10); @@ -367,7 +361,7 @@ X509Utils.prepareX509Infrastructure(metadata, folder, this); return true; } - + private List<X509Certificate> findCerts(File folder, String username) { List<X509Certificate> list = new ArrayList<X509Certificate>(); File userFolder = new File(folder, X509Utils.CERTS + File.separator + username); @@ -382,7 +376,7 @@ }); try { CertificateFactory factory = CertificateFactory.getInstance("X.509"); - for (File cert : certs) { + for (File cert : certs) { BufferedInputStream is = new BufferedInputStream(new FileInputStream(cert)); X509Certificate x509 = (X509Certificate) factory.generateCertificate(is); is.close(); @@ -393,16 +387,16 @@ } return list; } - - private Container getUI() { + + private Container getUI() { userCertificatePanel = new UserCertificatePanel(this) { - + private static final long serialVersionUID = 1L; @Override public Insets getInsets() { return Utils.INSETS; } - + @Override public boolean isAllowEmail() { return mail.isReady(); @@ -418,12 +412,12 @@ c.set(Calendar.MILLISECOND, 0); return c.getTime(); } - + @Override public boolean saveUser(String username, UserCertificateModel ucm) { return userService.updateUserModel(username, ucm.user); } - + @Override public boolean newCertificate(UserCertificateModel ucm, X509Metadata metadata, boolean sendEmail) { if (!prepareX509Infrastructure()) { @@ -433,9 +427,9 @@ Date notAfter = metadata.notAfter; setMetadataDefaults(metadata); metadata.notAfter = notAfter; - + // set user's specified OID values - UserModel user = ucm.user; + UserModel user = ucm.user; if (!StringUtils.isEmpty(user.organizationalUnit)) { metadata.oids.put("OU", user.organizationalUnit); } @@ -459,21 +453,21 @@ if (ucm.expires == null || metadata.notAfter.before(ucm.expires)) { ucm.expires = metadata.notAfter; } - + updateAuthorityConfig(ucm); - + // refresh user ucm.certs = null; - int modelIndex = table.convertRowIndexToModel(table.getSelectedRow()); + int selectedIndex = table.getSelectedRow(); tableModel.fireTableDataChanged(); - table.getSelectionModel().setSelectionInterval(modelIndex, modelIndex); - + table.getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex); + if (sendEmail) { sendEmail(user, metadata, zip); } return true; } - + @Override public boolean revoke(UserCertificateModel ucm, X509Certificate cert, RevocationReason reason) { if (!prepareX509Infrastructure()) { @@ -500,20 +494,20 @@ } catch (Exception e) { Utils.showException(GitblitAuthority.this, e); } - + // refresh user ucm.certs = null; int modelIndex = table.convertRowIndexToModel(table.getSelectedRow()); tableModel.fireTableDataChanged(); table.getSelectionModel().setSelectionInterval(modelIndex, modelIndex); - + return true; } - + return false; } }; - + table = Utils.newTable(tableModel, Utils.DATE_FORMAT); table.setRowSorter(defaultSorter); table.setDefaultRenderer(CertificateStatus.class, new CertificateStatusRenderer()); @@ -536,9 +530,9 @@ userCertificatePanel.setUserCertificateModel(ucm); } }); - + JPanel usersPanel = new JPanel(new BorderLayout()) { - + private static final long serialVersionUID = 1L; @Override @@ -549,10 +543,10 @@ usersPanel.add(new HeaderPanel(Translation.get("gb.users"), "users_16x16.png"), BorderLayout.NORTH); usersPanel.add(new JScrollPane(table), BorderLayout.CENTER); usersPanel.setMinimumSize(new Dimension(400, 10)); - + certificateDefaultsButton = new JButton(new ImageIcon(getClass().getResource("/settings_16x16.png"))); certificateDefaultsButton.setFocusable(false); - certificateDefaultsButton.setToolTipText(Translation.get("gb.newCertificateDefaults")); + certificateDefaultsButton.setToolTipText(Translation.get("gb.newCertificateDefaults")); certificateDefaultsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -570,6 +564,7 @@ certificateConfig.update(metadata); } InputVerifier verifier = new InputVerifier() { + @Override public boolean verify(JComponent comp) { boolean returnValue; JTextField textField = (JTextField) comp; @@ -594,18 +589,18 @@ validityTF.setText("" + certificateConfig.duration); JPanel validityPanel = Utils.newFieldPanel(Translation.get("gb.validity"), validityTF, Translation.get("gb.duration.days").replace("{0}", "").trim()); - + JPanel p1 = new JPanel(new GridLayout(0, 1, 5, 2)); p1.add(siteNamePanel); p1.add(validityPanel); - + DefaultOidsPanel oids = new DefaultOidsPanel(metadata); JPanel panel = new JPanel(new BorderLayout()); panel.add(p1, BorderLayout.NORTH); panel.add(oids, BorderLayout.CENTER); - int result = JOptionPane.showConfirmDialog(GitblitAuthority.this, + int result = JOptionPane.showConfirmDialog(GitblitAuthority.this, panel, Translation.get("gb.newCertificateDefaults"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, new ImageIcon(getClass().getResource("/settings_32x32.png"))); if (result == JOptionPane.OK_OPTION) { @@ -614,7 +609,7 @@ certificateConfig.duration = Integer.parseInt(validityTF.getText()); certificateConfig.store(config, metadata); config.save(); - + Map<String, String> updates = new HashMap<String, String>(); updates.put(Keys.web.siteName, siteNameTF.getText()); gitblitSettings.saveSettings(updates); @@ -624,10 +619,10 @@ } } }); - + newSSLCertificate = new JButton(new ImageIcon(getClass().getResource("/rosette_16x16.png"))); newSSLCertificate.setFocusable(false); - newSSLCertificate.setToolTipText(Translation.get("gb.newSSLCertificate")); + newSSLCertificate.setToolTipText(Translation.get("gb.newSSLCertificate")); newSSLCertificate.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -641,7 +636,7 @@ final Date expires = dialog.getExpiration(); final String hostname = dialog.getHostname(); final boolean serveCertificate = dialog.isServeCertificate(); - + AuthorityWorker worker = new AuthorityWorker(GitblitAuthority.this) { @Override @@ -649,12 +644,12 @@ if (!prepareX509Infrastructure()) { return false; } - + // read CA private key and certificate File caKeystoreFile = new File(folder, X509Utils.CA_KEY_STORE); PrivateKey caPrivateKey = X509Utils.getPrivateKey(X509Utils.CA_ALIAS, caKeystoreFile, caKeystorePassword); X509Certificate caCert = X509Utils.getCertificate(X509Utils.CA_ALIAS, caKeystoreFile, caKeystorePassword); - + // generate new SSL certificate X509Metadata metadata = new X509Metadata(hostname, caKeystorePassword); setMetadataDefaults(metadata); @@ -674,24 +669,24 @@ @Override protected void onSuccess() { if (serveCertificate) { - JOptionPane.showMessageDialog(GitblitAuthority.this, + JOptionPane.showMessageDialog(GitblitAuthority.this, MessageFormat.format(Translation.get("gb.sslCertificateGeneratedRestart"), hostname), Translation.get("gb.newSSLCertificate"), JOptionPane.INFORMATION_MESSAGE); } else { - JOptionPane.showMessageDialog(GitblitAuthority.this, + JOptionPane.showMessageDialog(GitblitAuthority.this, MessageFormat.format(Translation.get("gb.sslCertificateGenerated"), hostname), Translation.get("gb.newSSLCertificate"), JOptionPane.INFORMATION_MESSAGE); } } }; - + worker.execute(); } }); - + JButton emailBundle = new JButton(new ImageIcon(getClass().getResource("/mail_16x16.png"))); emailBundle.setFocusable(false); - emailBundle.setToolTipText(Translation.get("gb.emailCertificateBundle")); + emailBundle.setToolTipText(Translation.get("gb.emailCertificateBundle")); emailBundle.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -708,7 +703,7 @@ if (!zip.exists()) { return; } - + AuthorityWorker worker = new AuthorityWorker(GitblitAuthority.this) { @Override protected Boolean doRequest() throws IOException { @@ -726,15 +721,15 @@ JOptionPane.showMessageDialog(GitblitAuthority.this, MessageFormat.format(Translation.get("gb.clientCertificateBundleSent"), ucm.user.getDisplayName())); } - + }; - worker.execute(); + worker.execute(); } }); - + JButton logButton = new JButton(new ImageIcon(getClass().getResource("/script_16x16.png"))); logButton.setFocusable(false); - logButton.setToolTipText(Translation.get("gb.log")); + logButton.setToolTipText(Translation.get("gb.log")); logButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -748,19 +743,21 @@ } } }); - + final JTextField filterTextfield = new JTextField(15); filterTextfield.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { filterUsers(filterTextfield.getText()); } }); filterTextfield.addKeyListener(new KeyAdapter() { + @Override public void keyReleased(KeyEvent e) { filterUsers(filterTextfield.getText()); } }); - + JToolBar buttonControls = new JToolBar(JToolBar.HORIZONTAL); buttonControls.setFloatable(false); buttonControls.add(certificateDefaultsButton); @@ -771,17 +768,17 @@ JPanel userControls = new JPanel(new FlowLayout(FlowLayout.RIGHT, Utils.MARGIN, Utils.MARGIN)); userControls.add(new JLabel(Translation.get("gb.filter"))); userControls.add(filterTextfield); - + JPanel topPanel = new JPanel(new BorderLayout(0, 0)); topPanel.add(buttonControls, BorderLayout.WEST); topPanel.add(userControls, BorderLayout.EAST); - + JPanel leftPanel = new JPanel(new BorderLayout()); leftPanel.add(topPanel, BorderLayout.NORTH); leftPanel.add(usersPanel, BorderLayout.CENTER); - + userCertificatePanel.setMinimumSize(new Dimension(375, 10)); - + JLabel statusLabel = new JLabel(); statusLabel.setHorizontalAlignment(SwingConstants.RIGHT); if (X509Utils.unlimitedStrength) { @@ -789,9 +786,10 @@ } else { statusLabel.setText("JCE Standard Encryption Policy"); } - + JPanel root = new JPanel(new BorderLayout()) { private static final long serialVersionUID = 1L; + @Override public Insets getInsets() { return Utils.INSETS; } @@ -802,13 +800,16 @@ root.add(statusLabel, BorderLayout.SOUTH); return root; } - + private void filterUsers(final String fragment) { + table.clearSelection(); + userCertificatePanel.setUserCertificateModel(null); if (StringUtils.isEmpty(fragment)) { table.setRowSorter(defaultSorter); return; } RowFilter<UserCertificateTableModel, Object> containsFilter = new RowFilter<UserCertificateTableModel, Object>() { + @Override public boolean include(Entry<? extends UserCertificateTableModel, ? extends Object> entry) { for (int i = entry.getValueCount() - 1; i >= 0; i--) { if (entry.getStringValue(i).toLowerCase().contains(fragment.toLowerCase())) { @@ -823,7 +824,7 @@ sorter.setRowFilter(containsFilter); table.setRowSorter(sorter); } - + @Override public void log(String message) { BufferedWriter writer = null; @@ -843,32 +844,22 @@ } } } - + private boolean sendEmail(UserModel user, X509Metadata metadata, File zip) { // send email try { if (mail.isReady()) { - Message message = mail.createMessage(user.emailAddress); - message.setSubject("Your Gitblit client certificate for " + metadata.serverHostname); - - // body of email + Mailing mailing = Mailing.newPlain(); + mailing.subject = "Your Gitblit client certificate for " + metadata.serverHostname; + mailing.setRecipients(user.emailAddress); String body = X509Utils.processTemplate(new File(folder, X509Utils.CERTS + File.separator + "mail.tmpl"), metadata); if (StringUtils.isEmpty(body)) { body = MessageFormat.format("Hi {0}\n\nHere is your client certificate bundle.\nInside the zip file are installation instructions.", user.getDisplayName()); } - Multipart mp = new MimeMultipart(); - MimeBodyPart messagePart = new MimeBodyPart(); - messagePart.setText(body); - mp.addBodyPart(messagePart); + mailing.content = body; + mailing.addAttachment(zip); - // attach zip - MimeBodyPart filePart = new MimeBodyPart(); - FileDataSource fds = new FileDataSource(zip); - filePart.setDataHandler(new DataHandler(fds)); - filePart.setFileName(fds.getName()); - mp.addBodyPart(filePart); - - message.setContent(mp); + Message message = mail.createMessage(mailing); mail.sendNow(message); return true; @@ -880,13 +871,13 @@ } return false; } - + private void setMetadataDefaults(X509Metadata metadata) { metadata.serverHostname = gitblitSettings.getString(Keys.web.siteName, Constants.NAME); if (StringUtils.isEmpty(metadata.serverHostname)) { metadata.serverHostname = Constants.NAME; } - + // set default values from config file File certificatesConfigFile = new File(folder, X509Utils.CA_CONFIG); FileBasedConfig config = new FileBasedConfig(certificatesConfigFile, FS.detect()); @@ -900,7 +891,7 @@ certificateConfig.update(metadata); } } - + private void updateAuthorityConfig(UserCertificateModel ucm) { File certificatesConfigFile = new File(folder, X509Utils.CA_CONFIG); FileBasedConfig config = new FileBasedConfig(certificatesConfigFile, FS.detect()); -- Gitblit v1.9.1