-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Try to improve code readability by introducing a callback method for the interaction between the SingleUseCredentialsProvider and the PersistentCredentials class. Improve thread safety by making the getUsernameAndPassword method syncronized. This avoids to show multiple dialogues in parallel to the user in parallel.
- Loading branch information
Showing
2 changed files
with
117 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
...a/org/mastodon/mamut/tomancak/collaboration/credentials/SingleUseCredentialsProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package org.mastodon.mamut.tomancak.collaboration.credentials; | ||
|
||
import org.apache.commons.lang3.tuple.Pair; | ||
import org.eclipse.jgit.errors.UnsupportedCredentialItem; | ||
import org.eclipse.jgit.transport.CredentialItem; | ||
import org.eclipse.jgit.transport.CredentialsProvider; | ||
import org.eclipse.jgit.transport.URIish; | ||
|
||
/** | ||
* The JGIT api does not tell a CredentialsProvider if the credentials | ||
* where correct. It simply asks for them again if they were wrong. | ||
* <p> | ||
* We can exploit this behavior by counting the number of times the | ||
* CredentialsProvider was asked for credentials. If it was asked more than | ||
* once, we assume that the credentials were wrong. | ||
* <p> | ||
* This only works if the CredentialsProvider is only used once. | ||
*/ | ||
class SingleUseCredentialsProvider extends CredentialsProvider | ||
{ | ||
private final Callback callback; | ||
|
||
private int counter = 0; | ||
|
||
public SingleUseCredentialsProvider( Callback callback ) | ||
{ | ||
this.callback = callback; | ||
} | ||
|
||
@Override | ||
public boolean isInteractive() | ||
{ | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean supports( CredentialItem... items ) | ||
{ | ||
for ( CredentialItem item : items ) | ||
if ( !isUsernameOrPassword( item ) ) | ||
return false; | ||
return true; | ||
} | ||
|
||
private boolean isUsernameOrPassword( CredentialItem item ) | ||
{ | ||
return ( item instanceof CredentialItem.Username ) || ( item instanceof CredentialItem.Password ); | ||
} | ||
|
||
@Override | ||
public boolean get( URIish uri, CredentialItem... items ) throws UnsupportedCredentialItem | ||
{ | ||
if ( !supports( items ) ) | ||
throw new UnsupportedCredentialItem( uri, "" ); | ||
counter++; | ||
boolean previousAuthenticationFailed = counter > 1; | ||
Pair< String, String > usernameAndPassword = callback.getUsernameAndPassword( uri, previousAuthenticationFailed ); | ||
if ( usernameAndPassword == null ) | ||
return false; | ||
fillUsernameAndPassword( items, usernameAndPassword.getLeft(), usernameAndPassword.getRight() ); | ||
return true; | ||
} | ||
|
||
private void fillUsernameAndPassword( CredentialItem[] items, String username, String password ) | ||
{ | ||
for ( CredentialItem item : items ) | ||
fillItem( item, username, password ); | ||
} | ||
|
||
private void fillItem( CredentialItem item, String username, String password ) | ||
{ | ||
if ( item instanceof CredentialItem.Username ) | ||
( ( CredentialItem.Username ) item ).setValue( username ); | ||
else if ( item instanceof CredentialItem.Password ) | ||
( ( CredentialItem.Password ) item ).setValue( password.toCharArray() ); | ||
} | ||
|
||
/** | ||
* Callback interface for {@link SingleUseCredentialsProvider}. | ||
*/ | ||
interface Callback | ||
{ | ||
|
||
/** | ||
* The {@link SingleUseCredentialsProvider} calls this method to get | ||
* username and password for the given {@link URIish}. | ||
* | ||
* @param uri the URI for which credentials are requested. | ||
* @param authenticationFailure true if the SingleUseCredentialsProvider | ||
* thinks that the credentials were wrong. | ||
* @return username and password or null if the user canceled the | ||
* request. | ||
* @see SingleUseCredentialsProvider | ||
*/ | ||
Pair< String, String > getUsernameAndPassword( URIish uri, boolean authenticationFailure ); | ||
} | ||
} |