| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/logging.h" | 5 #include "base/logging.h" |
| 6 #include "base/stringprintf.h" | 6 #include "base/stringprintf.h" |
| 7 #include "chrome/browser/extensions/activity_log/blocked_actions.h" | 7 #include "chrome/browser/extensions/activity_log/blocked_actions.h" |
| 8 #include "content/public/browser/browser_thread.h" | 8 #include "content/public/browser/browser_thread.h" |
| 9 | 9 |
| 10 using content::BrowserThread; | 10 using content::BrowserThread; |
| 11 | 11 |
| 12 namespace extensions { | 12 namespace extensions { |
| 13 | 13 |
| 14 const char* BlockedAction::kTableName = "activitylog_blocked"; | 14 const char* BlockedAction::kTableName = "activitylog_blocked"; |
| 15 const char* BlockedAction::kTableContentFields[] = | 15 const char* BlockedAction::kTableContentFields[] = |
| 16 {"api_call", "args", "reason", "extra"}; | 16 {"api_call", "args", "reason", "extra"}; |
| 17 const char* BlockedAction::kTableFieldTypes[] = |
| 18 {"LONGVARCHAR", "LONGVARCHAR", "INTEGER", "LONGVARCHAR"}; |
| 17 | 19 |
| 18 BlockedAction::BlockedAction(const std::string& extension_id, | 20 BlockedAction::BlockedAction(const std::string& extension_id, |
| 19 const base::Time& time, | 21 const base::Time& time, |
| 20 const std::string& api_call, | 22 const std::string& api_call, |
| 21 const std::string& args, | 23 const std::string& args, |
| 22 const BlockedAction::Reason reason, | 24 const BlockedAction::Reason reason, |
| 23 const std::string& extra) | 25 const std::string& extra) |
| 24 : Action(extension_id, time), | 26 : Action(extension_id, time), |
| 25 api_call_(api_call), | 27 api_call_(api_call), |
| 26 args_(args), | 28 args_(args), |
| 27 reason_(reason), | 29 reason_(reason), |
| 28 extra_(extra) { } | 30 extra_(extra) { } |
| 29 | 31 |
| 30 BlockedAction::BlockedAction(const sql::Statement& s) | 32 BlockedAction::BlockedAction(const sql::Statement& s) |
| 31 : Action(s.ColumnString(0), | 33 : Action(s.ColumnString(0), |
| 32 base::Time::FromInternalValue(s.ColumnInt64(1))), | 34 base::Time::FromInternalValue(s.ColumnInt64(1))), |
| 33 api_call_(s.ColumnString(2)), | 35 api_call_(s.ColumnString(2)), |
| 34 args_(s.ColumnString(3)), | 36 args_(s.ColumnString(3)), |
| 35 reason_(StringAsReason(s.ColumnString(4))), | 37 reason_(static_cast<Reason>(s.ColumnInt(4))), |
| 36 extra_(s.ColumnString(5)) { } | 38 extra_(s.ColumnString(5)) { } |
| 37 | 39 |
| 38 BlockedAction::~BlockedAction() { | 40 BlockedAction::~BlockedAction() { |
| 39 } | 41 } |
| 40 | 42 |
| 41 // static | 43 // static |
| 42 bool BlockedAction::InitializeTable(sql::Connection* db) { | 44 bool BlockedAction::InitializeTable(sql::Connection* db) { |
| 43 // The original table schema was different than the existing one. | 45 // The original table schema was different than the existing one. |
| 44 // Sqlite doesn't let you delete or modify existing columns, so we drop it. | 46 // Sqlite doesn't let you delete or modify existing columns, so we drop it. |
| 45 // The old version can be identified because it had a field named | 47 // The old version can be identified because it had a field named |
| 46 // blocked_action. Any data loss incurred here doesn't matter since these | 48 // blocked_action. Any data loss incurred here doesn't matter since these |
| 47 // fields existed before we started using the AL for anything. | 49 // fields existed before we started using the AL for anything. |
| 48 if (db->DoesColumnExist(kTableName, "blocked_action")) { | 50 if (db->DoesColumnExist(kTableName, "blocked_action")) { |
| 49 std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName); | 51 std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName); |
| 50 if (!db->Execute(drop_table.c_str())) | 52 if (!db->Execute(drop_table.c_str())) |
| 51 return false; | 53 return false; |
| 52 } | 54 } |
| 55 // We also now use INTEGER instead of VARCHAR for url_action_type. |
| 56 if (db->DoesColumnExist(kTableName, "reason")) { |
| 57 std::string select = base::StringPrintf( |
| 58 "SELECT reason FROM %s ORDER BY rowid LIMIT 1", kTableName); |
| 59 sql::Statement statement(db->GetUniqueStatement(select.c_str())); |
| 60 if (statement.DeclaredColumnType(0) != sql::COLUMN_TYPE_INTEGER) { |
| 61 std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName); |
| 62 if (!db->Execute(drop_table.c_str())) |
| 63 return false; |
| 64 } |
| 65 } |
| 53 return InitializeTableInternal(db, | 66 return InitializeTableInternal(db, |
| 54 kTableName, | 67 kTableName, |
| 55 kTableContentFields, | 68 kTableContentFields, |
| 69 kTableFieldTypes, |
| 56 arraysize(kTableContentFields)); | 70 arraysize(kTableContentFields)); |
| 57 } | 71 } |
| 58 | 72 |
| 59 void BlockedAction::Record(sql::Connection* db) { | 73 void BlockedAction::Record(sql::Connection* db) { |
| 60 std::string sql_str = "INSERT INTO " + std::string(kTableName) | 74 std::string sql_str = "INSERT INTO " + std::string(kTableName) |
| 61 + " (extension_id, time, api_call, args, reason, extra)" | 75 + " (extension_id, time, api_call, args, reason, extra)" |
| 62 " VALUES (?,?,?,?,?,?)"; | 76 " VALUES (?,?,?,?,?,?)"; |
| 63 sql::Statement statement(db->GetCachedStatement( | 77 sql::Statement statement(db->GetCachedStatement( |
| 64 sql::StatementID(SQL_FROM_HERE), sql_str.c_str())); | 78 sql::StatementID(SQL_FROM_HERE), sql_str.c_str())); |
| 65 statement.BindString(0, extension_id()); | 79 statement.BindString(0, extension_id()); |
| 66 statement.BindInt64(1, time().ToInternalValue()); | 80 statement.BindInt64(1, time().ToInternalValue()); |
| 67 statement.BindString(2, api_call_); | 81 statement.BindString(2, api_call_); |
| 68 statement.BindString(3, args_); | 82 statement.BindString(3, args_); |
| 69 statement.BindString(4, ReasonAsString()); | 83 statement.BindInt(4, static_cast<int>(reason_)); |
| 70 statement.BindString(5, extra_); | 84 statement.BindString(5, extra_); |
| 71 if (!statement.Run()) | 85 if (!statement.Run()) |
| 72 LOG(ERROR) << "Activity log database I/O failed: " << sql_str; | 86 LOG(ERROR) << "Activity log database I/O failed: " << sql_str; |
| 73 } | 87 } |
| 74 | 88 |
| 75 std::string BlockedAction::PrintForDebug() { | 89 std::string BlockedAction::PrintForDebug() { |
| 76 // TODO(felt): implement this for real when the UI is redesigned. | |
| 77 return "ID: " + extension_id() + ", blocked action " + api_call_ + | 90 return "ID: " + extension_id() + ", blocked action " + api_call_ + |
| 78 ", reason: " + ReasonAsString(); | 91 ", reason: " + ReasonAsString(); |
| 79 } | 92 } |
| 80 | 93 |
| 81 std::string BlockedAction::ReasonAsString() const { | 94 std::string BlockedAction::ReasonAsString() const { |
| 82 if (reason_ == ACCESS_DENIED) | 95 if (reason_ == ACCESS_DENIED) |
| 83 return std::string("access denied"); | 96 return std::string("access denied"); |
| 84 else if (reason_ == QUOTA_EXCEEDED) | 97 else if (reason_ == QUOTA_EXCEEDED) |
| 85 return std::string("quota exceeded"); | 98 return std::string("quota exceeded"); |
| 86 else | 99 else |
| 87 return std::string("unknown"); | 100 return std::string("unknown"); |
| 88 } | 101 } |
| 89 | 102 |
| 90 // static | |
| 91 BlockedAction::Reason BlockedAction::StringAsReason(const std::string& reason) { | |
| 92 if (reason == "access denied") | |
| 93 return ACCESS_DENIED; | |
| 94 else if (reason == "quota exceeded") | |
| 95 return QUOTA_EXCEEDED; | |
| 96 else | |
| 97 return UNKNOWN; | |
| 98 } | |
| 99 | |
| 100 } // namespace extensions | 103 } // namespace extensions |
| 101 | 104 |
| OLD | NEW |