Cloud ACL Modifications
[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 void addACE(List<HashMap<String, Object>> aclist) {
152
153         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
154             .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
155
156         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
157             .get(Constants.REQ_ACL_LIST);
158
159
160         for(HashMap<String, Object> ace : aclist) {
161             ace.put(Constants.REQ_ACE_ID, UUID.randomUUID().toString());
162         }
163
164         List<HashMap<String, Object>> newAcList = new ArrayList<HashMap<String, Object>>(
165                 aclist);
166
167         if (aclDbList != null) {
168             newAcList.addAll(aclDbList);
169         }
170         hashmap.put(Constants.REQ_ACL_LIST, newAcList);
171         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
172                 hashmap);
173         notifyToSubscriber(getResponsePayload(true));
174     }
175
176     public void updateACE(String aceid, HashMap<String, Object> ace) {
177
178         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
179             .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
180
181         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap.get(Constants.REQ_ACL_LIST);
182
183         ace.put(Constants.REQ_ACE_ID, aceid);
184
185         ListIterator<HashMap<String, Object>> iterator = aclDbList.listIterator();
186         while (iterator.hasNext()) {
187             HashMap<String, Object> aceMap = iterator.next();
188             if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
189                 // replace current iterator with new element
190                 iterator.set(ace);
191                 break;
192             }
193         }
194
195         hashmap.put(Constants.REQ_ACL_LIST, aclDbList);
196         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE, hashmap);
197         notifyToSubscriber(getResponsePayload(true));
198     }
199
200     public void deleteACE(String aceid) {
201
202         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
203             .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
204
205         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
206             .get(Constants.REQ_ACL_LIST);
207
208
209         ListIterator<HashMap<String, Object>> iterator = aclDbList.listIterator();
210         while (iterator.hasNext()) {
211             HashMap<String, Object> aceMap = iterator.next();
212             if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
213                 // Remove the current element from the iterator
214                 iterator.remove();
215                 break;
216             }
217         }
218
219         hashmap.put(Constants.REQ_ACL_LIST, aclDbList);
220         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
221                 hashmap);
222         notifyToSubscriber(getResponsePayload(true));
223     }
224
225     public void deleteAclist() {
226         AclTable aclTable = getAclTable();
227         aclTable.setAclist(null);
228         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
229             mTypeAcl.convertObjectToMap(aclTable));
230         notifyToSubscriber(getResponsePayload(true));
231     }
232
233     public HashMap<String, Object> getInfo() {
234         return getResponsePayload(true);
235     }
236
237     public HashMap<String, Object> addSubscriber(String di, Device subscriber,
238             IRequest request) {
239
240         verifyAclTableDi(di);
241         AclSubscriber newSubscriber = new AclSubscriber(subscriber, request);
242         mSubscribers.put(di, newSubscriber);
243         return getInfo();
244     }
245
246     public HashMap<String, Object> removeSubscriber(String di) {
247
248         HashMap<String, Object> responsePayload = getResponsePayload(true);
249         if (mSubscribers.containsKey(di)) {
250             mSubscribers.remove(di);
251         }
252         return responsePayload;
253     }
254
255     private void verifyAclTableDi(String di) {
256         AclTable aclTable = getAclTable();
257         if (aclTable.getDi() == null) {
258             throw new BadRequestException("di is invalid in Acl");
259         }
260         String mDi = aclTable.getDi();
261         if (!mDi.equals(di)) {
262             throw new UnAuthorizedException(
263                 di + "is not Device ID of this ACL");
264         }
265     }
266
267     private void notifyToSubscriber(
268             HashMap<String, Object> notifyBytePayloadData) {
269         synchronized (mSubscribers) {
270
271             Iterator<String> iterator = mSubscribers.keySet().iterator();
272             while(iterator.hasNext()) {
273                 String key = iterator.next();
274                 AclSubscriber aclSubscriber = mSubscribers.get(key);
275                 aclSubscriber.mSubscriber.sendResponse(
276                     MessageBuilder.createResponse(aclSubscriber.mRequest,
277                         ResponseStatus.CONTENT,
278                         ContentFormat.APPLICATION_CBOR,
279                         mCbor.encodingPayloadToCbor(
280                             notifyBytePayloadData)));
281             }
282         }
283     }
284
285     private AclTable getAclTable() {
286         AclTable getAclTable = new AclTable();
287         getAclTable = convertMaptoAclObject(
288                 AccountDBManager.getInstance().selectRecord(
289                     Constants.ACL_TABLE, getCondition()).get(0));
290         return getAclTable;
291     }
292
293     private HashMap<String, Object> getAclTablePayLoad() {
294         HashMap<String, Object> aclPayload = new HashMap<>();
295         aclPayload = AccountDBManager.getInstance()
296             .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
297         return aclPayload;
298     }
299
300     private HashMap<String, Object> getResponsePayload(boolean isAliveAcl) {
301         return isAliveAcl ? getAclTablePayLoad() : null;
302     }
303
304     private HashMap<String, Object> getCondition() {
305         HashMap<String, Object> condition = new HashMap<>();
306         condition.put(Constants.REQ_ACL_ID, mAclid);
307         return condition;
308     }
309
310
311 }