Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / permissions / set_disjunction_permission.h
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:
31   explicit SetDisjunctionPermission(const APIPermissionInfo* info)
32     : APIPermission(info) {
33   }
34
35   ~SetDisjunctionPermission() {
36   }
37
38   // APIPermission overrides
39   virtual bool HasMessages() const OVERRIDE {
40     return !data_set_.empty();
41   }
42
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
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
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
68   virtual APIPermission* Clone() const OVERRIDE {
69     SetDisjunctionPermission* result = new DerivedType(info());
70     result->data_set_ = data_set_;
71     return result;
72   }
73
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
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
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
113   virtual bool FromValue(const base::Value* value,
114                          std::string* error) OVERRIDE {
115     data_set_.clear();
116     const base::ListValue* list = NULL;
117
118     if (!value || !value->GetAsList(&list) || list->GetSize() == 0) {
119       if (error)
120         *error = "NULL or empty permission list";
121       return false;
122     }
123
124     for (size_t i = 0; i < list->GetSize(); ++i) {
125       const base::Value* item_value = NULL;
126       bool got_item = list->Get(i, &item_value);
127       DCHECK(got_item);
128       DCHECK(item_value);
129
130       PermissionDataType data;
131       if (!data.FromValue(item_value)) {
132         if (error)
133           *error = "Cannot parse an item from the permission list";
134         return false;
135       }
136
137       data_set_.insert(data);
138     }
139     return true;
140   }
141
142   virtual scoped_ptr<base::Value> ToValue() const OVERRIDE {
143     base::ListValue* list = new base::ListValue();
144     typename std::set<PermissionDataType>::const_iterator i;
145     for (i = data_set_.begin(); i != data_set_.end(); ++i) {
146       scoped_ptr<base::Value> item_value(i->ToValue());
147       list->Append(item_value.release());
148     }
149     return scoped_ptr<base::Value>(list);
150   }
151
152   virtual void Write(IPC::Message* m) const OVERRIDE {
153     IPC::WriteParam(m, data_set_);
154   }
155
156   virtual bool Read(const IPC::Message* m, PickleIterator* iter) OVERRIDE {
157     return IPC::ReadParam(m, iter, &data_set_);
158   }
159
160   virtual void Log(std::string* log) const OVERRIDE {
161     IPC::LogParam(data_set_, log);
162   }
163
164  protected:
165   std::set<PermissionDataType> data_set_;
166 };
167
168 }  // namespace extensions
169
170 #endif  // CHROME_COMMON_EXTENSIONS_PERMISSIONS_SET_DISJUNCTION_PERMISSION_H_