Add repository with keyring
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 29 Sep 2011 16:56:34 +0000 (16:56 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 29 Sep 2011 16:56:34 +0000 (16:56 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@4766 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

server/plugins/org.argeo.jcr.ui.explorer/META-INF/MANIFEST.MF
server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/commands.xml
server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/jcr.xml
server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/osgi.xml
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/AddRemoteRepository.java

index bea753babb38b2d84187c46cac1d0d3eab107277..b903e07630acdb3730c69ccb9fe0d28c064b0c5e 100644 (file)
@@ -30,8 +30,12 @@ Import-Package: javax.jcr,
  org.argeo.eclipse.ui.specific,
  org.argeo.eclipse.ui.utils,
  org.argeo.jcr,
+ org.argeo.jcr.security,
  org.argeo.jcr.spring,
+ org.argeo.security.jcr,
+ org.argeo.security.ui,
  org.argeo.util,
+ org.argeo.util.crypto,
  org.eclipse.ui.forms,
  org.eclipse.ui.forms.editor,
  org.eclipse.ui.forms.events,
index 93845192925cd85ad18814453baa38faeb1c3345..8a2f071eb6dbe06c158722069d7a864e51a8343f 100644 (file)
@@ -23,6 +23,7 @@
        <bean id="addRemoteRepository" class="org.argeo.jcr.ui.explorer.commands.AddRemoteRepository">
                <property name="repositoryFactory" ref="repositoryFactory" />
                <property name="bundleContext" ref="bundleContext" />
+               <property name="keyring" ref="jcrKeyring" />
        </bean>
 
        <bean id="addFolderNode" class="org.argeo.jcr.ui.explorer.commands.AddFolderNode"
index 2701948bdd790c90081f311d891189ec8f99fdf9..728e005b5d7f63d4ba7c558488b5a233f5c0afa8 100644 (file)
@@ -7,4 +7,14 @@
 
        <bean id="repositoryRegister" class="org.argeo.jcr.DefaultRepositoryRegister">
        </bean>
+
+       <bean id="nodeSession" class="org.argeo.security.jcr.SecureThreadBoundSession">
+               <property name="repository" ref="nodeRepository" />
+       </bean>
+
+       <bean id="jcrKeyring" class="org.argeo.jcr.security.JcrKeyring">
+               <property name="session" ref="nodeSession" />
+               <property name="defaultCallbackHandler" ref="defaultCallbackHandler" />
+       </bean>
+
 </beans>
index 0aa6ff3a3b401c69108c2ff60a3a48e6e61572d2..6771ecc560769c76b768dff98a71a2aead49def8 100644 (file)
@@ -16,4 +16,9 @@
 \r
        <reference id="repositoryFactory" interface="javax.jcr.RepositoryFactory" />\r
 \r
+       <reference id="nodeRepository" interface="javax.jcr.Repository"\r
+               filter="(argeo.jcr.repository.alias=node)" />\r
+\r
+       <reference id="defaultCallbackHandler" interface="javax.security.auth.callback.CallbackHandler" />\r
+\r
 </beans:beans>
\ No newline at end of file
index 9f12281d40c73b9529ef09e577657a54e1607982..4e120ac478a88afab8946ba058c490afe2f5a769 100644 (file)
@@ -1,38 +1,66 @@
 package org.argeo.jcr.ui.explorer.commands;
 
+import java.net.URI;
 import java.util.Hashtable;
 
+import javax.jcr.Node;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
 
 import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.eclipse.ui.dialogs.SingleValue;
 import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.security.JcrKeyring;
 import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
 import org.osgi.framework.BundleContext;
 
 /**
- * Connect to a remote repository and, if usccessful publish it as an OSGi
+ * Connect to a remote repository and, if successful publish it as an OSGi
  * service.
  */
 public class AddRemoteRepository extends AbstractHandler implements
-               JcrExplorerConstants {
+               JcrExplorerConstants, ArgeoNames {
 
        private RepositoryFactory repositoryFactory;
        private BundleContext bundleContext;
 
+       private JcrKeyring keyring;
+
        public Object execute(ExecutionEvent event) throws ExecutionException {
-               String uri;
-               if (event.getParameters().containsKey(PARAM_REPOSITORY_URI))
+               String uri = null;
+               if (event.getParameters().containsKey(PARAM_REPOSITORY_URI)) {
                        uri = event.getParameter(PARAM_REPOSITORY_URI);
-               else
-                       uri = SingleValue
-                                       .ask("URI",
-                                                       "Remote repository URI"
-                                                                       + " (e.g. http://localhost:7070/org.argeo.jcr.webapp/remoting/node)");
+               } else {
+                       RemoteRepositoryLoginDialog dlg = new RemoteRepositoryLoginDialog(
+                                       Display.getDefault().getActiveShell());
+                       if (dlg.open() == Dialog.OK) {
+                               uri = dlg.getUri();
+                       }
+               }
 
                if (uri == null)
                        return null;
@@ -59,4 +87,127 @@ public class AddRemoteRepository extends AbstractHandler implements
                this.bundleContext = bundleContext;
        }
 
+       public void setKeyring(JcrKeyring keyring) {
+               this.keyring = keyring;
+       }
+
+       class RemoteRepositoryLoginDialog extends TitleAreaDialog {
+               private String uri;
+               private Text name;
+               private Text uriText;
+               private Text username;
+               private Text password;
+
+               public RemoteRepositoryLoginDialog(Shell parentShell) {
+                       super(parentShell);
+               }
+
+               protected Point getInitialSize() {
+                       return new Point(600, 400);
+               }
+
+               protected Control createDialogArea(Composite parent) {
+                       Composite dialogarea = (Composite) super.createDialogArea(parent);
+                       dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
+                                       true));
+                       Composite composite = new Composite(dialogarea, SWT.NONE);
+                       composite.setLayout(new GridLayout(2, false));
+                       composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
+                                       false));
+                       setMessage("Login to remote repository", IMessageProvider.NONE);
+                       name = createLT(composite, "Name", "remoteRepository");
+                       uriText = createLT(composite, "URI",
+                                       "http://localhost:7070/org.argeo.jcr.webapp/remoting/node");
+                       username = createLT(composite, "User", "");
+                       password = createLP(composite, "Password");
+                       parent.pack();
+                       return composite;
+               }
+
+               @Override
+               protected void createButtonsForButtonBar(Composite parent) {
+                       super.createButtonsForButtonBar(parent);
+                       Button test = createButton(parent, 2, "Test", false);
+                       test.addSelectionListener(new SelectionAdapter() {
+                               public void widgetSelected(SelectionEvent arg0) {
+                                       testConnection();
+                               }
+                       });
+               }
+
+               void testConnection() {
+                       Session session = null;
+                       try {
+                               URI checkedUri = new URI(uriText.getText());
+                               String checkedUriStr = checkedUri.toString();
+
+                               Hashtable<String, String> params = new Hashtable<String, String>();
+                               params.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, checkedUriStr);
+                               // by default we use the URI as alias
+                               params.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS,
+                                               checkedUriStr);
+                               Repository repository = repositoryFactory.getRepository(params);
+                               if (username.getText().trim().equals("")) {// anonymous
+                                       session = repository.login();
+                               } else {
+                                       // FIXME use getTextChars() when upgrading to 3.7
+                                       // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=297412
+                                       char[] pwd = password.getText().toCharArray();
+                                       SimpleCredentials sc = new SimpleCredentials(
+                                                       username.getText(), pwd);
+                                       session = repository.login(sc);
+                                       MessageDialog.openInformation(getParentShell(), "Success",
+                                                       "Connection to " + uri + "successful");
+                               }
+                       } catch (Exception e) {
+                               ErrorFeedback.show(
+                                               "Connection test failed for " + uriText.getText(), e);
+                       } finally {
+                               JcrUtils.logoutQuietly(session);
+                       }
+               }
+
+               @Override
+               protected void okPressed() {
+                       try {
+                               Session nodeSession = keyring.getSession();
+                               Node home = JcrUtils.getUserHome(nodeSession);
+                               Node remote = home.hasNode(ARGEO_REMOTE) ? home
+                                               .getNode(ARGEO_REMOTE) : home.addNode(ARGEO_REMOTE);
+                               Node remoteRepository = remote.addNode(name.getText(),
+                                               ArgeoTypes.ARGEO_REMOTE_REPOSITORY);
+                               remoteRepository.setProperty(ARGEO_URI, uriText.getText());
+                               remoteRepository.setProperty(ARGEO_USER_ID, username.getText());
+                               Node pwd = remoteRepository.addNode(ARGEO_PASSWORD);
+                               keyring.set(pwd.getPath(), password.getText().toCharArray());
+                               nodeSession.save();
+                       } catch (Exception e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+                       uri = uriText.getText();
+                       super.okPressed();
+               }
+
+               /** Creates label and text. */
+               protected Text createLT(Composite parent, String label, String initial) {
+                       new Label(parent, SWT.NONE).setText(label);
+                       Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
+                       text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+                       text.setText(initial);
+                       return text;
+               }
+
+               protected Text createLP(Composite parent, String label) {
+                       new Label(parent, SWT.NONE).setText(label);
+                       Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER
+                                       | SWT.PASSWORD);
+                       text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+                       return text;
+               }
+
+               public String getUri() {
+                       return uri;
+               }
+       }
 }