• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 #ifndef CHROME_COMMON_EXTENSIONS_PERMISSIONS_SET_DISJUNCTION_PERMISSION_H_
6 #define CHROME_COMMON_EXTENSIONS_PERMISSIONS_SET_DISJUNCTION_PERMISSION_H_
7 
8 #include <algorithm>
9 #include <set>
10 #include <string>
11 
12 #include "base/memory/scoped_ptr.h"
13 #include "base/values.h"
14 #include "chrome/common/extensions/extension_messages.h"
15 #include "extensions/common/permissions/api_permission.h"
16 #include "ipc/ipc_message.h"
17 #include "ipc/ipc_message_utils.h"
18 
19 namespace extensions {
20 
21 // An abstract base class for permissions that are represented by the
22 // disjunction of a set of conditions.  Each condition is represented by a
23 // |PermissionDataType| (e.g. SocketPermissionData).  If an
24 // APIPermission::CheckParam matches any of the conditions in the set, the
25 // permission is granted.
26 //
27 // For an example of how to use this class, see SocketPermission.
28 template <class PermissionDataType, class DerivedType>
29 class SetDisjunctionPermission : public APIPermission {
30  public:
SetDisjunctionPermission(const APIPermissionInfo * info)31   explicit SetDisjunctionPermission(const APIPermissionInfo* info)
32     : APIPermission(info) {
33   }
34 
~SetDisjunctionPermission()35   ~SetDisjunctionPermission() {
36   }
37 
38   // APIPermission overrides
HasMessages()39   virtual bool HasMessages() const OVERRIDE {
40     return !data_set_.empty();
41   }
42 
Check(const APIPermission::CheckParam * param)43   virtual bool Check(const APIPermission::CheckParam* param) const OVERRIDE {
44     for (typename std::set<PermissionDataType>::const_iterator i =
45         data_set_.begin(); i != data_set_.end(); ++i) {
46       if (i->Check(param))
47         return true;
48     }
49     return false;
50   }
51 
Contains(const APIPermission * rhs)52   virtual bool Contains(const APIPermission* rhs) const OVERRIDE {
53     CHECK(rhs->info() == info());
54     const SetDisjunctionPermission* perm =
55         static_cast<const SetDisjunctionPermission*>(rhs);
56     return std::includes(
57         data_set_.begin(), data_set_.end(),
58         perm->data_set_.begin(), perm->data_set_.end());
59   }
60 
Equal(const APIPermission * rhs)61   virtual bool Equal(const APIPermission* rhs) const OVERRIDE {
62     CHECK(rhs->info() == info());
63     const SetDisjunctionPermission* perm =
64         static_cast<const SetDisjunctionPermission*>(rhs);
65     return data_set_ == perm->data_set_;
66   }
67 
Clone()68   virtual APIPermission* Clone() const OVERRIDE {
69     SetDisjunctionPermission* result = new DerivedType(info());
70     result->data_set_ = data_set_;
71     return result;
72   }
73 
Diff(const APIPermission * rhs)74   virtual APIPermission* Diff(const APIPermission* rhs) const OVERRIDE {
75     CHECK(rhs->info() == info());
76     const SetDisjunctionPermission* perm =
77         static_cast<const SetDisjunctionPermission*>(rhs);
78     scoped_ptr<SetDisjunctionPermission> result(new DerivedType(info()));
79     std::set_difference(
80         data_set_.begin(), data_set_.end(),
81         perm->data_set_.begin(), perm->data_set_.end(),
82         std::inserter<std::set<PermissionDataType> >(
83             result->data_set_, result->data_set_.begin()));
84     return result->data_set_.empty() ? NULL : result.release();
85   }
86 
Union(const APIPermission * rhs)87   virtual APIPermission* Union(const APIPermission* rhs) const OVERRIDE {
88     CHECK(rhs->info() == info());
89     const SetDisjunctionPermission* perm =
90         static_cast<const SetDisjunctionPermission*>(rhs);
91     scoped_ptr<SetDisjunctionPermission> result(new DerivedType(info()));
92     std::set_union(
93         data_set_.begin(), data_set_.end(),
94         perm->data_set_.begin(), perm->data_set_.end(),
95         std::inserter<std::set<PermissionDataType> >(
96             result->data_set_, result->data_set_.begin()));
97     return result.release();
98   }
99 
Intersect(const APIPermission * rhs)100   virtual APIPermission* Intersect(const APIPermission* rhs) const OVERRIDE {
101     CHECK(rhs->info() == info());
102     const SetDisjunctionPermission* perm =
103         static_cast<const SetDisjunctionPermission*>(rhs);
104     scoped_ptr<SetDisjunctionPermission> result(new DerivedType(info()));
105     std::set_intersection(
106         data_set_.begin(), data_set_.end(),
107         perm->data_set_.begin(), perm->data_set_.end(),
108         std::inserter<std::set<PermissionDataType> >(
109             result->data_set_, result->data_set_.begin()));
110     return result->data_set_.empty() ? NULL : result.release();
111   }
112 
FromValue(const base::Value * value)113   virtual bool FromValue(const base::Value* value) OVERRIDE {
114     data_set_.clear();
115     const base::ListValue* list = NULL;
116 
117     if (!value)
118       return false;
119 
120     if (!value->GetAsList(&list) || list->GetSize() == 0)
121       return false;
122 
123     for (size_t i = 0; i < list->GetSize(); ++i) {
124       const base::Value* item_value;
125       if (!list->Get(i, &item_value))
126         return false;
127 
128       PermissionDataType data;
129       if (!data.FromValue(item_value))
130         return false;
131 
132       data_set_.insert(data);
133     }
134     return true;
135   }
136 
ToValue()137   virtual scoped_ptr<base::Value> ToValue() const OVERRIDE {
138     base::ListValue* list = new base::ListValue();
139     typename std::set<PermissionDataType>::const_iterator i;
140     for (i = data_set_.begin(); i != data_set_.end(); ++i) {
141       scoped_ptr<base::Value> item_value(i->ToValue());
142       list->Append(item_value.release());
143     }
144     return scoped_ptr<base::Value>(list);
145   }
146 
Write(IPC::Message * m)147   virtual void Write(IPC::Message* m) const OVERRIDE {
148     IPC::WriteParam(m, data_set_);
149   }
150 
Read(const IPC::Message * m,PickleIterator * iter)151   virtual bool Read(const IPC::Message* m, PickleIterator* iter) OVERRIDE {
152     return IPC::ReadParam(m, iter, &data_set_);
153   }
154 
Log(std::string * log)155   virtual void Log(std::string* log) const OVERRIDE {
156     IPC::LogParam(data_set_, log);
157   }
158 
159  protected:
160   std::set<PermissionDataType> data_set_;
161 };
162 
163 }  // namespace extensions
164 
165 #endif  // CHROME_COMMON_EXTENSIONS_PERMISSIONS_SET_DISJUNCTION_PERMISSION_H_
166