Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EGit / JGit » Determining which authentication method(Figuring out which authentication method (HTTP, SSH, etc) is appropriate for a repo)
Determining which authentication method [message #1731236] Tue, 03 May 2016 16:21 Go to next message
Dave Musicant is currently offline Dave MusicantFriend
Messages: 15
Registered: May 2016
Junior Member
I'm trying to use JGit to determine which authentication method should be used for an existing repo. With the regular command-line Git client, this info is baked into the remote definition; issuing a "git fetch," for example, knows whether HTTP or SSH (or whatever) is the right one to use.

I've written the following code to perform the same auto-detection using JGit. It seems to work, but I've got some questions as to whether there is a better way:

       ... repo is the Repository of interest ....
        Config storedConfig = repo.getConfig();
        Set<String> remotes = storedConfig.getSubsections("remote");
        // challenges here if I have more than one remote, but that's a separate problem
        String repoUrl = storedConfig.getString("remote", remote, "url"));

        List<TransportProtocol> protocols = TransportGitSsh.getTransportProtocols();
        List<String> repoURLs = getLinkedRemoteRepoURLs();

        for (TransportProtocol protocol : protocols) {
            String protocolName = protocol.getName();
            try {
                if (protocol.canHandle(new URIish(repoURL))) {
                    if (protocolName.equals("HTTP"))
                        // do whatever I want from here, point is I've discovered HTTP is the right protocol
                    else if (protocolName.equals("SSH"))
                        // do whatever I want from here, point is I've discovered SSH is the right protocol
                    else
                        continue;
                }
            } catch (URISyntaxException e) {
                throw new RuntimeException(e);
            }
        }


This seems to work, but I've got the following concerns:


  • Is using the protocol name a reliable way to do this? Is that likely to be stable over multiple versions of JGit?
  • Iterating over all possible protocols and testing the name to see if it's the one I want seems clunky. Is there a way for me to more directly just ask: does this repo support SSH?
  • Can it be the case that canHandle returns true for more than one protocol? I'll need to rig up a priority structure in that case.


