blob: 6077d4e257675106808de1111147b8a783eaa32b [file] [log] [blame]
// Copyright 2014 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 "extensions/browser/extension_util.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/site_instance.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/features/behavior_feature.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_provider.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_handlers/incognito_info.h"
#include "extensions/common/manifest_handlers/shared_module_info.h"
namespace extensions {
namespace util {
bool CanBeIncognitoEnabled(const Extension* extension) {
return IncognitoInfo::IsIncognitoAllowed(extension) &&
(!extension->is_platform_app() ||
extension->location() == Manifest::COMPONENT);
}
bool IsIncognitoEnabled(const std::string& extension_id,
content::BrowserContext* context) {
const Extension* extension =
ExtensionRegistry::Get(context)->GetExtensionById(
extension_id, ExtensionRegistry::ENABLED);
if (extension) {
if (!CanBeIncognitoEnabled(extension))
return false;
// If this is an existing component extension we always allow it to
// work in incognito mode.
if (Manifest::IsComponentLocation(extension->location()))
return true;
if (extension->is_login_screen_extension())
return true;
}
return ExtensionPrefs::Get(context)->IsIncognitoEnabled(extension_id);
}
bool CanCrossIncognito(const Extension* extension,
content::BrowserContext* context) {
// We allow the extension to see events and data from another profile iff it
// uses "spanning" behavior and it has incognito access. "split" mode
// extensions only see events for a matching profile.
CHECK(extension);
return IsIncognitoEnabled(extension->id(), context) &&
!IncognitoInfo::IsSplitMode(extension);
}
GURL GetSiteForExtensionId(const std::string& extension_id,
content::BrowserContext* context) {
return content::SiteInstance::GetSiteForURL(
context, Extension::GetBaseURLFromExtensionId(extension_id));
}
content::StoragePartition* GetStoragePartitionForExtensionId(
const std::string& extension_id,
content::BrowserContext* browser_context) {
GURL site_url = content::SiteInstance::GetSiteForURL(
browser_context, Extension::GetBaseURLFromExtensionId(extension_id));
content::StoragePartition* storage_partition =
content::BrowserContext::GetStoragePartitionForSite(browser_context,
site_url);
return storage_partition;
}
// This function is security sensitive. Bugs could cause problems that break
// restrictions on local file access or NaCl's validation caching. If you modify
// this function, please get a security review from a NaCl person.
bool MapUrlToLocalFilePath(const ExtensionSet* extensions,
const GURL& file_url,
bool use_blocking_api,
base::FilePath* file_path) {
// Check that the URL is recognized by the extension system.
const Extension* extension = extensions->GetExtensionOrAppByURL(file_url);
if (!extension)
return false;
// This is a short-cut which avoids calling a blocking file operation
// (GetFilePath()), so that this can be called on the non blocking threads. It
// only handles a subset of the urls.
if (!use_blocking_api) {
if (file_url.SchemeIs(extensions::kExtensionScheme)) {
std::string path = file_url.path();
base::TrimString(path, "/", &path); // Remove first slash
*file_path = extension->path().AppendASCII(path);
return true;
}
return false;
}
std::string path = file_url.path();
ExtensionResource resource;
if (SharedModuleInfo::IsImportedPath(path)) {
// Check if this is a valid path that is imported for this extension.
std::string new_extension_id;
std::string new_relative_path;
SharedModuleInfo::ParseImportedPath(path, &new_extension_id,
&new_relative_path);
const Extension* new_extension = extensions->GetByID(new_extension_id);
if (!new_extension)
return false;
if (!SharedModuleInfo::ImportsExtensionById(extension, new_extension_id))
return false;
resource = new_extension->GetResource(new_relative_path);
} else {
// Check that the URL references a resource in the extension.
resource = extension->GetResource(path);
}
if (resource.empty())
return false;
// GetFilePath is a blocking function call.
const base::FilePath resource_file_path = resource.GetFilePath();
if (resource_file_path.empty())
return false;
*file_path = resource_file_path;
return true;
}
} // namespace util
} // namespace extensions