supervised_user_blacklist.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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 "chrome/browser/supervised_user/experimental/supervised_user_blacklist.h"
6
7#include <algorithm>
8#include <cstring>
9#include <fstream>
10
11#include "base/files/file_path.h"
12#include "base/files/memory_mapped_file.h"
13#include "content/public/browser/browser_thread.h"
14#include "url/gurl.h"
15
16using content::BrowserThread;
17
18namespace {
19
20scoped_ptr<std::vector<SupervisedUserBlacklist::Hash> >
21ReadFromBinaryFileOnFileThread(const base::FilePath& path) {
22  DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
23
24  scoped_ptr<std::vector<SupervisedUserBlacklist::Hash> > host_hashes(
25      new std::vector<SupervisedUserBlacklist::Hash>);
26
27  base::MemoryMappedFile file;
28  file.Initialize(path);
29  if (!file.IsValid())
30    return host_hashes.Pass();
31
32  size_t size = file.length();
33  if (size <= 0 || size % base::kSHA1Length != 0)
34    return host_hashes.Pass();
35
36  size_t hash_count = size / base::kSHA1Length;
37  host_hashes->resize(hash_count);
38
39  for (size_t i = 0; i < hash_count; i++) {
40    memcpy((*host_hashes.get())[i].data,
41           file.data() + i * base::kSHA1Length,
42           base::kSHA1Length);
43  }
44
45  std::sort(host_hashes->begin(), host_hashes->end());
46
47  return host_hashes.Pass();
48}
49
50} // namespace
51
52SupervisedUserBlacklist::Hash::Hash(const std::string& host) {
53  const unsigned char* host_bytes =
54      reinterpret_cast<const unsigned char*>(host.c_str());
55  base::SHA1HashBytes(host_bytes, host.length(), data);
56}
57
58bool SupervisedUserBlacklist::Hash::operator<(const Hash& rhs) const {
59  return memcmp(data, rhs.data, base::kSHA1Length) < 0;
60}
61
62SupervisedUserBlacklist::SupervisedUserBlacklist() : weak_ptr_factory_(this) {}
63
64SupervisedUserBlacklist::~SupervisedUserBlacklist() {}
65
66bool SupervisedUserBlacklist::HasURL(const GURL& url) const {
67  Hash hash(url.host());
68  return std::binary_search(host_hashes_.begin(), host_hashes_.end(), hash);
69}
70
71size_t SupervisedUserBlacklist::GetEntryCount() const {
72  return host_hashes_.size();
73}
74
75void SupervisedUserBlacklist::ReadFromFile(const base::FilePath& path,
76                                           const base::Closure& done_callback) {
77  base::PostTaskAndReplyWithResult(
78      BrowserThread::GetBlockingPool(),
79      FROM_HERE,
80      base::Bind(&ReadFromBinaryFileOnFileThread, path),
81      base::Bind(&SupervisedUserBlacklist::OnReadFromFileCompleted,
82                 weak_ptr_factory_.GetWeakPtr(),
83                 done_callback));
84}
85
86void SupervisedUserBlacklist::OnReadFromFileCompleted(
87    const base::Closure& done_callback,
88    scoped_ptr<std::vector<Hash> > host_hashes) {
89  host_hashes_.swap(*host_hashes);
90  LOG_IF(WARNING, host_hashes_.empty()) << "Got empty blacklist";
91
92  if (!done_callback.is_null())
93    done_callback.Run();
94}
95