diff options
Diffstat (limited to 'ufund-api/src/main')
11 files changed, 108 insertions, 67 deletions
diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/AuthController.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/AuthController.java index 1a545f6..b0390ae 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/AuthController.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/AuthController.java @@ -20,8 +20,10 @@ public class AuthController {      /**       * Attempts to log in as a user -     * @param params A map/json object in the format {username: string, password: string} -     * @return An api key if the auth was successful, null otherwise +     * +     * @param params A json object in the format {username: string, password: string} +     * @return An api key and status OK if the authentication was successful, +     * Status UNAUTHORIZED if the authentication failed and INTERNAL SERVER ERROR otherwise.       */      @PostMapping("")      public ResponseEntity<String> login(@RequestBody Map<String, String> params) { @@ -30,19 +32,26 @@ public class AuthController {          try {              String key = authService.login(username, password);              return new ResponseEntity<>(key, HttpStatus.OK); -        } catch (IOException ex) { -            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);          } catch (IllegalAccessException e) {              return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); +        } catch (IOException ex) { +            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);          }      }      /** -     * TODO -     * @return +     * Logs out the current user +     * +     * @param key The API sent by the client in the header +     * @return OK if the user was successfully logged out, INTERNAL_SERVER_ERROR otherwise.       */      @DeleteMapping("") -    public ResponseEntity<Object> logout() { -        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); +    public ResponseEntity<Object> logout(@RequestHeader("jelly-api-key") String key) { +        try { +            authService.logout(key); +            return new ResponseEntity<>(HttpStatus.OK); +        } catch (IOException e) { +            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); +        }      }  } 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 6b0bb71..dfcb8a3 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 @@ -40,8 +40,11 @@ public class CupboardController {      /**       * Creates a Need with the provided object       * -     * @param need The need to create -     * @return OK response and the need if it was successful, INTERNAL_SERVER_ERROR otherwise +     * @param params The need to create +     * @return OK response and the need if it was successful, +     *         CONFLICT if another need with the same name exists +     *         UNPROCESSABLE_ENTITY if the need contains bad data +     *         INTERNAL_SERVER_ERROR otherwise       */      @PostMapping("")      public ResponseEntity<Need> createNeed(@RequestBody Map<String, String> params) { @@ -50,10 +53,8 @@ public class CupboardController {          Need.GoalType goalType = GoalType.valueOf(params.get("maxGoal"));          try { -                          Need need = cupboardService.createNeed(name, maxGoal, goalType);              return new ResponseEntity<>(need, HttpStatus.OK); -          } catch (DuplicateKeyException ex) {              return new ResponseEntity<>(HttpStatus.CONFLICT);          } catch (IllegalArgumentException ex) { @@ -113,10 +114,8 @@ public class CupboardController {       *        * @param id The id used to locate the {@link Need need}       *  -     * @return ResponseEntity with {@link Need need} object and HTTP status of OK if -     *         found<br> +     * @return ResponseEntity with {@link Need need} object and HTTP status of OK if found<br>       *         ResponseEntity with HTTP status of NOT_FOUND if not found<br> -     *         ResponseEntity with HTTP status of INTERNAL_SERVER_ERROR otherwise       */      @GetMapping("/{id}")      public ResponseEntity<Need> getNeed(@PathVariable int id) { @@ -129,7 +128,6 @@ public class CupboardController {              } else {                  return new ResponseEntity<>(HttpStatus.NOT_FOUND);              } -          } catch (IOException e) {              LOG.log(Level.SEVERE, e.getLocalizedMessage());              return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); @@ -143,7 +141,6 @@ public class CupboardController {       * @param need The need to update       * @return OK response and the need if it was successful, or INTERNAL_SERVER_ERROR if there was an issue       */ -      @PutMapping("")      public ResponseEntity<Need> updateNeed(@RequestBody Need need) {          try { diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardDAO.java index 6baf3e4..c8285a0 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/CupboardDAO.java @@ -14,8 +14,6 @@ public interface CupboardDAO {       * Retrieves all {@linkplain Need needs}       *        * @return An array of {@link Need need} objects, may be empty -     *  -     * @throws IOException if an issue with underlying storage       */      Need[] getNeeds() throws IOException; @@ -27,8 +25,6 @@ public interface CupboardDAO {       * @return a {@link Need need} object with the matching name       * <br>       * null if no {@link Need need} with a matching name is found -     *  -     * @throws IOException if an issue with underlying storage       */      Need getNeed(int id) throws IOException; 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 84ea693..c4aaca3 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 @@ -11,14 +11,14 @@ import java.util.Map;  import java.util.TreeMap;  @Component -public class CupboardFileDao implements CupboardDAO { +public class CupboardFileDAO implements CupboardDAO {      private final Map<Integer, Need> needs; // cache      private final ObjectMapper objectMapper;      private static int nextId;      private final String filename; -    public CupboardFileDao(@Value("${cupboard.file}") String filename, ObjectMapper objectMapper) throws IOException { +    public CupboardFileDAO(@Value("${cupboard.file}") String filename, ObjectMapper objectMapper) throws IOException {          this.filename = filename;          this.objectMapper = objectMapper;          needs = new TreeMap<>(); diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserAuthDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserAuthDAO.java index 45515b8..355aae4 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserAuthDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserAuthDAO.java @@ -8,16 +8,25 @@ public interface UserAuthDAO {      /**       * Get a user authentication profile +     *       * @param key The auth key       * @return The authentication profile or null if there was none       */ -    UserAuth getUserAuth(String key); +    UserAuth getUserAuth(String key) throws IOException;      /**       * Add a user authentication profile +     *       * @param userAuth The user auth profile to add -     * @return True if it was successful -     * @throws IOException On any file writing error +     * @throws IOException Thrown on any file writing error       */ -    boolean addUserAuth(UserAuth userAuth) throws IOException; +    void addUserAuth(UserAuth userAuth) throws IOException; + +    /** +     * Remove a user authentication profile +     * +     * @param key The key of the user auth profile to remove +     * @throws IOException Thrown on any file writing error +     */ +    void removeUserAuth(String key) throws IOException;  } 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 67918cc..4494939 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 @@ -24,6 +24,11 @@ public class UserAuthFIleDAO implements UserAuthDAO {          load();      } +    /** +     * Loads the data from the file into the map +     * +     * @throws IOException Thrown if there was an issue reading the file +     */      private void load() throws IOException {          userAuthMap.clear(); @@ -34,29 +39,35 @@ public class UserAuthFIleDAO implements UserAuthDAO {          }      } +    /** +     * Saves the data from the map into the json file +     * +     * @throws IOException Thrown on any problem writing the file +     */      private void save() throws IOException {          objectMapper.writeValue(new File(filename), userAuthMap.values());      } -    public UserAuth[] getAuthKeys() { +    @Override +    public UserAuth getUserAuth(String key) {          synchronized (userAuthMap) { -            return userAuthMap.values().toArray(UserAuth[]::new); +            return userAuthMap.get(key);          }      }      @Override -    public UserAuth getUserAuth(String key) { +    public void addUserAuth(UserAuth userAuth) throws IOException {          synchronized (userAuthMap) { -            return userAuthMap.get(key); +            userAuthMap.put(userAuth.getKey(), userAuth);          } +        save();      }      @Override -    public boolean addUserAuth(UserAuth userAuth) throws IOException { +    public void removeUserAuth(String key) throws IOException {          synchronized (userAuthMap) { -            userAuthMap.put(userAuth.getKey(), userAuth); -            save(); -            return true; +            userAuthMap.remove(key);          } +        save();      }  } diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java index dca812b..1ef3032 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java @@ -2,6 +2,7 @@ package com.ufund.api.ufundapi.persistence;  import java.io.File;  import java.io.IOException; +import java.util.HashMap;  import java.util.Map;  import java.util.TreeMap; @@ -21,7 +22,7 @@ public class UserFileDAO implements UserDAO {      public UserFileDAO(@Value("${users.file}") String filename, ObjectMapper objectMapper) throws IOException {          this.filename = filename;          this.objectMapper = objectMapper; -        users = new TreeMap<>(); +        users = new HashMap<>();          load(); // load the users from the file      } @@ -47,25 +48,14 @@ public class UserFileDAO implements UserDAO {       * @throws IOException If there was an IO issue saving the file       */      private boolean save() throws IOException { -        User[] userArray = getUserArray(); - -        objectMapper.writeValue(new File(filename), userArray); +        objectMapper.writeValue(new File(filename), users.values());          return true;      } -    /** -     * Return an array of the needs -     * -     * @return An array of all the needs -     */ -    private User[] getUserArray() { -        return users.values().toArray(User[]::new); -    } -      @Override -    public User[] getUsers() throws IOException { +    public User[] getUsers() {          synchronized (users) { -            return getUserArray(); +            return users.values().toArray(User[]::new);          }      } @@ -75,10 +65,9 @@ public class UserFileDAO implements UserDAO {       * @param username Name of desired user       *        * @return Desired user, null otherwise -     * @throws IOException If there was an IO issue saving the file       */      @Override -    public User getUser(String username) throws IOException { +    public User getUser(String username) {          synchronized (users) {              return users.getOrDefault(username, null);          } 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 2e644ee..ac86ff1 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 @@ -17,17 +17,29 @@ public class AuthService {          this.userService = userService;      } -    public UserAuth getUserAuth(String key) { -        return userAuthDAO.getUserAuth(key); -    } - +    /** +     * Check if the provided key has access to the provided user. +     * +     * @param username The username of the user trying to be accessed. +     * @param key The api key obtained by the client from logging in. +     * @throws IllegalAccessException Thrown if access was denied to the user. +     */      public void authenticate(String username, String key) throws IllegalAccessException { -        var userAuth = getUserAuth(key); +        var userAuth = userAuthDAO.getUserAuth(key);          if (userAuth == null || !userAuth.getUsername().equals(username)) {              throw new IllegalAccessException("Unauthorized");          }      } +    /** +     * Attempt to log in with the provided credentials +     * +     * @param username The username of the user +     * @param password The password of the user +     * @return An API key if the authentication was successful. +     * @throws IllegalAccessException Thrown if the username or password was incorrect +     * @throws IOException If there was an issue saving the authentication +     */      public String login(String username, String password) throws IllegalAccessException, IOException {          var usr = userService.getUser(username);          if (usr == null || !usr.verifyPassword(password)) { @@ -38,4 +50,14 @@ public class AuthService {          return userAuth.getKey();      } +    /** +     * Logs out the current user +     * +     * @param key The API key to of the client +     * @throws IOException Thrown if there was an error saving the authentication +     */ +    public void logout(String key) throws IOException { +        userAuthDAO.removeUserAuth(key); +    } +  } 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 860a2a8..6052e4f 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 @@ -5,17 +5,17 @@ import java.util.Arrays;  import com.ufund.api.ufundapi.model.Need;  import com.ufund.api.ufundapi.persistence.CupboardDAO; +import org.springframework.stereotype.Component; +@Component  public class CupboardService {      private final CupboardDAO cupboardDAO;      public class DuplicateKeyException extends Exception { -          public DuplicateKeyException(String message) {              super(message);          } -      }      public CupboardService(CupboardDAO cupboardDAO) { @@ -57,27 +57,34 @@ public class CupboardService {      }      /** -     * @param id -     * @return -     * @throws IOException +     * Gets a need with the specified ID +     * +     * @param id the ID of the need +     * @return The resulting Need or null if the need was not found       */      public Need getNeed(int id) throws IOException {          return cupboardDAO.getNeed(id);      }      /** -     *  +     * Modify a need +     *       * @param need       * @return -     * @throws IOException +     * @throws IOException Thrown if there was an issue saving the changes       */      public Need updateNeed(Need need) throws IOException {          return cupboardDAO.updateNeed(need);      } +    /** +     * Delete a need from the cupboard +     * +     * @param id the ID of the need +     * @return True if the need was deleted +     * @throws IOException Thrown on any problem removing the need +     */      public boolean deleteNeed(int id) throws IOException {          return cupboardDAO.deleteNeed(id);      } - -      } 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 a545029..6af3897 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 @@ -16,7 +16,7 @@ public class UserService {       *       * @param userDao The Data Access Object       */ -    public UserService(UserDAO userDao, AuthService authService) { +    public UserService(UserDAO userDao) {          this.userDAO = userDao;      } diff --git a/ufund-api/src/main/resources/application.properties b/ufund-api/src/main/resources/application.properties index a866f98..70cb171 100644 --- a/ufund-api/src/main/resources/application.properties +++ b/ufund-api/src/main/resources/application.properties @@ -3,6 +3,7 @@ server.error.include-message=always  cupboard.file=data/cupboard.json  users.file=data/users.json +authKeys.file=data/userAuths.json  spring.jackson.mapper.auto-detect-getters=false  spring.jackson.mapper.auto-detect-setters=false  | 
