// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import "package:crypto/crypto.dart";
import "package:expect/expect.dart";
import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:utf';

class Server {
  HttpServer server;
  int unauthCount = 0;  // Counter of the 401 responses.
  int successCount = 0;  // Counter of the successful responses.
  int nonceCount = 0;  // Counter of use of current nonce.
  var ha1;

  static Future<Server> start(String algorithm,
                              String qop,
                              {int nonceStaleAfter,
                               bool useNextNonce: false}) {
    return new Server()._start(algorithm, qop, nonceStaleAfter, useNextNonce);
  }

  Future<Server> _start(String serverAlgorithm,
                        String serverQop,
                        int nonceStaleAfter,
                        bool useNextNonce) {
    Set ncs = new Set();
    // Calculate ha1.
    String realm = "test";
    String username = "dart";
    String password = "password";
    var hasher = new MD5();
    hasher.add("${username}:${realm}:${password}".codeUnits);
    ha1 = CryptoUtils.bytesToHex(hasher.close());

    var nonce = "12345678";  // No need for random nonce in test.

    var completer = new Completer();
    HttpServer.bind("127.0.0.1", 0).then((s) {
      server = s;
      server.listen((HttpRequest request) {
        sendUnauthorizedResponse(HttpResponse response, {stale: false}) {
          response.statusCode = HttpStatus.UNAUTHORIZED;
          StringBuffer authHeader = new StringBuffer();
          authHeader.write('Digest');
          authHeader.write(', realm="$realm"');
          authHeader.write(', nonce="$nonce"');
          if (stale) authHeader.write(', stale="true"');
          if (serverAlgorithm != null) {
            authHeader.write(', algorithm=$serverAlgorithm');
          }
          authHeader.write(', domain="/digest/"');
          if (serverQop != null) authHeader.write(', qop="$serverQop"');
          response.headers.set(HttpHeaders.WWW_AUTHENTICATE, authHeader);
          unauthCount++;
        }

        var response = request.response;
        if (request.headers[HttpHeaders.AUTHORIZATION] != null) {
          Expect.equals(1, request.headers[HttpHeaders.AUTHORIZATION].length);
          String authorization =
            request.headers[HttpHeaders.AUTHORIZATION][0];
          HeaderValue header =
              HeaderValue.parse(
                  authorization, parameterSeparator: ",");
          if (header.value.toLowerCase() == "basic") {
            sendUnauthorizedResponse(response);
          } else if (!useNextNonce && nonceCount == nonceStaleAfter) {
            nonce = "87654321";
            nonceCount = 0;
            sendUnauthorizedResponse(response, stale: true);
          } else {
            var uri = header.parameters["uri"];
            var qop = header.parameters["qop"];
            var cnonce = header.parameters["cnonce"];
            var nc = header.parameters["nc"];
            Expect.equals("digest", header.value.toLowerCase());
            Expect.equals("dart", header.parameters["username"]);
            Expect.equals(realm, header.parameters["realm"]);
            Expect.equals("MD5", header.parameters["algorithm"]);
            Expect.equals(nonce, header.parameters["nonce"]);
            Expect.equals(request.uri.toString(), uri);
            if (qop != null) {
              // A server qop of auth-int is downgraded to none by the client.
              Expect.equals("auth", serverQop);
              Expect.equals("auth", header.parameters["qop"]);
              Expect.isNotNull(cnonce);
              Expect.isNotNull(nc);
              Expect.isFalse(ncs.contains(nc));
              ncs.add(nc);
            } else {
              Expect.isNull(cnonce);
              Expect.isNull(nc);
            }
            Expect.isNotNull(header.parameters["response"]);

            var hasher = new MD5();
            hasher.add("${request.method}:${uri}".codeUnits);
            var ha2 = CryptoUtils.bytesToHex(hasher.close());

            var x;
            hasher = new MD5();
            if (qop == null || qop == "" || qop == "none") {
              hasher.add("$ha1:${nonce}:$ha2".codeUnits);
            } else {
              hasher.add("$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits);
            }
            Expect.equals(CryptoUtils.bytesToHex(hasher.close()),
                          header.parameters["response"]);

            successCount++;
            nonceCount++;

            // Add a bogus Authentication-Info for testing.
            var info = 'rspauth="77180d1ab3d6c9de084766977790f482", '
                       'cnonce="8f971178", '
                       'nc=000002c74, '
                       'qop=auth';
            if (useNextNonce && nonceCount == nonceStaleAfter) {
              nonce = "abcdef01";
              info += ', nextnonce="$nonce"';
            }
            response.headers.set("Authentication-Info", info);
          }
        } else {
          sendUnauthorizedResponse(response);
        }
        response.close();
      });
      completer.complete(this);
    });
    return completer.future;
  }

  void shutdown() {
    server.close();
  }

  int get port => server.port;
}

void testNoCredentials(String algorithm, String qop) {
  Server.start(algorithm, qop).then((server) {
    HttpClient client = new HttpClient();

    // Add digest credentials which does not match the path requested.
    client.addCredentials(
        Uri.parse("http://127.0.0.1:${server.port}/xxx"),
        "test",
        new HttpClientDigestCredentials("dart", "password"));

    // Add basic credentials for the path requested.
    client.addCredentials(
        Uri.parse("http://127.0.0.1:${server.port}/digest"),
        "test",
        new HttpClientBasicCredentials("dart", "password"));

    Future makeRequest(Uri url) {
      return client.getUrl(url)
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
          Expect.equals(HttpStatus.UNAUTHORIZED, response.statusCode);
          return response.fold(null, (x, y) {});
        });
    }

    var futures = [];
    for (int i = 0; i < 5; i++) {
      futures.add(
          makeRequest(
              Uri.parse("http://127.0.0.1:${server.port}/digest")));
    }
    Future.wait(futures).then((_) {
      server.shutdown();
      client.close();
    });
  });
}

