commit c0e443374f0ab4208856a05b6d226dfad93970f0
Author: Jiri Trefil <badjokke@gmail.com>
Date:   Fri Apr 28 20:57:10 2023 +0200

    #10517 dummy end point vytvořen. Repository napojeno a databáze pro uchování configurací vytvořena společně s Petrem Štěpánkem.

diff --git a/db/spade-configurations.sql b/db/spade-configurations.sql
new file mode 100644
index 0000000..b83eb64
--- /dev/null
+++ b/db/spade-configurations.sql
@@ -0,0 +1,184 @@
+use [authspade];
+begin transaction create_enviroment
+if not exists (select * from sysobjects where name='configurations' and xtype='U')
+create table configurations (
+	id int identity(1, 1),
+	configHash nvarchar(255),
+	config nvarchar(max) not null,
+	isDefault char(1) not null,
+	PRIMARY KEY(id)
+);
+
+if not exists (select * from sysobjects where name='users' and xtype='U')
+create table users(
+id int identity(1,1),
+email nvarchar(255) not null,
+name nvarchar(255) not null,
+password varchar(255) not null
+PRIMARY KEY(id)
+);
+
+
+--rozkladova tabulka mapujici uzivatele a k nemu asociovane konfigurace
+if not exists (select * from sysobjects where name='user_configurations' and xtype='U')
+create table user_configurations (
+	userId int not null,
+	configId int not null,
+	foreign key(userId) references users(id),
+	foreign key(configId) references configurations(id),
+	primary key(userId,configId)
+)
+
+insert into configurations (config, isDefault) values (
+	'{
+    "configuration": [
+        {
+            "antiPattern": "TooLongSprint",
+            "thresholds": [
+                {
+                    "thresholdName": "maxIterationLength",
+                    "value": "21"
+                },
+                {
+                    "thresholdName": "maxNumberOfTooLongIterations",
+                    "value": "0"
+                }
+            ]
+        },
+        {
+            "antiPattern": "VaryingSprintLength",
+            "thresholds": [
+                {
+                    "thresholdName": "maxDaysDifference",
+                    "value": "7"
+                },
+                {
+                    "thresholdName": "maxIterationChanged",
+                    "value": "1"
+                }
+            ]
+        },
+        {
+            "antiPattern": "BusinessAsUsual",
+            "thresholds": [
+                {
+                    "thresholdName": "divisionOfIterationsWithRetrospective",
+                    "value": "66.66f"
+                },
+                {
+                    "thresholdName": "searchSubstringsWithRetrospective",
+                    "value": "%retr%||%revi%||%week%scrum%"
+                }
+            ]
+        },
+        {
+            "antiPattern": "SpecifyNothing",
+            "thresholds": [
+                {
+                    "thresholdName": "minNumberOfWikiPagesWithSpecification",
+                    "value": "1"
+                },
+                {
+                    "thresholdName": "minNumberOfActivitiesWithSpecification",
+                    "value": "1"
+                },
+                {
+                    "thresholdName": "minAvgLengthOfActivityDescription",
+                    "value": "150"
+                },
+                {
+                    "thresholdName": "searchSubstringsWithProjectSpecification",
+                    "value": "%dsp%||%specifikace%||%specification%||%vize%proj%||%vize%produ%"
+                }
+            ]
+        },
+        {
+            "antiPattern": "RoadToNowhere",
+            "thresholds": [
+                {
+                    "thresholdName": "minNumberOfWikiPagesWithProjectPlan",
+                    "value": "1"
+                },
+                {
+                    "thresholdName": "minNumberOfActivitiesWithProjectPlan",
+                    "value": "1"
+                },
+                {
+                    "thresholdName": "searchSubstringsWithProjectPlan",
+                    "value": "%pl�n projektu%||%project plan%||%plan project%||%projektov� pl�n%"
+                }
+            ]
+        },
+        {
+            "antiPattern": "LongOrNonExistentFeedbackLoops",
+            "thresholds": [
+                {
+                    "thresholdName": "divisionOfIterationsWithFeedbackLoop",
+                    "value": "50.00f"
+                },
+                {
+                    "thresholdName": "maxGapBetweenFeedbackLoopRate",
+                    "value": "2f"
+                },
+                {
+                    "thresholdName": "searchSubstringsWithFeedbackLoop",
+                    "value": "%sch�z%z�kazn�k%||%p�edveden�%z�kazn�k%||%z�kazn%demo%||%sch�z%zadavat%||%inform%sch�z%||%z�kazn%||%zadavatel%"
+                }
+            ]
+        },
+        {
+            "antiPattern": "NinetyNinetyRule",
+            "thresholds": [
+                {
+                    "thresholdName": "maxDivisionRange",
+                    "value": "1.25f"
+                },
+                {
+                    "thresholdName": "maxBadDivisionLimit",
+                    "value": "2"
+                }
+            ]
+        },
+        {
+            "antiPattern": "UnknownPoster",
+            "thresholds": [
+                {
+                    "thresholdName": "searchSubstringsInvalidNames",
+                    "value": "%unknown%||%anonym%"
+                }
+            ]
+        },
+        {
+            "antiPattern": "BystanderApathy",
+            "thresholds": [
+                {
+                    "thresholdName": "searchSubstringsInvalidContributors",
+                    "value": "%dependabot%"
+                },
+                {
+                    "thresholdName": "maximumPercentageOfTasksWithoutTeamwork",
+                    "value": "30f"
+                }
+            ]
+        },
+        {
+            "antiPattern": "YetAnotherProgrammer",
+            "thresholds": [
+                {
+                    "thresholdName": "maxNumberOfNewContributors",
+                    "value": "5"
+                },
+                {
+                    "thresholdName": "numberOfFirstMonthsWithoutDetection",
+                    "value": "2"
+                }
+            ]
+        }
+    ]
+}',
+	'Y'
+
+
+)
+
+commit
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
new file mode 100644
index 0000000..6053390
--- /dev/null
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/ConfigurationController.java
@@ -0,0 +1,33 @@
+package cz.zcu.fav.kiv.antipatterndetectionapp.v2.controller;
+
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.model.Configuration;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.model.User;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.model.UserConfigKey;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.model.UserConfiguration;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.repository.UserConfigurationRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Author Jiri Trefil
+ * Controller providing API for configuration management
+ */
+@RestController
+@RequestMapping("v2/configuration")
+public class ConfigurationController {
+    @Autowired
+    private UserConfigurationRepository userConfigurationRepository ;
+
+    @GetMapping(value="/test")
+    public String test(){
+        UserConfigKey key = new UserConfigKey(1,1);
+        UserConfiguration tmp = userConfigurationRepository.save(new UserConfiguration(key));
+        return "test";
+    }
+
+
+
+
+}
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/Configuration.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/Configuration.java
new file mode 100644
index 0000000..331fa7d
--- /dev/null
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/Configuration.java
@@ -0,0 +1,41 @@
+package cz.zcu.fav.kiv.antipatterndetectionapp.v2.model;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name="configuration")
+public class Configuration {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private int id;
+    //configuration json file
+    private String config;
+    //hash of the configuration so users cant upload duplicates
+    private String configHash;
+    // 'Y' if the configuration is accessible to everyone, 'N' if its user defined
+    private char isDefault;
+
+    public Configuration(){}
+    public Configuration(String config, String configHash, boolean isDefault){
+        this.config = config;
+        this.configHash = configHash;
+        this.isDefault = isDefault?'Y':'N';
+    }
+
+
+    public int getId() {
+        return id;
+    }
+
+    public String getConfig() {
+        return config;
+    }
+
+    public String getConfigHash() {
+        return configHash;
+    }
+
+    public char getIsDefault() {
+        return isDefault;
+    }
+}
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/User.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/User.java
index 4c483c8..43b2935 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/User.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/User.java
@@ -28,7 +28,7 @@ public class User {
      */
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
+    private int id;
 
     /**
      * Name of the User
@@ -67,7 +67,7 @@ public class User {
      * Getter of id
      * @return id of the user
      */
-    public Long getId() {
+    public int getId() {
         return id;
     }
 
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/UserConfigKey.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/UserConfigKey.java
new file mode 100644
index 0000000..6456b7c
--- /dev/null
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/UserConfigKey.java
@@ -0,0 +1,21 @@
+package cz.zcu.fav.kiv.antipatterndetectionapp.v2.model;
+
+import javax.persistence.Embeddable;
+import java.io.Serializable;
+
+@Embeddable
+public class UserConfigKey implements Serializable {
+
+private int userId;
+private int configId;
+
+public UserConfigKey(int userId,int configId){
+    this.userId = userId;
+    this.configId = configId;
+}
+
+
+    public UserConfigKey() {
+
+    }
+}
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/UserConfiguration.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/UserConfiguration.java
new file mode 100644
index 0000000..63c5f03
--- /dev/null
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/model/UserConfiguration.java
@@ -0,0 +1,30 @@
+package cz.zcu.fav.kiv.antipatterndetectionapp.v2.model;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+/**
+ * @Author Jiri Trefil
+ * Join table between user and configuration
+ * One user can have multiple (or none) configurations associated with him
+ * One configuration can have associated multiple users
+ * there this Many:Many relationship has to be decomposed with this table
+ * Primary key is a Composite key (userId+configId is always a unique pair)
+ */
+@Entity
+@Table(name="user_configurations")
+public class UserConfiguration {
+    @EmbeddedId
+    private UserConfigKey id;
+
+
+    public UserConfiguration(){
+    }
+
+    public UserConfiguration(UserConfigKey id){
+        this.id = id;
+    }
+    public UserConfigKey getUserConfigKey(){
+        return this.id;
+    }
+}
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/repository/UserConfigurationRepository.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/repository/UserConfigurationRepository.java
new file mode 100644
index 0000000..7046863
--- /dev/null
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/repository/UserConfigurationRepository.java
@@ -0,0 +1,8 @@
+package cz.zcu.fav.kiv.antipatterndetectionapp.v2.repository;
+
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.model.UserConfigKey;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.model.UserConfiguration;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UserConfigurationRepository extends JpaRepository<UserConfiguration, UserConfigKey> {
+}
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java
index bc46ca6..03f67ab 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java
@@ -74,7 +74,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                 .and()
                 .csrf().disable()
                 .authorizeRequests()
-                .mvcMatchers("/v2/user/register", "/v2/user/login", "/v2/user/refresh", "/v2/user/logout").permitAll()
+                .mvcMatchers("/v2/user/register", "/v2/user/login", "/v2/user/refresh", "/v2/user/logout","/v2/configuration//test").permitAll()
                 .anyRequest().authenticated()
                 .and()
                 .sessionManagement()
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/UserServiceImpl.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/UserServiceImpl.java
index 7bba75e..8c7b849 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/UserServiceImpl.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/UserServiceImpl.java
@@ -58,7 +58,6 @@ public class UserServiceImpl implements UserService {
             return UserModelStatusCodes.USER_CREATION_FAILED;
         }
 
-        //TODO request to OAuth for token - send user info to the oauth app for token
         //return okay status code, the user was created
         return UserModelStatusCodes.USER_CREATED;
     }
