Cloud ACE update
[platform/upstream/iotivity.git] / cloud / account / src / main / java / org / iotivity / cloud / accountserver / resources / acl / id / Acl.java
1 /*
2  * //******************************************************************
3  * //
4  * // Copyright 2016 Samsung Electronics All Rights Reserved.
5  * //
6  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  * //
8  * // Licensed under the Apache License, Version 2.0 (the "License");
9  * // you may not use this file except in compliance with the License.
10  * // You may obtain a copy of the License at
11  * //
12  * //      http://www.apache.org/licenses/LICENSE-2.0
13  * //
14  * // Unless required by applicable law or agreed to in writing, software
15  * // distributed under the License is distributed on an "AS IS" BASIS,
16  * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * // See the License for the specific language governing permissions and
18  * // limitations under the License.
19  * //
20  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22 package org.iotivity.cloud.accountserver.resources.acl.id;
23
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.UUID;
32 import java.util.ListIterator;
33
34 import org.iotivity.cloud.accountserver.Constants;
35 import org.iotivity.cloud.accountserver.db.AccountDBManager;
36 import org.iotivity.cloud.accountserver.db.AclTable;
37 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
38 import org.iotivity.cloud.base.device.Device;
39 import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
40 import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException;
41 import org.iotivity.cloud.base.exception.ServerException.UnAuthorizedException;
42 import org.iotivity.cloud.base.protocols.IRequest;
43 import org.iotivity.cloud.base.protocols.MessageBuilder;
44 import org.iotivity.cloud.base.protocols.enums.ContentFormat;
45 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
46 import org.iotivity.cloud.util.Cbor;
47 import org.iotivity.cloud.util.Log;
48
49 public class Acl {
50
51     private Cbor<HashMap<String, Object>>  mCbor      = new Cbor<>();
52     private String                         mAclid     = null;
53     private String                         mOid       = null;
54     private String                         mDi        = null;
55     private TypeCastingManager<AclTable> mTypeAcl = new TypeCastingManager<>();
56
57     public Acl(String aclid) {
58         mAclid = aclid;
59     }
60
61     public Acl(String aclid, String oid, String di) {
62         mAclid = aclid;
63         mOid = oid;
64         mDi = di;
65     }
66
67     private class AclSubscriber {
68         AclSubscriber(Device subscriber, IRequest request) {
69             mSubscriber = subscriber;
70             mRequest = request;
71         }
72
73         public Device mSubscriber;
74         public IRequest mRequest;
75     }
76
77     private HashMap<String, AclSubscriber> mSubscribers  = new HashMap<>();
78
79     public static String valueOf(Object object) {
80         return (object == null) ? "" : object.toString();
81     }
82
83     @SuppressWarnings("unchecked")
84         public static AclTable convertMaptoAclObject(HashMap<String, Object> aclMap) {
85             AclTable aclTable = new AclTable();
86             try {
87                 aclTable.setAclid(valueOf(aclMap.get(Constants.KEYFIELD_ACLID)));
88                 aclTable.setDi(valueOf(aclMap.get(Constants.KEYFIELD_DI)));
89                 aclTable.setOid(valueOf(aclMap.get(Constants.REQ_OWNER_ID)));
90                 aclTable.setRowneruuid(valueOf(aclMap.get(Constants.REQ_ROWNER_ID)));
91
92                 List<Ace> aceList = new ArrayList<Ace>();
93
94                 List<HashMap<String, Object>> aclist = (List<HashMap<String, Object>>) aclMap
95                     .get(Constants.REQ_ACL_LIST);
96
97                 if (aclist == null) {
98                     return aclTable;
99                 }
100
101                 for (HashMap<String, Object> eachAce : aclist) {
102
103                     Ace ace = new Ace();
104
105                     ace.setAceid(valueOf(eachAce.get(Constants.REQ_ACE_ID)));
106                     ace.setSubjectuuid(valueOf(eachAce
107                                 .get(Constants.KEYFIELD_ACE_SUBJECT_ID)));
108                     ace.setStype(Integer.valueOf(eachAce.get(
109                                     Constants.KEYFIELD_ACE_SUBJECT_TYPE).toString()));
110                     ace.setPermission(Integer.valueOf(eachAce.get(
111                                     Constants.KEYFIELD_ACE_PERMISSION).toString()));
112
113                     Object validity = eachAce.get(Constants.KEYFIELD_ACE_VALIDITY);
114                     if (validity != null) {
115                         ace.setValidity((List<String>) validity);
116                     }
117
118                     List<AceResource> resourceLst = new ArrayList<AceResource>();
119                     List<HashMap<String, Object>> resourceList = (List<HashMap<String, Object>>) eachAce
120                         .get(Constants.KEYFIELD_ACE_RESOURCE);
121                     for (HashMap<String, Object> resrouce : resourceList) {
122
123                         AceResource aceResource = new AceResource();
124                         aceResource.setHref(valueOf(resrouce
125                                     .get(Constants.KEYFIELD_ACE_RESOURCE_HREF)));
126                         List<String> rtList = (List<String>) resrouce
127                             .get(Constants.KEYFIELD_ACE_RESOURCE_RT);
128                         aceResource.setRt(rtList);
129                         List<String> ifList = (List<String>) resrouce
130                             .get(Constants.KEYFIELD_ACE_RESOURCE_IF);
131                         aceResource.setOicif(ifList);
132
133                         resourceLst.add(aceResource);
134                     }
135                     ace.setResources(resourceLst);
136
137                     aceList.add(ace);
138
139                 }
140                 aclTable.setAclist(aceList);
141             } catch (Exception e) {
142                 throw new InternalServerErrorException(
143                         "Map to Acl Object casting error " + e.getMessage());
144             }
145             return aclTable;
146
147         }
148
149     @SuppressWarnings("unchecked")
150
151         public List<HashMap<String, Object>> addACE(List<HashMap<String, Object>> aclist) {
152             Log.v("IN addACE");
153             HashMap<String, Object> hashmap = AccountDBManager.getInstance()
154                 .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
155             if (hashmap == null) {
156                 throw new BadRequestException("aclid is invalid");
157             }
158             List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
159                 .get(Constants.REQ_ACL_LIST);
160
161
162             ListIterator<HashMap<String, Object>> iterator = aclist.listIterator();
163             while (iterator.hasNext()) {
164                 HashMap<String, Object> aceMap = iterator.next();
165                 if (aceMap.get(Constants.KEYFIELD_ACE_SUBJECT_ID)
166                         .equals(hashmap.get(Constants.REQ_OWNER_ID))) {
167                     // remove current iterator
168                     iterator.remove();
169                     continue;
170                 }
171                 aceMap.put(Constants.REQ_ACE_ID, UUID.randomUUID().toString());
172             }
173
174             List<HashMap<String, Object>> newAcList = new ArrayList<HashMap<String, Object>>(
175                     aclist);
176
177             if (aclDbList != null) {
178                 newAcList.addAll(aclDbList);
179             }
180             hashmap.put(Constants.REQ_ACL_LIST, newAcList);
181             AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
182                     hashmap);
183             notifyToSubscriber(getResponsePayload(true));
184             Log.v("OUT addACE");
185             return aclist;
186         }
187
188     public HashMap<String, Object> getACE(String aceid) {
189         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
190             .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
191         if (hashmap == null) {
192             throw new BadRequestException("aclid is invalid");
193         }
194
195         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
196             .get(Constants.REQ_ACL_LIST);
197         ListIterator<HashMap<String, Object>> iterator = aclDbList
198             .listIterator();
199         while (iterator.hasNext()) {
200             HashMap<String, Object> aceMap = iterator.next();
201             if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
202                 // Return the current element from the iterator
203                 return aceMap;
204             }
205         }
206         throw new BadRequestException("aceid is invalid");
207     }
208     public boolean isValidAceId(String aceid) {
209         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
210             .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
211         if (hashmap == null) {
212             return false;
213         }
214
215         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
216             .get(Constants.REQ_ACL_LIST);
217         ListIterator<HashMap<String, Object>> iterator = aclDbList
218             .listIterator();
219         while (iterator.hasNext()) {
220             HashMap<String, Object> aceMap = iterator.next();
221             if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
222                 return true;
223             }
224         }
225         return false;
226     }
227     public void updateACE(String aceid, HashMap<String, Object> ace) {
228         Log.v("IN updateACE");
229
230         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
231             .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
232
233         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap.get(Constants.REQ_ACL_LIST);
234
235         ace.put(Constants.REQ_ACE_ID, aceid);
236
237         ListIterator<HashMap<String, Object>> iterator = aclDbList.listIterator();
238         while (iterator.hasNext()) {
239             HashMap<String, Object> aceMap = iterator.next();
240             if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
241                 // replace current iterator with new element
242                 iterator.set(ace);
243                 break;
244             }
245         }
246
247         hashmap.put(Constants.REQ_ACL_LIST, aclDbList);
248         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE, hashmap);
249         notifyToSubscriber(getResponsePayload(true));
250         Log.v("OUT updateACE");
251
252     }
253
254     public void deleteACE(String aceid) {
255
256         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
257             .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
258
259         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
260             .get(Constants.REQ_ACL_LIST);
261
262
263         ListIterator<HashMap<String, Object>> iterator = aclDbList.listIterator();
264         while (iterator.hasNext()) {
265             HashMap<String, Object> aceMap = iterator.next();
266             if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
267                 // Remove the current element from the iterator
268                 iterator.remove();
269                 break;
270             }
271         }
272
273         hashmap.put(Constants.REQ_ACL_LIST, aclDbList);
274         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
275                 hashmap);
276         notifyToSubscriber(getResponsePayload(true));
277     }
278
279     public void deleteAclist() {
280         AclTable aclTable = getAclTable();
281         aclTable.setAclist(null);
282         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
283             mTypeAcl.convertObjectToMap(aclTable));
284         notifyToSubscriber(getResponsePayload(true));
285     }
286
287     public HashMap<String, Object> getInfo() {
288         return getResponsePayload(true);
289     }
290
291     public HashMap<String, Object> addSubscriber(String di, Device subscriber,
292             IRequest request) {
293
294         verifyAclTableDi(di);
295         AclSubscriber newSubscriber = new AclSubscriber(subscriber, request);
296         mSubscribers.put(di, newSubscriber);
297         return getInfo();
298     }
299
300     public HashMap<String, Object> removeSubscriber(String di) {
301
302         HashMap<String, Object> responsePayload = getResponsePayload(true);
303         if (mSubscribers.containsKey(di)) {
304             mSubscribers.remove(di);
305         }
306         return responsePayload;
307     }
308
309     private void verifyAclTableDi(String di) {
310         AclTable aclTable = getAclTable();
311         if (aclTable.getDi() == null) {
312             throw new BadRequestException("di is invalid in Acl");
313         }
314         String mDi = aclTable.getDi();
315         if (!mDi.equals(di)) {
316             throw new UnAuthorizedException(
317                 di + "is not Device ID of this ACL");
318         }
319     }
320
321     private void notifyToSubscriber(
322             HashMap<String, Object> notifyBytePayloadData) {
323         synchronized (mSubscribers) {
324
325             Iterator<String> iterator = mSubscribers.keySet().iterator();
326             while(iterator.hasNext()) {
327                 String key = iterator.next();
328                 AclSubscriber aclSubscriber = mSubscribers.get(key);
329                 aclSubscriber.mSubscriber.sendResponse(
330                     MessageBuilder.createResponse(aclSubscriber.mRequest,
331                         ResponseStatus.CONTENT,
332                         ContentFormat.APPLICATION_CBOR,
333                         mCbor.encodingPayloadToCbor(
334                             notifyBytePayloadData)));
335             }
336         }
337     }
338
339     private AclTable getAclTable() {
340         AclTable getAclTable = new AclTable();
341         getAclTable = convertMaptoAclObject(
342                 AccountDBManager.getInstance().selectRecord(
343                     Constants.ACL_TABLE, getCondition()).get(0));
344         return getAclTable;
345     }
346
347     private HashMap<String, Object> getAclTablePayLoad() {
348         HashMap<String, Object> aclPayload = new HashMap<>();
349         aclPayload = AccountDBManager.getInstance()
350             .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
351         return aclPayload;
352     }
353
354     private HashMap<String, Object> getResponsePayload(boolean isAliveAcl) {
355         return isAliveAcl ? getAclTablePayLoad() : null;
356     }
357
358     private HashMap<String, Object> getCondition() {
359         HashMap<String, Object> condition = new HashMap<>();
360         condition.put(Constants.REQ_ACL_ID, mAclid);
361         return condition;
362     }
363
364
365 }