diff --git a/Lambdas/Lists/List/src/ListAdder.java b/Lambdas/Lists/List/src/ListAdder.java index a65d780..03fd809 100644 --- a/Lambdas/Lists/List/src/ListAdder.java +++ b/Lambdas/Lists/List/src/ListAdder.java @@ -8,7 +8,8 @@ public class ListAdder implements CallHandler { private Connection connection; private String cognitoID; - private final String LIST_CREATE = "INSERT INTO List (name, owner, lastUpdated) VALUES (?, ?, ?)"; + private final String LIST_CREATE = "INSERT INTO List (name, owner, lastUpdated) VALUES (?, ?, ?);"; + private final String LIST_ACCESS_GRANT = "INSERT INTO ListSharee(listID, userID) VALUES(?, ?);"; public ListAdder(Connection connection, String cognitoID) { this.connection = connection; @@ -17,7 +18,9 @@ public class ListAdder implements CallHandler { public Object conductAction(Map bodyMap, HashMap queryString, String cognitoID) throws SQLException { PreparedStatement statement = connection.prepareStatement(LIST_CREATE, Statement.RETURN_GENERATED_KEYS); - statement.setString(1, bodyMap.get("name").toString());//Needs safe checking + + String listName = bodyMap.get("name").toString();//Needs safe checking + statement.setString(1, listName); statement.setString(2, cognitoID); statement.setTimestamp(3, Timestamp.from(Instant.now())); System.out.println(statement); @@ -25,7 +28,13 @@ public class ListAdder implements CallHandler { ResultSet newIDRS = statement.getGeneratedKeys(); newIDRS.first(); Integer newID = newIDRS.getInt(1); + PreparedStatement accessGrant = connection.prepareStatement(LIST_ACCESS_GRANT); + accessGrant.setInt(1, newID); + accessGrant.setString(2, cognitoID); + System.out.println(accessGrant); + accessGrant.executeUpdate(); connection.commit(); + System.out.println(newID); return newID; } } diff --git a/Lambdas/Lists/List/src/ListDELETE.java b/Lambdas/Lists/List/src/ListDELETE.java new file mode 100644 index 0000000..d202b8d --- /dev/null +++ b/Lambdas/Lists/List/src/ListDELETE.java @@ -0,0 +1,12 @@ +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; + +import java.util.Map; + +public class ListDELETE implements RequestHandler, Object> { + + public Object handleRequest(Map inputMap, Context unfilled) { + return BasicHandler.handleRequest(inputMap, unfilled, ListDeleter.class); + } + +} diff --git a/Lambdas/Lists/List/src/ListDeleter.java b/Lambdas/Lists/List/src/ListDeleter.java new file mode 100644 index 0000000..0b71411 --- /dev/null +++ b/Lambdas/Lists/List/src/ListDeleter.java @@ -0,0 +1,50 @@ +import java.security.AccessControlException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +public class ListDeleter implements CallHandler { + private final Connection connection; + private final String cognitoID; + + private final String GET_LISTS = "SELECT * FROM List WHERE (owner = ? AND listID = ?);"; + private final String DELETE_LIST = "DELETE FROM List WHERE listID = ?;"; + private final String DELETE_LIST_ACCESS = "DELETE FROM ListSharee where listID = ?;"; + private final String DELETE_LIST_ENTRIES = "DELETE FROM ListProduct where listID = ?;"; + + public ListDeleter(Connection connection, String cognitoID) { + this.connection = connection; + this.cognitoID = cognitoID; + } + + @Override + public Object conductAction(Map bodyMap, HashMap queryMap, String cognitoID) throws SQLException { + Integer listID = Integer.parseInt(queryMap.get("id")); + PreparedStatement accessCheck = connection.prepareStatement(GET_LISTS); + accessCheck.setString(1, cognitoID); + accessCheck.setInt(2, listID); + System.out.println(accessCheck); + ResultSet userLists = accessCheck.executeQuery(); + + if (!userLists.next()) { + throw new AccessControlException("User does not have access to list"); + } + PreparedStatement cleanAccess = connection.prepareStatement(DELETE_LIST_ACCESS); + cleanAccess.setInt(1, listID); + System.out.println(cleanAccess); + cleanAccess.executeUpdate(); + PreparedStatement deleteEntries = connection.prepareStatement(DELETE_LIST_ENTRIES); + deleteEntries.setInt(1, listID); + System.out.println(deleteEntries); + deleteEntries.executeUpdate(); + PreparedStatement cleanList = connection.prepareStatement(DELETE_LIST); + cleanList.setInt(1, listID); + System.out.println(cleanList); + cleanList.executeUpdate(); + connection.commit(); + return null; + } +} diff --git a/Lambdas/Lists/List/src/ListGetter.java b/Lambdas/Lists/List/src/ListGetter.java index 0ad47f9..c5a9ed1 100644 --- a/Lambdas/Lists/List/src/ListGetter.java +++ b/Lambdas/Lists/List/src/ListGetter.java @@ -11,7 +11,7 @@ public class ListGetter implements CallHandler{ private final String cognitoID; private final String GET_LIST = "SELECT * FROM List WHERE listID = ?;"; - private final String GET_LISTS = "SELECT listID FROM List WHERE owner = ?;"; + private final String GET_LISTS = "SELECT listID FROM ListSharee WHERE userID = ?;"; private final String GET_ENTRIES = "SELECT * FROM ListProduct WHERE listID = ?;"; public ListGetter(Connection connection, String cognitoID) { diff --git a/Lambdas/Lists/ListShare/src/ListSharePOST.java b/Lambdas/Lists/ListShare/src/ListSharePOST.java new file mode 100644 index 0000000..c986edd --- /dev/null +++ b/Lambdas/Lists/ListShare/src/ListSharePOST.java @@ -0,0 +1,11 @@ +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; + +import java.util.Map; + +public class ListSharePOST implements RequestHandler, Object> { + + public Object handleRequest(Map inputMap, Context unfilled) { + return BasicHandler.handleRequest(inputMap, unfilled, ListSharer.class); + } +} diff --git a/Lambdas/Lists/ListShare/src/ListSharer.java b/Lambdas/Lists/ListShare/src/ListSharer.java new file mode 100644 index 0000000..6b15c3b --- /dev/null +++ b/Lambdas/Lists/ListShare/src/ListSharer.java @@ -0,0 +1,68 @@ +import com.amazonaws.services.lambda.AWSLambdaClientBuilder; +import com.amazonaws.services.lambda.model.InvokeRequest; +import com.amazonaws.services.lambda.model.InvokeResult; + +import java.security.AccessControlException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.InputMismatchException; +import java.util.Map; + +public class ListSharer implements CallHandler { + + private Connection connection; + private String cognitoID; + + public ListSharer(Connection connection, String cognitoID) { + this.connection = connection; + this.cognitoID = cognitoID; + } + + final private String CHECK_ACCESS = "SELECT * from ListSharee WHERE listID = ? AND userID = ?;"; + final private String SHARE_LIST = "INSERT INTO ListSharee(listID, userID) VALUES(?, ?);"; + + public Object conductAction(Map bodyMap, HashMap queryString, String cognitoID) throws SQLException { + PreparedStatement checkAccess = connection.prepareStatement(CHECK_ACCESS); + Integer listID = Integer.parseInt(bodyMap.get("listID").toString()); + checkAccess.setInt(1, listID); + checkAccess.setString(2, cognitoID); + ResultSet checkAccessRS = checkAccess.executeQuery(); + if (!checkAccessRS.next()) { + throw new AccessControlException("The requesting user does not have access to the requested list"); + } + InvokeRequest invokeRequest = new InvokeRequest(); + invokeRequest.setFunctionName("UserGET"); + invokeRequest.setPayload("{" + + " \"body\": {" + + " \"emailToCheck\": \"" + bodyMap.get("shareWith").toString() + "\"" + + " }," + + " \"params\": {" + + " \"querystring\": {" + + " }" + + " }," + + " \"context\": {" + + " \"sub\": \"not used\"" + + " }" + + "}"); + InvokeResult invokeResult = AWSLambdaClientBuilder.defaultClient().invoke(invokeRequest); + if (invokeResult.getStatusCode() != 200) { + throw new InputMismatchException("Could not find specified user to share with"); + } + String shareWithSub = new String(invokeResult.getPayload().array()).replace("\"", ""); + checkAccess.setString(2, shareWithSub); + checkAccessRS = checkAccess.executeQuery(); + if (checkAccessRS.next()) { + throw new InputMismatchException("The specified user already has access"); + } + + PreparedStatement shareList = connection.prepareStatement(SHARE_LIST); + shareList.setInt(1, listID); + shareList.setString(2, shareWithSub); + shareList.executeUpdate(); + connection.commit(); + return null; + } +} diff --git a/Lambdas/Lists/User/src/UserDeleter.java b/Lambdas/Lists/User/src/UserDeleter.java index b440d9e..e89776b 100644 --- a/Lambdas/Lists/User/src/UserDeleter.java +++ b/Lambdas/Lists/User/src/UserDeleter.java @@ -19,6 +19,8 @@ public class UserDeleter implements CallHandler { private final String GET_LISTS = "SELECT * FROM List WHERE (owner = ?);"; private final String DELETE_LIST_PRODUCT = "DELETE FROM ListProduct WHERE (listID = ?);"; private final String DELETE_LISTS = "DELETE FROM List WHERE (owner = ?);"; + private final String DELETE_LIST_SHARES = "DELETE FROM ListSharee WHERE (listID = ?);"; + private final String DELETE_LIST_ACCESS = "DELETE FROM ListSharee WHERE (userID = ?);"; public UserDeleter(Connection connection, String cognitoID) { this.connection = connection; @@ -57,13 +59,23 @@ public class UserDeleter implements CallHandler { statement = connection.prepareStatement(DELETE_LIST_PRODUCT); statement.setInt(1, listID); System.out.println(statement); - statement.executeQuery(); + statement.executeUpdate(); + + statement = connection.prepareStatement(DELETE_LIST_SHARES); + statement.setInt(1, listID); + System.out.println(statement); + statement.executeUpdate(); } statement = connection.prepareStatement(DELETE_LISTS); statement.setString(1, cognitoID); System.out.println(statement); - statement.executeQuery(); + statement.executeUpdate(); + statement = connection.prepareStatement(DELETE_LIST_ACCESS); + statement.setString(1, cognitoID); + System.out.println(statement); + statement.executeUpdate(); + connection.commit(); return null; diff --git a/Lambdas/Lists/User/src/UserGET.java b/Lambdas/Lists/User/src/UserGET.java new file mode 100644 index 0000000..d9a7244 --- /dev/null +++ b/Lambdas/Lists/User/src/UserGET.java @@ -0,0 +1,11 @@ +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; + +import java.util.Map; + +public class UserGET implements RequestHandler, Object> { + + public Object handleRequest(Map inputMap, Context unfilled) { + return BasicHandler.handleRequest(inputMap, unfilled, UserGetter.class); + } +} diff --git a/Lambdas/Lists/User/src/UserGetter.java b/Lambdas/Lists/User/src/UserGetter.java new file mode 100644 index 0000000..043a0c2 --- /dev/null +++ b/Lambdas/Lists/User/src/UserGetter.java @@ -0,0 +1,60 @@ +import com.amazonaws.services.cognitoidp.AWSCognitoIdentityProvider; +import com.amazonaws.services.cognitoidp.AWSCognitoIdentityProviderClientBuilder; +import com.amazonaws.services.cognitoidp.model.AttributeType; +import com.amazonaws.services.cognitoidp.model.ListUsersRequest; +import com.amazonaws.services.cognitoidp.model.ListUsersResult; +import com.amazonaws.services.cognitoidp.model.UserType; + +import java.io.IOException; +import java.sql.Connection; +import java.util.*; + +public class UserGetter implements CallHandler { + private String cognitoID; + + public UserGetter(Connection connection, String cognitoID) { + this.cognitoID = cognitoID; + } + @Override + public Object conductAction(Map bodyMap, HashMap queryMap, String cognitoID) { + Properties cognitoProperties; + try { + cognitoProperties = DBConnector.loadProperties("cognitoProperties.json"); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + String userPoolId = cognitoProperties.get("userPoolId").toString(); + System.out.println(userPoolId); + ListUsersRequest checkRequest = new ListUsersRequest().withUserPoolId(userPoolId); + Object emailObject = bodyMap.get("emailToCheck"); + if (emailObject != null) { + checkRequest.setFilter("email=\"" + emailObject.toString() +"\""); + } else { + // checkRequest.setFilter("sub=\"" + cognitoID + "\""); + return cognitoID; + } + System.out.println(checkRequest); + AWSCognitoIdentityProvider awsCognitoIdentityProvider = AWSCognitoIdentityProviderClientBuilder.defaultClient(); + ListUsersResult foundUsersResult = awsCognitoIdentityProvider.listUsers(checkRequest); + List foundUsers = foundUsersResult.getUsers(); + if (foundUsers.size() != 1) { + System.out.println(foundUsers); + if (foundUsers.size() == 0) { + throw new InputMismatchException("Not user with given email"); + } + throw new InputMismatchException("Found more than one user with supposedly unique email"); + } + UserType foundUser = foundUsers.get(0); + System.out.println(foundUser.getAttributes()); + String sub = ""; + for (AttributeType attribute : foundUser.getAttributes()) { + if (attribute.getName().equals("sub")) { + sub = attribute.getValue(); + break; + } + System.out.println(attribute.getName() + ": " + attribute.getValue()); + } + return sub; + } +} diff --git a/Lambdas/Lists/pom.xml b/Lambdas/Lists/pom.xml index c80c2c7..6fbc972 100644 --- a/Lambdas/Lists/pom.xml +++ b/Lambdas/Lists/pom.xml @@ -14,10 +14,15 @@ aws-lambda-java-core 1.2.1 + + com.amazonaws + aws-java-sdk-lambda + 1.11.875 + com.amazonaws aws-lambda-java-events - 3.1.0 + 3.4.0 com.amazonaws @@ -42,7 +47,7 @@ org.apache.httpcomponents httpclient - 4.5.12 + 4.5.13 com.google.code.gson diff --git a/Listify/app/src/main/java/com/example/listify/data/ListShare.java b/Listify/app/src/main/java/com/example/listify/data/ListShare.java new file mode 100644 index 0000000..406f286 --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/data/ListShare.java @@ -0,0 +1,27 @@ +package com.example.listify.data; + +public class ListShare { + Integer listID; + String shareWithEmail; + + public ListShare(Integer listID, String shareWithEmail) { + this.listID = listID; + this.shareWithEmail = shareWithEmail; + } + + public Integer getListID() { + return listID; + } + + public void setListID(Integer listID) { + this.listID = listID; + } + + public String getShareWithEmail() { + return shareWithEmail; + } + + public void setShareWithEmail(String shareWithEmail) { + this.shareWithEmail = shareWithEmail; + } +}