79aa4946dfbd24903cea94f37d3513c0d3677747
[iotivity.git] / cloud / account / src / main / java / org / iotivity / cloud / accountserver / resources / acl / group / GroupManager.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.group;
23
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.List;
28
29 import org.iotivity.cloud.accountserver.Constants;
30 import org.iotivity.cloud.accountserver.db.AccountDBManager;
31 import org.iotivity.cloud.accountserver.db.GroupTable;
32 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
33 import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
34 import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
35 import org.iotivity.cloud.util.Log;
36
37 /**
38  *
39  * This class provides a set of APIs to manage group
40  *
41  */
42
43 public class GroupManager {
44     private static GroupManager            mGrManager          = new GroupManager();
45     private TypeCastingManager<GroupTable> mTypeGroup          = new TypeCastingManager<GroupTable>();
46     private GroupPolicyManager             mGroupPolicyManager = new GroupPolicyManager();
47     private GroupAclManager                mGroupAclManager    = GroupAclManager
48             .getInstance();
49
50     /**
51      * Function to get GroupManager as a singleton
52      * 
53      * @return GroupManager as a singleton
54      */
55     public static GroupManager getInstance() {
56         return mGrManager;
57     }
58
59     /**
60      * API to replace group name to the group
61      * 
62      * @param gid
63      *            group id
64      * @param gname
65      *            group name
66      */
67     public void replaceGnameToGroup(String gid, String gname) {
68         replaceProperties(gid, Constants.KEYFIELD_GROUP_NAME, gname);
69     }
70
71     /**
72      * API to replace owner id to the group
73      * 
74      * @param gid
75      *            group id
76      * @param owner
77      *            owner id
78      */
79     public void replaceOwnerToGroup(String gid, String owner) {
80         replaceProperties(gid, Constants.KEYFIELD_GROUP_OWNER, owner);
81     }
82
83     /**
84      * API to add members to the group
85      * 
86      * @param gid
87      *            group id
88      * @param values
89      *            user uuid list
90      */
91     public void addMembersToGroup(String gid, ArrayList<String> members) {
92         addProperties(gid, Constants.KEYFIELD_GROUP_MEMBERS, members);
93     }
94
95     /**
96      * API to add masters to the group
97      * 
98      * @param gid
99      *            group id
100      * @param values
101      *            user uuid list
102      */
103     public void addMastersToGroup(String gid, ArrayList<String> masters) {
104         addProperties(gid, Constants.KEYFIELD_GROUP_MASTERS, masters);
105         addProperties(gid, Constants.KEYFIELD_GROUP_MEMBERS, masters);
106     }
107
108     /**
109      * API to add resources to the group
110      * 
111      * @param gid
112      *            group id
113      * @param values
114      *            resource list
115      */
116     public void addResourcesToGroup(String gid, ArrayList<Object> resources) {
117         ArrayList<Object> addedResources = new ArrayList<>();
118         // filter added resource list : if the device is already to the
119         // group, the resource is not added to the group
120         for (Object resource : resources) {
121             String deviceId = getDeviceIdFromResource(
122                     (HashMap<String, Object>) resource);
123             ArrayList<String> devices = getGroupTable(gid).getDevices();
124             if (devices == null) {
125                 addedResources.add(resource);
126             } else {
127                 if (!devices.contains(deviceId)) {
128                     addedResources.add(resource);
129                 }
130             }
131         }
132         addProperties(gid, Constants.KEYFIELD_GROUP_RESOURCES, addedResources);
133     }
134
135     /**
136      * API to add devices to the group
137      * 
138      * @param gid
139      *            group id
140      * @param values
141      *            device list
142      */
143     public void addDevicesToGroup(String gid, ArrayList<String> devices) {
144         // if resources regarding to the device is already registered, delete
145         // resources in advance
146         deleteResourcesOfDevices(gid, devices);
147         addProperties(gid, Constants.KEYFIELD_GROUP_DEVICES, devices);
148     }
149
150     /**
151      * API to delete member list from the group
152      * 
153      * @param gid
154      *            group id
155      * @param values
156      *            member uuid list
157      */
158     public void deleteMembersFromGroup(String gid, ArrayList<String> members) {
159         GroupTable groupTable = getGroupTable(gid);
160         ArrayList<String> devices = groupTable.getDevices();
161         if (devices != null) {
162             // delete devices owned by deleted members
163             ArrayList<String> deletedDevices = new ArrayList<String>();
164             for (String device : devices) {
165                 if (members.contains(findDeviceOwner(device))) {
166                     deletedDevices.add(device);
167                 }
168             }
169             deleteDevicesFromGroup(gid, deletedDevices);
170         }
171         deleteProperties(gid, Constants.KEYFIELD_GROUP_MEMBERS, members);
172         deleteProperties(gid, Constants.KEYFIELD_GROUP_MASTERS, members);
173     }
174
175     /**
176      * API to delete device and resources of each device from all groups
177      * 
178      * @param device
179      *            device id to be deleted from all groups
180      */
181     public void deleteDevicesFromAllGroup(String device) {
182         ArrayList<HashMap<String, Object>> groupList = readGroupList(
183                 Constants.KEYFIELD_GROUP_MEMBERS, findDeviceOwner(device));
184         if (groupList == null) {
185             return;
186         }
187         ArrayList<String> devices = new ArrayList<>();
188         devices.add(device);
189         for (HashMap<String, Object> group : groupList) {
190             // deleteProperties((String) group.get(Constants.REQ_GROUP_ID),
191             // Constants.KEYFIELD_GROUP_DEVICES, devices);
192             deleteDevicesFromGroup((String) group.get(Constants.REQ_GROUP_ID),
193                     devices);
194         }
195     }
196
197     private ArrayList<HashMap<String, Object>> readGroupList(String key,
198             String value) {
199         HashMap<String, Object> condition = new HashMap<>();
200         condition.put(key, value);
201         ArrayList<HashMap<String, Object>> records = AccountDBManager
202                 .getInstance().selectRecord(Constants.GROUP_TABLE, condition);
203         return records;
204     }
205
206     /**
207      * API to delete master list from the group
208      * 
209      * @param gid
210      *            group id
211      * @param values
212      *            master uuid list
213      */
214     public void deleteMastersFromGroup(String gid, ArrayList<String> masters) {
215         deleteProperties(gid, Constants.KEYFIELD_GROUP_MASTERS, masters);
216     }
217
218     /**
219      * API to delete resource list from the group
220      * 
221      * @param gid
222      *            group id
223      * @param values
224      *            resource list
225      */
226     public void deleteResourcesFromGroup(String gid,
227             ArrayList<Object> deletedResources) {
228         deleteProperties(gid, Constants.KEYFIELD_GROUP_RESOURCES,
229                 deletedResources);
230     }
231
232     /**
233      * API to delete device list from the group
234      * 
235      * @param gid
236      *            group id
237      * @param values
238      *            device list
239      */
240     public void deleteDevicesFromGroup(String gid, ArrayList<String> devices) {
241         // delete resources owned by deleted members
242         deleteResourcesOfDevices(gid, devices);
243         deleteProperties(gid, Constants.KEYFIELD_GROUP_DEVICES, devices);
244     }
245
246     /**
247      * API to verify if the member user is eligible to add/delete/replace the
248      * requested property values
249      * 
250      * @param gid
251      *            group id
252      * @param mid
253      *            user uuid
254      * @param properties
255      *            property key/value map to check
256      * @param operation
257      *            user operation
258      */
259     public void verifyPostRequestAuthz(String gid, String mid,
260             HashMap<String, Object> properties, UserOperation operation) {
261         ArrayList<String> keySet = new ArrayList<String>();
262         keySet.addAll(properties.keySet());
263         mGroupPolicyManager.verifyOperationAuthorization(gid, mid, operation,
264                 keySet);
265         switch (operation) {
266             case ADD:
267                 verifyPostAddPolicy(gid, mid, properties);
268                 break;
269             case DELETE:
270                 verifyPostDeletePolicy(gid, mid, properties);
271                 break;
272             case REPLACE:
273                 verifyPostReplacePolicy(gid, mid, properties);
274                 break;
275             default:
276                 throw new PreconditionFailedException(
277                         operation + " is not supported");
278         }
279     }
280
281     /**
282      * API to get added property value list to the group among the entire value
283      * list to update
284      * 
285      * @param gid
286      *            group id
287      * @param property
288      *            property to update
289      * @param values
290      *            value list to update
291      * @return property value list to be added to the group
292      */
293     public <T> ArrayList<T> getAddPropertyValues(String gid, String property,
294             ArrayList<T> values) {
295         GroupTable groupTable = getGroupTable(gid);
296         if (groupTable == null) {
297             throw new BadRequestException("group " + gid + " does not exist");
298         }
299         ArrayList<T> propertyValues = groupTable.getPropertyValue(property);
300         ArrayList<T> addedValues = new ArrayList<>();
301         for (int i = 0; i < values.size(); i++) {
302             if (!propertyValues.contains(values.get(i))) {
303                 addedValues.add(values.get(i));
304             }
305         }
306         return addedValues;
307     }
308
309     /**
310      * API to get deleted property value list from the group
311      * 
312      * @param gid
313      *            group id
314      * @param property
315      *            property to update
316      * @param values
317      *            value list to update
318      * @return property value list to be deleted from the group
319      */
320     public <T> ArrayList<T> getDeletePropertyValues(String gid, String property,
321             ArrayList<T> values) {
322         GroupTable groupTable = getGroupTable(gid);
323         if (groupTable == null) {
324             throw new BadRequestException("group " + gid + " does not exist");
325         }
326         ArrayList<T> propertyValues = groupTable.getPropertyValue(property);
327         ArrayList<T> deletedValues = new ArrayList<>();
328         for (int i = 0; i < propertyValues.size(); i++) {
329             if (!values.contains(propertyValues.get(i))) {
330                 deletedValues.add(propertyValues.get(i));
331             }
332         }
333         return deletedValues;
334     }
335
336     /**
337      * API to verify if the user is eligible to get the group information
338      * 
339      * @param gid
340      *            group id
341      * @param mid
342      *            user uuid
343      */
344     public void verifyGetRequestAuthz(String gid, String mid) {
345         verifyMemberExistenceInGroup(gid, mid);
346     }
347
348     /**
349      * API to verify if the user is eligible to delete the group
350      * 
351      * @param gid
352      *            group id
353      * @param mid
354      *            user uuid
355      */
356     public void verifyDeleteRequestAuthz(String gid, String mid) {
357         ArrayList<String> property = new ArrayList<>();
358         property.add(Constants.KEYFIELD_GROUP);
359         mGroupPolicyManager.verifyOperationAuthorization(gid, mid,
360                 UserOperation.DELETE, property);
361     }
362
363     /**
364      * API to delete a group
365      * 
366      * @param gmid
367      *            An unique identifier of member who must be a group master.
368      *            Group master can be user or resource client.
369      * @param gid
370      *            An unique identifier of the group created under user entity
371      *            who requested for group creation.
372      */
373     public void deleteGroup(String gid) {
374         GroupTable groupTable = getGroupTable(gid);
375         String parentGid = groupTable.getParent();
376         // delete subgroup ID of the parent group
377         if (parentGid != null && !parentGid.isEmpty()) {
378             ArrayList<Object> gidList = new ArrayList<Object>(
379                     Arrays.asList(gid));
380             deleteProperties(parentGid, Constants.KEYFIELD_GROUP_SUBGROUPS,
381                     gidList);
382         }
383         HashMap<String, Object> condition = new HashMap<>();
384         condition.put(Constants.KEYFIELD_GID, gid);
385         // delete group from the table
386         AccountDBManager.getInstance().deleteRecord(Constants.GROUP_TABLE,
387                 condition);
388         ArrayList<String> subgroups = (ArrayList<String>) groupTable
389                 .getSubgroups();
390         // delete subgroups
391         if (subgroups != null) {
392             for (String subgroup : subgroups) {
393                 deleteGroup(subgroup);
394                 mGroupAclManager.removeAceByGroup(subgroup);
395             }
396         }
397     }
398
399     /**
400      * API to get the group information from the db
401      * 
402      * @param gid
403      *            group id
404      * @return group information payload
405      */
406     public HashMap<String, Object> getGroupInfo(String gid) {
407         GroupTable grouptable = getGroupTable(gid);
408         return mTypeGroup.convertObjectToMap(grouptable);
409     }
410
411     /**
412      * API to add property value list to the group
413      * 
414      * @param gid
415      *            group id
416      * @param property
417      *            property
418      * @param values
419      *            value list
420      */
421     private <T> void addProperties(String gid, String property,
422             ArrayList<T> values) {
423         Log.d("added property name: " + property + ", values : " + values
424                 + " , to group : " + gid);
425         if (values == null || values.isEmpty()) {
426             return;
427         }
428         GroupTable groupTable = getGroupTable(gid);
429         ArrayList<T> propertyValues = groupTable.getPropertyValue(property);
430         if (propertyValues == null) {
431             propertyValues = new ArrayList<T>();
432         }
433         values.removeAll(propertyValues);
434         propertyValues.addAll(values);
435         groupTable.setPropertyValue(property, propertyValues);
436         AccountDBManager.getInstance().updateRecord(Constants.GROUP_TABLE,
437                 mTypeGroup.convertObjectToMap(groupTable));
438         updateAclist(property, values, UserOperation.ADD, groupTable);
439     }
440
441     /**
442      * API to delete property value list from the group
443      * 
444      * @param gid
445      *            group id
446      * @param property
447      *            property
448      * @param values
449      *            value list
450      */
451     private <T> void deleteProperties(String gid, String property,
452             ArrayList<T> values) {
453         Log.d("deleted property name: " + property + ", values : " + values
454                 + " , from group : " + gid);
455         GroupTable groupTable = getGroupTable(gid);
456         if (groupTable == null || values == null || values.isEmpty()) {
457             return;
458         }
459         ArrayList<T> propertyValues = groupTable.getPropertyValue(property);
460         if (propertyValues != null) {
461             if (propertyValues.removeAll(values) == false) {
462                 return;
463             }
464         }
465         groupTable.setPropertyValue(property, propertyValues);
466         AccountDBManager.getInstance().updateRecord(Constants.GROUP_TABLE,
467                 mTypeGroup.convertObjectToMap(groupTable));
468         ArrayList<String> subgroups = (ArrayList<String>) groupTable
469                 .getSubgroups();
470         updateAclist(property, values, UserOperation.DELETE, groupTable);
471         if (subgroups != null) {
472             for (int i = 0; i < subgroups.size(); i++) {
473                 deleteProperties(subgroups.get(i), property, values);
474             }
475         }
476     }
477
478     /**
479      * API to replace property value list to the group
480      * 
481      * @param gid
482      *            group id
483      * @param property
484      *            property
485      * @param value
486      *            value string
487      */
488     private void replaceProperties(String gid, String property, String value) {
489         Log.d("replaced property name: " + property + ", value : " + value
490                 + ", to group : " + gid);
491         if (value == null || value.isEmpty()) {
492             return;
493         }
494         GroupTable groupTable = getGroupTable(gid);
495         groupTable.setPropertyValue(property, value);
496         AccountDBManager.getInstance().updateRecord(Constants.GROUP_TABLE,
497                 mTypeGroup.convertObjectToMap(groupTable));
498     }
499
500     /**
501      * API to get group table as an instance of GroupTable class
502      * 
503      * @param gid
504      *            group id
505      * @return group table
506      */
507     public GroupTable getGroupTable(String gid) {
508         GroupTable getGroupTable = new GroupTable();
509         ArrayList<HashMap<String, Object>> groupList = AccountDBManager
510                 .getInstance().selectRecord(Constants.GROUP_TABLE,
511                         getCondition(Constants.REQ_GROUP_ID, gid));
512         if (groupList.isEmpty()) {
513             return null;
514         }
515         getGroupTable = mTypeGroup.convertMaptoObject(groupList.get(0),
516                 getGroupTable);
517         return getGroupTable;
518
519     }
520
521     private void deleteResourcesOfDevices(String gid,
522             ArrayList<String> devices) {
523         GroupTable groupTable = getGroupTable(gid);
524         ArrayList<Object> resources = groupTable.getResources();
525         if (resources == null) {
526             return;
527         }
528         ArrayList<Object> deletedResources = new ArrayList<>();
529         for (Object object : resources) {
530             HashMap<String, Object> resource = (HashMap<String, Object>) object;
531             String resourceHref = (String) resource
532                     .get(Constants.KEYFIELD_ACE_RESOURCE_HREF);
533             String splitHref[] = resourceHref.split("/");
534
535             String deviceId = new String();
536             for (int i = 0; i < splitHref.length; i++) {
537                 if (splitHref[i].equals(Constants.REQ_DEVICE_ID)
538                         && (i + 1) < splitHref.length) {
539                     deviceId = splitHref[i + 1];
540
541                     break;
542                 }
543             }
544             if (devices.contains(deviceId)) {
545                 deletedResources.add(resource);
546             }
547         }
548         deleteResourcesFromGroup(gid, deletedResources);
549     }
550
551     private void verifyPostReplacePolicy(String gid, String mid,
552             HashMap<String, Object> properties) {
553         ArrayList<String> updatedKeySet = new ArrayList<String>();
554         updatedKeySet.addAll(properties.keySet());
555         mGroupPolicyManager.verifyOperationAuthorization(gid, mid,
556                 UserOperation.REPLACE, updatedKeySet);
557         for (String key : properties.keySet()) {
558             if (!(properties.get(key) instanceof String)) {
559                 throw new BadRequestException(
560                         "replace property value should be an instance of String");
561             }
562         }
563     }
564
565     private void verifyMemberExistenceInGroup(String gid, String mid) {
566         GroupTable groupTable = getGroupTable(gid);
567         if (groupTable == null) {
568             throw new BadRequestException("group " + gid + " does not exist");
569         }
570         if (groupTable.getMembers() == null) {
571             throw new BadRequestException("there are no members in the group");
572         }
573         if (!groupTable.getMembers().contains(mid)) {
574             throw new BadRequestException("uid is not a member of the group");
575         }
576     }
577
578     private void verifyPostAddPolicy(String gid, String mid,
579             HashMap<String, Object> properties) {
580         for (String key : properties.keySet()) {
581             if (!(properties.get(key) instanceof List)) {
582                 throw new BadRequestException(
583                         "add property value should be an instance of Array");
584             }
585             switch (key) {
586                 case Constants.KEYFIELD_GROUP_DEVICES:
587                     verifyDeviceOwner(mid,
588                             (ArrayList<String>) properties.get(key));
589                     verifyExistenceInParentGroup(gid, key,
590                             (ArrayList<Object>) properties.get(key));
591                     break;
592                 case Constants.KEYFIELD_GROUP_RESOURCES:
593                     verifyResourceFormat(
594                             Arrays.asList(Constants.KEYFIELD_RESOURCE_RT,
595                                     Constants.KEYFIELD_RESOURCE_IF,
596                                     Constants.KEYFIELD_ACE_RESOURCE_HREF),
597                             (ArrayList<HashMap<String, Object>>) properties
598                                     .get(key));
599                     verifyResourceOwner(mid,
600                             (ArrayList<HashMap<String, Object>>) properties
601                                     .get(key));
602                     verifyExistenceInParentGroup(gid, key,
603                             filterResourceExistenceInParentGroupDeviceProperty(
604                                     gid,
605                                     (ArrayList<HashMap<String, Object>>) properties
606                                             .get(key)));
607                     break;
608                 case Constants.KEYFIELD_GROUP_MEMBERS:
609                 case Constants.KEYFIELD_GROUP_MASTERS:
610                     // TODO verify if members are registered to the Account user
611                     // DB
612                     verifyExistenceInParentGroup(gid,
613                             Constants.KEYFIELD_GROUP_MEMBERS,
614                             (ArrayList<Object>) properties.get(key));
615                     break;
616                 default:
617                     throw new PreconditionFailedException(
618                             key + " is not supported");
619             }
620         }
621     }
622
623     private void verifyResourceFormat(List<String> propertyList,
624             ArrayList<HashMap<String, Object>> resources) {
625         for (HashMap<String, Object> resource : resources) {
626             for (String property : propertyList) {
627                 if (!resource.containsKey(property))
628                     throw new PreconditionFailedException(
629                             property + " property is not included");
630                 switch (property) {
631                     case Constants.KEYFIELD_RESOURCE_RT:
632                     case Constants.KEYFIELD_RESOURCE_IF:
633                         if (!(resource.get(property) instanceof List)) {
634                             throw new BadRequestException(property
635                                     + " property values should be an instance of array");
636                         }
637                         break;
638                     case Constants.KEYFIELD_ACE_RESOURCE_HREF:
639                         if (resource.get(property) == null) {
640                             throw new BadRequestException(
641                                     property + " property is null");
642                         }
643                         break;
644                 }
645             }
646         }
647     }
648
649     private void verifyPostDeletePolicy(String gid, String mid,
650             HashMap<String, Object> properties) {
651         for (String key : properties.keySet()) {
652             if (!(properties.get(key) instanceof List)) {
653                 throw new BadRequestException(
654                         "delete property value should be an instance of Array");
655             }
656             switch (key) {
657                 case Constants.REQ_UUID_ID:
658                     break;
659                 case Constants.KEYFIELD_GROUP_DEVICES:
660                 case Constants.KEYFIELD_GROUP_RESOURCES:
661                 case Constants.KEYFIELD_GROUP_MEMBERS:
662                     if ((boolean) ((ArrayList<String>) properties.get(key))
663                             .contains(getGroupTable(gid).getOwner())) {
664                         throw new BadRequestException("cannot remove owner Id");
665                     }
666                 case Constants.KEYFIELD_GROUP_MASTERS:
667                     verifyExistenceInParentGroup(gid, key,
668                             (ArrayList<Object>) properties.get(key));
669                     break;
670                 default:
671                     throw new BadRequestException(
672                             key + " property is not supported to ");
673             }
674         }
675     }
676
677     private ArrayList<HashMap<String, Object>> filterResourceExistenceInParentGroupDeviceProperty(
678             String gid, ArrayList<HashMap<String, Object>> resources) {
679         GroupTable parentGroupTable = getParentGroupTable(gid);
680         if (parentGroupTable == null) {
681             return resources;
682         }
683         ArrayList<String> devices = parentGroupTable.getDevices();
684         if (devices == null) {
685             return resources;
686         }
687         for (HashMap<String, Object> resource : resources) {
688             // if the device is registered to the parent group, filter the
689             // resource list
690             String deviceId = getDeviceIdFromResource(resource);
691             if (devices.contains(deviceId)) {
692                 resources.remove(resource);
693             }
694         }
695         return resources;
696     }
697
698     private GroupTable getParentGroupTable(String gid) {
699         try {
700             return getGroupTable(getGroupTable(gid).getParent());
701         } catch (Exception e) {
702             return null;
703         }
704     }
705
706     private <T> void verifyExistenceInParentGroup(String gid, String property,
707             ArrayList<T> values) {
708         GroupTable parentGroupTable = getParentGroupTable(gid);
709         if (parentGroupTable == null) {
710             return;
711         }
712
713         ArrayList<Object> groupValues = parentGroupTable
714                 .getPropertyValue(property);
715         if (groupValues == null) {
716             throw new BadRequestException(
717                     "verifying parent group Existence failed");
718         }
719         if (!groupValues.containsAll(values)) {
720             throw new BadRequestException(
721                     "verifying parent group Existence failed");
722
723         }
724     }
725
726     private void verifyDeviceOwner(String mid, ArrayList<String> values) {
727         for (String deviceId : values) {
728             if (!findDeviceOwner(deviceId).equals(mid)) {
729                 throw new BadRequestException("verifying device owner failed");
730             }
731         }
732     }
733
734     private void verifyResourceOwner(String mid,
735             ArrayList<HashMap<String, Object>> resources) {
736         for (HashMap<String, Object> resource : resources) {
737             String deviceId = getDeviceIdFromResource(resource);
738             if (!findDeviceOwner(deviceId).equals(mid)) {
739                 throw new BadRequestException(
740                         "verifying resource owner failed");
741             }
742         }
743     }
744
745     private String getDeviceIdFromResource(HashMap<String, Object> resource) {
746         String resourceHref = (String) resource
747                 .get(Constants.KEYFIELD_ACE_RESOURCE_HREF);
748         String splitHref[] = resourceHref.split("/");
749         for (int i = 0; i < splitHref.length; i++) {
750             if (splitHref[i].equals(Constants.REQ_DEVICE_ID)
751                     && (i + 1) < splitHref.length) {
752                 return splitHref[i + 1];
753             }
754         }
755         return null;
756     }
757
758     private String findDeviceOwner(String deviceId) {
759         return mGroupAclManager.getDeviceOwnerId(deviceId);
760     }
761
762     private String findResourceOwner(String resourceHref) {
763         String splitHref[] = resourceHref.split("/");
764         for (int i = 0; i < splitHref.length; i++) {
765             if (splitHref[i].equals(Constants.REQ_DEVICE_ID)
766                     && (i + 1) < splitHref.length) {
767                 return findDeviceOwner(splitHref[i + 1]);
768             }
769         }
770         return null;
771     }
772
773     private HashMap<String, Object> getCondition(String property,
774             String value) {
775         HashMap<String, Object> condition = new HashMap<>();
776         condition.put(property, value);
777         return condition;
778     }
779
780     private <T> void updateAclist(String property, ArrayList<T> values,
781             UserOperation operation, GroupTable groupTable) {
782         switch (operation) {
783             case ADD:
784                 addAclist(property, values, groupTable);
785                 break;
786             case DELETE:
787                 removeAclist(property, values, groupTable);
788                 break;
789             default:
790                 throw new BadRequestException(
791                         operation + " is not supported operation in the group");
792         }
793     }
794
795     private <T> void addAclist(String property, ArrayList<T> values,
796             GroupTable groupTable) {
797         String gid = groupTable.getGid();
798         int permission = 0;
799         for (Object gaclObject : groupTable.getGacl()) {
800             HashMap<String, Object> gacl = (HashMap<String, Object>) gaclObject;
801             permission = (int) gacl.get(Constants.KEYFIELD_ACE_PERMISSION);
802         }
803         switch (property) {
804             case Constants.KEYFIELD_GROUP_MEMBERS:
805                 mGroupAclManager.addAceByMembers(gid, permission,
806                         (ArrayList<String>) values);
807                 break;
808             case Constants.KEYFIELD_GROUP_DEVICES:
809                 mGroupAclManager.addAceByDevices(gid, permission,
810                         (ArrayList<String>) values);
811                 break;
812             case Constants.KEYFIELD_GROUP_RESOURCES:
813                 mGroupAclManager.addAceByResources(gid, permission,
814                         (ArrayList<HashMap<String, Object>>) values);
815                 break;
816             case Constants.KEYFIELD_GROUP_OWNER:
817             case Constants.KEYFIELD_GROUP_MASTERS:
818             case Constants.KEYFIELD_GROUP_SUBGROUPS:
819             case Constants.KEYFIELD_GROUP_GACL:
820                 return;
821             default:
822                 throw new BadRequestException(
823                         property + " is not supported property in the group");
824         }
825     }
826
827     private <T> void removeAclist(String property, ArrayList<T> values,
828             GroupTable groupTable) {
829         String gid = groupTable.getGid();
830         switch (property) {
831             case Constants.KEYFIELD_GROUP_MEMBERS:
832                 mGroupAclManager.removeAceByMembers((ArrayList<String>) values,
833                         gid);
834                 break;
835             case Constants.KEYFIELD_GROUP_DEVICES:
836                 mGroupAclManager.removeAceByDevices((ArrayList<String>) values,
837                         gid);
838                 break;
839             case Constants.KEYFIELD_GROUP_RESOURCES:
840                 mGroupAclManager.removeAceByResources(
841                         (ArrayList<HashMap<String, Object>>) values, gid);
842                 break;
843             case Constants.KEYFIELD_GROUP_OWNER:
844             case Constants.KEYFIELD_GROUP_MASTERS:
845             case Constants.KEYFIELD_GROUP_SUBGROUPS:
846             case Constants.KEYFIELD_GROUP_GACL:
847                 return;
848             default:
849                 throw new BadRequestException(
850                         property + " is not supported property in the group");
851         }
852     }
853 }