activity_log_policy.cc revision 3551c9c881056c480085172ff9840cab31610854
1// Copyright 2013 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 "chrome/browser/extensions/activity_log/activity_log_policy.h" 6 7#include <stdint.h> 8 9#include "base/files/file_path.h" 10#include "base/json/json_string_value_serializer.h" 11#include "base/logging.h" 12#include "base/strings/stringprintf.h" 13#include "base/time/clock.h" 14#include "base/time/time.h" 15#include "chrome/browser/extensions/activity_log/activity_action_constants.h" 16#include "chrome/browser/profiles/profile.h" 17#include "chrome/common/extensions/extension.h" 18#include "content/public/browser/browser_thread.h" 19#include "url/gurl.h" 20 21using content::BrowserThread; 22 23namespace constants = activity_log_constants; 24 25namespace { 26// Obsolete database tables: these should be dropped from the database if 27// found. 28const char* kObsoleteTables[] = {"activitylog_apis", "activitylog_blocked", 29 "activitylog_urls"}; 30} // namespace 31 32namespace extensions { 33 34ActivityLogPolicy::ActivityLogPolicy(Profile* profile) {} 35 36ActivityLogPolicy::~ActivityLogPolicy() {} 37 38void ActivityLogPolicy::SetClockForTesting(scoped_ptr<base::Clock> clock) { 39 testing_clock_.reset(clock.release()); 40} 41 42base::Time ActivityLogPolicy::Now() const { 43 if (testing_clock_) 44 return testing_clock_->Now(); 45 else 46 return base::Time::Now(); 47} 48 49ActivityLogDatabasePolicy::ActivityLogDatabasePolicy( 50 Profile* profile, 51 const base::FilePath& database_name) 52 : ActivityLogPolicy(profile) { 53 CHECK(profile); 54 base::FilePath profile_base_path = profile->GetPath(); 55 db_ = new ActivityDatabase(this); 56 base::FilePath database_path = profile_base_path.Append(database_name); 57 ScheduleAndForget(db_, &ActivityDatabase::Init, database_path); 58} 59 60void ActivityLogDatabasePolicy::Flush() { 61 ScheduleAndForget(activity_database(), 62 &ActivityDatabase::AdviseFlush, 63 ActivityDatabase::kFlushImmediately); 64} 65 66sql::Connection* ActivityLogDatabasePolicy::GetDatabaseConnection() const { 67 return db_->GetSqlConnection(); 68} 69 70// static 71std::string ActivityLogPolicy::Util::Serialize(const base::Value* value) { 72 std::string value_as_text; 73 if (!value) { 74 value_as_text = ""; 75 } else { 76 JSONStringValueSerializer serializer(&value_as_text); 77 serializer.SerializeAndOmitBinaryValues(*value); 78 } 79 return value_as_text; 80} 81 82// static 83void ActivityLogPolicy::Util::StripPrivacySensitiveFields( 84 scoped_refptr<Action> action) { 85 // Clear incognito URLs/titles. 86 if (action->page_incognito()) { 87 action->set_page_url(GURL()); 88 action->set_page_title(""); 89 } 90 if (action->arg_incognito()) { 91 action->set_arg_url(GURL()); 92 } 93 94 // Strip query parameters, username/password, etc., from URLs. 95 if (action->page_url().is_valid() || action->arg_url().is_valid()) { 96 url_canon::Replacements<char> url_sanitizer; 97 url_sanitizer.ClearUsername(); 98 url_sanitizer.ClearPassword(); 99 url_sanitizer.ClearQuery(); 100 url_sanitizer.ClearRef(); 101 102 if (action->page_url().is_valid()) 103 action->set_page_url(action->page_url().ReplaceComponents(url_sanitizer)); 104 if (action->arg_url().is_valid()) 105 action->set_arg_url(action->arg_url().ReplaceComponents(url_sanitizer)); 106 } 107 108 // Clear WebRequest details; only keep a record of which types of 109 // modifications were performed. 110 if (action->action_type() == Action::ACTION_WEB_REQUEST) { 111 DictionaryValue* details = NULL; 112 if (action->mutable_other()->GetDictionary(constants::kActionWebRequest, 113 &details)) { 114 DictionaryValue::Iterator details_iterator(*details); 115 while (!details_iterator.IsAtEnd()) { 116 details->SetBoolean(details_iterator.key(), true); 117 details_iterator.Advance(); 118 } 119 } 120 } 121} 122 123// static 124void ActivityLogPolicy::Util::StripArguments( 125 const std::set<std::string>& api_whitelist, 126 scoped_refptr<Action> action) { 127 if (action->action_type() != Action::ACTION_API_CALL && 128 action->action_type() != Action::ACTION_API_EVENT && 129 action->action_type() != Action::UNUSED_ACTION_API_BLOCKED) 130 return; 131 132 if (api_whitelist.find(action->api_name()) == api_whitelist.end()) 133 action->set_args(scoped_ptr<ListValue>()); 134} 135 136// static 137base::Time ActivityLogPolicy::Util::AddDays(const base::Time& base_date, 138 int days) { 139 // To allow for time zone changes, add an additional partial day then round 140 // down to midnight. 141 return (base_date + base::TimeDelta::FromDays(days) + 142 base::TimeDelta::FromHours(4)).LocalMidnight(); 143} 144 145// static 146void ActivityLogPolicy::Util::ComputeDatabaseTimeBounds(const base::Time& now, 147 int days_ago, 148 int64* early_bound, 149 int64* late_bound) { 150 base::Time morning_midnight = now.LocalMidnight(); 151 if (days_ago == 0) { 152 *early_bound = morning_midnight.ToInternalValue(); 153 *late_bound = base::Time::Max().ToInternalValue(); 154 } else { 155 base::Time early_time = Util::AddDays(morning_midnight, -days_ago); 156 base::Time late_time = Util::AddDays(early_time, 1); 157 *early_bound = early_time.ToInternalValue(); 158 *late_bound = late_time.ToInternalValue(); 159 } 160} 161 162// static 163bool ActivityLogPolicy::Util::DropObsoleteTables(sql::Connection* db) { 164 for (size_t i = 0; i < arraysize(kObsoleteTables); i++) { 165 const char* table_name = kObsoleteTables[i]; 166 if (db->DoesTableExist(table_name)) { 167 std::string drop_statement = 168 base::StringPrintf("DROP TABLE %s", table_name); 169 if (!db->Execute(drop_statement.c_str())) { 170 return false; 171 } 172 } 173 } 174 return true; 175} 176 177} // namespace extensions 178