From: Jung Seungho Date: Sun, 9 Oct 2016 23:50:59 +0000 (+0900) Subject: added acl logic, when sign up, device delete and Request/Response relay. X-Git-Tag: 1.3.0~348^2^2~25 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1c02e8ef0ad3623a7260ef51fddb7d190b2a1467;p=platform%2Fupstream%2Fiotivity.git added acl logic, when sign up, device delete and Request/Response relay. - added create acl, when sign up - added remove acl, when device delete - added verify, when Request/Response relay - relocate singleton object(getInstance) to AclManager Patch #10: modified updateAclACE and add getAclACE, getACE Method in related class of Acl Patch #11: reflected on the comments from Glen Patch #14: modify addAclACE in AclManager and addACE in Acl to return generated aceids Patch #15: fixed bug in AclVerifyResource and AccountManager Patch #19: reflected on the comments from Eunok and fixed minor bug Patch #22: fixed merge conflict Signed-off-by: Jung Seungho Change-Id: I0507d2a994b1adf3d78bda4d1608cb7d9ec6c850 Reviewed-on: https://gerrit.iotivity.org/gerrit/13577 Tested-by: jenkins-iotivity Reviewed-by: Minji Park Reviewed-by: Jee Hyeok Kim --- 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 index 67fac58..9aca057 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java @@ -72,6 +72,10 @@ public class Constants extends OICConstants { public static final String KEYFIELD_DID = "did"; + public static final String KEYFIELD_UID = "uid"; + + public static final String KEYFIELD_OID = "oid"; + public static final String KEYFIELD_ACLID = "aclid"; public static final String KEYFIELD_DI = "di"; diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountManager.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountManager.java index de2d2be..3bd66c2 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountManager.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountManager.java @@ -40,6 +40,7 @@ import org.iotivity.cloud.accountserver.db.TokenTable; import org.iotivity.cloud.accountserver.db.UserTable; import org.iotivity.cloud.accountserver.oauth.OAuthProviderFactory; import org.iotivity.cloud.accountserver.resources.acl.group.GroupManager; +import org.iotivity.cloud.accountserver.resources.acl.id.AclResource; import org.iotivity.cloud.accountserver.util.TypeCastingManager; import org.iotivity.cloud.base.exception.ServerException.BadRequestException; import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException; @@ -106,7 +107,9 @@ public class AccountManager { // store token information and user information to the DB // private group creation and store group information to the DB - storeUserTokenInfo(userUuid, userInfo, tokenInfo, did); + userUuid = storeUserTokenInfo(userUuid, userInfo, tokenInfo, did); + + AclResource.getInstance().createAcl(userUuid, did); // make response HashMap response = makeSignUpResponse(tokenInfo); @@ -214,7 +217,7 @@ public class AccountManager { return response; } - private void storeUserTokenInfo(String userUuid, UserTable userInfo, + private String storeUserTokenInfo(String userUuid, UserTable userInfo, TokenTable tokenInfo, String did) { // store db // the user table is created @@ -232,6 +235,7 @@ public class AccountManager { tokenInfo.setUuid(userUuid); AccountDBManager.getInstance().insertAndReplaceRecord( Constants.TOKEN_TABLE, castTokenTableToMap(tokenInfo)); + return userUuid; } private String checkAuthProviderName(String authProvider) { @@ -570,6 +574,19 @@ public class AccountManager { GroupManager.getInstance().removeGroupDeviceinEveryGroup(uid, di); // TODO remove device record from the ACL table + HashMap getAcl = new HashMap<>(); + + getAcl = AclResource.getInstance().getAclid(di); + if (getAcl == null || getAcl.containsKey(Constants.KEYFIELD_ACLID)) { + throw new BadRequestException("getAcl is invalid"); + } + + if (getAcl.get(Constants.KEYFIELD_ACLID) == null) { + throw new BadRequestException("getAcl is null"); + } + + AclResource.getInstance() + .deleteAcl((String) getAcl.get(Constants.KEYFIELD_ACLID)); } } diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountResource.java index 6917690..30b0a48 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountResource.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountResource.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.List; import org.iotivity.cloud.accountserver.Constants; +import org.iotivity.cloud.accountserver.resources.acl.id.AclManager; import org.iotivity.cloud.base.device.Device; import org.iotivity.cloud.base.exception.ServerException; import org.iotivity.cloud.base.exception.ServerException.BadRequestException; diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/Constants.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/Constants.java index 8ca99b5..8466203 100644 --- a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/Constants.java +++ b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/Constants.java @@ -47,6 +47,13 @@ public class Constants extends OICConstants { public static final String REQ_INVITE = "invite"; public static final String REQ_PING_ARRAY = "inarray"; public static final String REQ_PING = "in"; + public static final String REQ_SEARCH_USER_ID = "sid"; + public static final String REQ_REQUEST_METHOD = "rm"; + public static final String REQ_REQUEST_URI = "uri"; + + public static final String RESP_GRANT_POLICY = "gp"; + public static final String RESP_ACL_ALLOWED = "Allowed"; + public static final String RESP_ACL_DENIED = "Denied"; public static final String REQ_LINKS = "links"; public static final String REQ_HREF = "href"; diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/DiResource.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/DiResource.java index cc029c4..efb81f5 100644 --- a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/DiResource.java +++ b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/DiResource.java @@ -26,6 +26,8 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; +import org.iotivity.cloud.base.OICConstants; +import org.iotivity.cloud.base.connector.ConnectorPool; import org.iotivity.cloud.base.device.CoapDevice; import org.iotivity.cloud.base.device.Device; import org.iotivity.cloud.base.device.IRequestChannel; @@ -39,6 +41,7 @@ import org.iotivity.cloud.base.protocols.IResponse; import org.iotivity.cloud.base.protocols.MessageBuilder; import org.iotivity.cloud.base.protocols.coap.CoapResponse; import org.iotivity.cloud.base.protocols.enums.ContentFormat; +import org.iotivity.cloud.base.protocols.enums.RequestMethod; import org.iotivity.cloud.base.protocols.enums.ResponseStatus; import org.iotivity.cloud.base.resource.Resource; import org.iotivity.cloud.ciserver.Constants; @@ -53,16 +56,14 @@ import org.iotivity.cloud.util.Cbor; */ public class DiResource extends Resource { - private CoapDevicePool mDevicePool = null; + private CoapDevicePool mDevicePool = null; + private IRequestChannel mASServer = null; + private Cbor> mCbor = new Cbor<>(); public DiResource(CoapDevicePool devicePool) { super(Arrays.asList(Constants.REQ_DEVICE_ID)); + mASServer = ConnectorPool.getConnection("account"); mDevicePool = devicePool; - - addQueryHandler( - Arrays.asList(Constants.RS_INTERFACE + "=" - + Constants.LINK_INTERFACE), - this::onLinkInterfaceRequestReceived); } private IRequestChannel getTargetDeviceChannel(IRequest request) @@ -155,31 +156,6 @@ public class DiResource extends Resource { } } - /** - * API for handling optional method for handling packet contains link - * interface. - * - * @param srcDevice - * device information contains response channel - * @param request - * received request to relay - */ - public void onLinkInterfaceRequestReceived(Device srcDevice, - IRequest request) throws ServerException { - IRequestChannel requestChannel = getTargetDeviceChannel(request); - - if (requestChannel == null) { - throw new NotFoundException(); - } - - String deviceId = request.getUriPathSegments().get(1); - - requestChannel.sendRequest( - MessageBuilder.modifyRequest(request, - extractTargetUriPath(request), null, null, null), - new LinkInterfaceHandler(deviceId, srcDevice)); - } - class DefaultResponseHandler implements IResponseEventHandler { private String mTargetDI = null; private Device mSrcDevice = null; @@ -196,22 +172,96 @@ public class DiResource extends Resource { } } - @Override - public void onDefaultRequestReceived(Device srcDevice, IRequest request) - throws ServerException { - // Find proper request channel using di in URI path field. - IRequestChannel requestChannel = getTargetDeviceChannel(request); + class AccountReceiveHandler implements IResponseEventHandler { + private IRequest mRequest = null; + private Device mSrcDevice = null; - if (requestChannel == null) { - throw new NotFoundException(); + public AccountReceiveHandler(Device srcDevice, IRequest request) { + mRequest = request; + mSrcDevice = srcDevice; } - String deviceId = request.getUriPathSegments().get(1); + @Override + public void onResponseReceived(IResponse response) { + switch (response.getStatus()) { + case CONTENT: + HashMap payloadData = mCbor + .parsePayloadFromCbor(response.getPayload(), + HashMap.class); + checkPayloadException(Constants.RESP_GRANT_POLICY, + payloadData); + String gp = (String) payloadData + .get(Constants.RESP_GRANT_POLICY); + verifyRequest(mSrcDevice, mRequest, gp); + break; + default: + mSrcDevice.sendResponse(MessageBuilder.createResponse( + mRequest, ResponseStatus.BAD_REQUEST)); + } + + } + } + + private void verifyRequest(Device srcDevice, IRequest request, + String grantPermisson) { + switch (grantPermisson) { + case Constants.RESP_ACL_ALLOWED: + IRequestChannel requestChannel = getTargetDeviceChannel( + request); + + if (requestChannel == null) { + throw new NotFoundException(); + } + + String deviceId = request.getUriPathSegments().get(1); + + IResponseEventHandler responseHandler = null; + if (request.getUriQuery() != null && checkQueryException( + Constants.RS_INTERFACE, request.getUriQueryMap())) { + boolean hasLinkInterface = request.getUriQuery() + .contains(Constants.LINK_INTERFACE); + if (hasLinkInterface) { + responseHandler = new LinkInterfaceHandler(deviceId, + srcDevice); + } + } else { + responseHandler = new DefaultResponseHandler(deviceId, + srcDevice); + } - requestChannel.sendRequest( - MessageBuilder.modifyRequest(request, - extractTargetUriPath(request), null, null, null), - new DefaultResponseHandler(deviceId, srcDevice)); + String uriPath = extractTargetUriPath(request); + IRequest requestToResource = MessageBuilder + .modifyRequest(request, uriPath, null, null, null); + requestChannel.sendRequest(requestToResource, responseHandler); + break; + case Constants.RESP_ACL_DENIED: + srcDevice.sendResponse(MessageBuilder.createResponse(request, + ResponseStatus.UNAUTHORIZED)); + break; + default: + srcDevice.sendResponse(MessageBuilder.createResponse(request, + ResponseStatus.BAD_REQUEST)); + } } + @Override + public void onDefaultRequestReceived(Device srcDevice, IRequest request) + throws ServerException { + // verify Permission + StringBuffer uriQuery = new StringBuffer(); + uriQuery.append(Constants.REQ_SEARCH_USER_ID + "=" + + srcDevice.getUserId() + ";"); + uriQuery.append(Constants.REQ_DEVICE_ID + "=" + + request.getUriPathSegments().get(1) + ";"); + uriQuery.append( + Constants.REQ_REQUEST_METHOD + "=" + request.getMethod() + ";"); + uriQuery.append(Constants.REQ_REQUEST_URI + "=" + + extractTargetUriPath(request)); + + IRequest verifyRequest = MessageBuilder.createRequest(RequestMethod.GET, + OICConstants.ACL_VERIFY_FULL_URI, uriQuery.toString()); + + mASServer.sendRequest(verifyRequest, + new AccountReceiveHandler(srcDevice, request)); + } } \ No newline at end of file diff --git a/cloud/interface/src/test/java/org/iotivity/cloud/ciserver/resources/DiResourceTest.java b/cloud/interface/src/test/java/org/iotivity/cloud/ciserver/resources/DiResourceTest.java index da98817..cb495a3 100644 --- a/cloud/interface/src/test/java/org/iotivity/cloud/ciserver/resources/DiResourceTest.java +++ b/cloud/interface/src/test/java/org/iotivity/cloud/ciserver/resources/DiResourceTest.java @@ -44,6 +44,7 @@ import org.iotivity.cloud.base.protocols.enums.ResponseStatus; import org.iotivity.cloud.ciserver.Constants; import org.iotivity.cloud.ciserver.DeviceServerSystem; import org.iotivity.cloud.ciserver.DeviceServerSystem.CoapDevicePool; +import org.iotivity.cloud.ciserver.resources.DiResource.AccountReceiveHandler; import org.iotivity.cloud.ciserver.resources.DiResource.DefaultResponseHandler; import org.iotivity.cloud.ciserver.resources.DiResource.LinkInterfaceHandler; import org.iotivity.cloud.util.Cbor; @@ -57,22 +58,26 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; public class DiResourceTest { - private static final String RELAY_URI = "/di"; - private static final String RESOURCE_URI = "/a/light/0"; - private String mDiServer = "resourceServerId"; - private CoapDevice mSourceDevice = mock( + private static final String RELAY_URI = "/di"; + private static final String RESOURCE_URI = "/a/light/0"; + private static final String VERIFY_URI = "/oic/acl/verify"; + private String mDiServer = "resourceServerId"; + private CoapDevice mSourceDevice = mock( CoapDevice.class); - private CoapDevice mTargetDevice = mock( + private CoapDevice mTargetDevice = mock( CoapDevice.class); - private IResponse mRes = null; - private IRequest mReq = null; - private DeviceServerSystem mDeviceServerSystem = new DeviceServerSystem(); - private final CountDownLatch mLatch = new CountDownLatch( + private IResponse mRes = null; + private IRequest mReq = null; + private DeviceServerSystem mDeviceServerSystem = new DeviceServerSystem(); + private final CountDownLatch mLatch = new CountDownLatch( 1); - private Cbor> mCbor = new Cbor<>(); - private IRequestChannel mTargetChannel = mock( + private Cbor> mCbor = new Cbor<>(); + private IRequestChannel mTargetChannel = mock( IRequestChannel.class); + @Mock(name = "mASServer") + IRequestChannel mRequestChannelASServer; + @Mock CoapDevicePool coapDevicePool; @@ -80,17 +85,28 @@ public class DiResourceTest { IRequestChannel requestChannel; @InjectMocks - DiResource diHandler = new DiResource( + DiResource diHandler = new DiResource( coapDevicePool); @InjectMocks - LinkInterfaceHandler linkInterfaceHandler = diHandler.new LinkInterfaceHandler( + LinkInterfaceHandler linkInterfaceHandler = diHandler.new LinkInterfaceHandler( "targetDeviceId", mSourceDevice); @InjectMocks - DefaultResponseHandler defaultResponseHandler = diHandler.new DefaultResponseHandler( + DefaultResponseHandler defaultResponseHandler = diHandler.new DefaultResponseHandler( "targetDeviceId", mSourceDevice); + IRequest requestDefault = makePutRequest(); + IRequest requestLinkInterface = makePutLinkInterfaceRequest(); + + @InjectMocks + AccountReceiveHandler accountDefaultReceiveHandler = diHandler.new AccountReceiveHandler( + mSourceDevice, requestDefault); + + @InjectMocks + AccountReceiveHandler accountLinkInterfaceReceiveHandler = diHandler.new AccountReceiveHandler( + mSourceDevice, requestLinkInterface); + @Before public void setUp() throws Exception { mRes = null; @@ -134,39 +150,72 @@ public class DiResourceTest { } }).when(mTargetChannel).sendRequest(Mockito.any(IRequest.class), Mockito.any(CoapDevice.class)); + Mockito.doAnswer(new Answer() { + @Override + public CoapRequest answer(InvocationOnMock invocation) + throws Throwable { + Object[] args = invocation.getArguments(); + CoapRequest request = (CoapRequest) args[0]; + System.out.println( + "\t----------payload : " + request.getPayloadString()); + System.out.println( + "\t----------uripath : " + request.getUriPath()); + System.out.println( + "\t---------uriquery : " + request.getUriQuery()); + mReq = request; + mLatch.countDown(); + return null; + } + }).when(mRequestChannelASServer).sendRequest( + Mockito.any(IRequest.class), Mockito.any(CoapDevice.class)); } @Test public void testOnDefaultRequestReceived() throws InterruptedException { IRequest request = makePutRequest(); diHandler.onDefaultRequestReceived(mSourceDevice, request); - assertTrue(mReq.getMethod().equals(RequestMethod.PUT)); - assertTrue(mReq.getUriPath().equals(RESOURCE_URI)); + assertTrue(mReq.getMethod().equals(RequestMethod.GET)); + assertTrue(mReq.getUriPath().equals(VERIFY_URI)); assertTrue(mLatch.await(1L, SECONDS)); } @Test - public void testOnLinkInterfaceRequestReceived() + public void testOnDefaultResponseHandleronResponseReceived() throws InterruptedException { - IRequest request = makePutLinkInterfaceRequest(); - diHandler.onLinkInterfaceRequestReceived(mSourceDevice, request); - assertTrue(mReq.getMethod().equals(RequestMethod.PUT)); - assertTrue(mReq.getUriPath().equals(RESOURCE_URI)); + IResponse response = makeContentResponse(); + defaultResponseHandler.onResponseReceived(response); + assertEquals(mRes, response); assertTrue(mLatch.await(1L, SECONDS)); } @Test - public void testOnDefaultResponseHandleronResponseReceived() + public void testOnAccountReceiveHandlerDeniedonResponseReceived() throws InterruptedException { - IResponse response = makeContentResponse(); - defaultResponseHandler.onResponseReceived(response); - assertEquals(mRes, response); + IResponse response = makeVerifyDeniedContentResponse(); + accountDefaultReceiveHandler.onResponseReceived(response); + } + + @Test + public void testOnAccountReceiveHandlerDefaultonResponseReceived() + throws InterruptedException { + IResponse response = makeVerifyAllowedContentResponse(); + accountDefaultReceiveHandler.onResponseReceived(response); + assertEquals(mReq, requestDefault); assertTrue(mLatch.await(1L, SECONDS)); } @Test public void testOnLinkInterfaceResponseHandleronResponseReceived() throws InterruptedException { + IResponse response = makeVerifyAllowedContentResponse(); + accountLinkInterfaceReceiveHandler.onResponseReceived(response); + assertEquals(mReq, requestLinkInterface); + assertTrue(mLatch.await(1L, SECONDS)); + } + + @Test + public void testOnAccountReceiveHandlerLinkInterfaceonResponseReceived() + throws InterruptedException { IResponse response = makeContentLinkResponse(); linkInterfaceHandler.onResponseReceived(response); assertEquals(mRes, response); @@ -207,6 +256,26 @@ public class DiResourceTest { return response; } + private IResponse makeVerifyAllowedContentResponse() { + + HashMap payloadData = new HashMap<>(); + payloadData.put("gp", "Allowed"); + IResponse response = MessageBuilder.createResponse(makeGetRequest(), + ResponseStatus.CONTENT, ContentFormat.APPLICATION_CBOR, + mCbor.encodingPayloadToCbor(payloadData)); + return response; + } + + private IResponse makeVerifyDeniedContentResponse() { + + HashMap payloadData = new HashMap<>(); + payloadData.put("gp", "Denied"); + IResponse response = MessageBuilder.createResponse(makeGetRequest(), + ResponseStatus.CONTENT, ContentFormat.APPLICATION_CBOR, + mCbor.encodingPayloadToCbor(payloadData)); + return response; + } + private IResponse makeContentLinkResponse() { HashMap payloadData = new HashMap<>(); ArrayList> linkPayload = new ArrayList<>(); diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/OICConstants.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/OICConstants.java index a76151d..22e7eb6 100755 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/OICConstants.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/OICConstants.java @@ -103,6 +103,10 @@ public class OICConstants { + OICConstants.PREFIX_OIC + "/" + OICConstants.ACL_URI + "/" + OICConstants.INVITE_URI; + public static final String ACL_VERIFY_FULL_URI = "/" + + OICConstants.PREFIX_OIC + "/" + OICConstants.ACL_URI + "/" + + OICConstants.VERIFY_URI; + public static final String KEEP_ALIVE_FULL_URI = "/" + PREFIX_OIC + "/" + OICConstants.KEEP_ALIVE_URI;