// 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;
}
