From 9306ab0966d621310a9d8f040a61e2031d7a09f2 Mon Sep 17 00:00:00 2001 From: Jongmin Choi Date: Tue, 13 Sep 2016 18:20:54 +0900 Subject: [PATCH] Cloud ACL Management Cloud ACL Management Patch #1-2: ACLTable, ACL Id, ACL Verify, request handler added Patch #3-5: ACL resources renamed, DB API added Patch #10: URI & Request Handler fixed Patch #11-15: Support for Observe Added Patch #16-18: Combine changes for acl verify and policy engine by Sunil Kumar Patch #19: Issue fixed regarding DB document object to HashMap Patch #20: Revisions in response to comments Change-Id: I3acbe47d268cb6ad647317de39185cbd7bd552db Signed-off-by: Jongmin Choi Signed-off-by: Sunil Kumar K R Signed-off-by: Jongmin Choi Reviewed-on: https://gerrit.iotivity.org/gerrit/10191 Tested-by: jenkins-iotivity Reviewed-by: dongik Lee Reviewed-by: Jee Hyeok Kim --- .../cloud/accountserver/AccountServer.java | 3 + .../iotivity/cloud/accountserver/Constants.java | 38 +++ .../iotivity/cloud/accountserver/db/AclTable.java | 88 +++++++ .../iotivity/cloud/accountserver/db/MongoDB.java | 19 +- .../cloud/accountserver/resources/acl/id/Ace.java | 104 +++++++++ .../resources/acl/id/AceResource.java | 71 ++++++ .../cloud/accountserver/resources/acl/id/Acl.java | 255 +++++++++++++++++++++ .../accountserver/resources/acl/id/AclManager.java | 107 +++++++++ .../resources/acl/id/AclResource.java | 169 ++++++++++++++ .../resources/acl/verify/AclVerifyResource.java | 149 ++++++++++++ .../resources/acl/verify/Permission.java | 19 ++ 11 files changed, 1019 insertions(+), 3 deletions(-) mode change 100755 => 100644 cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java mode change 100755 => 100644 cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java create mode 100644 cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AclTable.java create mode 100644 cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Ace.java create mode 100644 cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AceResource.java create mode 100644 cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Acl.java create mode 100644 cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclManager.java create mode 100644 cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclResource.java create mode 100644 cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/AclVerifyResource.java create mode 100644 cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/Permission.java diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java old mode 100755 new mode 100644 index a474686..1168093 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java @@ -28,6 +28,7 @@ import org.iotivity.cloud.accountserver.resources.account.AccountResource; import org.iotivity.cloud.accountserver.resources.account.session.SessionResource; import org.iotivity.cloud.accountserver.resources.account.tokenrefresh.TokenRefreshResource; import org.iotivity.cloud.accountserver.resources.acl.group.GroupResource; +import org.iotivity.cloud.accountserver.resources.acl.id.AclResource; import org.iotivity.cloud.accountserver.resources.acl.invite.InviteResource; import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateResource; import org.iotivity.cloud.accountserver.resources.credprov.crl.CrlResource; @@ -66,6 +67,8 @@ public class AccountServer { serverSystem.addResource(new CrlResource()); + serverSystem.addResource(new AclResource()); + serverSystem.addResource(new InviteResource()); serverSystem.addServer(new CoapServer( diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java old mode 100755 new mode 100644 index 84d4caa..092de7e --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java @@ -74,6 +74,8 @@ public class Constants extends OICConstants { public static final String KEYFIELD_ACLID = "aclid"; + public static final String KEYFIELD_DI = "di"; + public static final String KEYFIELD_GTYPE = "gtype"; public static final String KEYFIELD_GIDLIST = "gidlist"; @@ -94,6 +96,22 @@ public class Constants extends OICConstants { public static final String KEYFIELD_INVITED_USER = "invitedUser"; + public static final String KEYFIELD_ACE_SUBJECT_ID = "subjectuuid"; + + public static final String KEYFIELD_ACE_SUBJECT_TYPE = "stype"; + + public static final String KEYFIELD_ACE_RESOURCE= "resources"; + + public static final String KEYFIELD_ACE_VALIDITY = "validity"; + + public static final String KEYFIELD_ACE_PERMISSION = "permission"; + + public static final String KEYFIELD_ACE_RESOURCE_HREF = "href"; + + public static final String KEYFIELD_ACE_RESOURCE_RT = "rt"; + + public static final String KEYFIELD_ACE_RESOURCE_IF = "if"; + // Request payload key public static final String REQ_DEVICE_ID = "di"; @@ -102,6 +120,16 @@ public class Constants extends OICConstants { public static final String REQ_UUID_ID = "uid"; + public static final String REQ_ACE_ID = "aceid"; + + public static final String REQ_ACL_ID = "aclid"; + + public static final String REQ_ROWNER_ID = "rowneruuid"; + + public static final String REQ_ACL_LIST = "aclist"; + + public static final String REQ_OWNER_ID = "oid"; + public static final String REQ_AUTH_CODE = "authcode"; public static final String REQ_AUTH_PROVIDER = "authprovider"; @@ -116,6 +144,12 @@ public class Constants extends OICConstants { public static final String REQ_AUTH_OPTIONS = "options"; + public static final String REQ_REQUEST_METHOD = "rm"; + + public static final String REQ_REQUEST_URI = "uri"; + + public static final String REQ_SEARCH_USER_ID = "sid"; + public static final String REQ_SEARCH_CRITERIA = "search"; public static final String REQ_GROUP_ID = "gid"; @@ -188,6 +222,10 @@ public class Constants extends OICConstants { public static final String CERT_CHAIN = "certchain"; + public static final String RESP_ACL_ALLOWED = "Allowed"; + + public static final String RESP_ACL_DENIED = "Denied"; + // static token type public static final String TOKEN_TYPE_BEARER = "bearer"; diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AclTable.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AclTable.java new file mode 100644 index 0000000..fe9bc66 --- /dev/null +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AclTable.java @@ -0,0 +1,88 @@ +/* + * //****************************************************************** + * // + * // Copyright 2016 Samsung Electronics All Rights Reserved. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // Licensed under the Apache License, Version 2.0 (the "License"); + * // you may not use this file except in compliance with the License. + * // You may obtain a copy of the License at + * // + * // http://www.apache.org/licenses/LICENSE-2.0 + * // + * // Unless required by applicable law or agreed to in writing, software + * // distributed under the License is distributed on an "AS IS" BASIS, + * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * // See the License for the specific language governing permissions and + * // limitations under the License. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ +package org.iotivity.cloud.accountserver.db; + +import java.util.List; + +import org.iotivity.cloud.accountserver.resources.acl.id.Ace; + +public class AclTable { + + private String aclid; + private String oid; + private String di; + private String rowneruuid; + private List aclist; + + public AclTable(String aclid, String oid, String di, String rowneruuid, + List aclist) { + this.aclid = aclid; + this.oid = oid; + this.di = di; + this.rowneruuid = rowneruuid; + this.aclist = aclist; + } + + public AclTable() { + } + + public String getAclid() { + return aclid; + } + + public void setAclid(String aclid) { + this.aclid = aclid; + } + + public String getOid() { + return oid; + } + + public void setOid(String oid) { + this.oid = oid; + } + + public String getDi() { + return di; + } + + public void setDi(String di) { + this.di = di; + } + + public String getRowneruuid() { + return rowneruuid; + } + + public void setRowneruuid(String rowneruuid) { + this.rowneruuid = rowneruuid; + } + + public List getAclist() { + return aclist; + } + + public void setAclist(List aclist) { + this.aclist = aclist; + } + +} diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java index a6bb542..6be3be4 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java @@ -21,6 +21,7 @@ */ package org.iotivity.cloud.accountserver.db; +import java.util.List; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -252,15 +253,27 @@ public class MongoDB { while (entryIter.hasNext()) { - Map.Entry entry = (Map.Entry) entryIter - .next(); + Map.Entry entry = (Map.Entry) entryIter.next(); String entryKey = entry.getKey(); // remove a mongoDB index if (entry.getValue() != null && !entryKey.equals("_id")) { - resourceMap.put(entry.getKey(), entry.getValue()); + // if value is Array + if (entry.getValue() instanceof List && !((List) entry.getValue()).isEmpty() + && ((List) entry.getValue()).get(0) instanceof Document) + + { + List> list = new ArrayList>(); + + for (Document document : (List) entry.getValue()) { + list.add(convertDocumentToHashMap(document)); + } + resourceMap.put(entry.getKey(), list); + } else { + resourceMap.put(entry.getKey(), entry.getValue()); + } } } diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Ace.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Ace.java new file mode 100644 index 0000000..d54ed0c --- /dev/null +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Ace.java @@ -0,0 +1,104 @@ +/* + * //****************************************************************** + * // + * // Copyright 2016 Samsung Electronics All Rights Reserved. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // Licensed under the Apache License, Version 2.0 (the "License"); + * // you may not use this file except in compliance with the License. + * // You may obtain a copy of the License at + * // + * // http://www.apache.org/licenses/LICENSE-2.0 + * // + * // Unless required by applicable law or agreed to in writing, software + * // distributed under the License is distributed on an "AS IS" BASIS, + * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * // See the License for the specific language governing permissions and + * // limitations under the License. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ +package org.iotivity.cloud.accountserver.resources.acl.id; + +import java.util.List; + +/** + * + * This class holds Ace of Acl. + * + */ + +public class Ace { + + String aceid; + String subjectuuid; + int stype; + int permission; + List resources; + List validity; + + public Ace() { + + } + + public Ace(String aceid, String subjectuuid, int stype, int permission, + List resources, List validity) { + + this.aceid = aceid; + this.subjectuuid = subjectuuid; + this.stype = stype; + this.permission = permission; + this.resources = resources; + this.validity = validity; + } + + public String getAceid() { + return aceid; + } + + public void setAceid(String aceid) { + this.aceid = aceid; + } + + public String getSubjectuuid() { + return subjectuuid; + } + + public void setSubjectuuid(String subjectuuid) { + this.subjectuuid = subjectuuid; + } + + public int getStype() { + return stype; + } + + public void setStype(int stype) { + this.stype = stype; + } + + public int getPermission() { + return permission; + } + + public void setPermission(int permission) { + this.permission = permission; + } + + public List getResources() { + return resources; + } + + public void setResources(List resources) { + this.resources = resources; + } + + public List getValidity() { + return validity; + } + + public void setValidity(List validity) { + this.validity = validity; + } + +} diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AceResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AceResource.java new file mode 100644 index 0000000..fb36c35 --- /dev/null +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AceResource.java @@ -0,0 +1,71 @@ +/* + * //****************************************************************** + * // + * // Copyright 2016 Samsung Electronics All Rights Reserved. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // Licensed under the Apache License, Version 2.0 (the "License"); + * // you may not use this file except in compliance with the License. + * // You may obtain a copy of the License at + * // + * // http://www.apache.org/licenses/LICENSE-2.0 + * // + * // Unless required by applicable law or agreed to in writing, software + * // distributed under the License is distributed on an "AS IS" BASIS, + * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * // See the License for the specific language governing permissions and + * // limitations under the License. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ +package org.iotivity.cloud.accountserver.resources.acl.id; + +import java.util.List; + +/** + * + * This class holds resource of Ace. + * + */ +public class AceResource { + + String href; + List rt; + List oicif; + + public AceResource() { + + } + + public AceResource(String href, List rt, List oicif) { + this.href = href; + this.rt = rt; + this.oicif = oicif; + } + + public String getHref() { + return href; + } + + public void setHref(String href) { + this.href = href; + } + + public List getRt() { + return rt; + } + + public void setRt(List rt) { + this.rt = rt; + } + + public List getOicif() { + return oicif; + } + + public void setOicif(List oicif) { + this.oicif = oicif; + } + +} diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Acl.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Acl.java new file mode 100644 index 0000000..c7c9757 --- /dev/null +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Acl.java @@ -0,0 +1,255 @@ +/* + * //****************************************************************** + * // + * // Copyright 2016 Samsung Electronics All Rights Reserved. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // Licensed under the Apache License, Version 2.0 (the "License"); + * // you may not use this file except in compliance with the License. + * // You may obtain a copy of the License at + * // + * // http://www.apache.org/licenses/LICENSE-2.0 + * // + * // Unless required by applicable law or agreed to in writing, software + * // distributed under the License is distributed on an "AS IS" BASIS, + * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * // See the License for the specific language governing permissions and + * // limitations under the License. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ +package org.iotivity.cloud.accountserver.resources.acl.id; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +import org.iotivity.cloud.accountserver.Constants; +import org.iotivity.cloud.accountserver.db.AccountDBManager; +import org.iotivity.cloud.accountserver.db.AclTable; +import org.iotivity.cloud.accountserver.util.TypeCastingManager; +import org.iotivity.cloud.base.device.Device; +import org.iotivity.cloud.base.exception.ServerException.BadRequestException; +import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException; +import org.iotivity.cloud.base.exception.ServerException.UnAuthorizedException; +import org.iotivity.cloud.base.protocols.IRequest; +import org.iotivity.cloud.base.protocols.MessageBuilder; +import org.iotivity.cloud.base.protocols.enums.ContentFormat; +import org.iotivity.cloud.base.protocols.enums.ResponseStatus; +import org.iotivity.cloud.util.Cbor; +import org.iotivity.cloud.util.Log; + +public class Acl { + + private Cbor> mCbor = new Cbor<>(); + private String mAclid = null; + private String mOid = null; + private String mDi = null; + private TypeCastingManager mTypeAcl = new TypeCastingManager<>(); + + public Acl(String aclid) { + mAclid = aclid; + } + + public Acl(String aclid, String oid, String di) { + mAclid = aclid; + mOid = oid; + mDi = di; + } + + private class AclSubscriber { + AclSubscriber(Device subscriber, IRequest request) { + mSubscriber = subscriber; + mRequest = request; + } + + public Device mSubscriber; + public IRequest mRequest; + } + + private HashMap mSubscribers = new HashMap<>(); + + public static String valueOf(Object object) { + return (object == null) ? "" : object.toString(); + } + + @SuppressWarnings("unchecked") + public static AclTable convertMaptoAclObject(HashMap aclMap) { + AclTable aclTable = new AclTable(); + try { + aclTable.setAclid(valueOf(aclMap.get(Constants.KEYFIELD_ACLID))); + aclTable.setDi(valueOf(aclMap.get(Constants.KEYFIELD_DI))); + aclTable.setOid(valueOf(aclMap.get(Constants.REQ_OWNER_ID))); + aclTable.setRowneruuid(valueOf(aclMap.get(Constants.REQ_ROWNER_ID))); + + List aceList = new ArrayList(); + + List> aclist = (List>) aclMap + .get(Constants.REQ_ACL_LIST); + + if (aclist == null) { + return aclTable; + } + + for (HashMap eachAce : aclist) { + + Ace ace = new Ace(); + + ace.setAceid(valueOf(eachAce.get(Constants.REQ_ACE_ID))); + ace.setSubjectuuid(valueOf(eachAce + .get(Constants.KEYFIELD_ACE_SUBJECT_ID))); + ace.setStype(Integer.valueOf(eachAce.get( + Constants.KEYFIELD_ACE_SUBJECT_TYPE).toString())); + ace.setPermission(Integer.valueOf(eachAce.get( + Constants.KEYFIELD_ACE_PERMISSION).toString())); + + Object validity = eachAce.get(Constants.KEYFIELD_ACE_VALIDITY); + if (validity != null) { + ace.setValidity((List) validity); + } + + List resourceLst = new ArrayList(); + List> resourceList = (List>) eachAce + .get(Constants.KEYFIELD_ACE_RESOURCE); + for (HashMap resrouce : resourceList) { + + AceResource aceResource = new AceResource(); + aceResource.setHref(valueOf(resrouce + .get(Constants.KEYFIELD_ACE_RESOURCE_HREF))); + List rtList = (List) resrouce + .get(Constants.KEYFIELD_ACE_RESOURCE_RT); + aceResource.setRt(rtList); + List ifList = (List) resrouce + .get(Constants.KEYFIELD_ACE_RESOURCE_IF); + aceResource.setOicif(ifList); + + resourceLst.add(aceResource); + } + ace.setResources(resourceLst); + + aceList.add(ace); + + } + aclTable.setAclist(aceList); + } catch (Exception e) { + throw new InternalServerErrorException( + "Map to Acl Object casting error " + e.getMessage()); + } + return aclTable; + + } + + @SuppressWarnings("unchecked") + + public void addACE(List> aclist) { + + HashMap hashmap = AccountDBManager.getInstance() + .selectRecord(Constants.ACL_TABLE, getCondition()).get(0); + + List> aclDbList = (List>) hashmap + .get(Constants.REQ_ACL_LIST); + + List> newAcList = new ArrayList>( + aclist); + + if (aclDbList != null) { + newAcList.addAll(aclDbList); + } + hashmap.put(Constants.REQ_ACL_LIST, newAcList); + AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE, + hashmap); + notifyToSubscriber(getResponsePayload(true)); + } + + public void deleteAclist() { + AclTable aclTable = getAclTable(); + aclTable.setAclist(null); + AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE, + mTypeAcl.convertObjectToMap(aclTable)); + notifyToSubscriber(getResponsePayload(true)); + } + + public HashMap getInfo() { + return getResponsePayload(true); + } + + public HashMap addSubscriber(String di, Device subscriber, + IRequest request) { + + verifyAclTableDi(di); + AclSubscriber newSubscriber = new AclSubscriber(subscriber, request); + mSubscribers.put(di, newSubscriber); + return getInfo(); + } + + public HashMap removeSubscriber(String di) { + + HashMap responsePayload = getResponsePayload(true); + if (mSubscribers.containsKey(di)) { + mSubscribers.remove(di); + } + return responsePayload; + } + + private void verifyAclTableDi(String di) { + AclTable aclTable = getAclTable(); + if (aclTable.getDi() == null) { + throw new BadRequestException("di is invalid in Acl"); + } + String mDi = aclTable.getDi(); + if (!mDi.equals(di)) { + throw new UnAuthorizedException( + di + "is not Device ID of this ACL"); + } + } + + private void notifyToSubscriber( + HashMap notifyBytePayloadData) { + synchronized (mSubscribers) { + + Iterator iterator = mSubscribers.keySet().iterator(); + while(iterator.hasNext()) { + String key = iterator.next(); + AclSubscriber aclSubscriber = mSubscribers.get(key); + aclSubscriber.mSubscriber.sendResponse( + MessageBuilder.createResponse(aclSubscriber.mRequest, + ResponseStatus.CONTENT, + ContentFormat.APPLICATION_CBOR, + mCbor.encodingPayloadToCbor( + notifyBytePayloadData))); + } + } + } + + private AclTable getAclTable() { + AclTable getAclTable = new AclTable(); + getAclTable = convertMaptoAclObject( + AccountDBManager.getInstance().selectRecord( + Constants.ACL_TABLE, getCondition()).get(0)); + return getAclTable; + } + + private HashMap getAclTablePayLoad() { + HashMap aclPayload = new HashMap<>(); + aclPayload = AccountDBManager.getInstance() + .selectRecord(Constants.ACL_TABLE, getCondition()).get(0); + return aclPayload; + } + + private HashMap getResponsePayload(boolean isAliveAcl) { + return isAliveAcl ? getAclTablePayLoad() : null; + } + + private HashMap getCondition() { + HashMap condition = new HashMap<>(); + condition.put(Constants.REQ_ACL_ID, mAclid); + return condition; + } + + +} diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclManager.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclManager.java new file mode 100644 index 0000000..9dc9dca --- /dev/null +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclManager.java @@ -0,0 +1,107 @@ +/* + * //****************************************************************** + * // + * // Copyright 2016 Samsung Electronics All Rights Reserved. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // Licensed under the Apache License, Version 2.0 (the "License"); + * // you may not use this file except in compliance with the License. + * // You may obtain a copy of the License at + * // + * // http://www.apache.org/licenses/LICENSE-2.0 + * // + * // Unless required by applicable law or agreed to in writing, software + * // distributed under the License is distributed on an "AS IS" BASIS, + * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * // See the License for the specific language governing permissions and + * // limitations under the License. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ +package org.iotivity.cloud.accountserver.resources.acl.id; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +import org.iotivity.cloud.accountserver.Constants; +import org.iotivity.cloud.accountserver.db.AccountDBManager; +import org.iotivity.cloud.accountserver.db.AclTable; +import org.iotivity.cloud.accountserver.util.TypeCastingManager; + +import org.iotivity.cloud.base.device.Device; +import org.iotivity.cloud.base.exception.ServerException.BadRequestException; +import org.iotivity.cloud.base.protocols.IRequest; + +import org.iotivity.cloud.util.Log; + +public class AclManager { + public HashMap mAcls = new HashMap<>(); + private TypeCastingManager mTypeAcl = new TypeCastingManager(); + + public HashMap createAcl(String oid, String di) { + HashMap responsePayload = new HashMap<>(); + String aclid = null; + aclid = UUID.randomUUID().toString(); + + AclTable newAclTable = new AclTable(aclid, oid, di, null, null); + + AccountDBManager.getInstance().insertRecord(Constants.ACL_TABLE, + mTypeAcl.convertObjectToMap(newAclTable)); + mAcls.put(aclid, new Acl(aclid)); + responsePayload.put(Constants.REQ_ACL_ID, aclid); + return responsePayload; + } + + public Acl getAcl(String aclid) { + return mAcls.get(aclid); + } + + public HashMap getAclid(String di) { + HashMap responsePayload = new HashMap<>(); + ArrayList aclidList = new ArrayList(); + HashMap condition = new HashMap<>(); + condition.put(Constants.KEYFIELD_DI, di); + ArrayList> result = AccountDBManager + .getInstance().selectRecord(Constants.ACL_TABLE, condition); + for (HashMap element : result) { + AclTable getAclTable = new AclTable(); + getAclTable = Acl.convertMaptoAclObject(element); + aclidList.add(getAclTable.getAclid()); + } + responsePayload.put(Constants.KEYFIELD_ACLID, aclidList); + return responsePayload; + } + + public void deleteAcl(String aclid) { + HashMap condition = new HashMap<>(); + condition.put(Constants.REQ_ACL_ID, aclid); + AccountDBManager.getInstance().deleteRecord(Constants.ACL_TABLE, + condition); + mAcls.remove(aclid); + } + + public void addAclACE(String aclid, List> aclist) { + getAcl(aclid).addACE(aclist); + } + + public void deleteAclACE(String aclid) { + getAcl(aclid).deleteAclist(); + } + + public HashMap addAclSubscriber(String aclid, String di, + Device srcDevice, IRequest request) { + return getAcl(aclid).addSubscriber(di, srcDevice, request); + } + + public HashMap removeAclSubscriber(String aclid, String di) { + return getAcl(aclid).removeSubscriber(di); + } + + public HashMap getAclInfo(String aclid) { + return getAcl(aclid).getInfo(); + } + +} diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclResource.java new file mode 100644 index 0000000..5216b0d --- /dev/null +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclResource.java @@ -0,0 +1,169 @@ +package org.iotivity.cloud.accountserver.resources.acl.id; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + + +import org.iotivity.cloud.accountserver.Constants; +import org.iotivity.cloud.base.device.Device; +import org.iotivity.cloud.base.exception.ServerException; +import org.iotivity.cloud.base.exception.ServerException.BadRequestException; +import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException; +import org.iotivity.cloud.base.protocols.IRequest; +import org.iotivity.cloud.base.protocols.IResponse; +import org.iotivity.cloud.base.protocols.MessageBuilder; +import org.iotivity.cloud.base.protocols.enums.ContentFormat; +import org.iotivity.cloud.base.protocols.enums.ResponseStatus; +import org.iotivity.cloud.base.resource.Resource; +import org.iotivity.cloud.util.Cbor; + +public class AclResource extends Resource { + + private Cbor> mCbor = new Cbor<>(); + private static AclManager mAclManager = new AclManager(); + + public AclResource() { + super(Arrays.asList(Constants.PREFIX_OIC, + Constants.ACL_URI, Constants.ID_URI)); + } + + public static AclManager getInstance() { + return mAclManager; + } + + @Override + public void onDefaultRequestReceived(Device srcDevice, IRequest request) + throws ServerException { + + IResponse response = null; + + if (request.getUriPathSegments().size() > getUriPathSegments().size() + + 1) { + throw new BadRequestException("uriPath is invalid"); + } + + switch (request.getMethod()) { + case PUT: + response = handlePutRequest(request); + break; + case POST: + response = handlePostRequest(request); + break; + case GET: + response = handleGetRequest(srcDevice, request); + break; + case DELETE: + response = handleDeleteRequest(request); + break; + default: + throw new BadRequestException( + request.getMethod() + " request type is not support"); + } + + srcDevice.sendResponse(response); + } + + private IResponse handlePutRequest(IRequest request) + throws ServerException { + + if (getUriPathSegments().containsAll(request.getUriPathSegments())) { + String oid = request.getUriQueryMap().get(Constants.REQ_OWNER_ID).get(0); + String di = request.getUriQueryMap().get(Constants.REQ_DEVICE_ID).get(0); + + return MessageBuilder.createResponse(request, + ResponseStatus.CREATED, ContentFormat.APPLICATION_CBOR, + mCbor.encodingPayloadToCbor( + mAclManager.createAcl(oid, di))); + } + + throw new BadRequestException("uriPath is invalid"); + } + + private IResponse handlePostRequest(IRequest request) + throws ServerException { + + HashMap payloadData = mCbor + .parsePayloadFromCbor(request.getPayload(), HashMap.class); + + if (!getUriPathSegments().containsAll(request.getUriPathSegments())) { + String aclid = request.getUriPathSegments().get(getUriPathSegments().size()); + + List> aclist = null; + if (!payloadData.containsKey(Constants.REQ_ACL_LIST)) { + throw new BadRequestException("aclist not included in payload"); + } + aclist = (List>) payloadData + .get(Constants.REQ_ACL_LIST); + mAclManager.addAclACE(aclid, aclist); + return MessageBuilder.createResponse(request, ResponseStatus.CHANGED); + } + + throw new BadRequestException("uriPath is invalid"); + + } + + @SuppressWarnings("unchecked") + + private IResponse handleGetRequest(Device srcDevice, IRequest request) + throws ServerException { + + HashMap responsePayload = null; + String di = null; + + if (getUriPathSegments().containsAll(request.getUriPathSegments())) { + di = request.getUriQueryMap().get(Constants.REQ_DEVICE_ID).get(0); + if (di == null) { + throw new PreconditionFailedException("di is invalid"); + } + responsePayload = mAclManager.getAclid(di); + } else { + String aclid = request.getUriPathSegments().get(getUriPathSegments().size()); + switch(request.getObserve()) { + case NOTHING: + responsePayload = mAclManager.getAclInfo(aclid); + break; + case SUBSCRIBE: + di = request.getUriQueryMap().get(Constants.REQ_DEVICE_ID).get(0); + responsePayload = mAclManager.addAclSubscriber(aclid, di, + srcDevice, request); + break; + case UNSUBSCRIBE: + di = request.getUriQueryMap().get(Constants.REQ_DEVICE_ID).get(0); + responsePayload = mAclManager.removeAclSubscriber(aclid, di); + break; + default: + throw new BadRequestException(request.getObserve() + + " observe type is not supported"); + } + + } + + return MessageBuilder.createResponse(request, ResponseStatus.CONTENT, + ContentFormat.APPLICATION_CBOR, + mCbor.encodingPayloadToCbor(responsePayload)); + + } + + private IResponse handleDeleteRequest(IRequest request) + throws ServerException { + + String aclid = null; + + if (getUriPathSegments().containsAll(request.getUriPathSegments())) { + aclid = request.getUriQueryMap().get(Constants.REQ_ACL_ID) + .get(0); + if (aclid == null) { + throw new PreconditionFailedException( + "aclid is invalid"); + } + mAclManager.deleteAcl(aclid); + } else { + aclid = request.getUriPathSegments().get(getUriPathSegments().size()); + mAclManager.deleteAclACE(aclid); + } + + return MessageBuilder.createResponse(request, ResponseStatus.DELETED); + } + +} diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/AclVerifyResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/AclVerifyResource.java new file mode 100644 index 0000000..3682b7a --- /dev/null +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/AclVerifyResource.java @@ -0,0 +1,149 @@ +package org.iotivity.cloud.accountserver.resources.acl.verify; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import org.iotivity.cloud.accountserver.Constants; +import org.iotivity.cloud.accountserver.db.AccountDBManager; +import org.iotivity.cloud.accountserver.db.AclTable; +import org.iotivity.cloud.accountserver.resources.acl.id.Ace; +import org.iotivity.cloud.accountserver.resources.acl.id.AceResource; +import org.iotivity.cloud.accountserver.resources.acl.id.Acl; +import org.iotivity.cloud.accountserver.util.TypeCastingManager; +import org.iotivity.cloud.base.device.Device; +import org.iotivity.cloud.base.exception.ServerException; +import org.iotivity.cloud.base.exception.ServerException.BadRequestException; +import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException; +import org.iotivity.cloud.base.protocols.IRequest; +import org.iotivity.cloud.base.protocols.IResponse; +import org.iotivity.cloud.base.protocols.MessageBuilder; +import org.iotivity.cloud.base.protocols.enums.ContentFormat; +import org.iotivity.cloud.base.protocols.enums.ResponseStatus; +import org.iotivity.cloud.base.resource.Resource; +import org.iotivity.cloud.util.Cbor; + +public class AclVerifyResource extends Resource { + + private Cbor> mCbor = new Cbor<>(); + + public AclVerifyResource() { + super(Arrays.asList(Constants.PREFIX_OIC, Constants.ACL_URI, + Constants.VERIFY_URI)); + } + + @Override + public void onDefaultRequestReceived(Device srcDevice, IRequest request) + throws ServerException { + + IResponse response = null; + + switch (request.getMethod()) { + case GET: + response = handleGetRequest(request); + break; + default: + throw new BadRequestException(request.getMethod() + + " request type is not supported"); + } + + srcDevice.sendResponse(response); + } + + private boolean checkPermission(int permissionValue, String rme) + throws ServerException { + Permission per = null; + int rm_value = 0; + if (rme.equals("get")) { + per = Permission.Read; + } else if (rme.equals("post")) { + per = Permission.Update; + } else if (rme.equals("delete")) { + per = Permission.Delete; + } + if (per != null) { + rm_value = per.getValue(); + } + // bit and operation + return ((permissionValue & rm_value) == rm_value); + } + + private boolean checkResourceUri(List aceResources, String uri) + throws ServerException { + for (AceResource aceResource : aceResources) { + if (aceResource.getHref().equals(uri)) { + return true; + } + } + return false; + } + + private boolean verifyAcl(String sid, String di, String rm, String uri) + throws ServerException { + + HashMap condition = new HashMap<>(); + condition.put(Constants.KEYFIELD_DI, di); + + // Query AclTable with condition deviceId(di) + ArrayList> aclResult = AccountDBManager + .getInstance().selectRecord(Constants.ACL_TABLE, condition); + + // if aclResult size is zero then (di) does not exist + if (aclResult == null || aclResult.size() == 0) { + return false; + } + + for (HashMap eachAclMap : aclResult) { + + AclTable aclTable = Acl.convertMaptoAclObject(eachAclMap); + if (aclTable.getAclist() == null) { + return false; + } + for (Ace ace : aclTable.getAclist()) { + if (ace.getSubjectuuid().equals(sid)) { + // check permission matches + if (checkPermission(ace.getPermission(), rm.toLowerCase())) { + // check resource uri matches + if (checkResourceUri(ace.getResources(), uri)) { + return true; + } + } + } + } + } + return false; + } + + private IResponse handleGetRequest(IRequest request) throws ServerException { + + String sid = null; + String di = null; + String rm = null; + String uri = null; + + if (getUriPathSegments().containsAll(request.getUriPathSegments())) { + sid = request.getUriQueryMap().get(Constants.REQ_SEARCH_USER_ID) + .get(0); + di = request.getUriQueryMap().get(Constants.REQ_DEVICE_ID).get(0); + rm = request.getUriQueryMap().get(Constants.REQ_REQUEST_METHOD) + .get(0); + uri = request.getUriQueryMap().get(Constants.REQ_REQUEST_URI) + .get(0); + } else { + throw new BadRequestException("uriPath is invalid"); + } + + HashMap responsePayload = new HashMap<>(); + if (verifyAcl(sid, di, rm, uri)) { + responsePayload.put("gp", Constants.RESP_ACL_ALLOWED); + } else { + responsePayload.put("gp", Constants.RESP_ACL_DENIED); + } + + return MessageBuilder.createResponse(request, ResponseStatus.CONTENT, + ContentFormat.APPLICATION_CBOR, + mCbor.encodingPayloadToCbor(responsePayload)); + } + +} diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/Permission.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/Permission.java new file mode 100644 index 0000000..86965c0 --- /dev/null +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/Permission.java @@ -0,0 +1,19 @@ +package org.iotivity.cloud.accountserver.resources.acl.verify; + +import java.util.ArrayList; +import java.util.List; + +public enum Permission { + Create(1), Read(2), Update(4), Delete(8), Notify(16); + + private int value; + + Permission(int val) { + value = val; + } + + public int getValue() { + return value; + } + +} -- 2.7.4