17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file. 47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_log_policy.h" 6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <stdint.h> 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/files/file_path.h" 10ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/json/json_string_value_serializer.h" 117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/logging.h" 12ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/strings/stringprintf.h" 13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/time/clock.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 15ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/extensions/activity_log/activity_action_constants.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using content::BrowserThread; 22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 23ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace constants = activity_log_constants; 24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 25ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace { 26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Obsolete database tables: these should be dropped from the database if 27ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// found. 28ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst char* kObsoleteTables[] = {"activitylog_apis", "activitylog_blocked", 29ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "activitylog_urls"}; 30ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace 31ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace extensions { 337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 34ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochActivityLogPolicy::ActivityLogPolicy(Profile* profile) {} 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ActivityLogPolicy::~ActivityLogPolicy() {} 37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 38ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ActivityLogPolicy::SetClockForTesting(scoped_ptr<base::Clock> clock) { 39ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch testing_clock_.reset(clock.release()); 40ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 41ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)base::Time ActivityLogPolicy::Now() const { 43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (testing_clock_) 44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return testing_clock_->Now(); 45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) else 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return base::Time::Now(); 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ActivityLogDatabasePolicy::ActivityLogDatabasePolicy( 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Profile* profile, 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const base::FilePath& database_name) 52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : ActivityLogPolicy(profile) { 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CHECK(profile); 54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::FilePath profile_base_path = profile->GetPath(); 55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) db_ = new ActivityDatabase(this); 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) database_path_ = profile_base_path.Append(database_name); 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ActivityLogDatabasePolicy::Init() { 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScheduleAndForget(db_, &ActivityDatabase::Init, database_path_); 61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ActivityLogDatabasePolicy::Flush() { 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScheduleAndForget(activity_database(), 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &ActivityDatabase::AdviseFlush, 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ActivityDatabase::kFlushImmediately); 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)sql::Connection* ActivityLogDatabasePolicy::GetDatabaseConnection() const { 70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return db_->GetSqlConnection(); 71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static 74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstd::string ActivityLogPolicy::Util::Serialize(const base::Value* value) { 75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string value_as_text; 76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!value) { 77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch value_as_text = ""; 78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch JSONStringValueSerializer serializer(&value_as_text); 80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch serializer.SerializeAndOmitBinaryValues(*value); 81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return value_as_text; 83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static 86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ActivityLogPolicy::Util::StripPrivacySensitiveFields( 87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_refptr<Action> action) { 88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Clear incognito URLs/titles. 89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (action->page_incognito()) { 90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch action->set_page_url(GURL()); 91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch action->set_page_title(""); 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) action->set_page_incognito(false); 93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (action->arg_incognito()) { 95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch action->set_arg_url(GURL()); 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) action->set_arg_incognito(false); 97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 98ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 99ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Strip query parameters, username/password, etc., from URLs. 100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (action->page_url().is_valid() || action->arg_url().is_valid()) { 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::Replacements<char> url_sanitizer; 102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch url_sanitizer.ClearUsername(); 103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch url_sanitizer.ClearPassword(); 104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch url_sanitizer.ClearQuery(); 105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch url_sanitizer.ClearRef(); 106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (action->page_url().is_valid()) 108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch action->set_page_url(action->page_url().ReplaceComponents(url_sanitizer)); 109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (action->arg_url().is_valid()) 110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch action->set_arg_url(action->arg_url().ReplaceComponents(url_sanitizer)); 111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Clear WebRequest details; only keep a record of which types of 114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // modifications were performed. 115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (action->action_type() == Action::ACTION_WEB_REQUEST) { 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* details = NULL; 117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (action->mutable_other()->GetDictionary(constants::kActionWebRequest, 118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch &details)) { 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue::Iterator details_iterator(*details); 120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch while (!details_iterator.IsAtEnd()) { 121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch details->SetBoolean(details_iterator.key(), true); 122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch details_iterator.Advance(); 123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ActivityLogPolicy::Util::StripArguments(const ApiSet& api_whitelist, 13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<Action> action) { 13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (api_whitelist.find( 13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::make_pair(action->action_type(), action->api_name())) == 13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) api_whitelist.end()) { 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) action->set_args(scoped_ptr<base::ListValue>()); 13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbase::Time ActivityLogPolicy::Util::AddDays(const base::Time& base_date, 140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int days) { 141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // To allow for time zone changes, add an additional partial day then round 142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // down to midnight. 143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return (base_date + base::TimeDelta::FromDays(days) + 144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::TimeDelta::FromHours(4)).LocalMidnight(); 145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static 148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ActivityLogPolicy::Util::ComputeDatabaseTimeBounds(const base::Time& now, 149ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int days_ago, 150ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int64* early_bound, 151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int64* late_bound) { 152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Time morning_midnight = now.LocalMidnight(); 153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (days_ago == 0) { 154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch *early_bound = morning_midnight.ToInternalValue(); 155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch *late_bound = base::Time::Max().ToInternalValue(); 156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Time early_time = Util::AddDays(morning_midnight, -days_ago); 158ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Time late_time = Util::AddDays(early_time, 1); 159ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch *early_bound = early_time.ToInternalValue(); 160ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch *late_bound = late_time.ToInternalValue(); 161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 162ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 163ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 164ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static 165ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool ActivityLogPolicy::Util::DropObsoleteTables(sql::Connection* db) { 166ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (size_t i = 0; i < arraysize(kObsoleteTables); i++) { 167ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const char* table_name = kObsoleteTables[i]; 168ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (db->DoesTableExist(table_name)) { 169ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string drop_statement = 170ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::StringPrintf("DROP TABLE %s", table_name); 171ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!db->Execute(drop_statement.c_str())) { 172ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return false; 173ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 175ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 176ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 177ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 178ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace extensions 180