]> source.dussan.org Git - jgit.git/commitdiff
Creates HttpAuthMethod type enum to support auth ordering 88/22488/2
authorLaurent Goujon <lgoujon@twitter.com>
Mon, 24 Feb 2014 21:52:33 +0000 (13:52 -0800)
committerChris Aniszczyk <caniszczyk@gmail.com>
Wed, 21 May 2014 15:48:35 +0000 (10:48 -0500)
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>
org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java

index 225af4b496db4195065a48eddb248c6bf333b6f7..4d80acc53f227716f4ee0f5e69e0d28a05e728a9 100644 (file)
@@ -69,8 +69,39 @@ import org.eclipse.jgit.util.Base64;
  * may need to maintain per-connection state information.
  */
 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 SCHEMA_NAME_SEPARATOR = " "; //$NON-NLS-1$
 
@@ -83,7 +114,7 @@ abstract class HttpAuthMethod {
         */
        static HttpAuthMethod scanResponse(final HttpConnection conn) {
                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()) {
                        if (HDR_WWW_AUTHENTICATE.equalsIgnoreCase(entry.getKey())) {
@@ -93,19 +124,23 @@ abstract class HttpAuthMethod {
                                                        final String[] valuePart = value.split(
                                                                        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;
                                                                if (valuePart.length == 1)
                                                                        param = EMPTY_STRING;
                                                                else
                                                                        param = valuePart[1];
 
-                                                               authentication = new Digest(param);
-                                                               break;
+                                                               authentication = methodType
+                                                                               .method(param);
+                                                       } catch (IllegalArgumentException e) {
+                                                               // This auth method is not supported
                                                        }
-
-                                                       if (Basic.NAME.equalsIgnoreCase(valuePart[0]))
-                                                               authentication = new Basic();
                                                }
                                        }
                                }
@@ -116,6 +151,12 @@ abstract class HttpAuthMethod {
                return authentication;
        }
 
+       protected final Type type;
+
+       protected HttpAuthMethod(Type type) {
+               this.type = type;
+       }
+
        /**
         * Update this method with the credentials from the URIish.
         *
@@ -170,8 +211,22 @@ abstract class HttpAuthMethod {
         */
        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. */
        private static class None extends HttpAuthMethod {
+               static final None INSTANCE = new None();
+               public None() {
+                       super(Type.NONE);
+               }
+
                @Override
                void authorize(String user, String pass) {
                        // Do nothing when no authentication is enabled.
@@ -185,12 +240,14 @@ abstract class HttpAuthMethod {
 
        /** Performs HTTP basic authentication (plaintext username/password). */
        private static class Basic extends HttpAuthMethod {
-               static final String NAME = "Basic"; //$NON-NLS-1$
-
                private String user;
 
                private String pass;
 
+               public Basic() {
+                       super(Type.BASIC);
+               }
+
                @Override
                void authorize(final String username, final String password) {
                        this.user = username;
@@ -201,14 +258,13 @@ abstract class HttpAuthMethod {
                void configureRequest(final HttpConnection conn) throws IOException {
                        String ident = user + ":" + pass; //$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. */
        private static class Digest extends HttpAuthMethod {
-               static final String NAME = "Digest"; //$NON-NLS-1$
-
                private static final Random PRNG = new Random();
 
                private final Map<String, String> params;
@@ -220,6 +276,7 @@ abstract class HttpAuthMethod {
                private String pass;
 
                Digest(String hdr) {
+                       super(Type.DIGEST);
                        params = parse(hdr);
 
                        final String qop = params.get("qop"); //$NON-NLS-1$
@@ -288,7 +345,8 @@ abstract class HttpAuthMethod {
                                v.append(e.getValue());
                                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) {
index f4471bf83b94f844f01ffcd1b66095fa6c4d7f96..e13bfd3005c26a804cc17c9917b607d066a6c5c4 100644 (file)
@@ -246,7 +246,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
 
        private boolean useSmartHttp = true;
 
-       private HttpAuthMethod authMethod = HttpAuthMethod.NONE;
+       private HttpAuthMethod authMethod = HttpAuthMethod.Type.NONE.method(null);
 
        private Map<String, String> headers;
 
@@ -479,7 +479,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
                                        // background (e.g Kerberos/SPNEGO).
                                        // That may not work for streaming requests and jgit
                                        // explicit authentication would be required
-                                       if (authMethod == HttpAuthMethod.NONE
+                                       if (authMethod.getType() == HttpAuthMethod.Type.NONE
                                                        && conn.getHeaderField(HDR_WWW_AUTHENTICATE) != null)
                                                authMethod = HttpAuthMethod.scanResponse(conn);
                                        return conn;
@@ -490,7 +490,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
 
                                case HttpConnection.HTTP_UNAUTHORIZED:
                                        authMethod = HttpAuthMethod.scanResponse(conn);
-                                       if (authMethod == HttpAuthMethod.NONE)
+                                       if (authMethod.getType() == HttpAuthMethod.Type.NONE)
                                                throw new TransportException(uri, MessageFormat.format(
                                                                JGitText.get().authenticationNotSupported, uri));
                                        CredentialsProvider credentialsProvider = getCredentialsProvider();