CBOR rebase onto master for merge/review
[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 "oic_malloc.h"
28 #include "cJSON.h"
29 #include "cainterface.h"
30 #include "secureresourcemanager.h"
31 #include "securevirtualresourcetypes.h"
32 #include "srmresourcestrings.h"
33 #include "aclresource.h"
34
35 using namespace std;
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 extern char * BinToAclJSON(const OicSecAcl_t * acl);
41 extern OicSecAcl_t * JSONToAclBin(const char * jsonStr);
42 char* ReadFile(const char* filename);
43 extern void DeleteACLList(OicSecAcl_t* acl);
44 OCStackResult  GetDefaultACL(OicSecAcl_t** defaultAcl);
45 OCEntityHandlerResult ACLEntityHandler (OCEntityHandlerFlag flag,
46                                         OCEntityHandlerRequest * ehRequest);
47 #ifdef __cplusplus
48 }
49 #endif
50
51 const char* JSON_FILE_NAME = "oic_unittest.json";
52 const char* DEFAULT_ACL_JSON_FILE_NAME = "oic_unittest_default_acl.json";
53 const char* ACL1_JSON_FILE_NAME = "oic_unittest_acl1.json";
54
55 #define NUM_ACE_FOR_WILDCARD_IN_ACL1_JSON (2)
56
57 char* ReadFile(const char* filename)
58 {
59
60     FILE *fp = NULL;
61     char *data = NULL;
62     struct stat st;
63     // TODO: Find the location of the executable and concatenate the SVR file name
64     // before opening it.
65     fp = fopen(filename, "r");
66     if (fp)
67     {
68         if (stat(filename, &st) == 0)
69         {
70             data = (char*)OICMalloc(st.st_size);
71             if (data)
72             {
73                 if (fread(data, 1, st.st_size, fp) != (size_t)st.st_size)
74                 {
75                     printf("Error in reading file %s", filename);
76                 }
77             }
78         }
79         fclose(fp);
80     }
81     else
82     {
83         printf("Unable to open %s file", filename);
84     }
85
86     return data;
87 }
88
89 void SetPersistentHandler(OCPersistentStorage *ps, bool set)
90 {
91     if (set)
92     {
93         ps->open = fopen;
94         ps->read = fread;
95         ps->write = fwrite;
96         ps->close = fclose;
97         ps->unlink = unlink;
98     }
99     else
100     {
101         memset(ps, 0, sizeof(OCPersistentStorage));
102     }
103     EXPECT_EQ(OC_STACK_OK,
104             OCRegisterPersistentStorageHandler(ps));
105 }
106
107 // JSON Marshalling Tests
108 TEST(ACLResourceTest, JSONMarshallingTests)
109 {
110     char *jsonStr1 = ReadFile(ACL1_JSON_FILE_NAME);
111     if (jsonStr1)
112     {
113         cJSON_Minify(jsonStr1);
114         /* Workaround : cJSON_Minify does not remove all the unwanted characters
115          from the end. Here is an attempt to remove those characters */
116         int len = strlen(jsonStr1);
117         while (len > 0)
118         {
119             if (jsonStr1[--len] == '}')
120             {
121                 break;
122             }
123         }
124         jsonStr1[len + 1] = 0;
125
126         OicSecAcl_t * acl = JSONToAclBin(jsonStr1);
127         EXPECT_TRUE(NULL != acl);
128
129         char * jsonStr2 = BinToAclJSON(acl);
130         EXPECT_TRUE(NULL != jsonStr2);
131
132         EXPECT_STREQ(jsonStr1, jsonStr2);
133
134         OICFree(jsonStr1);
135         OICFree(jsonStr2);
136         DeleteACLList(acl);
137     }
138 }
139
140 // Default ACL tests
141 TEST(ACLResourceTest, GetDefaultACLTests)
142 {
143     // Read default ACL from the file
144     char *jsonStr = ReadFile(DEFAULT_ACL_JSON_FILE_NAME);
145     if (jsonStr)
146     {
147         OicSecAcl_t * acl = JSONToAclBin(jsonStr);
148         EXPECT_TRUE(NULL != acl);
149
150         // Invoke API to generate default ACL
151         OicSecAcl_t * defaultAcl = NULL;
152         OCStackResult ret = GetDefaultACL(&defaultAcl);
153         EXPECT_TRUE(NULL == defaultAcl);
154
155         EXPECT_TRUE(OC_STACK_ERROR == ret);
156
157         // Verify if the SRM generated default ACL matches with unit test default
158         if (acl && defaultAcl)
159         {
160             EXPECT_TRUE(memcmp(&(acl->subject), &(defaultAcl->subject), sizeof(OicUuid_t)) == 0);
161             EXPECT_EQ(acl->resourcesLen, defaultAcl->resourcesLen);
162             for (size_t i = 0; i < acl->resourcesLen; i++)
163             {
164                 EXPECT_EQ(strlen(acl->resources[i]), strlen(defaultAcl->resources[i]));
165                 EXPECT_TRUE(
166                         memcmp(acl->resources[i], defaultAcl->resources[i],
167                                 strlen(acl->resources[i])) == 0);
168             }
169             EXPECT_EQ(acl->permission, defaultAcl->permission);
170         }
171
172         // Perform cleanup
173         DeleteACLList(acl);
174         DeleteACLList(defaultAcl);
175         OICFree(jsonStr);
176     }
177 }
178
179
180 // 'POST' ACL tests
181 TEST(ACLResourceTest, ACLPostTest)
182 {
183     OCEntityHandlerRequest ehReq = {};
184
185     // Read an ACL from the file
186     char *jsonStr = ReadFile(ACL1_JSON_FILE_NAME);
187     if (jsonStr)
188     {
189         static OCPersistentStorage ps =
190         { };
191         SetPersistentHandler(&ps, true);
192
193         // Create Entity Handler POST request payload
194         ehReq.method = OC_REST_POST;
195         ehReq.payload = (OCPayload*)calloc(1, sizeof(OCSecurityPayload));
196         ehReq.payload->type = PAYLOAD_TYPE_SECURITY;
197         ((OCSecurityPayload*)ehReq.payload)->securityData = jsonStr;
198
199         OCEntityHandlerResult ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
200         EXPECT_TRUE(OC_EH_ERROR == ehRet);
201
202         // Convert JSON into OicSecAcl_t for verification
203         OicSecAcl_t * acl = JSONToAclBin(jsonStr);
204         EXPECT_TRUE(NULL != acl);
205
206         // Verify if SRM contains ACL for the subject
207         OicSecAcl_t* savePtr = NULL;
208         const OicSecAcl_t* subjectAcl = GetACLResourceData(&(acl->subject), &savePtr);
209         EXPECT_TRUE(NULL != subjectAcl);
210
211         // Perform cleanup
212         DeleteACLList(acl);
213         DeInitACLResource();
214         OICFree(jsonStr);
215     }
216 }
217
218
219 // GetACLResource tests
220 TEST(ACLResourceTest, GetACLResourceTests)
221 {
222     // gAcl is a pointer to the the global ACL used by SRM
223     extern OicSecAcl_t  *gAcl;
224
225     // Read an ACL from the file
226     char *jsonStr = ReadFile(ACL1_JSON_FILE_NAME);
227     if (jsonStr)
228     {
229         gAcl = JSONToAclBin(jsonStr);
230         EXPECT_TRUE(NULL != gAcl);
231
232         // Verify that ACL file contains 2 ACE entries for 'WILDCARD' subject
233         const OicSecAcl_t* acl = NULL;
234         OicSecAcl_t* savePtr = NULL;
235         OicUuid_t subject = WILDCARD_SUBJECT_ID;
236         int count = 0;
237
238         do
239         {
240             acl = GetACLResourceData(&subject, &savePtr);
241             count = (NULL != acl) ? count + 1 : count;
242         } while (acl != NULL);
243
244         EXPECT_EQ(count, NUM_ACE_FOR_WILDCARD_IN_ACL1_JSON);
245
246         /* Perform cleanup */
247         DeleteACLList(gAcl);
248         gAcl = NULL;
249         OICFree(jsonStr);
250     }
251 }
252