commit dec281a6effd04efffb8d8a3a810d44926cecaa4
Author: Hrabikv <hrabikv@students.zcu.cz>
Date:   Thu Oct 26 13:17:04 2023 +0200

    https://kivprogrammers.atlassian.net/browse/TSP2-30 kontrolo validace dat

diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/ConfigurationController.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/ConfigurationController.java
index f7c6595..be53078 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/ConfigurationController.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/ConfigurationController.java
@@ -43,6 +43,21 @@ public class ConfigurationController {
         return new ResponseEntity<>(JSONBuilder.buildJSON(json),HttpStatus.valueOf(returnCode.getStatusCode()));
     }
 
+    /**
+     * Method updates existing configuration
+     * @param userConfiguration wrapper around client request for update - same as for inserting a new configuration
+     * @return ResponseEntity with status code and message informing client about result of the update operation
+     */
+    @PutMapping(value="/update_configuration")
+    public ResponseEntity<String> updateConfiguration(@RequestBody UserConfiguration userConfiguration) {
+        ConfigurationControllerStatusCodes returnCode = configurationService.updateConfiguration(userConfiguration);
+        String message = returnCode.getLabel();
+        Map<String,Object> json = new HashMap<>();
+        json.put("message",message);
+        //ResponseEntity<String> response = configurationService.addConfiguration(userConfiguration);
+        return new ResponseEntity<>(JSONBuilder.buildJSON(json),HttpStatus.valueOf(returnCode.getStatusCode()));
+    }
+
 
     @PostMapping(value="/configuration")
     public ResponseEntity<String> getConfiguration(@RequestBody UserConfiguration userConfiguration) {
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/dials/ConfigurationControllerStatusCodes.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/dials/ConfigurationControllerStatusCodes.java
index 32c6917..64cb5c2 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/dials/ConfigurationControllerStatusCodes.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/dials/ConfigurationControllerStatusCodes.java
@@ -9,6 +9,10 @@ public enum ConfigurationControllerStatusCodes {
     EMPTY_CONFIGURATION_DEFINITION("No configuration definition provided",400),
     EMPTY_CONFIGURATION_NAME("No configuration name provided",400),
 
+    CONFIGURATION_IS_DEFAULT("Default configurations can not be changed", 400),
+
+    USER_DONT_HAVE_RIGHTS_TO_CHANGE_CONFIGURATION("You don't have rights to change configuration", 403 ),
+
     INSERT_FAILED("Failed to save configuration",500),
 
     INSERT_SUCCESSFUL("Configuration saved",200),
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/configuration/ConfigService.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/configuration/ConfigService.java
index 4f3de98..fa9ce9b 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/configuration/ConfigService.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/configuration/ConfigService.java
@@ -12,6 +12,7 @@ public interface ConfigService {
     //upload configuration
     ConfigurationControllerStatusCodes addConfiguration(Configuration cfg);
     ConfigurationControllerStatusCodes addConfiguration(UserConfiguration cfg);
+    ConfigurationControllerStatusCodes updateConfiguration(UserConfiguration cfg);
 
     ConfigurationControllerStatusCodes pairConfigurationWithUser(User user, Configuration configuration);
 
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/configuration/ConfigurationServiceImplementation.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/configuration/ConfigurationServiceImplementation.java
index 23b7bc2..d972461 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/configuration/ConfigurationServiceImplementation.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/configuration/ConfigurationServiceImplementation.java
@@ -60,15 +60,11 @@ public class ConfigurationServiceImplementation implements ConfigService {
         if (configuration == null) {
             return ConfigurationControllerStatusCodes.EMPTY_CONFIGURATION_DEFINITION;
         }
-
-        if (cfg.getConfigurationName() == null || cfg.getConfigurationName().equals("")) {
+        if (isConfigurationNameInvalid(cfg)) {
             return ConfigurationControllerStatusCodes.EMPTY_CONFIGURATION_NAME;
         }
-
-        User user = cfg.getUser();
-        String userName = user.getName();
         //fetch the user from db because user in UserConfiguration does not contain id
-        user = this.userService.getUserByName(userName);
+        User user = this.getUser(cfg.getUser());
 
         //create the hash of the configuration (w/o salting)
         String configHash = Crypto.hashString(configuration.getConfig());
@@ -92,6 +88,75 @@ public class ConfigurationServiceImplementation implements ConfigService {
         return ConfigurationControllerStatusCodes.INSERT_SUCCESSFUL;
     }
 
+    /**
+     * Wrapper around user service for fetching user from database by username
+     * @param user Userdto with username only
+     * @return User from db or null if user does not exist
+     */
+
+    private User getUser(User user) {
+        String userName = user.getName();
+        //fetch the user from db because user in UserConfiguration does not contain id
+        return this.userService.getUserByName(userName);
+    }
+
+    /**
+     * Quick verification if configuration name is empty
+     * @param cfg dto wrapper around user update / insert configuration request
+     * @return true if configuration name is empty or empty string
+     */
+    private boolean isConfigurationNameInvalid(UserConfiguration cfg) {
+        return cfg.getConfigurationName() == null || cfg.getConfigurationName().equals("");
+    }
+
+    /**
+     * Util function for creating hash of configuration definition
+     * @param configuration Configuration instance with configuration definition as string
+     * @return String hash created from configuration definition
+     *         empty string if configuration definition is null
+     */
+    private String createConfigurationHash(Configuration configuration) {
+        if(configuration == null) {return "";}
+        return Crypto.hashString(configuration.getConfig());
+    }
+
+    /**
+     * Method updates existing non default user configuration
+     * the user in request must have the rights to access the configuration, ie entry userId,configId must exist in join table
+     * @param cfg UserConfiguration wrapper around update request
+     * @return enum with http code and message informing about the result of the operation
+     */
+    @Override
+    public ConfigurationControllerStatusCodes updateConfiguration(UserConfiguration cfg) {
+        Configuration configuration = parseUserConfiguration(cfg);
+        //if the request is missing the configuration definition then we kill it
+        if (configuration == null) {
+            return ConfigurationControllerStatusCodes.EMPTY_CONFIGURATION_DEFINITION;
+        }
+
+        if (isConfigurationNameInvalid(cfg)) {
+            return ConfigurationControllerStatusCodes.EMPTY_CONFIGURATION_NAME;
+        }
+        int configurationId = Integer.parseInt(cfg.getConfigurationName());
+        Configuration oldConfiguration = this.getConfiguration(cfg.getUser().getName(), configurationId);
+
+        if (oldConfiguration == null) {
+            return ConfigurationControllerStatusCodes.USER_DONT_HAVE_RIGHTS_TO_CHANGE_CONFIGURATION;
+        }
+
+        if (oldConfiguration.getIsDefault().equals("Y")) {
+            return ConfigurationControllerStatusCodes.CONFIGURATION_IS_DEFAULT;
+        }
+        String updatedConfigHash = this.createConfigurationHash(configuration);
+        int configuration1 = this.configurationRepository.updateHashAndConfigurationDefinition(configurationId,configuration.getConfig(),updatedConfigHash);
+
+        if (configuration1 == 0) {
+            return ConfigurationControllerStatusCodes.INSERT_FAILED;
+        }
+
+        return ConfigurationControllerStatusCodes.UPDATE_SUCCESSFUL;
+    }
+
     /**
      * Parser for user request wrapped around configuration
      * @param cfg UserConfiguration instance - wrapper around user request
@@ -173,6 +238,9 @@ public class ConfigurationServiceImplementation implements ConfigService {
 
     public Configuration getConfiguration(String userName, int id) {
         User user = this.userService.getUserByName(userName);
+        if (user == null) {
+            return null;
+        }
         UserConfigKey key = new UserConfigKey(user.getId(), id);
         Configuration configuration = this.configurationRepository.findConfigurationByUserNameAndID(key);
         return configuration;
