diff options
Diffstat (limited to 'ufund-api/src/main')
10 files changed, 119 insertions, 30 deletions
diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/CupboardController.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/CupboardController.java index 36ae341..664b53b 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/CupboardController.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/CupboardController.java @@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -162,6 +163,34 @@ public class CupboardController { } /** + * Checks out a need by checkoutAmount + * + * @param data JSON object with paramters needID and amount + * @param key Key used to authenticate user + * @return OK if successful, other statuses if failure + * @throws IllegalAccessException + */ + @PutMapping("/checkout") + public ResponseEntity<Object> checkoutNeeds(@RequestBody Map<String, Integer> data, @RequestHeader("jelly-api-key") String key) throws IllegalAccessException { + int needID = data.get("needID"); + int checkoutAmount = data.get("amount"); + LOG.log(Level.INFO, "Checking out need with ID: " + needID + " by " + checkoutAmount); + try { + cupboardService.checkoutNeed(needID, checkoutAmount, key); + return new ResponseEntity<>(HttpStatus.OK); + } catch (IllegalArgumentException ex) { + ex.printStackTrace(); + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } catch (IOException ex) { + ex.printStackTrace(); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + /** * Deletes a single need from the cupboard using the Need's id * * @param id The need's ID diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java index dfaad3a..b0dbd1d 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java @@ -99,12 +99,13 @@ public class UserController { * @param key The authentication key of the user * @return OK response and the user if it was successful, or * INTERNAL_SERVER_ERROR if there was an issue + * @throws IllegalAccessException */ @PutMapping("/{username}") - public ResponseEntity<User> updateUser(@RequestBody User user, @PathVariable String username, @RequestHeader("jelly-api-key") String key) { - LOG.log(Level.INFO,"PUT: " + user + " " + username + " " + key.toString()); + public ResponseEntity<User> updateUser(@RequestHeader("jelly-api-key") String key, @RequestBody User user, @PathVariable String username) throws IllegalAccessException { + LOG.log(Level.INFO,"PUT: " + user + " " + username + " " + key); try { - //authService.authenticate(username, key); + authService.authenticate(username, key); user = userService.updateUser(user, username); if (user != null) { return new ResponseEntity<>(user, HttpStatus.OK); diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/Need.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/Need.java index c0e9214..22e86e3 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/Need.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/Need.java @@ -17,14 +17,14 @@ public class Need { @JsonProperty("current") private double current; /** - * Create a new need + * Create a new need, used by the controller * * @param name The name of the need * @param id The unique ID of the need * @param maxGoal The maximum goal for this need * @param type The type of need (monetary, physical) */ - public Need(@JsonProperty("name") String name, @JsonProperty("id") int id, @JsonProperty("maxGoal") double maxGoal, GoalType type) { + public Need(@JsonProperty("name") String name, @JsonProperty("id") int id, @JsonProperty("maxGoal") double maxGoal, @JsonProperty("type") GoalType type) { this.id = id; this.name = name; this.maxGoal = maxGoal; @@ -86,6 +86,10 @@ public class Need { this.current = current; } + public void incrementCurrent(double incrementAmount) { + this.current += incrementAmount; + } + public void setFilterAttributes(String[] filterAttributes) { this.filterAttributes = filterAttributes; } diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java index 6de1a8a..2871916 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java @@ -43,10 +43,21 @@ public class User { return username; } + /** + * Verifies if the provided password's hash is the same as the user's actual hash + * + * @param password The password to check if valid + * @return True or false depending on if it's equal + */ public boolean verifyPassword(String password) { return password.hashCode() == passwordHash; } + /** + * Adds a need's ID to a user's basket + * + * @param need The need to add + */ public void addToBasket(Need need) { basket.add(need.getId()); } @@ -59,6 +70,11 @@ public class User { return basket.remove(needID); } + /** + * Returns a user without a password hash for security purposes + * + * @return new User with empty password hash + */ public User withoutPasswordHash() { return new User(this.username, 0, this.basket, this.type); } @@ -71,6 +87,7 @@ public class User { this.passwordHash = other.passwordHash; } + @Override public String toString() { return this.username + "; basket: " + this.basket + "; type:" + this.type + "; hash: " + this.passwordHash; } diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/UserAuth.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/UserAuth.java index 1c11a28..78dccec 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/UserAuth.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/UserAuth.java @@ -1,10 +1,10 @@ package com.ufund.api.ufundapi.model; -import com.fasterxml.jackson.annotation.JsonProperty; - import java.time.LocalDateTime; import java.util.UUID; +import com.fasterxml.jackson.annotation.JsonProperty; + public class UserAuth { @JsonProperty("key") String key; @JsonProperty("username") String username; @@ -12,12 +12,13 @@ public class UserAuth { public UserAuth(@JsonProperty("key") String key, @JsonProperty("username") String username, @JsonProperty("expiration") LocalDateTime expiration) { this.key = key; - this.expiration = expiration; this.username = username; + this.expiration = expiration; } /** * Generate a new user authentication profile + * * @param username the username the key will belong to * @return The new user authentication profile */ diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardFileDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardFileDAO.java index 521acae..4d11554 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardFileDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardFileDAO.java @@ -1,15 +1,16 @@ package com.ufund.api.ufundapi.persistence; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.ufund.api.ufundapi.model.Need; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - import java.io.File; import java.io.IOException; import java.util.Map; import java.util.TreeMap; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ufund.api.ufundapi.model.Need; + @Component public class CupboardFileDAO implements CupboardDAO { diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserAuthFIleDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserAuthFIleDAO.java index 1fc1e92..9023b42 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserAuthFIleDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserAuthFIleDAO.java @@ -1,15 +1,17 @@ package com.ufund.api.ufundapi.persistence; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.ufund.api.ufundapi.model.UserAuth; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - import java.io.File; import java.io.IOException; +import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ufund.api.ufundapi.model.UserAuth; + @Component public class UserAuthFIleDAO implements UserAuthDAO { @@ -35,7 +37,9 @@ public class UserAuthFIleDAO implements UserAuthDAO { UserAuth[] userAuthKeysArray = objectMapper.readValue(new File(filename), UserAuth[].class); for (UserAuth userAuth : userAuthKeysArray) { - userAuthMap.put(userAuth.getKey(), userAuth); + if (userAuth.getExpiration().compareTo(LocalDateTime.now()) > -1) { // Someone else double check the logic is correct. Checks if auth is valid and adds if so + userAuthMap.put(userAuth.getKey(), userAuth); + } } } diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/service/AuthService.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/service/AuthService.java index 87a16a6..71b8f41 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/service/AuthService.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/service/AuthService.java @@ -1,11 +1,12 @@ package com.ufund.api.ufundapi.service; +import java.io.IOException; + +import org.springframework.stereotype.Component; + import com.ufund.api.ufundapi.model.User; import com.ufund.api.ufundapi.model.UserAuth; import com.ufund.api.ufundapi.persistence.UserAuthDAO; -import org.springframework.stereotype.Component; - -import java.io.IOException; @Component public class AuthService { @@ -30,12 +31,19 @@ public class AuthService { if (userAuth == null) { throw new IllegalAccessException("Unauthenticated"); } -// -// var username = userAuth.getUsername(); -// var userType = userService.getUser(username).getType(); -// if (!username.equals(targetUsername) && userType != User.UserType.MANAGER) { -// throw new IllegalAccessException("Unauthorized"); -// } + + var username = userAuth.getUsername(); + var userType = userService.getUser(username).getType(); + if (!username.equals(targetUsername) && userType != User.UserType.MANAGER) { + throw new IllegalAccessException("Unauthorized"); + } + } + + public void authenticate(String key) throws IOException, IllegalAccessException { + var userAuth = userAuthDAO.getUserAuth(key); + if (userAuth == null) { + throw new IllegalAccessException("Unauthenticated"); + } } /** diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/service/CupboardService.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/service/CupboardService.java index 2398745..8713882 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/service/CupboardService.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/service/CupboardService.java @@ -3,6 +3,7 @@ package com.ufund.api.ufundapi.service; import java.io.IOException; import java.util.Arrays; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import com.ufund.api.ufundapi.DuplicateKeyException; @@ -13,8 +14,10 @@ import com.ufund.api.ufundapi.persistence.CupboardDAO; public class CupboardService { private final CupboardDAO cupboardDAO; + final AuthService authService; - public CupboardService(CupboardDAO cupboardDAO) { + public CupboardService(@Lazy AuthService authService, CupboardDAO cupboardDAO) { + this.authService = authService; this.cupboardDAO = cupboardDAO; } @@ -97,6 +100,23 @@ public class CupboardService { } /** + * Checks out a need with the desired amount + * + * @param id The ID of the need to update + * @param checkoutAmount The amount to update the need by + * @throws IOException + * @throws IllegalAccessException + */ + public void checkoutNeed(int id, double checkoutAmount, String key) throws IOException, IllegalAccessException { + if (checkoutAmount <= 0) { + throw new IllegalArgumentException("Amount must be greather than 0"); + } + authService.authenticate(key); + Need need = cupboardDAO.getNeed(id); + need.incrementCurrent(checkoutAmount); + } + + /** * Delete a need from the cupboard * * @param id the ID of the need diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/service/UserService.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/service/UserService.java index caf9f4c..aaa2f06 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/service/UserService.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/service/UserService.java @@ -2,6 +2,7 @@ package com.ufund.api.ufundapi.service; import java.io.IOException; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import com.ufund.api.ufundapi.DuplicateKeyException; @@ -12,7 +13,7 @@ import com.ufund.api.ufundapi.persistence.UserDAO; public class UserService { private final UserDAO userDAO; - private final CupboardService cupboardService; + final CupboardService cupboardService; public UserService(UserDAO userDao, CupboardService cupboardService) { this.userDAO = userDao; @@ -44,6 +45,9 @@ public class UserService { */ public User getUser(String username) throws IOException { User user = userDAO.getUser(username); + if (user == null) { + return null; + } for (int needId : user.getNeeds()) { if (cupboardService.getNeed(needId) == null) { user.removeBasketNeed(needId); |