/**************************************************************************
OmegaT - Computer Assisted Translation (CAT) tool
with fuzzy matching, translation memory, keyword search,
glossaries, and translation leveraging into updated projects.
Copyright (C) 2015 Alex Buloichik
Home page: http://www.omegat.org/
Support center: http://groups.yahoo.com/group/OmegaT/
This file is part of OmegaT.
OmegaT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OmegaT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
package org.omegat.core.team2.impl;
import java.util.logging.Logger;
import javax.net.ssl.TrustManager;
import org.omegat.core.Core;
import org.omegat.core.KnownException;
import org.omegat.core.team2.ProjectTeamSettings;
import org.omegat.core.team2.TeamSettings;
import org.omegat.util.Log;
import org.omegat.util.OStrings;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider;
import org.tmatesoft.svn.core.auth.ISVNProxyManager;
import org.tmatesoft.svn.core.auth.SVNAuthentication;
import org.tmatesoft.svn.core.auth.SVNPasswordAuthentication;
import org.tmatesoft.svn.core.auth.SVNSSHAuthentication;
import org.tmatesoft.svn.core.auth.SVNUserNameAuthentication;
import org.tmatesoft.svn.core.io.SVNRepository;
import com.jcraft.jsch.agentproxy.AgentProxyException;
import com.jcraft.jsch.agentproxy.ConnectorFactory;
import com.jcraft.jsch.agentproxy.TrileadAgentProxy;
/**
* Authentication manager for SVN. See details about authentication at the
* http://wiki.svnkit.com/Authentication. Authentication manager created for each repository instance.
*
* Only username+password authentication supported. Proxy not supported for https:// repositories.
*
* @author Alex Buloichik (alex73mail@gmail.com)
*/
public class SVNAuthenticationManager implements ISVNAuthenticationManager {
static final int CONNECT_TIMEOUT = 30 * 1000; // 30 seconds
static final int READ_TIMEOUT = 60 * 1000; // 60 seconds
static final String KEY_USERNAME_SUFFIX = "username";
static final String KEY_PASSWORD_SUFFIX = "password";
private static final Logger LOGGER = Logger.getLogger(SVNAuthenticationManager.class.getName());
private final String repoUrl;
private final String predefinedUser;
private final String predefinedPass;
//private final ProjectTeamSettings teamSettings;
public SVNAuthenticationManager(String repoUrl, String predefinedUser, String predefinedPass,
ProjectTeamSettings teamSettings) {
this.repoUrl = repoUrl;
this.predefinedUser = predefinedUser;
this.predefinedPass = predefinedPass;
//this.teamSettings = teamSettings;
}
@Override
public void acknowledgeAuthentication(boolean accepted, String kind, String realm,
SVNErrorMessage errorMessage, SVNAuthentication authentication) throws SVNException {
if (!accepted) {
Log.logDebug(LOGGER, "SVN authentication error: {0}", errorMessage);
}
}
@Override
public void acknowledgeTrustManager(TrustManager manager) {
throw new UnsupportedOperationException();
}
@Override
public int getConnectTimeout(SVNRepository repository) {
return CONNECT_TIMEOUT;
}
@Override
public int getReadTimeout(SVNRepository repository) {
return READ_TIMEOUT;
}
protected SVNAuthentication ask(String kind, SVNURL url, String message) throws SVNException {
if (ISVNAuthenticationManager.PASSWORD.equals(kind)) {
// ask username+password
} else if (ISVNAuthenticationManager.SSH.equals(kind)) {
// ask username+password
} else if (ISVNAuthenticationManager.USERNAME.equals(kind)) {
// user auth shouldn't be null.
return SVNUserNameAuthentication.newInstance("", false, url, false);
} else {
// auth type not supported for OmegaT
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.RA_UNKNOWN_AUTH));
}
SVNUserPassDialog userPassDialog = new SVNUserPassDialog(Core.getMainWindow().getApplicationFrame());
userPassDialog.setLocationRelativeTo(Core.getMainWindow().getApplicationFrame());
userPassDialog.descriptionTextArea.setText(message);
userPassDialog.setVisible(true);
if (userPassDialog.getReturnStatus() != SVNUserPassDialog.RET_OK) {
return null;
}
String user = userPassDialog.userText.getText();
String pass = new String(userPassDialog.passwordField.getPassword());
TeamSettings.set(repoUrl + "!" + KEY_USERNAME_SUFFIX, user);
TeamSettings.set(repoUrl + "!" + KEY_PASSWORD_SUFFIX, TeamUtils.encodePassword(pass));
if (ISVNAuthenticationManager.PASSWORD.equals(kind)) {
return SVNPasswordAuthentication.newInstance(user, pass.toCharArray(), false, url, false);
} else if (ISVNAuthenticationManager.SSH.equals(kind)) {
return SVNSSHAuthentication.newInstance(user, pass.toCharArray(), -1, false, url, false);
} else {
// auth type not supported for OmegaT
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.RA_UNKNOWN_AUTH));
}
}
@Override
public SVNAuthentication getFirstAuthentication(String kind, String realm, SVNURL url)
throws SVNException {
if (predefinedUser != null && predefinedPass != null) {
if (ISVNAuthenticationManager.PASSWORD.equals(kind)) {
return SVNPasswordAuthentication.newInstance(predefinedUser, predefinedPass.toCharArray(),
false, url, false);
} else if (ISVNAuthenticationManager.SSH.equals(kind)) {
return SVNSSHAuthentication.newInstance(predefinedUser, predefinedPass.toCharArray(), -1,
false, url, false);
} else {
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.AUTHN_NO_PROVIDER));
}
} else if (predefinedUser != null) {
try {
return SVNSSHAuthentication.newInstance(predefinedUser,
new TrileadAgentProxy(ConnectorFactory.getDefault().createConnector()), -1, url, false);
} catch (AgentProxyException e) {
Log.logDebug(LOGGER, "ssh-agent support couldn't be initialized: {0}", e.getMessage());
}
}
String user = TeamSettings.get(repoUrl + "!" + KEY_USERNAME_SUFFIX);
String pass = TeamUtils.decodePassword(TeamSettings.get(repoUrl + "!" + KEY_PASSWORD_SUFFIX));
if (user != null && pass != null) {
if (ISVNAuthenticationManager.PASSWORD.equals(kind)) {
return SVNPasswordAuthentication.newInstance(user, pass.toCharArray(), false, url, false);
} else if (ISVNAuthenticationManager.SSH.equals(kind)) {
return SVNSSHAuthentication.newInstance(user, pass.toCharArray(), -1, false, url, false);
} else {
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.AUTHN_NO_PROVIDER));
}
}
return ask(kind, url, OStrings.getString("TEAM_USERPASS_FIRST"));
}
public SVNAuthentication getNextAuthentication(String kind, String realm, SVNURL url) throws SVNException {
if (predefinedUser != null && predefinedPass != null) {
throw new KnownException("TEAM_PREDEFINED_CREDENTIALS_ERROR");
}
return ask(kind, url, OStrings.getString("TEAM_USERPASS_WRONG"));
};
@Override
public ISVNProxyManager getProxyManager(SVNURL url) throws SVNException {
return NO_PROXY;
}
@Override
public TrustManager getTrustManager(SVNURL url) throws SVNException {
return null;
}
@Override
public boolean isAuthenticationForced() {
return false;
}
@Override
public void setAuthenticationProvider(ISVNAuthenticationProvider provider) {
throw new UnsupportedOperationException();
}
ISVNProxyManager NO_PROXY = new ISVNProxyManager() {
public String getProxyHost() {
return null;
}
public String getProxyPassword() {
return null;
}
public int getProxyPort() {
return -1;
}
public String getProxyUserName() {
return null;
}
public void acknowledgeProxyContext(boolean accepted, SVNErrorMessage errorMessage) {
}
};
}