I think all of the above can be summarized by asking "is there a better canonical way to do what I'm trying to do?"
Re: Determining which authentication method [message #1731370 is a reply to message #1731236] Wed, 04 May 2016 16:18 Go to previous messageGo to next message
Matthias Sohn is currently offline Matthias SohnFriend
Messages: 1097
Registered: July 2009
Senior Member
JGit also reads the .git/config so if you create a FetchCommand and set the remote you want to fetch from this should use
the URL configured in the remote's configuration in the repository configuration.
Re: Determining which authentication method [message #1731543 is a reply to message #1731370] Fri, 06 May 2016 16:24 Go to previous messageGo to next message
Dave Musicant is currently offline Dave MusicantFriend
Messages: 15
Registered: May 2016
Junior Member
Matthias: thanks. The problem I'm particularly trying to solve is authenticating when issuing that FetchCommand. Depending on whether the remote is https vs ssh, my understanding is that the code I need to use (credential setting, SshSessionFactory or not, etc) is different. I'm running with this explanation here:

http://www.codeaffine.com/2014/12/09/jgit-authentication/

Going with this approach, it seems that being able to fetch automatically doesn't help if I don't know what authentication technique is being used. Or is there a way?
Re: Determining which authentication method [message #1731895 is a reply to message #1731543] Tue, 10 May 2016 16:58 Go to previous messageGo to next message
Rüdiger Herrmann is currently offline Rüdiger HerrmannFriend
Messages: 581
Registered: July 2009
Senior Member
Dave,

maybe there is a misunderstanding on my side, but you should be able to
1. either deduce the necessary authentication technique from the
protocol of the URL and install a suitable authentication provider
2. or blindly install all known authentication providers and let JGit
call back to the required one

HTH
Rüdiger

On 06.05.2016 18:24, Dave Musicant wrote:
> Matthias: thanks. The problem I'm particularly trying to solve is
> authenticating when issuing that FetchCommand. Depending on whether the
> remote is https vs ssh, my understanding is that the code I need to use
> (credential setting, SshSessionFactory or not, etc) is different. I'm
> running with this explanation here:
>
> http://www.codeaffine.com/2014/12/09/jgit-authentication/
>
> Going with this approach, it seems that being able to fetch
> automatically doesn't help if I don't know what authentication technique
> is being used. Or is there a way?
>
--
Rüdiger Herrmann
http://codeaffine.com
Re: Determining which authentication method [message #1731904 is a reply to message #1731895] Tue, 10 May 2016 18:16 Go to previous messageGo to next message
Dave Musicant is currently offline Dave MusicantFriend
Messages: 15
Registered: May 2016
Junior Member
Rüdiger -

I appreciate the response, thank you.

Of your two approaches, does either of those match the "Which Authentication Method to Use?" section of your blog posting? If I understand what you're suggesting (and I may not, so I'd appreciate the help if I'm confused), method 1 is ripping the protocol out of the URL as a strong operation. That sounds different than testing via a TransportProtocol canHandle method. Regarding method 2: the blog posting mentions using callbacks for ssh (password or public key), but not for HTTP. Is your method 2 here recommending adding a callback for HTTP as well?

Dave
Re: Determining which authentication method [message #1731911 is a reply to message #1731904] Tue, 10 May 2016 20:33 Go to previous messageGo to next message
Rüdiger Herrmann is currently offline Rüdiger HerrmannFriend
Messages: 581
Registered: July 2009
Senior Member
Hi Dave,

the two suggested methods don't exactly match the "Which Authentication
Method to Use?". The latter would make a third method, but similar to my
first suggestion.
Both, in essence, try to determine beforehand which protocol will be
used and configure the JGit operation accordingly. Method one however
wouldn't be "ripping the protocol out of the URL". The ideas is -
similar to what the blog post suggests - inspect the URL to find out
which protocol will be used.

But again, I think it won't harm to configure the operation with all
known authentication methods (method two) and have the operation "pick"
the appropriate one.

HTH
Rüdiger


On 10.05.2016 20:16, Dave Musicant wrote:
> Rüdiger -
>
> I appreciate the response, thank you.
>
> Of your two approaches, does either of those match the "Which
> Authentication Method to Use?" section of your blog posting? If I
> understand what you're suggesting (and I may not, so I'd appreciate the
> help if I'm confused), method 1 is ripping the protocol out of the URL
> as a strong operation. That sounds different than testing via a
> TransportProtocol canHandle method. Regarding method 2: the blog posting
> mentions using callbacks for ssh (password or public key), but not for
> HTTP. Is your method 2 here recommending adding a callback for HTTP as
> well?
>
> Dave
--
Rüdiger Herrmann
http://codeaffine.com
Re: Determining which authentication method [message #1731997 is a reply to message #1731911] Wed, 11 May 2016 14:32 Go to previous messageGo to next message
Dave Musicant is currently offline Dave MusicantFriend
Messages: 15
Registered: May 2016
Junior Member
Ok, thanks. It's still not entirely clear to me (yet) how to use callbacks to have the operation pick the appropriate authentication method, but I'll play around with it and see what I can do. If it doesn't become clear to me as I try to code it up, I'll followup with a more specific question if/when I've got one!
Re: Determining which authentication method [message #1732491 is a reply to message #1731997] Tue, 17 May 2016 15:54 Go to previous messageGo to next message
Dave Musicant is currently offline Dave MusicantFriend
Messages: 15
Registered: May 2016
Junior Member
Hi folks, I'm back. I'm trying to work with Rüdiger's suggestion to "configure the operation with all known authentication methods (method two) and have the operation 'pick' the appropriate one."

I've ended up with some prototype code that looks like:

        LsRemoteCommand command = Git.lsRemoteRepository();
        //command.setRemote("https://github.com/....repo1...");
        command.setRemote("git@github.com:...repo2...");

        SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
            @Override
            protected void configure(OpenSshConfig.Host host, Session session ) {
                // do nothing
            }
        };

        command.setTransportConfigCallback( new TransportConfigCallback() {
            @Override
            public void configure( Transport transport ) {
                System.out.println(transport.getClass());
                SshTransport sshTransport = ( SshTransport )transport;
                sshTransport.setSshSessionFactory( sshSessionFactory );

        }
        } );
        command.call();


When I run the code as given, I'm setting the remote to an SSH remote. The callback receives a TransportGitSSh transport object, and setting up the SshSessionFactory works as expected. When I comment out the line with repo2 and instead use repo1, the callback instead receives a TransportHttp object, and then of course casting the transport object to an SshTransport fails. I could solve this via an instanceof test, but that felt to me like I wasn't understanding the spirit of Rüdiger's idea of "configuring with all known authentication methods." I would only be able to configure it for ssh if the transport object was of the appropriate type. Am I headed in the right direction with instanceof tests, or am I missing the point?
Re: Determining which authentication method [message #1732892 is a reply to message #1732491] Sun, 22 May 2016 09:35 Go to previous messageGo to next message
Rüdiger Herrmann is currently offline Rüdiger HerrmannFriend
Messages: 581
Registered: July 2009
Senior Member
Dave,

the instaneof tests are the best I could come up with. While this works
in practice, there is certainly room for improvement in readability and
maintainability. You may for example consider a generic
TransportConfigCallback that let others contribute 'configurers' for
certain protocols.

From a practical POV, SSH is the only protocol I know of that requires
an extra configuration step. For the remaining protocols a credentials
provider is sufficient.

Hence the TransportConfigCallback I have in use looks like this:

@Override
public void configure( Transport transport ) {
transport.setCredentialsProvider( new MyCredentialsProvider() );
if( transport instanceof SshTransport ) {
SshTransport sshTransport = ( SshTransport )transport;
sshTransport.setSshSessionFactory( new MySshSessionFactory() );
}
}

where MyCredentialsProvider is a ChainingCredentialsProvider that chains
a NetRCCredentialsProvider and a user/password credentials provider.

HTH
Rüdiger

On 17.05.2016 17:54, Dave Musicant wrote:
> Hi folks, I'm back. I'm trying to work with Rüdiger's suggestion to
> "configure the operation with all known authentication methods (method
> two) and have the operation 'pick' the appropriate one."
>
> I've ended up with some prototype code that looks like:
>
>
> LsRemoteCommand command = Git.lsRemoteRepository();
> //command.setRemote("https://github.com/....repo1...");
> command.setRemote("git@xxxxxxxx:...repo2...");
>
> SshSessionFactory sshSessionFactory = new
> JschConfigSessionFactory() {
> @Override
> protected void configure(OpenSshConfig.Host host, Session
> session ) {
> // do nothing
> }
> };
>
> command.setTransportConfigCallback( new TransportConfigCallback() {
> @Override
> public void configure( Transport transport ) {
> System.out.println(transport.getClass());
> SshTransport sshTransport = ( SshTransport )transport;
> sshTransport.setSshSessionFactory( sshSessionFactory );
>
> }
> } );
> command.call();
>
>
> When I run the code as given, I'm setting the remote to an SSH remote.
> The callback receives a TransportGitSSh transport object, and setting up
> the SshSessionFactory works as expected. When I comment out the line
> with repo2 and instead use repo1, the callback instead receives a
> TransportHttp object, and then of course casting the transport object to
> an SshTransport fails. I could solve this via an instanceof test, but
> that felt to me like I wasn't understanding the spirit of Rüdiger's idea
> of "configuring with all known authentication methods." I would only be
> able to configure it for ssh if the transport object was of the
> appropriate type. Am I headed in the right direction with instanceof
> tests, or am I missing the point?
Re: Determining which authentication method [message #1732954 is a reply to message #1732892] Mon, 23 May 2016 11:32 Go to previous message
Dave Musicant is currently offline Dave MusicantFriend
Messages: 15
Registered: May 2016
Junior Member
That's great and helps immensely. Thanks, Rüdiger.

--
Dave
Previous Topic:Clear working directory before checkout in eGit
Next Topic:How to Detect Checkout
Goto Forum:
  


Current Time: Tue Oct 22 19:54:09 GMT 2019

Powered by FUDForum. Page generated in 0.02385 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top