package bluej.groupwork.git;

import bluej.Config;
import bluej.groupwork.Repository;
import bluej.groupwork.TeamSettings;
import bluej.groupwork.TeamworkCommandError;
import bluej.groupwork.TeamworkCommandResult;
import bluej.groupwork.TeamworkCommandUnsupportedSetting;
import bluej.groupwork.TeamworkProvider;
import bluej.groupwork.UnsupportedSettingException;
import bluej.utility.Debug;
import bluej.utility.DialogManager;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.Arrays;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.LsRemoteCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.SshTransport;
import org.eclipse.jgit.transport.Transport;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.util.FS;

import threadchecker.OnThread;
import threadchecker.Tag;


| Teamwork provider for Git. | | @author Fabio Hedayioglu | @OnThread(Tag.Any) public class GitProvider implements TeamworkProvider { private String gitUrlString; @Override public String getProviderName() { return "Git"; } @Override public String[] getProtocols() { return new String[]{"https", "http", "ssh", "git"}; } @Override public String getProtocolKey(int protocol) { return getProtocols()[protocol]; } @Override public String getProtocolLabel(String protocolKey) { return protocolKey; } @Override public TeamworkCommandResult checkConnection(TeamSettings settings) { try { gitUrlString = makeGitUrl(settings); LsRemoteCommand lsRemoteCommand = Git.lsRemoteRepository(); UsernamePasswordCredentialsProvider cp = new UsernamePasswordCredentialsProvider(settings.getUserName(), settings.getPassword()); lsRemoteCommand.setRemote(gitUrlString); lsRemoteCommand.setCredentialsProvider(cp); lsRemoteCommand.setTags(false); lsRemoteCommand.setHeads(false); if (gitUrlString.startsWith("ssh")) { SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() { @Override protected void configure(OpenSshConfig.Host host, Session sn) { java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); sn.setConfig(config); } @Override protected JSch createDefaultJSch(FS fs) throws JSchException { return super.createDefaultJSch(fs); } }; lsRemoteCommand.setTransportConfigCallback((Transport t) -> { SshTransport sshTransport = (SshTransport) t; sshTransport.setSshSessionFactory(sshSessionFactory); }); } lsRemoteCommand.call(); } catch (GitAPIException ex) { if (ex instanceof TransportException) { TeamworkCommandResult diagnosis = connectionDiagnosis(gitUrlString); if (!diagnosis.isError()) { if (ex.getLocalizedMessage().contains("access denied or repository not exported")) { return new TeamworkCommandError(DialogManager.getMessage("team-denied-invalidUser"), DialogManager.getMessage("team-denied-invalidUser")); } if (ex.getLocalizedMessage().contains("Auth fail")) { return new TeamworkCommandError(DialogManager.getMessage("team-denied-invalidUser"), DialogManager.getMessage("team-denied-invalidUser")); } if (ex.getLocalizedMessage().contains("does not appear to be a git repository")) { String message = DialogManager.getMessage("team-noRepository-uri", ex.getLocalizedMessage()); return new TeamworkCommandError( message, message); } if (settings.getProtocol().contains("file") || settings.getProtocol().contains("http") || settings.getProtocol().contains("git")) { String message = DialogManager.getMessage("team-noRepository-uri", ex.getLocalizedMessage()); return new TeamworkCommandError(message, message); } } return diagnosis; } return new TeamworkCommandError(ex.getMessage(), ex.getLocalizedMessage()); } catch (UnsupportedSettingException ex) { return new TeamworkCommandUnsupportedSetting(ex.getLocalizedMessage()); } return new TeamworkCommandResult(); } @Override public Repository getRepository(File projectDir, TeamSettings settings) throws UnsupportedSettingException { try { return new GitRepository(projectDir, settings.getProtocol(), makeGitUrl(settings), settings.getUserName(), settings.getPassword(), settings.getYourName(), settings.getYourEmail()); } catch (UnsupportedSettingException e) { Debug.reportError("Unsupported Git Repository Settings " + e.getMessage()); throw new UnsupportedSettingException(e.getLocalizedMessage()); } }
| Construct a git URL based on the given team settings | | @param settings the teamwork settings to build the connection string | from. | @return the git-compatible connection string | @throws bluej.groupwork.UnsupportedSettingException | @OnThread(Tag.Any) protected String makeGitUrl(TeamSettings settings) throws UnsupportedSettingException { String protocol = settings.getProtocol(); if (protocol == null || !Arrays.asList(settings.getProvider().getProtocols()).contains(protocol)){ throw new UnsupportedSettingException(Config.getString("team.error.unknownProtocol")); } String server = settings.getServer(); if ((server == null || server.isEmpty()) /*&& !protocol.equals("file") // file protocol is unsupported currently*/ ){ throw new UnsupportedSettingException(Config.getString("team.error.cannotParseServer")); } String prefix = settings.getPrefix(); if (prefix == null || prefix.isEmpty()){ throw new UnsupportedSettingException(Config.getString("team.error.cannotParsePath")); } String gitUrl = protocol + "://"; //There is a bug in jGit where the username is ignored in a ssh connection. //the workaround is to inject the username in the url string. if (protocol.contains("ssh")){ gitUrl += settings.getUserName()+"@"; } if (server != null) gitUrl += server; if (prefix.length() != 0 && !prefix.startsWith("/")) { gitUrl += "/"; } gitUrl += prefix; return gitUrl; } /** * This method creates a connection to the server and then diagnose * the possible causes. This method detects the following connection | problems: | unknown host | wrong protocol | malformed uri. | | @param gitUrlString the string containing the connection uri; | @return A {}link TeamworkCommandResult} with a useful error if the problem | is that we cannot connect at all to the server, but a successful | result if we can connect to the server. The username/password is not | checked, and neither is the server type. We only open a socket, | no more. | public static TeamworkCommandResult connectionDiagnosis(String gitUrlString) { try { URI uri = new URI(gitUrlString); if (uri.getScheme().equals("file")) return new TeamworkCommandResult(); int port = uri.getPort(); if (port <= 0) { switch (uri.getScheme().toLowerCase()) { case "http": port = 80; break; case "https": port = 443; break; case "ssh": port = 22; break; case "git": port = 9418; break; } } Socket s = new Socket(uri.getHost(), port); s.close(); return new TeamworkCommandResult(); } catch (IOException ex) { if (ex instanceof UnknownHostException) { return new TeamworkCommandError(DialogManager.getMessage("team-cant-connect"), DialogManager.getMessage("team-cant-connect")); } else if (ex instanceof ConnectException) { return new TeamworkCommandError(DialogManager.getMessage("team-wrong-protocol"), DialogManager.getMessage("team-wrong-protocol")); } Debug.reportError(ex.getMessage()); return new TeamworkCommandError(ex.getMessage(), ex.getLocalizedMessage()); } catch (URISyntaxException ex) { Debug.reportError(ex.getMessage()); return new TeamworkCommandError(DialogManager.getMessage("team-malformed-uri"), DialogManager.getMessage("team-malformed-uri")); } } @Override public boolean needsEmail() { return true; } @Override public boolean needsName() { return true; }
| Find the user email as configured for the repository, if any. | | @param projectPath path to the BlueJ project | @return the stored name, if any, or null | @Override public String getYourNameFromRepo(File projectPath) { String result = null; try { try (Git repo = Git.open(projectPath)) { StoredConfig repoConfig = repo.getRepository().getConfig(); result = repoConfig.getString("user", null, "name"); } } catch (IOException ex) { Debug.reportError("Git: Could not get user name from repository", ex); } return result; }
| Find the user email as configured for the repository, if any. | | @param projectPath path to the BlueJ project | @return the stored email address, if any, or null | @Override public String getYourEmailFromRepo(File projectPath) { String result = null; try { try (Git repo = Git.open(projectPath)) { StoredConfig repoConfig = repo.getRepository().getConfig(); result = repoConfig.getString("user", null, "email"); } } catch (IOException ex) { Debug.reportError("Git: Could not get user email from repository", ex); } return result; } @Override public boolean isDVCS() { return true; } }
top, use, map, class GitProvider

.   getProviderName
.   getProtocols
.   getProtocolKey
.   getProtocolLabel
.   checkConnection
.   configure
.   createDefaultJSch
.   getRepository
.   makeGitUrl
.   connectionDiagnosis
.   needsEmail
.   needsName
.   getYourNameFromRepo
.   getYourEmailFromRepo
.   isDVCS




379 neLoCode + 24 LoComm