1 package org.iotivity.cloud.accountserver.resources.acl.group;
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.HashMap;
7 import java.util.ListIterator;
9 import org.iotivity.cloud.accountserver.Constants;
10 import org.iotivity.cloud.accountserver.db.AccountDBManager;
11 import org.iotivity.cloud.accountserver.db.AceTable;
12 import org.iotivity.cloud.accountserver.db.GroupTable;
13 import org.iotivity.cloud.accountserver.resources.acl.id.AceResource;
14 import org.iotivity.cloud.accountserver.resources.acl.id.AclResource;
15 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
16 import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
17 import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException;
21 * This class provides a set of APIs to manage between AclManager and
27 public class GroupAclManager {
28 private static GroupAclManager mGrAclManager = new GroupAclManager();
29 private TypeCastingManager<AceTable> mTypeAceTable = new TypeCastingManager<AceTable>();
30 private TypeCastingManager<AceResource> mTypeAceResource = new TypeCastingManager<AceResource>();
32 private GroupAclManager() {
35 public static GroupAclManager getInstance() {
40 * API to add acl table by members
45 * resource permission of group acl in group
47 * member list which add into group
49 public void addAceByMembers(String gid, int permission,
50 ArrayList<String> members) {
52 // make default acelist for each new member
53 for (String device : getGroupDevices(gid)) {
54 addAceList(gid, device, makeAceList(members, permission, null));
57 // make acelist with specific resources for each new member
58 addAceByResources(gid, permission, getGroupResources(gid), members);
62 * API to add acl table by devices
67 * resource permission of group acl in group
69 * device list which add into group
71 public void addAceByDevices(String gid, int permission,
72 ArrayList<String> devices) {
74 // make default acelist for each existing member
75 for (String device : devices) {
76 addAceList(gid, device,
77 makeAceList(getGroupMembers(gid), permission, null));
82 * API to add acl table by resources
87 * resource permission of group acl in group
89 * resource list which add into group
91 public void addAceByResources(String gid, int permission,
92 ArrayList<HashMap<String, Object>> resources) {
94 addAceByResources(gid, permission, resources, getGroupMembers(gid));
98 * API to remove acl table by group
103 public void removeAceByGroup(String gid) {
105 HashMap<String, Object> condition = new HashMap<>();
106 condition.put(Constants.KEYFIELD_GID, gid);
108 ArrayList<AceTable> getAceTable = searchAceTableList(condition);
109 if (getAceTable.isEmpty()) {
113 removeAceList(getAceTable);
114 deleteAceRecords(condition);
118 * API to remove acl table by members
121 * member list which remove in group
125 public void removeAceByMembers(ArrayList<String> members, String gid) {
126 for (String member : members) {
127 removeAceByMember(member, gid);
128 removeAceByOwner(member, gid);
133 * API to remove acl table by devices
136 * device list which remove in group
140 public void removeAceByDevices(ArrayList<String> devices, String gid) {
141 for (String device : devices) {
142 removeAceByDevice(device, gid);
147 * API to remove acl table by resources
150 * resource list which remove in group
154 public void removeAceByResources(
155 ArrayList<HashMap<String, Object>> resources, String gid) {
156 for (HashMap<String, Object> href : resources) {
158 href.get(Constants.KEYFIELD_ACE_RESOURCE_HREF).toString(),
164 * API to get device owner id
167 * resource list which remove in group
171 public String getDeviceOwnerId(String di) {
173 String aclid = getAclid(di);
175 HashMap<String, Object> acl = AclResource.getInstance().getAcl(aclid)
178 if (acl == null || acl.containsKey(Constants.REQ_OWNER_ID) == false) {
179 throw new BadRequestException(
180 "Error while getting device owner id for " + di);
183 return acl.get(Constants.REQ_OWNER_ID).toString();
186 private void removeAceByMember(String uid, String gid) {
187 HashMap<String, Object> condition = new HashMap<>();
188 condition.put(Constants.KEYFIELD_UID, uid);
189 condition.put(Constants.KEYFIELD_GID, gid);
191 ArrayList<AceTable> getAceTable = searchAceTableList(condition);
192 if (getAceTable.isEmpty()) {
196 removeAceList(getAceTable);
197 deleteAceRecords(condition);
200 private void removeAceByOwner(String oid, String gid) {
201 HashMap<String, Object> condition = new HashMap<>();
202 condition.put(Constants.KEYFIELD_OID, oid);
203 condition.put(Constants.KEYFIELD_GID, gid);
205 ArrayList<AceTable> getAceTable = searchAceTableList(condition);
206 if (getAceTable.isEmpty()) {
210 removeAceList(getAceTable);
211 deleteAceRecords(condition);
214 private void removeAceByDevice(String di, String gid) {
215 HashMap<String, Object> condition = new HashMap<>();
216 condition.put(Constants.KEYFIELD_DI, di);
217 condition.put(Constants.KEYFIELD_GID, gid);
219 ArrayList<AceTable> getAceTable = searchAceTableList(condition);
220 if (getAceTable.isEmpty()) {
224 removeAceList(getAceTable);
225 deleteAceRecords(condition);
228 private void removeAceByResource(String href, String gid) {
229 String removeHref = extractHref(href);
230 String di = Arrays.asList(href.split("/")).get(2);
231 HashMap<String, Object> condition = new HashMap<>();
232 condition.put(Constants.KEYFIELD_DI, di);
233 condition.put(Constants.KEYFIELD_GID, gid);
235 ArrayList<AceTable> aceTableList = searchAceTableList(condition);
236 ArrayList<HashMap<String, Object>> aceMapList = searchAceMapList(
239 for (HashMap<String, Object> aceMap : aceMapList) {
240 ArrayList<HashMap<String, Object>> AceResourceList = (ArrayList) aceMap
241 .get(Constants.KEYFIELD_ACE_RESOURCE);
242 ListIterator<HashMap<String, Object>> iterator = AceResourceList
244 while (iterator.hasNext()) {
245 AceResource res = new AceResource();
246 res = mTypeAceResource.convertMaptoObject(iterator.next(), res);
248 if (res.getHref().contains(removeHref)) {
254 condition.put(Constants.KEYFIELD_UID,
255 aceMap.get(Constants.KEYFIELD_ACE_SUBJECT_ID));
257 ArrayList<AceTable> getAceTable = searchAceTableList(condition);
258 if (getAceTable.isEmpty()) {
262 if (AceResourceList.isEmpty()) {
263 removeAceList(getAceTable);
264 deleteAceRecords(condition);
266 updateAce(getAceTable.get(0), aceMap);
272 private ArrayList<AceTable> searchAceTableList(
273 HashMap<String, Object> condition) {
274 ArrayList<AceTable> getAceTableList = new ArrayList<>();
275 ArrayList<HashMap<String, Object>> getAceList = AccountDBManager
276 .getInstance().selectRecord(Constants.ACE_TABLE, condition);
277 if (getAceList == null) {
280 for (HashMap<String, Object> getAce : getAceList) {
281 AceTable getAceTable = new AceTable();
282 getAceTable = mTypeAceTable.convertMaptoObject(getAce, getAceTable);
283 getAceTableList.add(getAceTable);
285 return getAceTableList;
288 private ArrayList<HashMap<String, Object>> searchAceMapList(
289 ArrayList<AceTable> aceList) {
290 ArrayList<HashMap<String, Object>> getAceList = new ArrayList<>();
291 for (AceTable getAce : aceList) {
292 getAceList.add(getAce(getAce));
297 private void removeAceList(ArrayList<AceTable> aceTableList) {
298 for (AceTable removeAce : aceTableList) {
299 removeAce(removeAce);
303 private void updateAce(AceTable updateAce, HashMap<String, Object> ace) {
304 AclResource.getInstance().updateACE(getAclid(updateAce),
305 getAceid(updateAce), ace);
308 private void removeAce(AceTable removeAce) {
309 AclResource.getInstance().deleteAclACE(getAclid(removeAce),
310 getAceid(removeAce));
313 private HashMap<String, Object> getAce(AceTable getAce) {
314 return AclResource.getInstance().getAclACE(getAclid(getAce),
318 private String extractHref(String href) {
320 List<String> segment = new ArrayList<String>(
321 Arrays.asList(href.split("/")));
323 // Remove prefix path
328 StringBuilder uriPath = new StringBuilder();
329 for (String path : segment) {
330 uriPath.append("/" + path);
333 return uriPath.toString();
336 private String getAceid(AceTable aceTable) {
337 if (aceTable.getAceid() == null) {
338 throw new InternalServerErrorException("aceid is invalid");
340 return aceTable.getAceid();
343 private String getAclid(AceTable aceTable) {
345 if (aceTable.getDi() == null) {
346 throw new InternalServerErrorException("di is invalid");
348 di = aceTable.getDi();
353 private String getAclid(String di) {
355 HashMap<String, Object> acl = AclResource.getInstance().getAclid(di);
357 if (acl == null || !acl.containsKey(Constants.KEYFIELD_ACLID)) {
358 throw new InternalServerErrorException("aclid is invalid");
361 return (String) acl.get(Constants.KEYFIELD_ACLID);
364 private void addAceList(String gid, String di,
365 ArrayList<HashMap<String, Object>> acelist) {
367 String aclid = getAclid(di);
368 String oid = getDeviceOwnerId(di);
370 acelist = (ArrayList<HashMap<String, Object>>) AclResource.getInstance()
371 .addAclACE(aclid, acelist);
373 insertAceRecords(gid, di, oid, acelist);
376 private void addAceByResources(String gid, int permission,
377 ArrayList<HashMap<String, Object>> resources,
378 ArrayList<String> members) {
380 HashMap<String, ArrayList<HashMap<String, Object>>> sortedResources = sortResources(
383 for (String di : sortedResources.keySet()) {
385 // query aceid using gid-di in GroupACE table
386 HashMap<String, Object> condition = new HashMap<>();
387 condition.put(Constants.KEYFIELD_GID, gid);
388 condition.put(Constants.KEYFIELD_DI, di);
389 ArrayList<AceTable> aceTables = searchAceTableList(condition);
391 if (aceTables == null || aceTables.isEmpty()) {
393 addAceList(gid, di, makeAceList(members, permission,
394 sortedResources.get(di)));
398 updateAceByResources(gid, permission, di, sortedResources,
404 private void updateAceByResources(String gid, int permission, String di,
405 HashMap<String, ArrayList<HashMap<String, Object>>> sortedResources,
406 ArrayList<AceTable> aceTables) {
408 String aclid = getAclid(aceTables.get(0));
409 String aceid = getAceid(aceTables.get(0));
411 @SuppressWarnings("unchecked")
412 ArrayList<HashMap<String, Object>> updatedAceResources = (ArrayList<HashMap<String, Object>>) AclResource
413 .getInstance().getAclACE(aclid, aceid)
414 .get(Constants.KEYFIELD_ACE_RESOURCE);
416 if (updatedAceResources.isEmpty() == false && updatedAceResources.get(0)
417 .get(Constants.KEYFIELD_ACE_RESOURCE_HREF).equals("*")) {
419 updatedAceResources.clear();
422 updatedAceResources.addAll(sortedResources.get(di));
424 for (AceTable acetable : aceTables) {
425 updateAce(acetable, makeAce(acetable.getUid(), permission,
426 updatedAceResources));
430 private ArrayList<HashMap<String, Object>> makeAceList(
431 ArrayList<String> members, int permission,
432 ArrayList<HashMap<String, Object>> resources) {
434 ArrayList<HashMap<String, Object>> acelist = new ArrayList<>();
436 for (String member : members) {
437 acelist.add(makeAce(member, permission, resources));
443 private HashMap<String, Object> makeAce(String mid, int permission,
444 ArrayList<HashMap<String, Object>> resources) {
446 if (resources == null) {
447 resources = new ArrayList<>();
448 HashMap<String, Object> resource = new HashMap<>();
449 resource.put(Constants.KEYFIELD_ACE_RESOURCE_HREF, "*");
450 resource.put(Constants.KEYFIELD_ACE_RESOURCE_RT, Arrays.asList(""));
451 resource.put(Constants.KEYFIELD_ACE_RESOURCE_IF, Arrays.asList(""));
453 resources.add(resource);
456 HashMap<String, Object> newAce = new HashMap<>();
457 newAce.put(Constants.KEYFIELD_ACE_SUBJECT_ID, mid);
458 newAce.put(Constants.KEYFIELD_ACE_SUBJECT_TYPE, 1);
459 newAce.put(Constants.KEYFIELD_ACE_PERMISSION, permission);
460 newAce.put(Constants.KEYFIELD_ACE_RESOURCE, resources);
465 private void insertAceRecords(String gid, String di, String oid,
466 ArrayList<HashMap<String, Object>> acelist) {
468 for (HashMap<String, Object> ace : acelist) {
470 AceTable aceTable = new AceTable();
471 aceTable.setAceid(ace.get(Constants.KEYFIELD_ACE_ID).toString());
473 ace.get(Constants.KEYFIELD_ACE_SUBJECT_ID).toString());
474 aceTable.setGid(gid);
476 aceTable.setOid(oid);
478 AccountDBManager.getInstance().insertAndReplaceRecord(
480 mTypeAceTable.convertObjectToMap(aceTable));
484 private void deleteAceRecords(HashMap<String, Object> condition) {
486 AccountDBManager.getInstance().deleteRecord(Constants.ACE_TABLE,
490 private ArrayList<String> getGroupMembers(String gid) {
492 GroupTable groupTable = GroupManager.getInstance().getGroupTable(gid);
493 ArrayList<String> members = new ArrayList<>();
495 if (groupTable.getMembers() != null) {
496 members = groupTable.getMembers();
501 private ArrayList<String> getGroupDevices(String gid) {
503 GroupTable groupTable = GroupManager.getInstance().getGroupTable(gid);
504 ArrayList<String> devices = new ArrayList<>();
506 if (groupTable.getDevices() != null) {
507 devices = groupTable.getDevices();
512 private ArrayList<HashMap<String, Object>> getGroupResources(String gid) {
514 ArrayList<HashMap<String, Object>> resources = new ArrayList<>();
515 GroupTable groupTable = GroupManager.getInstance().getGroupTable(gid);
517 if (groupTable.getResources() == null) {
521 for (Object resource : groupTable.getResources()) {
523 @SuppressWarnings("unchecked")
524 HashMap<String, Object> resourceInfo = (HashMap<String, Object>) resource;
525 resources.add(resourceInfo);
531 // classify resources in group according to device id
532 private HashMap<String, ArrayList<HashMap<String, Object>>> sortResources(
533 ArrayList<HashMap<String, Object>> resources) {
535 HashMap<String, ArrayList<HashMap<String, Object>>> sortedResources = new HashMap<>();
537 for (HashMap<String, Object> resource : resources) {
539 HashMap<String, Object> resourceInfo = new HashMap<>(resource);
541 String href = resourceInfo.get(Constants.KEYFIELD_ACE_RESOURCE_HREF)
543 String di = Arrays.asList(href.split("/")).get(2);
544 href = extractHref(href);
546 resourceInfo.put(Constants.KEYFIELD_ACE_RESOURCE_HREF, href);
548 if (sortedResources.containsKey(di) == false) {
549 sortedResources.put(di, new ArrayList<>());
552 sortedResources.get(di).add(resourceInfo);
555 return sortedResources;