// Copyright 2019 The Flutter Authors. 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:convert';
import 'dart:io';

import 'package:appengine/appengine.dart';
import 'package:gcloud/db.dart';
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';

import '../../cocoon_service.dart';
import '../foundation/providers.dart';
import '../foundation/typedefs.dart';
import '../model/appengine/allowed_account.dart';
import '../model/google/token_info.dart';
import '../service/logging.dart';
import 'exceptions.dart';

/// Class capable of authenticating [HttpRequest]s.
///
/// There are two types of authentication this class supports:
///
///  1. If the request has the `'X-Appengine-Cron'` HTTP header set to "true",
///     then the request will be authenticated as an App Engine cron job.
///
///     The `'X-Appengine-Cron'` HTTP header is set automatically by App Engine
///     and will be automatically stripped from the request by the App Engine
///     runtime if the request originated from anything other than a cron job.
///     Thus, the header is safe to trust as an authentication indicator.
///
///  2. If the request has the `'X-Flutter-IdToken'` HTTP header
///     set to a valid encrypted JWT token, then the request will be authenticated
///     as a user account.
///
///     @google.com accounts can call APIs using curl and gcloud.
///     E.g. curl '<api_url>' -H "X-Flutter-IdToken: $(gcloud auth print-identity-token)"
///
///     User accounts are only authorized if the user is either a "@google.com"
///     account or is an [AllowedAccount] in Cocoon's Datastore.
///
/// If none of the above authentication methods yield an authenticated
/// request, then the request is unauthenticated, and any call to
/// [authenticate] will throw an [Unauthenticated] exception.
///
/// See also:
///
///  * <https://cloud.google.com/appengine/docs/standard/python/reference/request-response-headers>
@immutable
class AuthenticationProvider {
  const AuthenticationProvider(
    this.config, {
    this.clientContextProvider = Providers.serviceScopeContext,
    this.httpClientProvider = Providers.freshHttpClient,
  });

  /// The Cocoon config, guaranteed to be non-null.
  final Config config;

  /// Provides the App Engine client context as part of the
  /// [AuthenticatedContext].
  ///
  /// This is guaranteed to be non-null.
  final ClientContextProvider clientContextProvider;

  /// Provides the HTTP client that will be used (if necessary) to verify OAuth
  /// ID tokens (JWT tokens).
  ///
  /// This is guaranteed to be non-null.
  final HttpClientProvider httpClientProvider;

  /// Authenticates the specified [request] and returns the associated
  /// [AuthenticatedContext].
  ///
  /// See the class documentation on [AuthenticationProvider] for a discussion
  /// of the different types of authentication that are accepted.
  ///
  /// This will throw an [Unauthenticated] exception if the request is
  /// unauthenticated.
  Future<AuthenticatedContext> authenticate(HttpRequest request) async {
    final bool isCron = request.headers.value('X-Appengine-Cron') == 'true';
    final String? idTokenFromHeader = request.headers.value('X-Flutter-IdToken');
    final ClientContext clientContext = clientContextProvider();
    if (isCron) {
      // Authenticate cron requests
      return AuthenticatedContext(clientContext: clientContext);
    } else if (idTokenFromHeader != null) {
      TokenInfo token;
      try {
        token = await tokenInfo(request);
      } on Unauthenticated {
        token = await tokenInfo(request, tokenType: 'access_token');
      }
      return authenticateToken(token, clientContext: clientContext);
    }

    throw const Unauthenticated('User is not signed in');
  }

  /// Gets oauth token information. This method requires the token to be stored in
  /// X-Flutter-IdToken header.
  Future<TokenInfo> tokenInfo(HttpRequest request, {String tokenType = 'id_token'}) async {
    final String? idTokenFromHeader = request.headers.value('X-Flutter-IdToken');
    final http.Client client = httpClientProvider();
    try {
      final http.Response verifyTokenResponse = await client.get(Uri.https(
        'oauth2.googleapis.com',
        '/tokeninfo',
        <String, String?>{
          tokenType: idTokenFromHeader,
        },
      ));

      if (verifyTokenResponse.statusCode != HttpStatus.ok) {
        /// Google Auth API returns a message in the response body explaining why
        /// the request failed. Such as "Invalid Token".
        log.fine('Token verification failed: ${verifyTokenResponse.statusCode}; ${verifyTokenResponse.body}');
        throw const Unauthenticated('Invalid ID token');
      }

      try {
        return TokenInfo.fromJson(json.decode(verifyTokenResponse.body) as Map<String, dynamic>);
      } on FormatException {
        throw InternalServerError('Invalid JSON: "${verifyTokenResponse.body}"');
      }
    } finally {
      client.close();
    }
  }

  Future<AuthenticatedContext> authenticateToken(TokenInfo token, {required ClientContext clientContext}) async {
    // Authenticate as a signed-in Google account via OAuth id token.
    final String clientId = await config.oauthClientId;
    if (token.audience != clientId && !token.email!.endsWith('@google.com')) {
      log.warning('Possible forged token: "${token.audience}" (expected "$clientId")');
      throw const Unauthenticated('Invalid ID token');
    }

    if (token.hostedDomain != 'google.com') {
      final bool isAllowed = await _isAllowed(token.email);
      if (!isAllowed) {
        throw Unauthenticated('${token.email} is not authorized to access the dashboard');
      }
    }
    return AuthenticatedContext(clientContext: clientContext);
  }

  Future<bool> _isAllowed(String? email) async {
    final Query<AllowedAccount> query = config.db.query<AllowedAccount>()
      ..filter('email =', email)
      ..limit(20);

    return !(await query.run().isEmpty);
  }
}

/// Class that represents an authenticated request having been made, and any
/// attached metadata to that request.
///
/// See also:
///
///  * [AuthenticationProvider]
@immutable
class AuthenticatedContext {
  /// Creates a new [AuthenticatedContext].
  const AuthenticatedContext({
    required this.clientContext,
  });

  /// The App Engine [ClientContext] of the current request.
  ///
  /// This is guaranteed to be non-null.
  final ClientContext clientContext;
}
