Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/password_manager/core/browser/export/password_exporter.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/files/file_path.h" | |
| 9 #include "base/files/file_util.h" | |
| 10 #include "base/json/json_writer.h" | |
| 11 #include "base/location.h" | |
| 12 #include "base/strings/utf_string_conversions.h" | |
| 13 #include "base/task_runner.h" | |
| 14 #include "base/values.h" | |
| 15 #include "components/autofill/core/common/password_form.h" | |
| 16 #include "components/password_manager/core/browser/export/csv_writer.h" | |
| 17 | |
| 18 namespace password_manager { | |
| 19 | |
| 20 namespace { | |
| 21 | |
| 22 using autofill::PasswordForm; | |
| 23 | |
| 24 typedef std::map<std::string, std::string> ColumnNameToValueMap; | |
| 25 | |
| 26 // PasswordWriterBase --------------------------------------------------------- | |
| 27 | |
| 28 // Interface for writing a list of passwords into various formats. | |
| 29 class PasswordWriterBase { | |
| 30 public: | |
| 31 virtual ~PasswordWriterBase() = 0; | |
| 32 | |
| 33 // Serializes the list of |passwords|. | |
| 34 virtual std::string SerializePasswords( | |
| 35 ScopedVector<PasswordForm> passwords) = 0; | |
| 36 }; | |
| 37 | |
| 38 PasswordWriterBase::~PasswordWriterBase() { | |
| 39 } | |
| 40 | |
| 41 // PasswordCSVWriter ---------------------------------------------------------- | |
| 42 | |
| 43 class PasswordCSVWriter : public PasswordWriterBase { | |
| 44 public: | |
| 45 static const base::FilePath::CharType kFileExtension[]; | |
| 46 | |
| 47 PasswordCSVWriter() {} | |
| 48 | |
| 49 // PasswordWriterBase: | |
| 50 std::string SerializePasswords( | |
| 51 ScopedVector<PasswordForm> passwords) override { | |
| 52 std::vector<std::string> header; | |
| 53 header.push_back(kTitleFieldName); | |
| 54 header.push_back(kUrlFieldName); | |
| 55 header.push_back(kUsernameFieldName); | |
| 56 header.push_back(kPasswordFieldName); | |
| 57 | |
| 58 std::vector<ColumnNameToValueMap> records; | |
| 59 records.reserve(passwords.size()); | |
| 60 for (ScopedVector<PasswordForm>::const_iterator it = passwords.begin(); | |
| 61 it != passwords.end(); ++it) { | |
| 62 records.push_back(PasswordFormToRecord(*it)); | |
| 63 } | |
| 64 std::string result; | |
| 65 WriteCSV(header, records, &result); | |
| 66 return result; | |
| 67 } | |
| 68 | |
| 69 private: | |
| 70 static const char kUrlFieldName[]; | |
| 71 static const char kUsernameFieldName[]; | |
| 72 static const char kPasswordFieldName[]; | |
| 73 static const char kTitleFieldName[]; | |
| 74 | |
| 75 ColumnNameToValueMap PasswordFormToRecord(PasswordForm* form) { | |
| 76 ColumnNameToValueMap record; | |
| 77 record[kUrlFieldName] = (form->origin).spec(); | |
| 78 record[kUsernameFieldName] = base::UTF16ToUTF8(form->username_value); | |
| 79 record[kPasswordFieldName] = base::UTF16ToUTF8(form->password_value); | |
| 80 record[kTitleFieldName] = form->origin.host(); | |
| 81 return record; | |
| 82 } | |
| 83 | |
| 84 DISALLOW_COPY_AND_ASSIGN(PasswordCSVWriter); | |
| 85 }; | |
| 86 | |
| 87 const base::FilePath::CharType PasswordCSVWriter::kFileExtension[] = ".csv"; | |
| 88 const char PasswordCSVWriter::kUrlFieldName[] = "url"; | |
| 89 const char PasswordCSVWriter::kUsernameFieldName[] = "username"; | |
| 90 const char PasswordCSVWriter::kPasswordFieldName[] = "password"; | |
| 91 const char PasswordCSVWriter::kTitleFieldName[] = "name"; | |
| 92 | |
| 93 // PasswordJSONWriter --------------------------------------------------------- | |
|
Garrett Casto
2015/06/23 23:42:36
Same as the importer, I wouldn't add this if we ar
xunlu
2015/06/25 17:12:16
Done.
| |
| 94 | |
| 95 class PasswordJSONWriter : public PasswordWriterBase { | |
| 96 public: | |
| 97 static const base::FilePath::CharType kFileExtension[]; | |
| 98 | |
| 99 PasswordJSONWriter() {} | |
| 100 | |
| 101 // PasswordWriterBase: | |
| 102 std::string SerializePasswords( | |
| 103 ScopedVector<PasswordForm> passwords) override { | |
| 104 scoped_ptr<base::ListValue> password_dictionaries(new base::ListValue); | |
| 105 for (std::vector<PasswordForm*>::const_iterator it = passwords.begin(); | |
| 106 it != passwords.end(); ++it) { | |
| 107 password_dictionaries->Append(PasswordFormToDictionary(*it).release()); | |
| 108 } | |
| 109 | |
| 110 std::string result; | |
| 111 if (!base::JSONWriter::Write(*password_dictionaries.get(), &result)) | |
| 112 NOTREACHED(); | |
| 113 return result; | |
| 114 } | |
| 115 | |
| 116 private: | |
| 117 scoped_ptr<base::DictionaryValue> PasswordFormToDictionary( | |
| 118 PasswordForm* form) { | |
| 119 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue); | |
| 120 dictionary->SetString("url", form->origin.spec()); | |
| 121 dictionary->SetString("username", form->username_value); | |
| 122 dictionary->SetString("password", form->password_value); | |
| 123 return dictionary.Pass(); | |
| 124 } | |
| 125 | |
| 126 DISALLOW_COPY_AND_ASSIGN(PasswordJSONWriter); | |
| 127 }; | |
| 128 | |
| 129 const base::FilePath::CharType PasswordJSONWriter::kFileExtension[] = ".json"; | |
| 130 | |
| 131 // Helper --------------------------------------------------------------------- | |
| 132 | |
| 133 void WriteToFile(const base::FilePath& path, const std::string& data) { | |
| 134 base::WriteFile(path, data.c_str(), data.size()); | |
| 135 } | |
| 136 | |
| 137 } // namespace | |
| 138 | |
| 139 // static | |
| 140 void PasswordExporter::Export( | |
| 141 const base::FilePath& path, | |
| 142 ScopedVector<PasswordForm> passwords, | |
| 143 scoped_refptr<base::TaskRunner> blocking_task_runner, | |
| 144 const base::Closure& completion) { | |
| 145 scoped_ptr<PasswordWriterBase> password_writer; | |
| 146 if (path.Extension() == PasswordCSVWriter::kFileExtension) | |
| 147 password_writer.reset(new PasswordCSVWriter); | |
| 148 else if (path.Extension() == PasswordJSONWriter::kFileExtension) | |
| 149 password_writer.reset(new PasswordJSONWriter); | |
| 150 else | |
| 151 NOTREACHED(); | |
| 152 | |
| 153 std::string serialized_passwords = | |
| 154 password_writer->SerializePasswords(passwords.Pass()); | |
| 155 blocking_task_runner->PostTaskAndReply( | |
| 156 FROM_HERE, base::Bind(&WriteToFile, path, serialized_passwords), | |
| 157 completion); | |
| 158 } | |
| 159 | |
| 160 // static | |
| 161 std::vector<std::string> GetSupportedFileExtensions() { | |
| 162 std::vector<std::string> extensions; | |
| 163 extensions.push_back(PasswordCSVWriter::kFileExtension); | |
| 164 // TODO(xunlu) re-enable JSON when we are ready support it | |
| 165 // extensions.push_back(PasswordJSONWriter::kFileExtension); | |
| 166 return extensions; | |
| 167 } | |
| 168 | |
| 169 } // namespace password_manager | |
| OLD | NEW |