Revert "[Bookmark] Moved checking privileges to JS layer."
[platform/core/api/webapi-plugins.git] / src / bookmark / bookmark_instance.cc
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 #include "bookmark/bookmark_instance.h"
18
19 #include <web/bookmark-adaptor.h>
20 #include <string>
21
22 #include "common/platform_exception.h"
23 #include "common/converter.h"
24 #include "common/logger.h"
25 #include "common/tools.h"
26
27 using common::ErrorCode;
28 using common::PlatformResult;
29
30 namespace extension {
31 namespace bookmark {
32
33 namespace {
34   const char kId[] = "id";
35   const char kTitle[] = "title";
36   const char kType[] = "type";
37   const char kParentId[] = "parentId";
38   const char kUrl[] = "url";
39
40   const std::string kPrivilegeBookmarkRead = "http://tizen.org/privilege/bookmark.read";
41   const std::string kPrivilegeBookmarkWrite = "http://tizen.org/privilege/bookmark.write";
42 }  // namespace
43
44 BookmarkInstance::BookmarkInstance() {
45   LoggerD("Enter");
46   using std::placeholders::_1;
47   using std::placeholders::_2;
48
49 #define REGISTER_SYNC(c,x) \
50     RegisterSyncHandler(c, std::bind(&BookmarkInstance::x, this, _1, _2));
51   REGISTER_SYNC("Bookmark_get", BookmarkGet);
52   REGISTER_SYNC("Bookmark_add", BookmarkAdd);
53   REGISTER_SYNC("Bookmark_remove", BookmarkRemove);
54   REGISTER_SYNC("Bookmark_removeAll", BookmarkRemoveAll);
55   REGISTER_SYNC("Bookmark_getRootId", BookmarkGetRootId);
56 #undef REGISTER_SYNC
57 }
58
59 BookmarkInstance::~BookmarkInstance() {
60   LoggerD("Enter");
61 }
62
63 bool BookmarkInstance::bookmark_foreach(
64     Context& ctx, bp_bookmark_info_fmt& info) {
65
66   LoggerD("Enter");
67   int ids_count = 0;
68   int* ids = NULL;
69   BookmarkObject item;
70   if (bp_bookmark_adaptor_get_ids_p(&ids, &ids_count, -1, 0, -1, -1, -1, -1,
71                                     BP_BOOKMARK_O_DATE_CREATED, 0) < 0)
72     return false;
73
74
75   if (ids_count > 0) {
76     for (int i = 0; i < ids_count; i++) {
77       bp_bookmark_adaptor_get_easy_all(ids[i], &info);
78       item.id = ids[i];
79       item.bookmark_info = info;
80       if ((ctx.shouldGetItems && item.bookmark_info.parent != ctx.id) ||
81         (!ctx.shouldGetItems && item.id != ctx.id))
82         continue;
83       ctx.folders.push_back(item);
84     }
85   }
86   free(ids);
87   return true;
88 }
89
90 PlatformResult BookmarkInstance::BookmarkUrlExists(const char* url,
91                                                    bool* exists) {
92   LoggerD("Enter");
93   int ids_count = 0;
94   int* ids = nullptr;
95   char* compare_url = nullptr;
96
97   int ntv_ret = bp_bookmark_adaptor_get_ids_p(
98                     &ids,  // ids
99                     &ids_count,  // count
100                     -1,  //limit
101                     0,  // offset
102                     -1,  //parent
103                     -1,  //type
104                     -1,  // is_operator
105                     -1,  // is_editable
106                     BP_BOOKMARK_O_DATE_CREATED,  // order_offset
107                     0  // ordering ASC
108                     );
109   if (ntv_ret < 0) {
110     return LogAndCreateResult(
111                 ErrorCode::UNKNOWN_ERR, "Failed to obtain bookmarks",
112                 ("bp_bookmark_adaptor_get_ids_p error: %d (%s)", ntv_ret, get_error_message(ntv_ret)));
113   }
114
115   PlatformResult result{ErrorCode::NO_ERROR};
116   bool url_found = false;
117   for (int i = 0; (i < ids_count) && result && !url_found; ++i) {
118     ntv_ret = bp_bookmark_adaptor_get_url(ids[i], &compare_url);
119     if (ntv_ret < 0) {
120       result = LogAndCreateResult(
121                     ErrorCode::UNKNOWN_ERR, "Failed to obtain URL",
122                     ("bp_bookmark_adaptor_get_url error: %d (%s)", ntv_ret, get_error_message(ntv_ret)));
123     } else {
124       url_found = (0 == strcmp(url, compare_url));
125       free(compare_url);
126       compare_url = nullptr;
127     }
128   }
129
130   if (result) {
131     *exists = url_found;
132   }
133
134   free(ids);
135
136   return result;
137 }
138
139 PlatformResult BookmarkInstance::BookmarkTitleExistsInParent(const char* title,
140                                                              int parent,
141                                                              bool* exists) {
142
143   LoggerD("Enter");
144   int ids_count = 0;
145   int compare_parent = -1;
146   int* ids = nullptr;
147   char* compare_title = nullptr;
148
149   int ntv_ret = bp_bookmark_adaptor_get_ids_p(
150                     &ids,  // ids
151                     &ids_count,  // count
152                     -1,  //limit
153                     0,  // offset
154                     -1,  //parent
155                     -1,  //type
156                     -1,  // is_operator
157                     -1,  // is_editable
158                     BP_BOOKMARK_O_DATE_CREATED,  // order_offset
159                     0  // ordering ASC
160                     );
161   if (ntv_ret < 0) {
162     return LogAndCreateResult(
163                 ErrorCode::UNKNOWN_ERR, "Failed to obtain bookmarks",
164                 ("bp_bookmark_adaptor_get_ids_p error: %d (%s)",
165                     ntv_ret, get_error_message(ntv_ret)));
166   }
167
168   PlatformResult result{ErrorCode::NO_ERROR};
169   bool title_found = false;
170   for (int i = 0; (i < ids_count) && result && !title_found; ++i) {
171     if ((ntv_ret = bp_bookmark_adaptor_get_parent_id(ids[i], &compare_parent)) < 0) {
172       result = LogAndCreateResult(
173                     ErrorCode::UNKNOWN_ERR, "Failed to obtain parent ID",
174                     ("bp_bookmark_adaptor_get_parent_id error: %d (%s)",
175                         ntv_ret, get_error_message(ntv_ret)));
176     } else if ((ntv_ret = bp_bookmark_adaptor_get_title(ids[i], &compare_title)) < 0) {
177       result = LogAndCreateResult(
178                     ErrorCode::UNKNOWN_ERR, "Failed to obtain title",
179                     ("bp_bookmark_adaptor_get_title error: %d (%s)",
180                         ntv_ret, get_error_message(ntv_ret)));
181     } else {
182       title_found = (parent == compare_parent) && (0 == strcmp(title, compare_title));
183       free(compare_title);
184       compare_title = nullptr;
185       compare_parent = -1;
186     }
187   }
188
189   if (result) {
190     *exists = title_found;
191   }
192
193   free(ids);
194
195   return result;
196 }
197
198 void BookmarkInstance::BookmarkGet(
199     const picojson::value& arg, picojson::object& o) {
200   CHECK_PRIVILEGE_ACCESS(kPrivilegeBookmarkRead, &o);
201
202   LoggerD("Enter");
203   Context ctx = {0};
204   bp_bookmark_info_fmt info = {0};
205   picojson::value::array arr;
206
207   ctx.shouldGetItems = arg.get("shouldGetItems").get<double>();
208   ctx.id             = arg.get(kId).get<double>();
209
210   if (!bookmark_foreach(ctx, info)) {
211     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get bookmark"), &o);
212     return;
213   }
214
215   std::vector<BookmarkObject>::iterator it;
216   for (it = ctx.folders.begin(); it!= ctx.folders.end(); ++it) {
217     picojson::object obj;
218     BookmarkObject entry = *it;
219
220     obj[kTitle] = picojson::value(entry.bookmark_info.title);
221     obj[kId] = picojson::value(std::to_string(entry.id));
222     obj[kType] = picojson::value(std::to_string(entry.bookmark_info.type));
223     obj[kParentId] = picojson::value(std::to_string(
224         entry.bookmark_info.parent));
225     if (!entry.bookmark_info.type)
226       obj[kUrl] = picojson::value(entry.bookmark_info.url);
227
228     arr.push_back(picojson::value(obj));
229   }
230   ReportSuccess(picojson::value(arr), o);
231 }
232
233 void BookmarkInstance::BookmarkAdd(
234     const picojson::value& arg, picojson::object& o) {
235   CHECK_PRIVILEGE_ACCESS(kPrivilegeBookmarkWrite, &o);
236
237   LoggerD("Enter");
238   int saved_id =-1;
239
240   const auto& title = arg.get(kTitle).get<std::string>();
241   const int parent = static_cast<int>(arg.get(kParentId).get<double>());
242   const int type = static_cast<int>(arg.get(kType).get<double>());
243   const auto& url = arg.get(kUrl).get<std::string>();
244
245   if (0 == type) {  // bookmark
246     bool exists = false;
247     auto result = BookmarkUrlExists(url.c_str(), &exists);
248     if (!result) {
249       LogAndReportError(result, &o);
250       return;
251     } else if (exists) {
252       LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Bookmark already exists"), &o);
253       return;
254     }
255   }
256
257   if (1 == type) {  // folder
258     bool exists = false;
259     auto result = BookmarkTitleExistsInParent(title.c_str(), parent, &exists);
260     if (!result) {
261       LogAndReportError(result, &o);
262       return;
263     } else if (exists) {
264       LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Bookmark already exists"), &o);
265       return;
266     }
267   }
268
269   int ntv_ret;
270
271   ntv_ret = bp_bookmark_adaptor_create(&saved_id);
272   if (ntv_ret < 0) {
273     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to create adaptor"), &o);
274     return;
275   }
276
277   ntv_ret = bp_bookmark_adaptor_set_title(saved_id, title.c_str());
278   if (ntv_ret < 0) {
279     bp_bookmark_adaptor_delete(saved_id);
280     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to set title"), &o);
281     return;
282   }
283
284   ntv_ret = bp_bookmark_adaptor_set_parent_id(saved_id, parent);
285   if (ntv_ret < 0) {
286     bp_bookmark_adaptor_delete(saved_id);
287     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to set parent id"), &o);
288     return;
289   }
290
291   ntv_ret = bp_bookmark_adaptor_set_type(saved_id, type);
292   if (ntv_ret < 0) {
293     bp_bookmark_adaptor_delete(saved_id);
294     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to set type"), &o);
295     return;
296   }
297
298   ntv_ret = bp_bookmark_adaptor_set_url(saved_id, url.c_str());
299   if (ntv_ret < 0) {
300     bp_bookmark_adaptor_delete(saved_id);
301     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to set url"), &o);
302     return;
303   }
304   ReportSuccess(picojson::value(std::to_string(saved_id)), o);
305 }
306
307 void BookmarkInstance::BookmarkRemove(
308     const picojson::value& arg, picojson::object& o) {
309   CHECK_PRIVILEGE_ACCESS(kPrivilegeBookmarkWrite, &o);
310
311   LoggerD("Enter");
312   int id = common::stol(
313       common::FromJson<std::string>(arg.get<picojson::object>(), kId));
314
315   int ntv_ret = bp_bookmark_adaptor_delete(id);
316   if (ntv_ret < 0) {
317     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to remove bookmark"), &o);
318     return;
319   }
320   ReportSuccess(o);
321 }
322
323 void BookmarkInstance::BookmarkRemoveAll(
324     const picojson::value& msg, picojson::object& o) {
325   CHECK_PRIVILEGE_ACCESS(kPrivilegeBookmarkWrite, &o);
326
327   LoggerD("Enter");
328   int ntv_ret = bp_bookmark_adaptor_reset();
329   if (ntv_ret < 0) {
330     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to remove bookmark"), &o);
331     return;
332   }
333   ReportSuccess(o);
334 }
335
336 void BookmarkInstance::BookmarkGetRootId(
337     const picojson::value& msg, picojson::object& o) {
338
339   LoggerD("Enter");
340   int rootId(0);
341   int ntv_ret = bp_bookmark_adaptor_get_root(&rootId);
342   if (ntv_ret < 0) {
343     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to remove bookmark"), &o);
344     return;
345   }
346   ReportSuccess(picojson::value(std::to_string(rootId)), o);
347 }
348 }  // namespace bookmark
349 }  // namespace extension