void testCredentials(String algorithm, String qop) {
  Server.start(algorithm, qop).then((server) {
    HttpClient client = new HttpClient();

    Future makeRequest(Uri url) {
      return client.getUrl(url)
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
            Expect.equals(HttpStatus.OK, response.statusCode);
            Expect.equals(1, response.headers["Authentication-Info"].length);
          return response.fold(null, (x, y) {});
        });
    }

    client.addCredentials(
        Uri.parse("http://127.0.0.1:${server.port}/digest"),
        "test",
        new HttpClientDigestCredentials("dart", "password"));

    var futures = [];
    for (int i = 0; i < 2; i++) {
      String uriBase = "http://127.0.0.1:${server.port}/digest";
      futures.add(
          makeRequest(
              Uri.parse(uriBase)));
      futures.add(
          makeRequest(
              Uri.parse("$uriBase?querystring")));
      futures.add(
          makeRequest(
              Uri.parse("$uriBase?querystring#fragment")));
    }
    Future.wait(futures).then((_) {
      server.shutdown();
      client.close();
    });
  });
}

void testAuthenticateCallback(String algorithm, String qop) {
  Server.start(algorithm, qop).then((server) {
    HttpClient client = new HttpClient();

    client.authenticate = (Uri url, String scheme, String realm) {
      Expect.equals("Digest", scheme);
      Expect.equals("test", realm);
      Completer completer = new Completer();
      new Timer(const Duration(milliseconds: 10), () {
          client.addCredentials(
              Uri.parse("http://127.0.0.1:${server.port}/digest"),
              "test",
              new HttpClientDigestCredentials("dart", "password"));
        completer.complete(true);
      });
      return completer.future;
    };

    Future makeRequest(Uri url) {
      return client.getUrl(url)
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
            Expect.equals(HttpStatus.OK, response.statusCode);
            Expect.equals(1, response.headers["Authentication-Info"].length);
          return response.fold(null, (x, y) {});
        });
    }

    var futures = [];
    for (int i = 0; i < 5; i++) {
      futures.add(
          makeRequest(
              Uri.parse("http://127.0.0.1:${server.port}/digest")));
    }
    Future.wait(futures).then((_) {
      server.shutdown();
      client.close();
    });
  });
}

