modified uri for searching user on account server
[platform/upstream/iotivity.git] / resource / src / OCAccountManager.cpp
1 /* ****************************************************************
2  *
3  * Copyright 2016 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include "OCAccountManager.h"
22 #include "OCUtilities.h"
23
24 #include "ocstack.h"
25
26 #define VERIFY_NON_EMPTY(arg, log_message, ret) \
27     if ((arg).empty()) \
28     { \
29         oclog() << log_message << std::flush; \
30         return result_guard(ret); \
31     } \
32
33 namespace OC {
34
35 using OC::result_guard;
36 using OC::checked_guard;
37
38 OCAccountManager::OCAccountManager(std::weak_ptr<IClientWrapper> clientWrapper,
39                                    const std::string& host,
40                                    OCConnectivityType connectivityType)
41  : m_clientWrapper(clientWrapper), m_host(host), m_userUuid(""),
42    m_invitationObserveHandle(nullptr), m_groupObserveHandle(nullptr), m_connType(connectivityType)
43 {
44     if (m_host.empty() || m_clientWrapper.expired())
45     {
46         throw OCException(OC::Exception::INVALID_PARAM);
47     }
48
49     const char* di = OCGetServerInstanceIDString();
50     if (!di)
51     {
52         oclog() << "The mode should be Server or Both to generate UUID" << std::flush;
53         throw OCException(OC::Exception::INVALID_PARAM);
54     }
55
56     m_deviceID.append(di);
57     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, m_defaultQos);
58 }
59
60 OCAccountManager::~OCAccountManager()
61 {
62 }
63
64 std::string OCAccountManager::host() const
65 {
66     return m_host;
67 }
68
69 OCConnectivityType OCAccountManager::connectivityType() const
70 {
71     return m_connType;
72 }
73
74 OCStackResult OCAccountManager::signUp(const std::string& authProvider,
75                                        const std::string& authCode,
76                                        PostCallback cloudConnectHandler)
77 {
78     return result_guard(signUp(authProvider, authCode, QueryParamsMap(), cloudConnectHandler));
79 }
80
81 OCStackResult OCAccountManager::signUp(const std::string& authProvider,
82                                        const std::string& authCode,
83                                        const QueryParamsMap& options,
84                                        PostCallback cloudConnectHandler)
85 {
86     VERIFY_NON_EMPTY(authProvider, "authProvider cannot be empty.", OC_STACK_INVALID_PARAM);
87     VERIFY_NON_EMPTY(authCode, "authCode cannot be empty.", OC_STACK_INVALID_PARAM);
88
89     std::string uri = m_host + OC_RSRVD_ACCOUNT_URI;
90
91     OCRepresentation rep;
92     rep.setValue<std::string>(OC_RSRVD_DEVICE_ID, m_deviceID);
93     rep.setValue<std::string>(OC_RSRVD_AUTHPROVIDER, authProvider);
94     rep.setValue<std::string>(OC_RSRVD_AUTHCODE, authCode);
95
96     if (!options.empty())
97     {
98         for (auto iter : options)
99         {
100             rep.setValue(iter.first, iter.second);
101         }
102     }
103
104     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
105                          OCDevAddr(), uri, rep, QueryParamsMap(), HeaderOptions(),
106                          m_connType, cloudConnectHandler, m_defaultQos);
107 }
108
109 OCStackResult OCAccountManager::signIn(const std::string& userUuid,
110                                        const std::string& accessToken,
111                                        PostCallback cloudConnectHandler)
112 {
113     VERIFY_NON_EMPTY(userUuid, "userUuid cannot be empty.", OC_STACK_INVALID_PARAM);
114     VERIFY_NON_EMPTY(accessToken, "accessToken cannot be empty.", OC_STACK_INVALID_PARAM);
115
116     OCStackResult result = result_guard(signInOut(userUuid, accessToken, true,
117                                                   cloudConnectHandler));
118     if (OC_STACK_OK == result)
119     {
120         m_userUuid = userUuid;
121     }
122
123     return result;
124 }
125
126 OCStackResult OCAccountManager::signOut(const std::string& accessToken,
127                                         PostCallback cloudConnectHandler)
128 {
129     VERIFY_NON_EMPTY(m_userUuid, "Need to sign-in first.", OC_STACK_ERROR);
130     VERIFY_NON_EMPTY(accessToken, "accessToken cannot be empty.", OC_STACK_INVALID_PARAM);
131
132     OCStackResult result = result_guard(signInOut(m_userUuid, accessToken, false,
133                                                   cloudConnectHandler));
134     if (OC_STACK_OK == result)
135     {
136         m_userUuid = "";
137     }
138
139     return result;
140 }
141
142 OCStackResult OCAccountManager::signInOut(const std::string& userUuid,
143                                           const std::string& accessToken,
144                                           bool isSignIn,
145                                           PostCallback cloudConnectHandler)
146 {
147     std::string uri = m_host + OC_RSRVD_ACCOUNT_SESSION_URI;
148
149     OCRepresentation rep;
150
151     if (isSignIn)
152     {
153         rep.setValue<std::string>(OC_RSRVD_USER_UUID, userUuid);
154     }
155     rep.setValue<std::string>(OC_RSRVD_DEVICE_ID, m_deviceID);
156     rep.setValue<std::string>(OC_RSRVD_ACCESS_TOKEN, accessToken);
157     rep.setValue<bool>(OC_RSRVD_LOGIN, isSignIn);
158
159     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
160                          OCDevAddr(), uri, rep, QueryParamsMap(), HeaderOptions(),
161                          m_connType, cloudConnectHandler, m_defaultQos);
162 }
163
164 OCStackResult OCAccountManager::refreshAccessToken(const std::string& userUuid,
165                                                    const std::string& refreshToken,
166                                                    PostCallback cloudConnectHandler)
167 {
168     VERIFY_NON_EMPTY(userUuid, "userUuid cannot be empty.", OC_STACK_INVALID_PARAM);
169     VERIFY_NON_EMPTY(refreshToken, "refreshToken cannot be empty.", OC_STACK_INVALID_PARAM);
170
171     std::string uri = m_host + OC_RSRVD_ACCOUNT_TOKEN_REFRESH_URI;
172
173     OCRepresentation rep;
174     rep.setValue<std::string>(OC_RSRVD_USER_UUID, userUuid);
175     rep.setValue<std::string>(OC_RSRVD_DEVICE_ID, m_deviceID);
176     rep.setValue<std::string>(OC_RSRVD_GRANT_TYPE, std::string(OC_RSRVD_GRANT_TYPE_REFRESH_TOKEN));
177     rep.setValue<std::string>(OC_RSRVD_REFRESH_TOKEN, refreshToken);
178
179     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
180                          OCDevAddr(), uri, rep, QueryParamsMap(), HeaderOptions(),
181                          m_connType, cloudConnectHandler, m_defaultQos);
182 }
183
184 OCStackResult OCAccountManager::searchUser(const std::string& userUuid,
185                                            GetCallback cloudConnectHandler)
186 {
187     VERIFY_NON_EMPTY(userUuid, "userUuid cannot be empty.", OC_STACK_INVALID_PARAM);
188
189     return result_guard(searchUser(userUuid, QueryParamsMap(), cloudConnectHandler));
190 }
191
192 OCStackResult OCAccountManager::searchUser(const QueryParamsMap& queryParams,
193                                            GetCallback cloudConnectHandler)
194 {
195     VERIFY_NON_EMPTY(queryParams, "queryParams cannot be empty.", OC_STACK_INVALID_PARAM);
196
197     return result_guard(searchUser("", queryParams, cloudConnectHandler));
198 }
199
200 OCStackResult OCAccountManager::searchUser(const std::string& userUuid,
201                                            const QueryParamsMap& queryParams,
202                                            GetCallback cloudConnectHandler)
203 {
204     std::string uri = m_host + OC_RSRVD_ACCOUNT_USER_URI;
205
206     QueryParamsMap fullQuery = {};
207
208     if (!userUuid.empty())
209     {
210         fullQuery.insert(std::make_pair(OC_RSRVD_USER_UUID, userUuid));
211     }
212
213     if (!queryParams.empty())
214     {
215         std::string searchQuery;
216         for (auto iter : queryParams)
217         {
218             searchQuery.append(iter.first + ":" + iter.second + ",");
219         }
220         searchQuery.resize(searchQuery.size() - 1);
221         fullQuery.insert(std::make_pair(OC_RSRVD_SEARCH, searchQuery));
222     }
223
224     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetResourceRepresentation,
225                          OCDevAddr(), uri, fullQuery, HeaderOptions(),
226                          m_connType, cloudConnectHandler, m_defaultQos);
227 }
228
229 OCStackResult OCAccountManager::deleteDevice(const std::string& accessToken,
230                                              const std::string& deviceId,
231                                              DeleteCallback cloudConnectHandler)
232 {
233     VERIFY_NON_EMPTY(accessToken, "accessToken cannot be empty.", OC_STACK_INVALID_PARAM);
234     VERIFY_NON_EMPTY(deviceId, "deviceId cannot be empty.", OC_STACK_INVALID_PARAM);
235
236     std::string uri = m_host + OC_RSRVD_ACCOUNT_URI
237                       + "?" + OC_RSRVD_ACCESS_TOKEN + "=" + accessToken
238                       + ";" + OC_RSRVD_DEVICE_ID + "=" + deviceId;
239
240     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::DeleteResource,
241                          OCDevAddr(), uri, HeaderOptions(),
242                          m_connType, cloudConnectHandler, m_defaultQos);
243 }
244
245 OCStackResult OCAccountManager::createGroup(PostCallback cloudConnectHandler)
246 {
247     return result_guard(createGroup(QueryParamsMap(), cloudConnectHandler));
248 }
249
250 OCStackResult OCAccountManager::createGroup(const QueryParamsMap& queryParams,
251                                             PostCallback cloudConnectHandler)
252 {
253     VERIFY_NON_EMPTY(m_userUuid, "Need to sign-in first.", OC_STACK_ERROR);
254
255     std::string uri = m_host + OC_RSRVD_ACL_GROUP_URI;
256
257     std::vector<std::string> members{m_userUuid};
258
259     OCRepresentation rep;
260     rep.setValue<std::string>(OC_RSRVD_OWNER, m_userUuid);
261     rep.setValue<std::vector<std::string>>(OC_RSRVD_MEMBERS, members);
262
263     if (!queryParams.empty())
264     {
265         for (auto iter : queryParams)
266         {
267             rep.setValue(iter.first, iter.second);
268         }
269     }
270
271     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
272                          OCDevAddr(), uri, rep, QueryParamsMap(), HeaderOptions(),
273                          m_connType, cloudConnectHandler, m_defaultQos);
274 }
275
276 OCStackResult OCAccountManager::deleteGroup(const std::string& groupId,
277                                             DeleteCallback cloudConnectHandler)
278 {
279     VERIFY_NON_EMPTY(m_userUuid, "Need to sign-in first.", OC_STACK_ERROR);
280     VERIFY_NON_EMPTY(groupId, "groupId cannot be empty.", OC_STACK_INVALID_PARAM);
281
282     std::string uri = m_host + OC_RSRVD_ACL_GROUP_URI + "/" + groupId
283                       + "?" + OC_RSRVD_OWNER + "=" + m_userUuid;
284
285     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::DeleteResource,
286                          OCDevAddr(), uri, HeaderOptions(),
287                          m_connType, cloudConnectHandler, m_defaultQos);
288 }
289
290 OCStackResult OCAccountManager::getGroupInfoAll(GetCallback cloudConnectHandler)
291 {
292     VERIFY_NON_EMPTY(m_userUuid, "Need to sign-in first.", OC_STACK_ERROR);
293
294     std::string uri = m_host + OC_RSRVD_ACL_GROUP_URI;
295
296     QueryParamsMap query = {};
297     query.insert(std::make_pair(OC_RSRVD_MEMBERS, m_userUuid));
298
299     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetResourceRepresentation,
300                          OCDevAddr(), uri, query, HeaderOptions(), m_connType,
301                          cloudConnectHandler, m_defaultQos);
302 }
303
304 OCStackResult OCAccountManager::getGroupInfo(const std::string& groupId,
305                                              GetCallback cloudConnectHandler)
306 {
307     VERIFY_NON_EMPTY(m_userUuid, "Need to sign-in first.", OC_STACK_ERROR);
308     VERIFY_NON_EMPTY(groupId, "groupId cannot be empty.", OC_STACK_INVALID_PARAM);
309
310     std::string uri = m_host + OC_RSRVD_ACL_GROUP_URI + "/" + groupId;
311
312     QueryParamsMap query = {};
313     query.insert(std::make_pair(OC_RSRVD_MEMBERS, m_userUuid));
314
315     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetResourceRepresentation,
316                          OCDevAddr(), uri, query, HeaderOptions(),
317                          m_connType, cloudConnectHandler, m_defaultQos);
318 }
319
320 OCStackResult OCAccountManager::addPropertyValueToGroup(const std::string& groupId,
321                                                         const OCRepresentation propertyValue,
322                                                         PostCallback cloudConnectHandler)
323 {
324     VERIFY_NON_EMPTY(groupId, "groupId cannot be empty.", OC_STACK_INVALID_PARAM);
325
326     std::string uri = m_host + OC_RSRVD_ACL_GROUP_URI + "/" + groupId;
327
328     QueryParamsMap query = {};
329     query.insert(std::make_pair(OC_RSRVD_OPERATION, OC_RSRVD_ADD));
330
331     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
332                          OCDevAddr(), uri, propertyValue, query, HeaderOptions(),
333                          m_connType, cloudConnectHandler, m_defaultQos);
334 }
335
336 OCStackResult OCAccountManager::deletePropertyValueFromGroup(const std::string& groupId,
337                                                              const OCRepresentation propertyValue,
338                                                              PostCallback cloudConnectHandler)
339 {
340     VERIFY_NON_EMPTY(groupId, "groupId cannot be empty.", OC_STACK_INVALID_PARAM);
341
342     std::string uri = m_host + OC_RSRVD_ACL_GROUP_URI + "/" + groupId;
343
344     QueryParamsMap query = {};
345     query.insert(std::make_pair(OC_RSRVD_OPERATION, OC_RSRVD_DELETE));
346
347     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
348                          OCDevAddr(), uri, propertyValue, query, HeaderOptions(),
349                          m_connType, cloudConnectHandler, m_defaultQos);
350 }
351
352 OCStackResult OCAccountManager::updatePropertyValueOnGroup(const std::string& groupId,
353                                                            const OCRepresentation propertyValue,
354                                                            PostCallback cloudConnectHandler)
355 {
356     VERIFY_NON_EMPTY(groupId, "groupId cannot be empty.", OC_STACK_INVALID_PARAM);
357
358     std::string uri = m_host + OC_RSRVD_ACL_GROUP_URI + "/" + groupId;
359
360     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
361                          OCDevAddr(), uri, propertyValue, QueryParamsMap(), HeaderOptions(),
362                          m_connType, cloudConnectHandler, m_defaultQos);
363 }
364
365 OCStackResult OCAccountManager::observeGroup(ObserveCallback cloudConnectHandler)
366 {
367     VERIFY_NON_EMPTY(m_userUuid, "Need to sign-in first.", OC_STACK_ERROR);
368
369     std::string uri = m_host + OC_RSRVD_ACL_GROUP_URI;
370
371     QueryParamsMap query = {};
372     query.insert(std::make_pair(OC_RSRVD_MEMBERS, m_userUuid));
373
374     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::ObserveResource,
375                          ObserveType::Observe, &m_groupObserveHandle, OCDevAddr(), uri,
376                          query, HeaderOptions(), cloudConnectHandler, m_defaultQos);
377 }
378
379 OCStackResult OCAccountManager::cancelObserveGroup()
380 {
381     VERIFY_NON_EMPTY(m_userUuid, "Need to sign-in first.", OC_STACK_ERROR);
382
383     if (nullptr == m_groupObserveHandle)
384     {
385         oclog() << "observeGroup() has not been done." << std::flush;
386         return result_guard(OC_STACK_INVALID_PARAM);
387     }
388
389     std::string uri = m_host + OC_RSRVD_ACL_GROUP_URI
390                       + "?" + OC_RSRVD_MEMBERS + "=" + m_userUuid;
391
392     OCStackResult result = checked_guard(m_clientWrapper.lock(),
393                                          &IClientWrapper::CancelObserveResource,
394                                          m_groupObserveHandle, (const char*)"", uri,
395                                          HeaderOptions(), m_defaultQos);
396     if (OC_STACK_OK == result)
397     {
398         m_groupObserveHandle = nullptr;
399     }
400
401     return result;
402 }
403
404 OCStackResult OCAccountManager::observeInvitation(ObserveCallback cloudConnectHandler)
405 {
406     std::string uri = m_host + OC_RSRVD_ACL_INVITE_URI;
407
408     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::ObserveResource,
409                          ObserveType::Observe, &m_invitationObserveHandle, OCDevAddr(), uri,
410                          QueryParamsMap(), HeaderOptions(), cloudConnectHandler, m_defaultQos);
411 }
412
413 OCStackResult OCAccountManager::cancelObserveInvitation()
414 {
415     if (nullptr == m_invitationObserveHandle)
416     {
417         oclog() << "observeInvitation() has not been done." << std::flush;
418         return result_guard(OC_STACK_INVALID_PARAM);
419     }
420
421     std::string uri = m_host + OC_RSRVD_ACL_INVITE_URI;
422
423     OCStackResult result = checked_guard(m_clientWrapper.lock(),
424                                          &IClientWrapper::CancelObserveResource,
425                                          m_invitationObserveHandle,
426                                          (const char*)"", uri, HeaderOptions(), m_defaultQos);
427     if (OC_STACK_OK == result)
428     {
429         m_invitationObserveHandle = nullptr;
430     }
431
432     return result;
433 }
434
435 OCStackResult OCAccountManager::sendInvitation(const std::string& groupId,
436                                                const std::string& userUuid,
437                                                PostCallback cloudConnectHandler)
438 {
439     VERIFY_NON_EMPTY(m_userUuid, "Need to sign-in first.", OC_STACK_ERROR);
440     VERIFY_NON_EMPTY(groupId, "groupId cannot be empty.", OC_STACK_INVALID_PARAM);
441     VERIFY_NON_EMPTY(userUuid, "userUuid cannot be empty.", OC_STACK_INVALID_PARAM);
442
443     std::string uri = m_host + OC_RSRVD_ACL_INVITE_URI;
444
445     OCRepresentation invitation;
446     invitation.setValue<std::string>(OC_RSRVD_GROUP_ID, groupId);
447     invitation.setValue<std::string>(OC_RSRVD_MEMBER_ID, userUuid);
448
449     std::vector<OCRepresentation> invite{invitation};
450
451     OCRepresentation rep;
452     rep.setValue<std::string>(OC_RSRVD_USER_UUID, m_userUuid);
453     rep.setValue<std::vector<OCRepresentation>>(OC_RSRVD_INVITE, invite);
454
455     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
456                          OCDevAddr(), uri, rep, QueryParamsMap(), HeaderOptions(),
457                          m_connType, cloudConnectHandler, m_defaultQos);
458 }
459
460 OCStackResult OCAccountManager::cancelInvitation(const std::string& groupId,
461                                                  const std::string& userUuid,
462                                                  DeleteCallback cloudConnectHandler)
463 {
464     VERIFY_NON_EMPTY(groupId, "groupId cannot be empty.", OC_STACK_INVALID_PARAM);
465     VERIFY_NON_EMPTY(userUuid, "userUuid cannot be empty.", OC_STACK_INVALID_PARAM);
466
467     std::string uri = m_host + OC_RSRVD_ACL_INVITE_URI + "?" + OC_RSRVD_GROUP_ID + "=" + groupId
468                       + ";" + OC_RSRVD_MEMBER_ID + "=" + userUuid;
469
470     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::DeleteResource,
471                          OCDevAddr(), uri, HeaderOptions(),
472                          m_connType, cloudConnectHandler, m_defaultQos);
473 }
474
475 OCStackResult OCAccountManager::replyToInvitation(const std::string& groupId,
476                                                   const bool accept,
477                                                   DeleteCallback cloudConnectHandler)
478 {
479     VERIFY_NON_EMPTY(groupId, "groupId cannot be empty.", OC_STACK_INVALID_PARAM);
480
481     std::string isAccept = accept ? "1" : "0";
482
483     std::string uri = m_host + OC_RSRVD_ACL_INVITE_URI + "?" + OC_RSRVD_GROUP_ID + "=" + groupId
484                       + ";" + OC_RSRVD_ACCEPT + "=" + isAccept;
485
486     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::DeleteResource,
487                          OCDevAddr(), uri, HeaderOptions(),
488                          m_connType, cloudConnectHandler, m_defaultQos);
489 }
490
491 } // namespace OC