08e7d2670d55ce9fd546cbacbb81f02e8517d990
[platform/upstream/iotivity.git] / resource / csdk / security / unittest / aclresourcetest.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH 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 "gtest/gtest.h"
22 #include <pwd.h>
23 #include <grp.h>
24 #include <linux/limits.h>
25 #include <sys/stat.h>
26 #include "ocstack.h"
27 #include "ocpayload.h"
28 #include "oic_malloc.h"
29 #include "oic_string.h"
30 #include "cJSON.h"
31 #include "cainterface.h"
32 #include "secureresourcemanager.h"
33 #include "securevirtualresourcetypes.h"
34 #include "srmresourcestrings.h"
35 #include "aclresource.h"
36 #include "srmtestcommon.h"
37 #include "srmutility.h"
38 #include "logger.h"
39
40 using namespace std;
41
42 #define TAG  "SRM-ACL-UT"
43
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47
48 extern char * BinToAclJSON(const OicSecAcl_t * acl);
49 extern OicSecAcl_t * JSONToAclBin(const char * jsonStr);
50 extern void DeleteACLList(OicSecAcl_t* acl);
51 OCStackResult  GetDefaultACL(OicSecAcl_t** defaultAcl);
52 OCEntityHandlerResult ACLEntityHandler (OCEntityHandlerFlag flag,
53                                         OCEntityHandlerRequest * ehRequest);
54 #ifdef __cplusplus
55 }
56 #endif
57
58 const char* JSON_FILE_NAME = "oic_unittest.json";
59 const char* DEFAULT_ACL_JSON_FILE_NAME = "oic_unittest_default_acl.json";
60 const char* ACL1_JSON_FILE_NAME = "oic_unittest_acl1.json";
61
62 #define NUM_ACE_FOR_WILDCARD_IN_ACL1_JSON (2)
63
64 // JSON Marshalling Tests
65 TEST(ACLResourceTest, JSONMarshallingTests)
66 {
67     char *jsonStr1 = ReadFile(ACL1_JSON_FILE_NAME);
68     if (jsonStr1)
69     {
70         cJSON_Minify(jsonStr1);
71         /* Workaround : cJSON_Minify does not remove all the unwanted characters
72          from the end. Here is an attempt to remove those characters */
73         int len = strlen(jsonStr1);
74         while (len > 0)
75         {
76             if (jsonStr1[--len] == '}')
77             {
78                 break;
79             }
80         }
81         jsonStr1[len + 1] = 0;
82
83         OicSecAcl_t * acl = JSONToAclBin(jsonStr1);
84         EXPECT_TRUE(NULL != acl);
85
86         char * jsonStr2 = BinToAclJSON(acl);
87         EXPECT_TRUE(NULL != jsonStr2);
88
89         EXPECT_STREQ(jsonStr1, jsonStr2);
90
91         OICFree(jsonStr1);
92         OICFree(jsonStr2);
93         DeleteACLList(acl);
94     }
95 }
96
97 // Default ACL tests
98 TEST(ACLResourceTest, GetDefaultACLTests)
99 {
100     // Read default ACL from the file
101     char *jsonStr = ReadFile(DEFAULT_ACL_JSON_FILE_NAME);
102     if (jsonStr)
103     {
104         OicSecAcl_t * acl = JSONToAclBin(jsonStr);
105         EXPECT_TRUE(NULL != acl);
106
107         // Invoke API to generate default ACL
108         OicSecAcl_t * defaultAcl = NULL;
109         OCStackResult ret = GetDefaultACL(&defaultAcl);
110         EXPECT_TRUE(NULL == defaultAcl);
111
112         EXPECT_TRUE(OC_STACK_ERROR == ret);
113
114         // Verify if the SRM generated default ACL matches with unit test default
115         if (acl && defaultAcl)
116         {
117             EXPECT_TRUE(memcmp(&(acl->subject), &(defaultAcl->subject), sizeof(OicUuid_t)) == 0);
118             EXPECT_EQ(acl->resourcesLen, defaultAcl->resourcesLen);
119             for (size_t i = 0; i < acl->resourcesLen; i++)
120             {
121                 EXPECT_EQ(strlen(acl->resources[i]), strlen(defaultAcl->resources[i]));
122                 EXPECT_TRUE(
123                         memcmp(acl->resources[i], defaultAcl->resources[i],
124                                 strlen(acl->resources[i])) == 0);
125             }
126             EXPECT_EQ(acl->permission, defaultAcl->permission);
127         }
128
129         // Perform cleanup
130         DeleteACLList(acl);
131         DeleteACLList(defaultAcl);
132         OICFree(jsonStr);
133     }
134 }
135
136
137 // 'POST' ACL tests
138 TEST(ACLResourceTest, ACLPostTest)
139 {
140     OCEntityHandlerRequest ehReq =  OCEntityHandlerRequest();
141
142     // Read an ACL from the file
143     char *jsonStr = ReadFile(ACL1_JSON_FILE_NAME);
144     if (jsonStr)
145     {
146         static OCPersistentStorage ps = OCPersistentStorage();
147
148         SetPersistentHandler(&ps, true);
149
150         // Create Entity Handler POST request payload
151         ehReq.method = OC_REST_POST;
152         ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
153
154         OCEntityHandlerResult ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
155         EXPECT_TRUE(OC_EH_ERROR == ehRet);
156
157         // Convert JSON into OicSecAcl_t for verification
158         OicSecAcl_t * acl = JSONToAclBin(jsonStr);
159         EXPECT_TRUE(NULL != acl);
160
161         // Verify if SRM contains ACL for the subject
162         OicSecAcl_t* savePtr = NULL;
163         const OicSecAcl_t* subjectAcl = GetACLResourceData(&(acl->subject), &savePtr);
164         EXPECT_TRUE(NULL != subjectAcl);
165
166         // Perform cleanup
167         DeleteACLList(acl);
168         DeInitACLResource();
169         OCPayloadDestroy(ehReq.payload);
170         OICFree(jsonStr);
171     }
172 }
173
174
175 // GetACLResource tests
176 TEST(ACLResourceTest, GetACLResourceTests)
177 {
178     // gAcl is a pointer to the the global ACL used by SRM
179     extern OicSecAcl_t  *gAcl;
180
181     // Read an ACL from the file
182     char *jsonStr = ReadFile(ACL1_JSON_FILE_NAME);
183     if (jsonStr)
184     {
185         gAcl = JSONToAclBin(jsonStr);
186         EXPECT_TRUE(NULL != gAcl);
187
188         // Verify that ACL file contains 2 ACE entries for 'WILDCARD' subject
189         const OicSecAcl_t* acl = NULL;
190         OicSecAcl_t* savePtr = NULL;
191         OicUuid_t subject = WILDCARD_SUBJECT_ID;
192         int count = 0;
193
194         do
195         {
196             acl = GetACLResourceData(&subject, &savePtr);
197             count = (NULL != acl) ? count + 1 : count;
198         } while (acl != NULL);
199
200         EXPECT_EQ(count, NUM_ACE_FOR_WILDCARD_IN_ACL1_JSON);
201
202         /* Perform cleanup */
203         DeleteACLList(gAcl);
204         gAcl = NULL;
205         OICFree(jsonStr);
206     }
207 }
208
209 static OCStackResult  populateAcl(OicSecAcl_t *acl,  int numRsrc)
210 {
211     OCStackResult ret = OC_STACK_ERROR;
212     memcpy(acl->subject.id, "2222222222222222", sizeof(acl->subject.id));
213     acl->resourcesLen = numRsrc;
214     acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
215     VERIFY_NON_NULL(TAG, acl->resources, ERROR);
216     acl->resources[0] = (char*)OICMalloc(strlen("/a/led")+1);
217     VERIFY_NON_NULL(TAG, acl->resources[0], ERROR);
218     OICStrcpy(acl->resources[0], sizeof(acl->resources[0]), "/a/led");
219     if(numRsrc == 2)
220     {
221         acl->resources[1] = (char*)OICMalloc(strlen("/a/fan")+1);
222         VERIFY_NON_NULL(TAG, acl->resources[1], ERROR);
223         OICStrcpy(acl->resources[1], sizeof(acl->resources[1]), "/a/fan");
224     }
225     acl->permission = 6;
226     acl->ownersLen = 1;
227     acl->owners = (OicUuid_t*)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
228     VERIFY_NON_NULL(TAG, acl->owners, ERROR);
229     memcpy(acl->owners->id, "1111111111111111", sizeof(acl->owners->id));
230
231     ret = OC_STACK_OK;
232 exit:
233     return ret;
234
235 }
236
237 //'DELETE' ACL test
238 TEST(ACLResourceTest, ACLDeleteWithSingleResourceTest)
239 {
240     OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
241     static OCPersistentStorage ps = OCPersistentStorage();
242     char *jsonStr = NULL;
243     OicSecAcl_t acl = OicSecAcl_t();
244     OicSecAcl_t* savePtr = NULL;
245     const OicSecAcl_t* subjectAcl1 = NULL;
246     const OicSecAcl_t* subjectAcl2 = NULL;
247     OCEntityHandlerResult ehRet = OC_EH_ERROR;
248     char query[] = "sub=MjIyMjIyMjIyMjIyMjIyMg==;rsrc=/a/led";
249
250     SetPersistentHandler(&ps, true);
251
252     //Populate ACL
253     VERIFY_SUCCESS(TAG, (OC_STACK_OK == populateAcl(&acl, 1)), ERROR);
254
255     //GET json POST payload
256     jsonStr = BinToAclJSON(&acl);
257     VERIFY_NON_NULL(TAG, jsonStr, ERROR);
258
259     // Create Entity Handler POST request payload
260     ehReq.method = OC_REST_POST;
261     ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
262     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
263     EXPECT_TRUE(OC_EH_ERROR == ehRet);
264
265     // Verify if SRM contains ACE for the subject
266     savePtr = NULL;
267     subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
268     EXPECT_TRUE(NULL != subjectAcl1);
269
270     // Create Entity Handler DELETE request
271     ehReq.method = OC_REST_DELETE;
272     ehReq.query = (char*)OICMalloc(strlen(query)+1);
273     VERIFY_NON_NULL(TAG, ehReq.query, ERROR);
274     OICStrcpy(ehReq.query, strlen(query)+1, query);
275     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
276     EXPECT_TRUE(OC_EH_ERROR == ehRet);
277
278     // Verify if SRM has deleted ACE for the subject
279     savePtr = NULL;
280     subjectAcl2 = GetACLResourceData(&acl.subject, &savePtr);
281     EXPECT_TRUE(NULL == subjectAcl2);
282
283 exit:
284     // Perform cleanup
285     if(NULL != subjectAcl1)
286     {
287         DeInitACLResource();
288     }
289     OCPayloadDestroy(ehReq.payload);
290     OICFree(ehReq.query);
291     OICFree(jsonStr);
292
293 }
294
295 TEST(ACLResourceTest, ACLDeleteWithMultiResourceTest)
296 {
297     OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
298     static OCPersistentStorage ps = OCPersistentStorage();
299     OicSecAcl_t acl = OicSecAcl_t();
300     char *jsonStr = NULL;
301     OicSecAcl_t* savePtr = NULL;
302     const OicSecAcl_t* subjectAcl1 = NULL;
303     const OicSecAcl_t* subjectAcl2 = NULL;
304     OCEntityHandlerResult ehRet = OC_EH_ERROR;
305     char query[] = "sub=MjIyMjIyMjIyMjIyMjIyMg==;rsrc=/a/led";
306
307     SetPersistentHandler(&ps, true);
308
309     //Populate ACL
310     VERIFY_SUCCESS(TAG, (OC_STACK_OK == populateAcl(&acl, 2)), ERROR);
311
312     //GET json POST payload
313     jsonStr = BinToAclJSON(&acl);
314     VERIFY_NON_NULL(TAG, jsonStr, ERROR);
315
316     // Create Entity Handler POST request payload
317     ehReq.method = OC_REST_POST;
318     ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
319     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
320     EXPECT_TRUE(OC_EH_ERROR == ehRet);
321
322     // Verify if SRM contains ACE for the subject with two resources
323     savePtr = NULL;
324     subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
325     EXPECT_TRUE(NULL != subjectAcl1);
326     EXPECT_TRUE(subjectAcl1->resourcesLen == 2);
327
328     // Create Entity Handler DELETE request
329     ehReq.method = OC_REST_DELETE;
330     ehReq.query = (char*)OICMalloc(strlen(query)+1);
331     VERIFY_NON_NULL(TAG, ehReq.query, ERROR);
332     OICStrcpy(ehReq.query, strlen(query)+1, query);
333
334     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
335     EXPECT_TRUE(OC_EH_ERROR == ehRet);
336
337     // Verify if SRM contains ACL for the subject but only with one resource
338     savePtr = NULL;
339     subjectAcl2 = GetACLResourceData(&acl.subject, &savePtr);
340     EXPECT_TRUE(NULL != subjectAcl2);
341     EXPECT_TRUE(subjectAcl2->resourcesLen == 1);
342
343 exit:
344     // Perform cleanup
345     if(NULL != subjectAcl1)
346     {
347         DeInitACLResource();
348     }
349     OCPayloadDestroy(ehReq.payload);
350     OICFree(ehReq.query);
351     OICFree(jsonStr);
352 }
353
354 //'GET' with query ACL test
355
356 TEST(ACLResourceTest, ACLGetWithQueryTest)
357 {
358     OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
359     static OCPersistentStorage ps = OCPersistentStorage();
360     OicSecAcl_t acl = OicSecAcl_t();
361     char *jsonStr = NULL;
362     OCEntityHandlerResult ehRet = OC_EH_ERROR;
363     char query[] = "sub=MjIyMjIyMjIyMjIyMjIyMg==;rsrc=/a/led";
364
365     SetPersistentHandler(&ps, true);
366
367     //Populate ACL
368     VERIFY_SUCCESS(TAG, (OC_STACK_OK == populateAcl(&acl, 1)), ERROR);
369
370     //GET json POST payload
371     jsonStr = BinToAclJSON(&acl);
372     VERIFY_NON_NULL(TAG, jsonStr, ERROR);
373
374     //Create Entity Handler POST request payload
375     ehReq.method = OC_REST_POST;
376     ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
377     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
378     EXPECT_TRUE(OC_EH_ERROR == ehRet);
379
380     //Create Entity Handler GET request wit query
381     ehReq.method =  OC_REST_GET;
382     ehReq.query = (char*)OICMalloc(strlen(query)+1);
383     VERIFY_NON_NULL(TAG, ehReq.query, ERROR);
384     OICStrcpy(ehReq.query, strlen(query)+1, query);
385
386     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
387     EXPECT_TRUE(OC_EH_OK == ehRet);
388
389 exit:
390     // Perform cleanup
391     OCPayloadDestroy(ehReq.payload);
392     OICFree(ehReq.query);
393     OICFree(jsonStr);
394 }