Cloud ACL Management
authorJongmin Choi <jminl.choi@samsung.com>
Tue, 13 Sep 2016 09:20:54 +0000 (18:20 +0900)
committerJee Hyeok Kim <jihyeok13.kim@samsung.com>
Mon, 19 Sep 2016 00:46:15 +0000 (00:46 +0000)
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 <jminl.choi@samsung.com>
Signed-off-by: Sunil Kumar K R <sunil.k14@samsung.com>
Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/10191
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: dongik Lee <dongik.lee@samsung.com>
Reviewed-by: Jee Hyeok Kim <jihyeok13.kim@samsung.com>
cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java [changed mode: 0755->0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java [changed mode: 0755->0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AclTable.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Ace.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AceResource.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Acl.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclManager.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclResource.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/AclVerifyResource.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/Permission.java [new file with mode: 0644]

old mode 100755 (executable)
new mode 100644 (file)
index a474686..1168093
@@ -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(
old mode 100755 (executable)
new mode 100644 (file)
index 84d4caa..092de7e
@@ -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 (file)
index 0000000..fe9bc66
--- /dev/null
@@ -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<Ace> aclist;
+
+    public AclTable(String aclid, String oid, String di, String rowneruuid,
+        List<Ace> 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<Ace> getAclist() {
+        return aclist;
+    }
+
+    public void setAclist(List<Ace> aclist) {
+        this.aclist = aclist;
+    }
+
+}
index a6bb542..6be3be4 100644 (file)
@@ -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<String, Object> entry = (Map.Entry<String, Object>) entryIter
-                    .next();
+            Map.Entry<String, Object> entry = (Map.Entry<String, Object>) 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<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
+
+                    for (Document document : (List<Document>) 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 (file)
index 0000000..d54ed0c
--- /dev/null
@@ -0,0 +1,104 @@
+/*\r
+ * //******************************************************************\r
+ * //\r
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.\r
+ * //\r
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ * //\r
+ * // Licensed under the Apache License, Version 2.0 (the "License");\r
+ * // you may not use this file except in compliance with the License.\r
+ * // You may obtain a copy of the License at\r
+ * //\r
+ * //      http://www.apache.org/licenses/LICENSE-2.0\r
+ * //\r
+ * // Unless required by applicable law or agreed to in writing, software\r
+ * // distributed under the License is distributed on an "AS IS" BASIS,\r
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * // See the License for the specific language governing permissions and\r
+ * // limitations under the License.\r
+ * //\r
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ */\r
+package org.iotivity.cloud.accountserver.resources.acl.id;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ *\r
+ * This class holds Ace of Acl.\r
+ *\r
+ */\r
+\r
+public class Ace {\r
+\r
+    String aceid;\r
+    String subjectuuid;\r
+    int stype;\r
+    int permission;\r
+    List<AceResource> resources;\r
+    List<String> validity;\r
+\r
+    public Ace() {\r
+\r
+    }\r
+\r
+    public Ace(String aceid, String subjectuuid, int stype, int permission,\r
+            List<AceResource> resources, List<String> validity) {\r
+\r
+        this.aceid = aceid;\r
+        this.subjectuuid = subjectuuid;\r
+        this.stype = stype;\r
+        this.permission = permission;\r
+        this.resources = resources;\r
+        this.validity = validity;\r
+    }\r
+\r
+    public String getAceid() {\r
+        return aceid;\r
+    }\r
+\r
+    public void setAceid(String aceid) {\r
+        this.aceid = aceid;\r
+    }\r
+\r
+    public String getSubjectuuid() {\r
+        return subjectuuid;\r
+    }\r
+\r
+    public void setSubjectuuid(String subjectuuid) {\r
+        this.subjectuuid = subjectuuid;\r
+    }\r
+\r
+    public int getStype() {\r
+        return stype;\r
+    }\r
+\r
+    public void setStype(int stype) {\r
+        this.stype = stype;\r
+    }\r
+\r
+    public int getPermission() {\r
+        return permission;\r
+    }\r
+\r
+    public void setPermission(int permission) {\r
+        this.permission = permission;\r
+    }\r
+\r
+    public List<AceResource> getResources() {\r
+        return resources;\r
+    }\r
+\r
+    public void setResources(List<AceResource> resources) {\r
+        this.resources = resources;\r
+    }\r
+\r
+    public List<String> getValidity() {\r
+        return validity;\r
+    }\r
+\r
+    public void setValidity(List<String> validity) {\r
+        this.validity = validity;\r
+    }\r
+\r
+}\r
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 (file)
index 0000000..fb36c35
--- /dev/null
@@ -0,0 +1,71 @@
+/*\r
+ * //******************************************************************\r
+ * //\r
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.\r
+ * //\r
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ * //\r
+ * // Licensed under the Apache License, Version 2.0 (the "License");\r
+ * // you may not use this file except in compliance with the License.\r
+ * // You may obtain a copy of the License at\r
+ * //\r
+ * //      http://www.apache.org/licenses/LICENSE-2.0\r
+ * //\r
+ * // Unless required by applicable law or agreed to in writing, software\r
+ * // distributed under the License is distributed on an "AS IS" BASIS,\r
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * // See the License for the specific language governing permissions and\r
+ * // limitations under the License.\r
+ * //\r
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ */\r
+package org.iotivity.cloud.accountserver.resources.acl.id;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ *\r
+ * This class holds resource of Ace.\r
+ *\r
+ */\r
+public class AceResource {\r
+\r
+    String href;\r
+    List<String> rt;\r
+    List<String> oicif;\r
+\r
+    public AceResource() {\r
+\r
+    }\r
+\r
+    public AceResource(String href, List<String> rt, List<String> oicif) {\r
+        this.href = href;\r
+        this.rt = rt;\r
+        this.oicif = oicif;\r
+    }\r
+\r
+    public String getHref() {\r
+        return href;\r
+    }\r
+\r
+    public void setHref(String href) {\r
+        this.href = href;\r
+    }\r
+\r
+    public List<String> getRt() {\r
+        return rt;\r
+    }\r
+\r
+    public void setRt(List<String> rt) {\r
+        this.rt = rt;\r
+    }\r
+\r
+    public List<String> getOicif() {\r
+        return oicif;\r
+    }\r
+\r
+    public void setOicif(List<String> oicif) {\r
+        this.oicif = oicif;\r
+    }\r
+\r
+}\r
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 (file)
index 0000000..c7c9757
--- /dev/null
@@ -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<HashMap<String, Object>>  mCbor      = new Cbor<>();
+    private String                         mAclid     = null;
+    private String                         mOid       = null;
+    private String                         mDi        = null;
+    private TypeCastingManager<AclTable> 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<String, AclSubscriber> mSubscribers  = new HashMap<>();
+
+    public static String valueOf(Object object) {
+        return (object == null) ? "" : object.toString();
+    }
+
+    @SuppressWarnings("unchecked")
+        public static AclTable convertMaptoAclObject(HashMap<String, Object> 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<Ace> aceList = new ArrayList<Ace>();
+
+                List<HashMap<String, Object>> aclist = (List<HashMap<String, Object>>) aclMap
+                    .get(Constants.REQ_ACL_LIST);
+
+                if (aclist == null) {
+                    return aclTable;
+                }
+
+                for (HashMap<String, Object> 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<String>) validity);
+                    }
+
+                    List<AceResource> resourceLst = new ArrayList<AceResource>();
+                    List<HashMap<String, Object>> resourceList = (List<HashMap<String, Object>>) eachAce
+                        .get(Constants.KEYFIELD_ACE_RESOURCE);
+                    for (HashMap<String, Object> resrouce : resourceList) {
+
+                        AceResource aceResource = new AceResource();
+                        aceResource.setHref(valueOf(resrouce
+                                    .get(Constants.KEYFIELD_ACE_RESOURCE_HREF)));
+                        List<String> rtList = (List<String>) resrouce
+                            .get(Constants.KEYFIELD_ACE_RESOURCE_RT);
+                        aceResource.setRt(rtList);
+                        List<String> ifList = (List<String>) 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<HashMap<String, Object>> aclist) {
+
+        HashMap<String, Object> hashmap = AccountDBManager.getInstance()
+            .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
+
+        List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
+            .get(Constants.REQ_ACL_LIST);
+
+        List<HashMap<String, Object>> newAcList = new ArrayList<HashMap<String, Object>>(
+                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<String, Object> getInfo() {
+        return getResponsePayload(true);
+    }
+
+    public HashMap<String, Object> addSubscriber(String di, Device subscriber,
+            IRequest request) {
+
+        verifyAclTableDi(di);
+        AclSubscriber newSubscriber = new AclSubscriber(subscriber, request);
+        mSubscribers.put(di, newSubscriber);
+        return getInfo();
+    }
+
+    public HashMap<String, Object> removeSubscriber(String di) {
+
+        HashMap<String, Object> 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<String, Object> notifyBytePayloadData) {
+        synchronized (mSubscribers) {
+
+            Iterator<String> 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<String, Object> getAclTablePayLoad() {
+        HashMap<String, Object> aclPayload = new HashMap<>();
+        aclPayload = AccountDBManager.getInstance()
+            .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
+        return aclPayload;
+    }
+
+    private HashMap<String, Object> getResponsePayload(boolean isAliveAcl) {
+        return isAliveAcl ? getAclTablePayLoad() : null;
+    }
+
+    private HashMap<String, Object> getCondition() {
+        HashMap<String, Object> 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 (file)
index 0000000..9dc9dca
--- /dev/null
@@ -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<String, Acl>          mAcls    = new HashMap<>();
+    private TypeCastingManager<AclTable> mTypeAcl = new TypeCastingManager<AclTable>();
+
+    public HashMap<String, Object> createAcl(String oid, String di) {
+        HashMap<String, Object> 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<String, Object> getAclid(String di) {
+        HashMap<String, Object> responsePayload = new HashMap<>();
+        ArrayList<String> aclidList = new ArrayList<String>();
+        HashMap<String, Object> condition = new HashMap<>();
+        condition.put(Constants.KEYFIELD_DI, di);
+        ArrayList<HashMap<String, Object>> result = AccountDBManager
+            .getInstance().selectRecord(Constants.ACL_TABLE, condition);
+        for (HashMap<String, Object> 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<String, Object> 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<HashMap<String, Object>> aclist) {
+        getAcl(aclid).addACE(aclist);
+    }
+
+    public void deleteAclACE(String aclid) {
+        getAcl(aclid).deleteAclist();
+    }
+
+    public HashMap<String, Object> addAclSubscriber(String aclid, String di,
+        Device srcDevice, IRequest request) {
+        return getAcl(aclid).addSubscriber(di, srcDevice, request);
+    }
+
+    public HashMap<String, Object> removeAclSubscriber(String aclid, String di) {
+        return getAcl(aclid).removeSubscriber(di);
+    }
+
+    public HashMap<String, Object> 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 (file)
index 0000000..5216b0d
--- /dev/null
@@ -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<HashMap<String, Object>> 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<String, Object> payloadData = mCbor
+                .parsePayloadFromCbor(request.getPayload(), HashMap.class);
+
+        if (!getUriPathSegments().containsAll(request.getUriPathSegments())) {
+            String aclid = request.getUriPathSegments().get(getUriPathSegments().size());
+
+            List<HashMap<String, Object>> aclist = null;
+            if (!payloadData.containsKey(Constants.REQ_ACL_LIST)) {
+                throw new BadRequestException("aclist not included in payload");
+            }
+                aclist = (List<HashMap<String, Object>>) 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<String, Object> 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 (file)
index 0000000..3682b7a
--- /dev/null
@@ -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<HashMap<String, Object>> 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<AceResource> 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<String, Object> condition = new HashMap<>();
+            condition.put(Constants.KEYFIELD_DI, di);
+
+            // Query AclTable with condition deviceId(di)
+            ArrayList<HashMap<String, Object>> 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<String, Object> 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<String, Object> 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 (file)
index 0000000..86965c0
--- /dev/null
@@ -0,0 +1,19 @@
+package org.iotivity.cloud.accountserver.resources.acl.verify;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+public enum Permission {\r
+    Create(1), Read(2), Update(4), Delete(8), Notify(16);\r
+\r
+    private int value;\r
+\r
+    Permission(int val) {\r
+        value = val;\r
+    }\r
+\r
+    public int getValue() {\r
+        return value;\r
+    }\r
+\r
+}\r