void testStaleNonce() {
  Server.start("MD5", "auth", nonceStaleAfter: 2).then((server) {
    HttpClient client = new HttpClient();

    Future makeRequest(Uri url) {
      return client.getUrl(url)
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
            Expect.equals(HttpStatus.OK, response.statusCode);
            Expect.equals(1, response.headers["Authentication-Info"].length);
          return response.fold(null, (x, y) {});
        });
    }

    Uri uri = Uri.parse("http://127.0.0.1:${server.port}/digest");
    var credentials = new HttpClientDigestCredentials("dart", "password");
    client.addCredentials(uri, "test", credentials);

    makeRequest(uri)
        .then((_) => makeRequest(uri))
        .then((_) => makeRequest(uri))
        .then((_) => makeRequest(uri))
        .then((_) {
          Expect.equals(2, server.unauthCount);
          Expect.equals(4, server.successCount);
          server.shutdown();
          client.close();
        });
  });
}

void testNextNonce() {
  Server.start("MD5",
               "auth",
               nonceStaleAfter: 2,
               useNextNonce: true).then((server) {
    HttpClient client = new HttpClient();

    Future makeRequest(Uri url) {
      return client.getUrl(url)
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
            Expect.equals(HttpStatus.OK, response.statusCode);
            Expect.equals(1, response.headers["Authentication-Info"].length);
          return response.fold(null, (x, y) {});
        });
    }

    Uri uri = Uri.parse("http://127.0.0.1:${server.port}/digest");
    var credentials = new HttpClientDigestCredentials("dart", "password");
    client.addCredentials(uri, "test", credentials);

    makeRequest(uri)
        .then((_) => makeRequest(uri))
        .then((_) => makeRequest(uri))
        .then((_) => makeRequest(uri))
        .then((_) {
          Expect.equals(1, server.unauthCount);
          Expect.equals(4, server.successCount);
          server.shutdown();
          client.close();
        });
  });
}

// An Apache virtual directory configuration like this can be used for
// running the local server tests.
//
//  <Directory "/usr/local/prj/website/digest/">
//    AllowOverride None
//    Order deny,allow
//    Deny from all
//    Allow from 127.0.0.0/255.0.0.0 ::1/128
//    AuthType Digest
//    AuthName "test"
//    AuthDigestDomain /digest/
//    AuthDigestAlgorithm MD5
//    AuthDigestQop auth
//    AuthDigestNonceLifetime 10
//    AuthDigestProvider file
//    AuthUserFile /usr/local/prj/apache/passwd/digest-passwd
//    Require valid-user
//  </Directory>
//

void testLocalServerDigest() {
  int count = 0;
  HttpClient client = new HttpClient();

  Future makeRequest() {
    return client.getUrl(Uri.parse("http://127.0.0.1/digest/test"))
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
            count++;
            if (count % 100 == 0) print(count);
            Expect.equals(HttpStatus.OK, response.statusCode);
            return response.fold(null, (x, y) {});
        });
  }

  client.addCredentials(
        Uri.parse("http://127.0.0.1/digest"),
        "test",
        new HttpClientDigestCredentials("dart", "password"));

  client.authenticate = (Uri url, String scheme, String realm) {
    client.addCredentials(
        Uri.parse("http://127.0.0.1/digest"),
        "test",
        new HttpClientDigestCredentials("dart", "password"));
    return new Future.value(true);
  };

  next() {
    makeRequest().then((_) => next());
  }
  next();
}

main() {
  testNoCredentials(null, null);
  testNoCredentials("MD5", null);
  testNoCredentials("MD5", "auth");
  testCredentials(null, null);
  testCredentials("MD5", null);
  testCredentials("MD5", "auth");
  testCredentials("MD5", "auth-int");
  testAuthenticateCallback(null, null);
  testAuthenticateCallback("MD5", null);
  testAuthenticateCallback("MD5", "auth");
  testAuthenticateCallback("MD5", "auth-int");
  testStaleNonce();
  testNextNonce();
  // These teste are not normally run. They can be used for locally
  // testing with another web server (e.g. Apache).
  //testLocalServerDigest();
}
