| Index: chrome/browser/extensions/api/developer_private/developer_private_api.cc
|
| diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
|
| index 3ccc046761a28bf75e94b8472ac95f7933b3b051..0a8fa7ec4e63e4a863a82eaff417b83480d44ec7 100644
|
| --- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
|
| +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
|
| @@ -48,6 +48,7 @@
|
| #include "webkit/blob/shareable_file_reference.h"
|
| #include "webkit/fileapi/file_system_context.h"
|
| #include "webkit/fileapi/file_system_operation.h"
|
| +#include "webkit/fileapi/local_file_system_operation.h"
|
| #include "webkit/fileapi/syncable/syncable_file_system_util.h"
|
|
|
| using content::RenderViewHost;
|
| @@ -76,6 +77,34 @@ GURL ToDataURL(const base::FilePath& path) {
|
| return GURL(kDataURLPrefix + contents_base64);
|
| }
|
|
|
| +std::vector<base::FilePath> ListFolder(const base::FilePath path) {
|
| + file_util::FileEnumerator files(path, false,
|
| + file_util::FileEnumerator::DIRECTORIES
|
| + | file_util::FileEnumerator::FILES);
|
| + std::vector<base::FilePath> paths;
|
| +
|
| + for (base::FilePath current_path = files.Next(); !current_path.empty();
|
| + current_path = files.Next()) {
|
| + paths.push_back(current_path);
|
| + }
|
| + return paths;
|
| +}
|
| +
|
| +bool ValidateFolderName(const base::FilePath::StringType& name) {
|
| + if (!name.length() || name[0] == '.' || name[0] == '-')
|
| + return false;
|
| +
|
| + for (size_t i = 0; i < name.length(); ++i) {
|
| + if (!((name[i] >= 'A' && name[i] <= 'Z') ||
|
| + (name[i] >= 'a' && name[i] <= 'z') ||
|
| + (name[i] >= '0' && name[i] <= '9') ||
|
| + (name[i] == '_' || name[i] == '-' || name[i] == '.'))) {
|
| + return false;
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace AllowFileAccess = api::developer_private::AllowFileAccess;
|
| @@ -764,8 +793,13 @@ DeveloperPrivatePackDirectoryFunction::~DeveloperPrivatePackDirectoryFunction()
|
| DeveloperPrivateLoadUnpackedFunction::~DeveloperPrivateLoadUnpackedFunction() {}
|
|
|
| bool DeveloperPrivateExportSyncfsFolderToLocalfsFunction::RunImpl() {
|
| + // TODO(grv) : add unittests.
|
| base::FilePath::StringType project_name;
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name));
|
| + if (!ValidateFolderName(project_name)) {
|
| + DLOG(INFO) << "Invalid project_name : [" << project_name << "]";
|
| + return false;
|
| + }
|
|
|
| context_ = content::BrowserContext::GetStoragePartition(profile(),
|
| render_view_host()->GetSiteInstance())->GetFileSystemContext();
|
| @@ -874,24 +908,101 @@ void DeveloperPrivateExportSyncfsFolderToLocalfsFunction::CopyFile(
|
| }
|
|
|
| DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
|
| - DeveloperPrivateExportSyncfsFolderToLocalfsFunction()
|
| -{}
|
| + DeveloperPrivateExportSyncfsFolderToLocalfsFunction() {}
|
|
|
| DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
|
| ~DeveloperPrivateExportSyncfsFolderToLocalfsFunction() {}
|
|
|
| bool DeveloperPrivateLoadProjectToSyncfsFunction::RunImpl() {
|
| - // TODO(grv) : implement
|
| + // TODO(grv) : add unittests.
|
| + base::FilePath::StringType project_name;
|
| + EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name));
|
| + if (!ValidateFolderName(project_name)) {
|
| + DLOG(INFO) << "Invalid project_name : [" << project_name << "]";
|
| + return false;
|
| + }
|
| +
|
| + context_ = content::BrowserContext::GetStoragePartition(profile(),
|
| + render_view_host()->GetSiteInstance())->GetFileSystemContext();
|
| + content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
|
| + base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::
|
| + CopyFolder,
|
| + this, project_name));
|
| return true;
|
| }
|
|
|
| +void DeveloperPrivateLoadProjectToSyncfsFunction::CopyFolder(
|
| + const base::FilePath::StringType& project_name) {
|
| + base::FilePath path(profile()->GetPath());
|
| + path = path.Append(kUnpackedAppsFolder);
|
| + path = path.Append(project_name);
|
| +
|
| + std::vector<base::FilePath> paths = ListFolder(path);
|
| + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::
|
| + CopyFiles,
|
| + this, paths));
|
| +}
|
| +
|
| +void DeveloperPrivateLoadProjectToSyncfsFunction::CopyFiles(
|
| + const std::vector<base::FilePath>& paths) {
|
| + std::string origin_url(
|
| + Extension::GetBaseURLFromExtensionId(extension_id()).spec());
|
| + fileapi::FileSystemURL url(sync_file_system::CreateSyncableFileSystemURL(
|
| + GURL(origin_url),
|
| + sync_file_system::DriveFileSyncService::kServiceName,
|
| + base::FilePath()));
|
| +
|
| + pendingCallbacksCount_ = paths.size();
|
| +
|
| + for (size_t i = 0; i < paths.size(); ++i) {
|
| + base::PlatformFileError error_code;
|
| + fileapi::FileSystemOperation* op
|
| + = context_->CreateFileSystemOperation(url, &error_code);
|
| + DCHECK(op);
|
| +
|
| + std::string origin_url(
|
| + Extension::GetBaseURLFromExtensionId(extension_id()).spec());
|
| + fileapi::FileSystemURL
|
| + dest_url(sync_file_system::CreateSyncableFileSystemURL(
|
| + GURL(origin_url),
|
| + sync_file_system::DriveFileSyncService::kServiceName,
|
| + base::FilePath(paths[i].BaseName())));
|
| +
|
| + op->AsLocalFileSystemOperation()->CopyInForeignFile(paths[i], dest_url,
|
| + base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::
|
| + CopyFilesCallback,
|
| + this));
|
| + }
|
| +}
|
| +
|
| +void DeveloperPrivateLoadProjectToSyncfsFunction::CopyFilesCallback(
|
| + const base::PlatformFileError result) {
|
| +
|
| + pendingCallbacksCount_--;
|
| +
|
| + if (success_ && result != base::PLATFORM_FILE_OK) {
|
| + SetError("Error in copying files to sync filesystem.");
|
| + success_ = false;
|
| + }
|
| +
|
| + if (!pendingCallbacksCount_) {
|
| + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&DeveloperPrivateLoadProjectToSyncfsFunction::SendResponse,
|
| + this,
|
| + success_));
|
| + }
|
| +}
|
| +
|
| DeveloperPrivateLoadProjectToSyncfsFunction::
|
| - DeveloperPrivateLoadProjectToSyncfsFunction() {}
|
| + DeveloperPrivateLoadProjectToSyncfsFunction()
|
| + : pendingCallbacksCount_(0), success_(true) {}
|
|
|
| DeveloperPrivateLoadProjectToSyncfsFunction::
|
| ~DeveloperPrivateLoadProjectToSyncfsFunction() {}
|
|
|
| bool DeveloperPrivateGetProjectsInfoFunction::RunImpl() {
|
| + // TODO(grv) : add unittests.
|
| content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
|
| base::Bind(&DeveloperPrivateGetProjectsInfoFunction::ReadFolder,
|
| this));
|
| @@ -905,16 +1016,15 @@ void DeveloperPrivateGetProjectsInfoFunction::ReadFolder() {
|
| base::FilePath path(profile()->GetPath());
|
| path = path.Append(kUnpackedAppsFolder);
|
|
|
| - file_util::FileEnumerator files(
|
| - path, false, file_util::FileEnumerator::DIRECTORIES);
|
| + std::vector<base::FilePath> paths = ListFolder(path);
|
| ProjectInfoList info_list;
|
| - for (base::FilePath current_path = files.Next(); !current_path.empty();
|
| - current_path = files.Next()) {
|
| + for (size_t i = 0; i < paths.size(); ++i) {
|
| scoped_ptr<developer::ProjectInfo> info(new developer::ProjectInfo());
|
| - info->name = current_path.BaseName().MaybeAsASCII();
|
| + info->name = paths[i].BaseName().MaybeAsASCII();
|
| info_list.push_back(
|
| make_linked_ptr<developer::ProjectInfo>(info.release()));
|
| }
|
| +
|
| results_ = developer::GetProjectsInfo::Results::Create(info_list);
|
| content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
| base::Bind(&DeveloperPrivateGetProjectsInfoFunction::SendResponse,
|
| @@ -933,6 +1043,11 @@ bool DeveloperPrivateLoadProjectFunction::RunImpl() {
|
| // TODO(grv) : add unit tests.
|
| base::FilePath::StringType project_name;
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name));
|
| + if (!ValidateFolderName(project_name)) {
|
| + DLOG(INFO) << "Invalid project_name : [" << project_name << "]";
|
| + return false;
|
| + }
|
| +
|
| base::FilePath path(profile()->GetPath());
|
| path = path.Append(kUnpackedAppsFolder);
|
| // TODO(grv) : Sanitize / check project_name.
|
|
|