Creates HttpAuthMethod type enum to support auth ordering
Refactors HttpAuthMethod to support more authentication methods, still sorted by priority orders. Bug: 428836 Change-Id: I049c1742e7afbc51f3f6033fa4d471b344813cfa Signed-off-by: Laurent Goujon <lgoujon@twitter.com> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
This commit is contained in:
parent
0e7622a915
commit
0b5441a8ce
|
@ -69,8 +69,39 @@
|
||||||
* may need to maintain per-connection state information.
|
* may need to maintain per-connection state information.
|
||||||
*/
|
*/
|
||||||
abstract class HttpAuthMethod {
|
abstract class HttpAuthMethod {
|
||||||
/** No authentication is configured. */
|
/**
|
||||||
static final HttpAuthMethod NONE = new None();
|
* Enum listing the http authentication method types supported by jgit. They
|
||||||
|
* are sorted by priority order!!!
|
||||||
|
*/
|
||||||
|
public enum Type {
|
||||||
|
NONE {
|
||||||
|
@Override
|
||||||
|
public HttpAuthMethod method(String hdr) {
|
||||||
|
return None.INSTANCE;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
BASIC {
|
||||||
|
@Override
|
||||||
|
public HttpAuthMethod method(String hdr) {
|
||||||
|
return new Basic();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DIGEST {
|
||||||
|
@Override
|
||||||
|
public HttpAuthMethod method(String hdr) {
|
||||||
|
return new Digest(hdr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Creates a HttpAuthMethod instance configured with the provided HTTP
|
||||||
|
* WWW-Authenticate header.
|
||||||
|
*
|
||||||
|
* @param hdr the http header
|
||||||
|
* @return a configured HttpAuthMethod instance
|
||||||
|
*/
|
||||||
|
public abstract HttpAuthMethod method(String hdr);
|
||||||
|
}
|
||||||
|
|
||||||
static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
||||||
static final String SCHEMA_NAME_SEPARATOR = " "; //$NON-NLS-1$
|
static final String SCHEMA_NAME_SEPARATOR = " "; //$NON-NLS-1$
|
||||||
|
|
||||||
|
@ -83,7 +114,7 @@ abstract class HttpAuthMethod {
|
||||||
*/
|
*/
|
||||||
static HttpAuthMethod scanResponse(final HttpConnection conn) {
|
static HttpAuthMethod scanResponse(final HttpConnection conn) {
|
||||||
final Map<String, List<String>> headers = conn.getHeaderFields();
|
final Map<String, List<String>> headers = conn.getHeaderFields();
|
||||||
HttpAuthMethod authentication = NONE;
|
HttpAuthMethod authentication = Type.NONE.method(EMPTY_STRING);
|
||||||
|
|
||||||
for (final Entry<String, List<String>> entry : headers.entrySet()) {
|
for (final Entry<String, List<String>> entry : headers.entrySet()) {
|
||||||
if (HDR_WWW_AUTHENTICATE.equalsIgnoreCase(entry.getKey())) {
|
if (HDR_WWW_AUTHENTICATE.equalsIgnoreCase(entry.getKey())) {
|
||||||
|
@ -93,19 +124,23 @@ static HttpAuthMethod scanResponse(final HttpConnection conn) {
|
||||||
final String[] valuePart = value.split(
|
final String[] valuePart = value.split(
|
||||||
SCHEMA_NAME_SEPARATOR, 2);
|
SCHEMA_NAME_SEPARATOR, 2);
|
||||||
|
|
||||||
if (Digest.NAME.equalsIgnoreCase(valuePart[0])) {
|
try {
|
||||||
|
Type methodType = Type.valueOf(valuePart[0].toUpperCase());
|
||||||
|
if (authentication.getType().compareTo(methodType) >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
final String param;
|
final String param;
|
||||||
if (valuePart.length == 1)
|
if (valuePart.length == 1)
|
||||||
param = EMPTY_STRING;
|
param = EMPTY_STRING;
|
||||||
else
|
else
|
||||||
param = valuePart[1];
|
param = valuePart[1];
|
||||||
|
|
||||||
authentication = new Digest(param);
|
authentication = methodType
|
||||||
break;
|
.method(param);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// This auth method is not supported
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Basic.NAME.equalsIgnoreCase(valuePart[0]))
|
|
||||||
authentication = new Basic();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,6 +151,12 @@ static HttpAuthMethod scanResponse(final HttpConnection conn) {
|
||||||
return authentication;
|
return authentication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final Type type;
|
||||||
|
|
||||||
|
protected HttpAuthMethod(Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update this method with the credentials from the URIish.
|
* Update this method with the credentials from the URIish.
|
||||||
*
|
*
|
||||||
|
@ -170,8 +211,22 @@ boolean authorize(URIish uri, CredentialsProvider credentialsProvider) {
|
||||||
*/
|
*/
|
||||||
abstract void configureRequest(HttpConnection conn) throws IOException;
|
abstract void configureRequest(HttpConnection conn) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives the method type associated to this http auth method
|
||||||
|
*
|
||||||
|
* @return the method type
|
||||||
|
*/
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
/** Performs no user authentication. */
|
/** Performs no user authentication. */
|
||||||
private static class None extends HttpAuthMethod {
|
private static class None extends HttpAuthMethod {
|
||||||
|
static final None INSTANCE = new None();
|
||||||
|
public None() {
|
||||||
|
super(Type.NONE);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void authorize(String user, String pass) {
|
void authorize(String user, String pass) {
|
||||||
// Do nothing when no authentication is enabled.
|
// Do nothing when no authentication is enabled.
|
||||||
|
@ -185,12 +240,14 @@ void configureRequest(HttpConnection conn) throws IOException {
|
||||||
|
|
||||||
/** Performs HTTP basic authentication (plaintext username/password). */
|
/** Performs HTTP basic authentication (plaintext username/password). */
|
||||||
private static class Basic extends HttpAuthMethod {
|
private static class Basic extends HttpAuthMethod {
|
||||||
static final String NAME = "Basic"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
private String user;
|
private String user;
|
||||||
|
|
||||||
private String pass;
|
private String pass;
|
||||||
|
|
||||||
|
public Basic() {
|
||||||
|
super(Type.BASIC);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void authorize(final String username, final String password) {
|
void authorize(final String username, final String password) {
|
||||||
this.user = username;
|
this.user = username;
|
||||||
|
@ -201,14 +258,13 @@ void authorize(final String username, final String password) {
|
||||||
void configureRequest(final HttpConnection conn) throws IOException {
|
void configureRequest(final HttpConnection conn) throws IOException {
|
||||||
String ident = user + ":" + pass; //$NON-NLS-1$
|
String ident = user + ":" + pass; //$NON-NLS-1$
|
||||||
String enc = Base64.encodeBytes(ident.getBytes("UTF-8")); //$NON-NLS-1$
|
String enc = Base64.encodeBytes(ident.getBytes("UTF-8")); //$NON-NLS-1$
|
||||||
conn.setRequestProperty(HDR_AUTHORIZATION, NAME + " " + enc); //$NON-NLS-1$
|
conn.setRequestProperty(HDR_AUTHORIZATION, type.name()
|
||||||
|
+ " " + enc); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Performs HTTP digest authentication. */
|
/** Performs HTTP digest authentication. */
|
||||||
private static class Digest extends HttpAuthMethod {
|
private static class Digest extends HttpAuthMethod {
|
||||||
static final String NAME = "Digest"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
private static final Random PRNG = new Random();
|
private static final Random PRNG = new Random();
|
||||||
|
|
||||||
private final Map<String, String> params;
|
private final Map<String, String> params;
|
||||||
|
@ -220,6 +276,7 @@ private static class Digest extends HttpAuthMethod {
|
||||||
private String pass;
|
private String pass;
|
||||||
|
|
||||||
Digest(String hdr) {
|
Digest(String hdr) {
|
||||||
|
super(Type.DIGEST);
|
||||||
params = parse(hdr);
|
params = parse(hdr);
|
||||||
|
|
||||||
final String qop = params.get("qop"); //$NON-NLS-1$
|
final String qop = params.get("qop"); //$NON-NLS-1$
|
||||||
|
@ -288,7 +345,8 @@ void configureRequest(final HttpConnection conn) throws IOException {
|
||||||
v.append(e.getValue());
|
v.append(e.getValue());
|
||||||
v.append('"');
|
v.append('"');
|
||||||
}
|
}
|
||||||
conn.setRequestProperty(HDR_AUTHORIZATION, NAME + " " + v); //$NON-NLS-1$
|
conn.setRequestProperty(HDR_AUTHORIZATION, type.name()
|
||||||
|
+ " " + v); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String uri(URL u) {
|
private static String uri(URL u) {
|
||||||
|
|
|
@ -246,7 +246,7 @@ private HttpConfig() {
|
||||||
|
|
||||||
private boolean useSmartHttp = true;
|
private boolean useSmartHttp = true;
|
||||||
|
|
||||||
private HttpAuthMethod authMethod = HttpAuthMethod.NONE;
|
private HttpAuthMethod authMethod = HttpAuthMethod.Type.NONE.method(null);
|
||||||
|
|
||||||
private Map<String, String> headers;
|
private Map<String, String> headers;
|
||||||
|
|
||||||
|
@ -479,7 +479,7 @@ private HttpConnection connect(final String service)
|
||||||
// background (e.g Kerberos/SPNEGO).
|
// background (e.g Kerberos/SPNEGO).
|
||||||
// That may not work for streaming requests and jgit
|
// That may not work for streaming requests and jgit
|
||||||
// explicit authentication would be required
|
// explicit authentication would be required
|
||||||
if (authMethod == HttpAuthMethod.NONE
|
if (authMethod.getType() == HttpAuthMethod.Type.NONE
|
||||||
&& conn.getHeaderField(HDR_WWW_AUTHENTICATE) != null)
|
&& conn.getHeaderField(HDR_WWW_AUTHENTICATE) != null)
|
||||||
authMethod = HttpAuthMethod.scanResponse(conn);
|
authMethod = HttpAuthMethod.scanResponse(conn);
|
||||||
return conn;
|
return conn;
|
||||||
|
@ -490,7 +490,7 @@ private HttpConnection connect(final String service)
|
||||||
|
|
||||||
case HttpConnection.HTTP_UNAUTHORIZED:
|
case HttpConnection.HTTP_UNAUTHORIZED:
|
||||||
authMethod = HttpAuthMethod.scanResponse(conn);
|
authMethod = HttpAuthMethod.scanResponse(conn);
|
||||||
if (authMethod == HttpAuthMethod.NONE)
|
if (authMethod.getType() == HttpAuthMethod.Type.NONE)
|
||||||
throw new TransportException(uri, MessageFormat.format(
|
throw new TransportException(uri, MessageFormat.format(
|
||||||
JGitText.get().authenticationNotSupported, uri));
|
JGitText.get().authenticationNotSupported, uri));
|
||||||
CredentialsProvider credentialsProvider = getCredentialsProvider();
|
CredentialsProvider credentialsProvider = getCredentialsProvider();
|
||||||
|
|
Loading…
Reference in New Issue