r1859 - in isis-fish/trunk: . src/main/java/fr/ifremer/isisfish/vcs src/main/resources/i18n
Author: chatellier Date: 2009-02-23 10:29:50 +0000 (Mon, 23 Feb 2009) New Revision: 1859 Modified: isis-fish/trunk/pom.xml isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCSSVN.java isis-fish/trunk/src/main/resources/i18n/isis-fish-en_GB.properties isis-fish/trunk/src/main/resources/i18n/isis-fish-fr_FR.properties Log: Ask for passphrase in svn+ssh connection Modified: isis-fish/trunk/pom.xml =================================================================== --- isis-fish/trunk/pom.xml 2009-02-23 09:02:58 UTC (rev 1858) +++ isis-fish/trunk/pom.xml 2009-02-23 10:29:50 UTC (rev 1859) @@ -302,6 +302,12 @@ <version>1.2.2.5405</version> <scope>compile</scope> </dependency> + <dependency> + <groupId>com.trilead</groupId> + <artifactId>trilead-ssh2</artifactId> + <version>build213-svnkit-1.2</version> + <scope>runtime</scope> + </dependency> <!-- fin svnkit pour communication subversion --> <dependency> @@ -350,12 +356,12 @@ <lutinj2r.version>0.2</lutinj2r.version> <jrst.version>0.8.4</jrst.version> <license-switcher.version>0.6</license-switcher.version> - <openmap.version>4.6.4</openmap.version> <aspectwerkz.version>2.0</aspectwerkz.version> <sshtool.version>0.2.2</sshtool.version> <xmlrpc.version>3.1</xmlrpc.version> - + <javadoc.version>2.5</javadoc.version> + <!--Main class in JAR --> <maven.jar.main.class>fr.ifremer.isisfish.IsisFish</maven.jar.main.class> Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCSSVN.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCSSVN.java 2009-02-23 09:02:58 UTC (rev 1858) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCSSVN.java 2009-02-23 10:29:50 UTC (rev 1859) @@ -30,6 +30,8 @@ import java.util.Map; import java.util.Set; +import javax.swing.JOptionPane; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.codelutin.util.VersionNumber; @@ -39,12 +41,14 @@ import org.tmatesoft.svn.core.SVNDirEntry; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.auth.BasicAuthenticationManager; import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; +import org.tmatesoft.svn.core.auth.SVNAuthentication; +import org.tmatesoft.svn.core.auth.SVNSSHAuthentication; import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory; import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory; import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl; import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions; -import org.tmatesoft.svn.core.wc.ISVNOptions; import org.tmatesoft.svn.core.wc.ISVNStatusHandler; import org.tmatesoft.svn.core.wc.SVNClientManager; import org.tmatesoft.svn.core.wc.SVNCommitClient; @@ -74,7 +78,7 @@ /** to use log facility, just put in your code: log.info(\"...\"); */ protected static Log log = LogFactory.getLog(VCSSVN.class); - static enum ConnectionState { + protected static enum ConnectionState { NOT_TESTED, OFF_LINE, ON_LINE } @@ -113,25 +117,54 @@ * @return SVNManager instance */ protected SVNClientManager getSVNManager() { + if (svnManager == null) { + + // log + if (log.isInfoEnabled()) { + try { + log.info("Try to connect to " + getRemoteURL()); + } catch (SVNException e) { + if (log.isErrorEnabled()) { + log.error("Can't get remote repo url"); + } + } + } + String login = getLogin(); String passwd = getPassword(); + DefaultSVNOptions options = SVNWCUtil.createDefaultOptions(true); if (getProtocol().contains("ssh")) { - ISVNOptions options = SVNWCUtil.createDefaultOptions(true); - // options.setPropertyValue("svnkit.ssh2.key", getSshKeyFile().getAbsolutePath()); - // options.setPropertyValue("svnkit.ssh2.username", login); - // if (passwd != null && !"".equals(passwd)) { - // options.setPropertyValue("svnkit.ssh2.passphrase", passwd); - // } - ISVNAuthenticationManager auth = SVNWCUtil - .createDefaultAuthenticationManager(SVNWCUtil - .getDefaultConfigurationDirectory(), login, - passwd, sshKeyFile, passwd, false); + ISVNAuthenticationManager auth = null; + + if (sshKeyFile != null && sshKeyFile.canRead()) { + + // log for private key + if (log.isInfoEnabled()) { + log.info("Unsing ssh private key : " + + sshKeyFile.getAbsolutePath()); + } + + // FIXME following AuthenticationManager will try to connect to + // realm and if it fail, will try to ask for passphrase + // even if there is another error + // FIXME 22 here + auth = new SSHSVNAuthenticationManager(login, sshKeyFile, + null, 22); + } else { + + // log for private key + if (log.isWarnEnabled()) { + log.warn("Cannot read ssh private key : " + sshKeyFile); + } + + auth = SVNWCUtil.createDefaultAuthenticationManager( + SVNWCUtil.getDefaultConfigurationDirectory(), + login, passwd); + } svnManager = SVNClientManager.newInstance(options, auth); } else { - DefaultSVNOptions options = SVNWCUtil - .createDefaultOptions(true); svnManager = SVNClientManager.newInstance(options, login, passwd); } @@ -165,15 +198,15 @@ getSVNManager().getWCClient().doGetProperty(url, "", SVNRevision.HEAD, SVNRevision.HEAD); connectionState = ConnectionState.ON_LINE; - - if(log.isInfoEnabled()) { + + if (log.isInfoEnabled()) { log.info(_("isisfish.vcs.vcssvn.isconnected.switchto", - getRemoteRepository())); + getRemoteRepository())); } } catch (SVNException eee) { - if(log.isWarnEnabled()) { + if (log.isWarnEnabled()) { log.warn(_("isisfish.vcs.vcssvn.isconnected.switchoff", - getRemoteRepository())); + getRemoteRepository()), eee); } connectionState = ConnectionState.OFF_LINE; } @@ -191,39 +224,42 @@ */ @Override public void checkProtocol() throws VCSException { - + // on doit verifier ici que seul le protocole a change // le doRelocate de svn, ne permet de ne change que // le protocol ou host par exemple // dans le cas d'un changement de path, le do relocate // echoue (operation non permise) - + try { // test que les protocoles, userInfo, host, port sont egaux. - + // copies locales File localRoot = getLocalRepository(); SVNInfo info = getSVNManager().getWCClient().doInfo(localRoot, SVNRevision.WORKING); SVNURL url = info.getURL(); - + // url distante (suposée) SVNURL newUrl = getRemoteURL(); - + // hack just for doRelocate to work newUrl = newUrl.setPath(url.getPath(), false); - + if (!url.getProtocol().equals(newUrl.getProtocol()) // http, svn ... - || (url.getUserInfo() == null && newUrl.getUserInfo() != url.getUserInfo()) // username - || (url.getUserInfo() != null && !url.getUserInfo().equals(newUrl.getUserInfo())) // username + || (url.getUserInfo() == null && newUrl.getUserInfo() != url + .getUserInfo()) // username + || (url.getUserInfo() != null && !url.getUserInfo().equals( + newUrl.getUserInfo())) // username || url.getPort() != newUrl.getPort() // 80 || !url.getHost().equals(newUrl.getHost())) { if (fireAction(VCSActionEvent.SWITCH_PROTOCOL)) { - if(log.isInfoEnabled()) { - log.info(_("isisfish.vcs.vcssvn.checkProtocol.relocate", localRoot, - url, newUrl)); + if (log.isInfoEnabled()) { + log.info(_( + "isisfish.vcs.vcssvn.checkProtocol.relocate", + localRoot, url, newUrl)); } - + // le relocate de SVNKit // ne supporte que le changement de protocole/host/port // pas le path @@ -390,7 +426,8 @@ SVNDepth.INFINITY); // depth if (log.isInfoEnabled()) { - log.info(_("isisfish.vcs.vcssvn.global.torevision", commitInfo.getNewRevision())); + log.info(_("isisfish.vcs.vcssvn.global.torevision", commitInfo + .getNewRevision())); } } catch (SVNException e) { throw new VCSException(_("isisfish.vcs.vcssvn.commit.error"), e); @@ -399,8 +436,7 @@ public void add(List<File> files, String msg) throws VCSException { if (!isWriteable()) { - throw new VCSException( - _("isisfish.vcs.vcssvn.add.errorreadonly")); + throw new VCSException(_("isisfish.vcs.vcssvn.add.errorreadonly")); } try { if (fireAction(VCSActionEvent.ADD, files.toArray(new File[files @@ -463,7 +499,8 @@ true); // boolean allowUnversionedObstructions if (log.isInfoEnabled()) { - log.info(_("isisfish.vcs.vcssvn.global.torevision", newRevision)); + log.info(_("isisfish.vcs.vcssvn.global.torevision", + newRevision)); } } } catch (SVNException eee) { @@ -557,7 +594,8 @@ return result; } catch (SVNException eee) { - throw new VCSException(_("isisfish.vcs.vcssvn.localstatus.error"), eee); + throw new VCSException(_("isisfish.vcs.vcssvn.localstatus.error"), + eee); } } @@ -623,7 +661,8 @@ return result; } catch (SVNException eee) { - throw new VCSException(_("isisfish.vcs.vcssvn.remotestatus.error"), eee); + throw new VCSException(_("isisfish.vcs.vcssvn.remotestatus.error"), + eee); } } @@ -638,7 +677,7 @@ public Map<File, String> getChanglog(List<File> files) throws VCSException { throw new UnsupportedOperationException("Not supported yet."); - + /*final Map<File, String> changLog = new HashMap<File, String>(); try { @@ -648,7 +687,7 @@ // Handler ISVNLogEntryHandler handler = new ISVNLogEntryHandler() { - + @Override public void handleLogEntry(SVNLogEntry logEntry) throws SVNException { @@ -790,13 +829,14 @@ final List<File> result = new ArrayList<File>(); ISVNStatusHandler handler = new ISVNStatusHandler() { + public void handleStatus(SVNStatus status) throws SVNException { // log if (log.isDebugEnabled()) { - log.debug(_("isisfish.vcs.vcssvn.global.filestatus", status.getFile() - .getAbsolutePath(), status - .getRemoteContentsStatus().toString())); + log.debug(_("isisfish.vcs.vcssvn.global.filestatus", + status.getFile().getAbsolutePath(), status + .getRemoteContentsStatus().toString())); } if (status.getRemoteContentsStatus() == SVNStatusType.STATUS_ADDED @@ -804,8 +844,8 @@ // log if (log.isDebugEnabled()) { - log.debug(_("isisfish.vcs.vcssvn.global.foundUpdatedFile", status - .getFile().getAbsolutePath())); + log.debug(_("isisfish.vcs.vcssvn.global.foundUpdatedFile", + status.getFile().getAbsolutePath())); } result.add(status.getFile()); @@ -826,7 +866,8 @@ return result; } catch (SVNException eee) { - throw new VCSException(_("isisfish.vcs.vcssvn.getupdate.error"), eee); + throw new VCSException(_("isisfish.vcs.vcssvn.getupdate.error"), + eee); } } @@ -837,13 +878,13 @@ * @throws VCSException */ public boolean haveUpdate() throws VCSException { - + // c'est juste si la liste renvoyé par getUpdatedFile() n'est pas vide ? List<File> updatedFiles = getUpdatedFile(); - + boolean result = false; - - if(updatedFiles != null && !updatedFiles.isEmpty()) { + + if (updatedFiles != null && !updatedFiles.isEmpty()) { result = true; } return result; @@ -857,29 +898,33 @@ * @throws VCSException */ public boolean isOnRemote(File file) throws VCSException { - + File localFile = file; if (localFile == null) { localFile = getLocalRepository(); } - + boolean result = false; try { SVNStatusClient statusClient = getSVNManager().getStatusClient(); - SVNStatus status = statusClient.doStatus(localFile, true /*remote*/); - + SVNStatus status = statusClient + .doStatus(localFile, true /*remote*/); + SVNStatusType localStatus = status.getContentsStatus(); SVNStatusType remoteStatus = status.getRemoteContentsStatus(); - - if(log.isDebugEnabled()) { - log.debug(_("isisfish.vcs.vcssvn.global.filelocalandremotestatus",localFile.getAbsolutePath(),localStatus, remoteStatus)); + + if (log.isDebugEnabled()) { + log.debug(_("isisfish.vcs.vcssvn.global.filelocalandremotestatus", + localFile.getAbsolutePath(), localStatus, + remoteStatus)); } - + // don't return true if: // - file is locally added // - file is remotely deleted - if(!localStatus.equals(SVNStatusType.STATUS_ADDED) && !remoteStatus.equals(SVNStatusType.STATUS_DELETED)) { + if (!localStatus.equals(SVNStatusType.STATUS_ADDED) + && !remoteStatus.equals(SVNStatusType.STATUS_DELETED)) { result = true; } @@ -887,11 +932,12 @@ // catch exception // if exception, file doesn't exists on server // result is still 'false' - if(log.isDebugEnabled()) { - log.debug(_("isisfish.vcs.vcssvn.isonremote.error",localFile.getAbsolutePath()),e); + if (log.isDebugEnabled()) { + log.debug(_("isisfish.vcs.vcssvn.isonremote.error", localFile + .getAbsolutePath()), e); } } - + return result; } @@ -904,31 +950,34 @@ */ @Override public boolean isUpToDate(File file) throws VCSException { - + File localFile = file; if (localFile == null) { localFile = getLocalRepository(); } - + boolean result = false; - + try { SVNStatusClient statusClient = getSVNManager().getStatusClient(); - SVNStatus status = statusClient.doStatus(localFile, true /*remote*/); + SVNStatus status = statusClient + .doStatus(localFile, true /*remote*/); SVNStatusType localStatus = status.getContentsStatus(); SVNStatusType remoteStatus = status.getRemoteContentsStatus(); - + // TODO peut on dire que le fichier est à jour // si le status local est normal et le distant est none - if (localStatus == SVNStatusType.STATUS_NORMAL && remoteStatus == SVNStatusType.STATUS_NONE) { + if (localStatus == SVNStatusType.STATUS_NORMAL + && remoteStatus == SVNStatusType.STATUS_NONE) { result = true; } } catch (SVNException eee) { - throw new VCSException(_("isisfish.vcs.vcssvn.isuptodate.error"), eee); + throw new VCSException(_("isisfish.vcs.vcssvn.isuptodate.error"), + eee); } - + return result; } @@ -966,7 +1015,8 @@ false); // boolean depthIsSticky if (log.isInfoEnabled()) { - log.info(_("isisfish.vcs.vcssvn.global.torevision", newRevision)); + log.info(_("isisfish.vcs.vcssvn.global.torevision", + newRevision)); } // recherche de tous les fichiers locaux en conflit @@ -1059,8 +1109,7 @@ } return result; } catch (SVNException eee) { - throw new VCSException( - _("isisfish.vcs.vcssvn.gettag.error"), eee); + throw new VCSException(_("isisfish.vcs.vcssvn.gettag.error"), eee); } } @@ -1069,9 +1118,9 @@ */ @Override public List<File> setTag(VersionNumber version) throws VCSException { - + List<File> filesInConflict = null; - + try { String tag = "/trunk"; @@ -1111,11 +1160,12 @@ // chatellier: allowUnversionedObstructions must be true // if there is unversionned file or folder in repo, update will fail // with org.tmatesoft.svn.core.SVNException: svn: Unable to lock 'xxx' - + if (log.isInfoEnabled()) { - log.info(_("isisfish.vcs.vcssvn.global.torevision", newRevision)); + log.info(_("isisfish.vcs.vcssvn.global.torevision", + newRevision)); } - + // recherche de tous les fichiers locaux en conflit apres le switch Map<File, SVNStatus> status = getLocalStatus(localRoot, true, SVNStatusType.STATUS_CONFLICTED); @@ -1134,14 +1184,72 @@ } } } - - + } catch (SVNException eee) { - throw new VCSException( - _("isisfish.vcs.vcssvn.setTag.error"), eee); + throw new VCSException(_("isisfish.vcs.vcssvn.setTag.error"), eee); } - + return filesInConflict; } +} + +/** + * Authentication manager, that ask for passphrase + * if first authentication fail. + * + * @author chatellier + * @version $Revision: 1.0 $ + * + * Last update : $Date: 23 févr. 2009 $ + * By : $Author: chatellier $ + */ +class SSHSVNAuthenticationManager extends BasicAuthenticationManager { + + protected String userName; + protected File keyFile; + protected int portNumber; + + /** + * Creates an auth manager given a user credential - a username and an ssh private key. + * + * @param userName + * @param keyFile + * @param passphrase + * @param portNumber + */ + public SSHSVNAuthenticationManager(String userName, File keyFile, + String passphrase, int portNumber) { + super(userName, keyFile, passphrase, portNumber); + this.userName = userName; + this.keyFile = keyFile; + this.portNumber = portNumber; + } + + /* + * @see org.tmatesoft.svn.core.auth.BasicAuthenticationManager#getNextAuthentication(java.lang.String, java.lang.String, org.tmatesoft.svn.core.SVNURL) + */ + @Override + public SVNAuthentication getNextAuthentication(String kind, String realm, + SVNURL url) throws SVNException { + + SVNAuthentication auth = null; + + if (kind.equals(ISVNAuthenticationManager.SSH) && keyFile != null) { + + String passphrase = JOptionPane.showInputDialog(null, _( + "isisfish.vcs.vcssvn.connection.message", keyFile + .getAbsolutePath()), _( + "isisfish.vcs.vcssvn.connection.title", realm) + + url, JOptionPane.QUESTION_MESSAGE); + + if (passphrase != null) { + auth = new SVNSSHAuthentication(userName, keyFile, passphrase, + portNumber, true); + } + } else { + auth = super.getNextAuthentication(kind, realm, url); + } + return auth; + } } \ No newline at end of file Modified: isis-fish/trunk/src/main/resources/i18n/isis-fish-en_GB.properties =================================================================== --- isis-fish/trunk/src/main/resources/i18n/isis-fish-en_GB.properties 2009-02-23 09:02:58 UTC (rev 1858) +++ isis-fish/trunk/src/main/resources/i18n/isis-fish-en_GB.properties 2009-02-23 10:29:50 UTC (rev 1859) @@ -938,6 +938,8 @@ isisfish.vcs.vcssvn.checkout.error=Can't checkout isisfish.vcs.vcssvn.commit.error=Can't commit files isisfish.vcs.vcssvn.commit.errorreadonly=You can't commit file, this repository is readonly +isisfish.vcs.vcssvn.connection.message=Passphrase for key %s +isisfish.vcs.vcssvn.connection.title=Connecting to %s isisfish.vcs.vcssvn.delete.error=Can't delete file isisfish.vcs.vcssvn.delete.errorreadonly=You can't delete file, this repository is readonly isisfish.vcs.vcssvn.diff.error=Can't get diff Modified: isis-fish/trunk/src/main/resources/i18n/isis-fish-fr_FR.properties =================================================================== --- isis-fish/trunk/src/main/resources/i18n/isis-fish-fr_FR.properties 2009-02-23 09:02:58 UTC (rev 1858) +++ isis-fish/trunk/src/main/resources/i18n/isis-fish-fr_FR.properties 2009-02-23 10:29:50 UTC (rev 1859) @@ -938,6 +938,8 @@ isisfish.vcs.vcssvn.checkout.error=Impossible de mettre \u00E0 jour isisfish.vcs.vcssvn.commit.error=Impossible de commiter isisfish.vcs.vcssvn.commit.errorreadonly=Vous ne pouvez pas commiter, le d\u00E9p\u00F4t est en lecture seule +isisfish.vcs.vcssvn.connection.message=Passphrase pour la cl\u00E9 %s +isisfish.vcs.vcssvn.connection.title=Connexion \u00E0 %s isisfish.vcs.vcssvn.delete.error=Impossible de supprimer des fichiers isisfish.vcs.vcssvn.delete.errorreadonly=Vous ne pouvez pas supprimer ce fichier, le d\u00E9p\u00F4t est en lecture seule isisfish.vcs.vcssvn.diff.error=Impossible d'obtenir le diff
participants (1)
-
chatellier@users.labs.libre-entreprise.org