Adjust coverage script after lcov upgrade
[platform/core/security/askuser.git] / src / client / api / askuser-notification-client.cpp
1 /*
2  *  Copyright (c) 2017-2020 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 /**
18  * @file        askuser-notification-client.cpp
19  * @author      Piotr Sawicki <p.sawicki2@partner.samsung.com>
20  * @author      Ernest Borowski <e.borowski@partner.samsung.com>
21  * @brief       This file contains the implementation of the askuser-notification client API.
22  */
23
24 #include <cstring>
25 #include <memory>
26 #include <unordered_set>
27 #include <vector>
28
29 #include <log/alog.h>
30 #include <askuser-notification-client.h>
31 #include <attributes/attributes.h>
32 #include <message-utils.h>
33
34 #include <ApiInterface.h>
35 #include <ApiInterfaceImpl.h>
36 #include <StatusCallbackClosure.h>
37 #include <TryCatch.h>
38
39 struct askuser_client {
40     AskUser::Client::ApiInterface *impl;
41
42     explicit askuser_client(AskUser::Client::ApiInterface *_impl) : impl(_impl) {
43     }
44
45     ~askuser_client() {
46         delete impl;
47     }
48 };
49
50 API
51 int askuser_client_initialize(askuser_client **pp_client,
52                               askuser_status_callback status_callback, void *p_user_data)
53 {
54     if (!pp_client || !status_callback) {
55         return ASKUSER_API_INVALID_PARAM;
56     }
57
58     init_agent_log();
59
60     return AskUser::Client::tryCatch([&]() {
61         AskUser::Client::StatusCallbackClosure closure(status_callback, p_user_data);
62
63         std::unique_ptr<AskUser::Client::ApiInterface> ptr;
64         ptr.reset(new AskUser::Client::ApiInterfaceImpl(closure));
65
66         *pp_client = new askuser_client(ptr.get());
67
68         ptr.release();
69
70         return ASKUSER_API_SUCCESS;
71     });
72 }
73
74 API
75 void askuser_client_finalize(askuser_client *p_client)
76 {
77     if (!p_client) {
78         return;
79     }
80
81     AskUser::Client::tryCatch([&]() {
82         delete p_client;
83         return ASKUSER_API_SUCCESS;
84     });
85 }
86
87 API
88 int askuser_client_process(askuser_client *p_client, int fd, int events)
89 {
90     if (!p_client) {
91         return ASKUSER_API_INVALID_PARAM;
92     }
93
94     return AskUser::Client::tryCatch([&]() {
95         return p_client->impl->process(fd, events);
96     });
97 }
98
99 API
100 int askuser_client_check_privilege(askuser_client *p_client,
101                                    const char *privilege, askuser_check_result *p_result)
102 {
103     if (!p_client || !privilege || !p_result) {
104         return ASKUSER_API_INVALID_PARAM;
105     }
106
107     if (std::strlen(privilege) == 0) {
108         return ASKUSER_API_INVALID_PARAM;
109     }
110
111     return AskUser::Client::tryCatch([&]() {
112         *p_result = p_client->impl->checkPrivilege(privilege);
113         return ASKUSER_API_SUCCESS;
114     });
115 }
116
117 API
118 int askuser_client_check_app_privilege(askuser_client *p_client,
119                                        const char *app_id,
120                                        const char *privilege,
121                                        askuser_check_result *p_result)
122 {
123     if (!p_client || !app_id || !privilege || !p_result) {
124         return ASKUSER_API_INVALID_PARAM;
125     }
126
127     if (std::strlen(privilege) == 0) {
128         return ASKUSER_API_INVALID_PARAM;
129     }
130
131     return AskUser::Client::tryCatch([&]() {
132         *p_result = p_client->impl->checkPrivilege(app_id, privilege);
133         return ASKUSER_API_SUCCESS;
134     });
135 }
136
137 API
138 int askuser_client_check_privileges(askuser_client *p_client, const char **privileges,
139                                     size_t privileges_count, askuser_check_result *p_results)
140 {
141     if (!p_client || !privileges || !p_results ||
142         privileges_count == 0 || privileges_count > AskUser::Protocol::MAX_PRIVS_NUMBER) {
143         return ASKUSER_API_INVALID_PARAM;
144     }
145
146     int ret = ASKUSER_API_SUCCESS;
147     for (size_t i = 0; i < privileges_count; ++i) {
148         ret = askuser_client_check_privilege(p_client, privileges[i], &(p_results[i]));
149         if (ret != ASKUSER_API_SUCCESS)
150             break;
151     }
152     return ret;
153 }
154
155 API
156 int askuser_client_check_app_privileges(askuser_client *p_client, const char *app_id,
157                                         const char **privileges, size_t privileges_count,
158                                         askuser_check_result *p_results)
159 {
160     if (!p_client || !app_id || !privileges || !p_results ||
161         privileges_count == 0 || privileges_count > AskUser::Protocol::MAX_PRIVS_NUMBER) {
162         return ASKUSER_API_INVALID_PARAM;
163     }
164
165     int ret = ASKUSER_API_SUCCESS;
166     for (size_t i = 0; i < privileges_count; ++i) {
167         ret = askuser_client_check_app_privilege(p_client, app_id, privileges[i], &(p_results[i]));
168         if (ret != ASKUSER_API_SUCCESS)
169             break;
170     }
171     return ret;
172 }
173
174 API
175 int askuser_client_popup_request(askuser_client *p_client, const char *privilege,
176                                  askuser_popup_response_callback response_callback,
177                                  void *p_user_data, int *p_request_id)
178 {
179     if (!p_client || !privilege || !response_callback) {
180         return ASKUSER_API_INVALID_PARAM;
181     }
182
183     if (std::strlen(privilege) == 0) {
184         return ASKUSER_API_INVALID_PARAM;
185     }
186
187     return AskUser::Client::tryCatch([&]() {
188         if (p_client->impl->popupRequestInProgress(privilege)) {
189             return ASKUSER_API_ALREADY_IN_PROGRESS;
190         }
191
192         AskUser::Client::RequestId id = p_client->impl->popupRequest(privilege, response_callback, p_user_data);
193
194         if (p_request_id) {
195             *p_request_id = id;
196         }
197
198         return ASKUSER_API_SUCCESS;
199     });
200 }
201
202 API
203 int askuser_client_popup_multiple_request(askuser_client *p_client, const char **privileges,
204                                           size_t privileges_count,
205                                           askuser_popup_multiple_response_callback response_callback,
206                                           void *p_user_data, int *p_request_id)
207 {
208     if (!privileges_count || !p_client || !privileges || !response_callback) {
209         return ASKUSER_API_INVALID_PARAM;
210     }
211
212     return AskUser::Client::tryCatch([&]() {
213         std::vector<std::string> privilegeVector;
214         for (size_t it = 0 ; it < privileges_count; it++) {
215             if (!privileges[it]  || std::strlen(privileges[it]) == 0) {
216                 return ASKUSER_API_INVALID_PARAM;
217             }
218             if (p_client->impl->popupRequestInProgress(privileges[it])) {
219                 return ASKUSER_API_ALREADY_IN_PROGRESS;
220             }
221             privilegeVector.push_back(privileges[it]);
222         }
223
224         std::unordered_set<std::string> uniquePrivileges(privilegeVector.begin(), privilegeVector.end());
225         if (privileges_count != uniquePrivileges.size()) {
226             ALOGE("Privileges passed to multiple request are not unique.");
227             return ASKUSER_API_INVALID_PARAM;
228         }
229         AskUser::Client::RequestId id = p_client->impl->popupRequest(privilegeVector, response_callback, p_user_data);
230
231         if (p_request_id) {
232             *p_request_id = id;
233         }
234
235         return ASKUSER_API_SUCCESS;
236     });
237
238 }
239
240 API
241 int askuser_popup_send_ext_response(askuser_client *p_client, int popup_id,
242                             const char **privacies,
243                             const askuser_popup_result responses[],
244                             size_t privacies_count)
245 {
246     if (!p_client || ((!privacies || !responses) && privacies_count > 0) ||
247         (privacies_count == 0 && (privacies || responses))) {
248         return ASKUSER_API_INVALID_PARAM;
249     }
250
251     return AskUser::Client::tryCatch([&]() {
252         std::vector<std::string> vprivacies(privacies_count);
253         std::vector<int> vresponses(privacies_count);
254
255         for (size_t i = 0; i < privacies_count; ++i) {
256             switch(responses[i]) {
257             case ASKUSER_POPUP_RESULT_ALLOW_FOREVER :
258                 vresponses[i] = ASKUSER_ALLOW_FOREVER;
259                 break;
260             case ASKUSER_POPUP_RESULT_DENY_FOREVER :
261                 vresponses[i] = ASKUSER_DENY_FOREVER;
262                 break;
263             case ASKUSER_POPUP_RESULT_DENY_ONCE :
264                 vresponses[i] = ASKUSER_DENY_ONCE;
265                 break;
266             default:
267                 return ASKUSER_API_INVALID_PARAM;
268             }
269             vprivacies[i] = privacies[i];
270         }
271
272
273         int ret = p_client->impl->popupResponseExt(popup_id, vprivacies, vresponses);
274
275         if (ret == -EACCES)
276             return ASKUSER_API_PERMISSION_DENIED;
277         if (ret == -EINVAL)
278             return ASKUSER_API_INVALID_PARAM;
279         return ret != 0 ? ASKUSER_API_CONNECTION_ERROR : ASKUSER_API_SUCCESS;
280     });
281 }