// 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 'dart:async';
import 'dart:io';

import "package:convert/convert.dart";
import "package:crypto/crypto.dart";
import "package:expect/expect.dart";

class Server {
  late 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 = md5.convert("${username}:${realm}:${password}".codeUnits);
    ha1 = hex.encode(hasher.bytes);

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

    var completer = new Completer<Server>();
    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.wwwAuthenticateHeader, authHeader);
          unauthCount++;
        }

        var response = request.response;
        if (request.headers[HttpHeaders.authorizationHeader] != null) {
          Expect.equals(
              1, request.headers[HttpHeaders.authorizationHeader]!.length);
          String authorization =
              request.headers[HttpHeaders.authorizationHeader]![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 = md5.convert("${request.method}:${uri}".codeUnits);
            var ha2 = hex.encode(hasher.bytes);

            var x;
            Digest digest;
            if (qop == null || qop == "" || qop == "none") {
              digest = md5.convert("$ha1:${nonce}:$ha2".codeUnits);
            } else {
              digest = md5.convert(
                  "$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits);
            }
            Expect.equals(
                hex.encode(digest.bytes), 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 = <Future>[];
    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 = <Future>[];
    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 = (url, scheme, realm) {
      Expect.equals("Digest", scheme);
      Expect.equals("test", realm);
      final completer = new Completer<bool>();
      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 = <Future>[];
    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 = (url, scheme, 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();
}
