// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/chrome_content_renderer_client.h"

#include <vector>

#include "base/strings/utf_string_conversions.h"
#include "chrome/renderer/searchbox/search_bouncer.h"
#include "content/public/common/webplugininfo.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/manifest_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/web/WebPluginParams.h"
#include "url/gurl.h"

using blink::WebPluginParams;
using blink::WebString;
using blink::WebVector;
using content::WebPluginInfo;
using content::WebPluginMimeType;

namespace {
const bool kNaClRestricted = false;
const bool kNaClUnrestricted = true;
const bool kExtensionRestricted = false;
const bool kExtensionUnrestricted = true;
const bool kExtensionNotFromWebStore = false;
const bool kExtensionFromWebStore = true;
const bool kNotHostedApp = false;
const bool kHostedApp = true;

const char kExtensionUrl[] = "chrome-extension://extension_id/background.html";

const char kPhotosAppURL1[] = "https://foo.plus.google.com";
const char kPhotosAppURL2[] = "https://foo.plus.sandbox.google.com";
const char kPhotosManifestURL1[] = "https://ssl.gstatic.com/s2/oz/nacl/foo";
const char kPhotosManifestURL2[] = "https://ssl.gstatic.com/photos/nacl/foo";

const char kChatAppURL1[] = "https://foo.talkgadget.google.com";
const char kChatAppURL2[] = "https://foo.talk.google.com";
const char kChatManifestURL[] = "https://ssl.gstatic.com/chat/apps/fx";

bool AllowsDevInterfaces(const WebPluginParams& params) {
  for (size_t i = 0; i < params.attributeNames.size(); ++i) {
    if (params.attributeNames[i] == WebString::fromUTF8("@dev"))
      return true;
  }
  return false;
}

void AddFakeDevAttribute(WebPluginParams* params) {
  WebVector<WebString> names(static_cast<size_t>(1));
  WebVector<WebString> values(static_cast<size_t>(1));
  names[0] = WebString::fromUTF8("@dev");
  values[0] = WebString();
  params->attributeNames.swap(names);
  params->attributeValues.swap(values);
}

void AddContentTypeHandler(content::WebPluginInfo* info,
                           const char* mime_type,
                           const char* manifest_url) {
  content::WebPluginMimeType mime_type_info;
  mime_type_info.mime_type = mime_type;
  mime_type_info.additional_param_names.push_back(UTF8ToUTF16("nacl"));
  mime_type_info.additional_param_values.push_back(
      UTF8ToUTF16(manifest_url));
  info->mime_types.push_back(mime_type_info);
}
}  // namespace

typedef testing::Test ChromeContentRendererClientTest;


scoped_refptr<const extensions::Extension> CreateTestExtension(
    bool is_unrestricted, bool is_from_webstore, bool is_hosted_app,
    const std::string& app_url) {
  extensions::Manifest::Location location = is_unrestricted ?
      extensions::Manifest::UNPACKED :
      extensions::Manifest::INTERNAL;
  int flags = is_from_webstore ?
      extensions::Extension::FROM_WEBSTORE:
      extensions::Extension::NO_FLAGS;

  base::DictionaryValue manifest;
  manifest.SetString("name", "NaCl Extension");
  manifest.SetString("version", "1");
  manifest.SetInteger("manifest_version", 2);
  if (is_hosted_app) {
    base::ListValue* url_list = new base::ListValue();
    url_list->Append(base::Value::CreateStringValue(app_url));
    manifest.Set(extensions::manifest_keys::kWebURLs, url_list);
    manifest.SetString(extensions::manifest_keys::kLaunchWebURL, app_url);
  }
  std::string error;
  return extensions::Extension::Create(base::FilePath(), location, manifest,
                                       flags, &error);
}

scoped_refptr<const extensions::Extension> CreateExtension(
    bool is_unrestricted, bool is_from_webstore) {
  return CreateTestExtension(
      is_unrestricted, is_from_webstore, kNotHostedApp, std::string());
}

