package org.zaproxy.zap.extension.httpsessions; import java.awt.Component; import java.awt.Dialog; import javax.swing.JOptionPane; import org.apache.log4j.Logger; import org.parosproxy.paros.Constant; import org.parosproxy.paros.control.Control; import org.parosproxy.paros.extension.ExtensionPopupMenuItem; import org.parosproxy.paros.model.Model; import org.parosproxy.paros.view.SessionDialog; import org.parosproxy.paros.view.View; import org.zaproxy.zap.authentication.ManualAuthenticationMethodType; import org.zaproxy.zap.authentication.ManualAuthenticationMethodType.ManualAuthenticationMethod; import org.zaproxy.zap.extension.authentication.ExtensionAuthentication; import org.zaproxy.zap.extension.stdmenus.PopupContextMenuItemFactory; import org.zaproxy.zap.extension.users.ContextUsersPanel; import org.zaproxy.zap.extension.users.DialogAddUser; import org.zaproxy.zap.extension.users.ExtensionUserManagement; import org.zaproxy.zap.model.Context; import org.zaproxy.zap.users.User; public class PopupMenuFactoryAddUserFromSession extends PopupContextMenuItemFactory { private static final Logger log = Logger.getLogger(PopupMenuFactoryAddUserFromSession.class); private static final long serialVersionUID = 2453839120088204122L; /** The extension. */ private ExtensionHttpSessions extension; /** The extension auth. */ private ExtensionAuthentication extensionAuth; /** The extension users management. */ private ExtensionUserManagement extensionUsers; public PopupMenuFactoryAddUserFromSession(ExtensionHttpSessions extension) { super(Constant.messages.getString("httpsessions.popup.session.addUser")); this.extension = extension; } @Override public ExtensionPopupMenuItem getContextMenu(Context context, String parentMenu) { return new PopupMenuAddUserFromSession(context); } /** * Gets the authentication extension * * @return the extension authentication */ private ExtensionAuthentication getExtensionAuthentication() { if (extensionAuth == null) { extensionAuth = (ExtensionAuthentication) Control.getSingleton().getExtensionLoader() .getExtension(ExtensionAuthentication.NAME); } return extensionAuth; } /** * Gets the Users extension * * @return the extension Users */ private ExtensionUserManagement getExtensionUserManagement() { if (extensionUsers == null) { extensionUsers = (ExtensionUserManagement) Control.getSingleton().getExtensionLoader() .getExtension(ExtensionUserManagement.NAME); } return extensionUsers; } protected class PopupMenuAddUserFromSession extends ExtensionPopupMenuItem { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 301409585294663964L; @Override public boolean isSubMenu() { return true; } @Override public String getParentMenuName() { return Constant.messages.getString("httpsessions.popup.session.addUser"); } private Context context; private boolean pendingUsersClearing; private User newUser; public PopupMenuAddUserFromSession(Context context) { super(context.getName()); this.context = context; this.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent e) { performAction(); } }); } @Override public boolean isEnableForComponent(Component invoker) { // Only enable if the authentication and the UsersManagement extensions are enabled if (getExtensionAuthentication() == null) { return false; } if (getExtensionUserManagement() == null) { return false; } // Only enable it for the HttpSessionsPanel if (invoker.getName() != null && invoker.getName().equals(HttpSessionsPanel.PANEL_NAME)) { return true; } // Enable always for now. // // Only enable if the currently selected site is in the context // TODO: WOuld require cleaning up the port number from site name // if (context.isInContext(extension.getHttpSessionsPanel().getCurrentSite())) // return true; return false; } @Override public int getParentMenuIndex() { return 1; } /** * Make sure the user acknowledges the Users corresponding to this context will be deleted. * * @return true, if successful */ private boolean confirmUsersDeletion(Context uiSharedContext) { if (getExtensionUserManagement() != null) { if (getExtensionUserManagement().getSharedContextUsers(uiSharedContext).size() > 0) { int choice = JOptionPane.showConfirmDialog(this, Constant.messages.getString("authentication.dialog.confirmChange.label"), Constant.messages.getString("authentication.dialog.confirmChange.title"), JOptionPane.OK_CANCEL_OPTION); if (choice == JOptionPane.CANCEL_OPTION) { return false; } } } return true; } /** * A dialog, based on {@link DialogAddUser} that uses credentials based on existing session. */ private class DialogAddUserBasedOnSession extends DialogAddUser { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 2269873123657767822L; /** The session. */ private HttpSession session; public DialogAddUserBasedOnSession(Dialog owner, ExtensionUserManagement extension, HttpSession session) { super(owner, extension); this.session = session; } @Override protected void init() { if (this.workingContext == null) throw new IllegalStateException("A working Context should be set before setting the 'Add Dialog' visible."); // Initialize the credentials that will be configured configuredCredentials = ManualAuthenticationMethodType.createAuthenticationCredentials(session); getNameTextField().setText(session.getName()); getEnabledCheckBox().setSelected(true); initializeCredentialsConfigPanel(); } } /** * Shows the add User dialogue for creating an user based on a session. Method imported from * {@link ContextUsersPanel}. * * @return the user, or null if cancel was pressed */ private User showAddUserDialogue(Context uiSharedContext, HttpSession session) { DialogAddUserBasedOnSession addDialog = null; if (addDialog == null) { addDialog = new DialogAddUserBasedOnSession(View.getSingleton().getOptionsDialog(null), getExtensionUserManagement(), session); addDialog.pack(); } addDialog.setWorkingContext(uiSharedContext); addDialog.setVisible(true); User user = addDialog.getUser(); addDialog.clear(); addDialog.dispose(); return user; } public void performAction() { // Manually create the UI shared contexts so any modifications are done // on an UI shared Context, so changes can be undone by pressing Cancel SessionDialog sessionDialog = View.getSingleton().getSessionDialog(); sessionDialog.recreateUISharedContexts(Model.getSingleton().getSession()); final Context uiSharedContext = sessionDialog.getUISharedContext(this.context.getIndex()); HttpSessionsPanel panel = extension.getHttpSessionsPanel(); HttpSession session = panel.getSelectedSession(); log.info("Creating user from HttpSession " + session.getName() + " for Context " + uiSharedContext.getName()); pendingUsersClearing = false; // Do the work/changes on the UI shared context // First make sure the authentication method is Manual Authentication if (!(uiSharedContext.getAuthenticationMethod() instanceof ManualAuthenticationMethod)) { log.info("Creating new Manual Authentication instance for Context " + uiSharedContext.getName()); ManualAuthenticationMethod method = new ManualAuthenticationMethodType().createAuthenticationMethod(context .getIndex()); if (!confirmUsersDeletion(uiSharedContext)) { log.debug("Cancelled change of authentication type."); return; } uiSharedContext.setAuthenticationMethod(method); pendingUsersClearing = true; } newUser = showAddUserDialogue(uiSharedContext, session); if (newUser == null) { log.debug("Cancelled creation of user from HttpSession."); return; } log.info("Created user: " + newUser.toString()); // Show the session dialog without recreating UI Shared contexts // NOTE: First init the panels of the dialog so old users data gets loaded and just then update the users // from the UI data model, otherwise the 'real' users from the non-shared context would be loaded // and would override any deletions made. View.getSingleton().showSessionDialog(Model.getSingleton().getSession(), ContextUsersPanel.getPanelName(context.getIndex()), false, new Runnable() { @Override public void run() { // Removing the users from the 'shared context' (the UI) will cause their removal at // save as well if (getExtensionUserManagement() != null) { if (pendingUsersClearing) getExtensionUserManagement().removeSharedContextUsers(uiSharedContext); getExtensionUserManagement().addSharedContextUser(uiSharedContext, newUser); } } }); } } }