scoped_refptr<const extensions::Extension> CreateHostedApp(
    bool is_unrestricted, bool is_from_webstore, const std::string& app_url) {
  return CreateTestExtension(is_unrestricted, is_from_webstore, kHostedApp,
                             app_url);
}

TEST_F(ChromeContentRendererClientTest, NaClRestriction) {
  // Unknown content types have no NaCl module.
  {
    WebPluginInfo info;
    EXPECT_EQ(GURL(),
              ChromeContentRendererClient::GetNaClContentHandlerURL(
                  "application/x-foo", info));
  }
  // Known content types have a NaCl module.
  {
    WebPluginInfo info;
    AddContentTypeHandler(&info, "application/x-foo", "www.foo.com");
    EXPECT_EQ(GURL("www.foo.com"),
              ChromeContentRendererClient::GetNaClContentHandlerURL(
                  "application/x-foo", info));
  }
  // --enable-nacl allows all NaCl apps, with 'dev' interfaces.
  {
    WebPluginParams params;
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(),
        GURL(),
        kNaClUnrestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_TRUE(AllowsDevInterfaces(params));
  }
  // Unrestricted extensions are allowed without --enable-nacl, with 'dev'
  // interfaces if called from an extension url.
  {
    WebPluginParams params;
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(),
        GURL(kExtensionUrl),
        kNaClRestricted,
        CreateExtension(kExtensionUnrestricted, kExtensionNotFromWebStore)
            .get(),
        &params));
    EXPECT_TRUE(AllowsDevInterfaces(params));
  }
  // CWS extensions are allowed without --enable-nacl, without 'dev'
  // interfaces if called from an extension url.
  {
    WebPluginParams params;
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(),
        GURL(kExtensionUrl),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
        &params));
    EXPECT_FALSE(AllowsDevInterfaces(params));
  }
  // CWS extensions can't get 'dev' interfaces with --enable-nacl.
  {
    WebPluginParams params;
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(),
        GURL(kExtensionUrl),
        kNaClUnrestricted,
        CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
        &params));
    EXPECT_FALSE(AllowsDevInterfaces(params));
  }
  // CWS extensions can't get 'dev' interfaces by injecting a fake
  // '@dev' attribute.
  {
    WebPluginParams params;
    AddFakeDevAttribute(&params);
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(),
        GURL(kExtensionUrl),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
        &params));
    EXPECT_FALSE(AllowsDevInterfaces(params));
  }
  // The NaCl PDF extension is allowed without --enable-nacl, with 'dev'
  // interfaces, from all URLs.
  {
    WebPluginParams params;
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL("chrome-extension://acadkphlmlegjaadjagenfimbpphcgnh"),
        GURL(),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
        &params));
    EXPECT_TRUE(AllowsDevInterfaces(params));
  }
  // Whitelisted URLs are allowed without --enable-nacl, without 'dev'
  // interfaces. There is a whitelist for the app URL and the manifest URL.
  {
    WebPluginParams params;
    // Whitelisted Photos app is allowed (two app URLs, two manifest URLs)
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(kPhotosManifestURL1),
        GURL(kPhotosAppURL1),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_FALSE(AllowsDevInterfaces(params));
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(kPhotosManifestURL1),
        GURL(kPhotosAppURL2),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_FALSE(AllowsDevInterfaces(params));
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(kPhotosManifestURL2),
        GURL(kPhotosAppURL1),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_FALSE(AllowsDevInterfaces(params));
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(kPhotosManifestURL2),
        GURL(kPhotosAppURL2),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_FALSE(AllowsDevInterfaces(params));
    // Whitelisted Chat app is allowed.
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(kChatManifestURL),
        GURL(kChatAppURL1),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(kChatManifestURL),
        GURL(kChatAppURL2),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));

    // Whitelisted manifest URL, bad app URLs, NOT allowed.
    EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(kPhotosManifestURL1),
        GURL("http://plus.google.com/foo"),  // http scheme
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(kPhotosManifestURL1),
        GURL("http://plus.sandbox.google.com/foo"),  // http scheme
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(kPhotosManifestURL1),
        GURL("https://plus.google.evil.com/foo"),  // bad host
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    // Whitelisted app URL, bad manifest URL, NOT allowed.
    EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
        GURL("http://ssl.gstatic.com/s2/oz/nacl/foo"),  // http scheme
        GURL(kPhotosAppURL1),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
        GURL("https://ssl.gstatic.evil.com/s2/oz/nacl/foo"),  // bad host
        GURL(kPhotosAppURL1),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
        GURL("https://ssl.gstatic.com/wrong/s2/oz/nacl/foo"),  // bad path
        GURL(kPhotosAppURL1),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
  }
  // Whitelisted URLs can't get 'dev' interfaces with --enable-nacl.
  {
    WebPluginParams params;
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(kPhotosManifestURL1),
        GURL(kPhotosAppURL1),
        kNaClUnrestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_FALSE(AllowsDevInterfaces(params));
  }
  // Whitelisted URLs can't get 'dev' interfaces by injecting a fake
  // '@dev' attribute.
  {
    WebPluginParams params;
    AddFakeDevAttribute(&params);
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(kPhotosManifestURL1),
        GURL(kPhotosAppURL1),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_FALSE(AllowsDevInterfaces(params));
  }
  // Non-whitelisted URLs are blocked without --enable-nacl.
  {
    WebPluginParams params;
    EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(),
        GURL("https://plus.google.com.evil.com/foo1"),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
        &params));
    EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(),
        GURL("https://plus.google.com.evil.com/foo2"),
        kNaClRestricted,
        CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
        &params));
    EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(),
        GURL("https://talkgadget.google.com.evil.com/foo3"),
        kNaClRestricted,
        CreateExtension(kExtensionUnrestricted, kExtensionNotFromWebStore)
            .get(),
        &params));
    EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(),
        GURL("https://talkgadget.google.com.evil.com/foo4"),
        kNaClRestricted,
        CreateExtension(kExtensionUnrestricted, kExtensionFromWebStore).get(),
        &params));
  }
  // Non chrome-extension:// URLs belonging to hosted apps are allowed.
  {
    WebPluginParams params;
    EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(),
        GURL("http://example.com/test.html"),
        kNaClRestricted,
        CreateHostedApp(kExtensionRestricted,
                        kExtensionNotFromWebStore,
                        "http://example.com/").get(),
        &params));
    EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
        GURL(),
        GURL("http://example.evil.com/test.html"),
        kNaClRestricted,
        CreateHostedApp(kExtensionRestricted,
                        kExtensionNotFromWebStore,
                        "http://example.com/").get(),
        &params));
  }
}

TEST_F(ChromeContentRendererClientTest, AllowPepperMediaStreamAPI) {
  ChromeContentRendererClient test;
#if !defined(OS_ANDROID)
  EXPECT_TRUE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL1)));
  EXPECT_TRUE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL2)));
#else
  EXPECT_FALSE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL1)));
  EXPECT_FALSE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL2)));
#endif
  EXPECT_FALSE(test.AllowPepperMediaStreamAPI(
      GURL("http://talkgadget.google.com")));
  EXPECT_FALSE(test.AllowPepperMediaStreamAPI(
      GURL("https://talkgadget.evil.com")));
}

TEST_F(ChromeContentRendererClientTest, ShouldSuppressErrorPage) {
  ChromeContentRendererClient client;
  client.search_bouncer_.reset(new SearchBouncer);
  client.search_bouncer_->OnSetSearchURLs(
      std::vector<GURL>(), GURL("http://example.com/n"));
  EXPECT_FALSE(client.ShouldSuppressErrorPage(GURL("http://example.com")));
  EXPECT_TRUE(client.ShouldSuppressErrorPage(GURL("http://example.com/n")));
}
