From 2003b717ed75e9067c371ff2b71b4181fc033f18 Mon Sep 17 00:00:00 2001 From: jan Date: Sat, 11 Jan 2025 20:06:19 +0100 Subject: [PATCH 01/13] TF-2: created repository for user and model --- build.gradle | 4 +++- src/main/java/com/example/tobenamed/model/User.java | 11 +++++++++++ .../example/tobenamed/repository/UserRepository.java | 8 ++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/example/tobenamed/model/User.java create mode 100644 src/main/java/com/example/tobenamed/repository/UserRepository.java diff --git a/build.gradle b/build.gradle index 1b64a67..6deb495 100644 --- a/build.gradle +++ b/build.gradle @@ -18,12 +18,14 @@ repositories { } dependencies { -// implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-groovy-templates' implementation 'org.springframework.boot:spring-boot-starter-web' developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + testImplementation group: 'com.h2database', name: 'h2', version: '1.3.148' + implementation group: 'org.springframework.security', name: 'spring-security-core', version: '6.4.1' } tasks.named('test') { diff --git a/src/main/java/com/example/tobenamed/model/User.java b/src/main/java/com/example/tobenamed/model/User.java new file mode 100644 index 0000000..96744d8 --- /dev/null +++ b/src/main/java/com/example/tobenamed/model/User.java @@ -0,0 +1,11 @@ +package com.example.tobenamed.model; + +import org.springframework.validation.annotation.Validated; + +@Validated +public class User { + private Long id; + private String username; + private String password; + private String email; +} diff --git a/src/main/java/com/example/tobenamed/repository/UserRepository.java b/src/main/java/com/example/tobenamed/repository/UserRepository.java new file mode 100644 index 0000000..014c639 --- /dev/null +++ b/src/main/java/com/example/tobenamed/repository/UserRepository.java @@ -0,0 +1,8 @@ +package com.example.tobenamed.repository; + +import com.example.tobenamed.model.User; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + +} From 9002a450b064f8d3bf16e6b1f92354609d24c020 Mon Sep 17 00:00:00 2001 From: jan Date: Sun, 12 Jan 2025 11:58:57 +0100 Subject: [PATCH 02/13] TF-2: changed project name --- .../example/{tobenamed => taskflow}/ToBeNamedApplication.java | 2 +- .../java/com/example/{tobenamed => taskflow}/model/User.java | 2 +- .../{tobenamed => taskflow}/repository/UserRepository.java | 4 ++-- .../{tobenamed => taskflow}/ToBeNamedApplicationTests.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename src/main/java/com/example/{tobenamed => taskflow}/ToBeNamedApplication.java (90%) rename src/main/java/com/example/{tobenamed => taskflow}/model/User.java (84%) rename src/main/java/com/example/{tobenamed => taskflow}/repository/UserRepository.java (61%) rename src/test/java/com/example/{tobenamed => taskflow}/ToBeNamedApplicationTests.java (86%) diff --git a/src/main/java/com/example/tobenamed/ToBeNamedApplication.java b/src/main/java/com/example/taskflow/ToBeNamedApplication.java similarity index 90% rename from src/main/java/com/example/tobenamed/ToBeNamedApplication.java rename to src/main/java/com/example/taskflow/ToBeNamedApplication.java index 0554d6e..6627c0b 100644 --- a/src/main/java/com/example/tobenamed/ToBeNamedApplication.java +++ b/src/main/java/com/example/taskflow/ToBeNamedApplication.java @@ -1,4 +1,4 @@ -package com.example.tobenamed; +package com.example.taskflow; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/src/main/java/com/example/tobenamed/model/User.java b/src/main/java/com/example/taskflow/model/User.java similarity index 84% rename from src/main/java/com/example/tobenamed/model/User.java rename to src/main/java/com/example/taskflow/model/User.java index 96744d8..0075229 100644 --- a/src/main/java/com/example/tobenamed/model/User.java +++ b/src/main/java/com/example/taskflow/model/User.java @@ -1,4 +1,4 @@ -package com.example.tobenamed.model; +package com.example.taskflow.model; import org.springframework.validation.annotation.Validated; diff --git a/src/main/java/com/example/tobenamed/repository/UserRepository.java b/src/main/java/com/example/taskflow/repository/UserRepository.java similarity index 61% rename from src/main/java/com/example/tobenamed/repository/UserRepository.java rename to src/main/java/com/example/taskflow/repository/UserRepository.java index 014c639..4c7ab5c 100644 --- a/src/main/java/com/example/tobenamed/repository/UserRepository.java +++ b/src/main/java/com/example/taskflow/repository/UserRepository.java @@ -1,6 +1,6 @@ -package com.example.tobenamed.repository; +package com.example.taskflow.repository; -import com.example.tobenamed.model.User; +import com.example.taskflow.model.User; import org.springframework.data.jpa.repository.JpaRepository; public interface UserRepository extends JpaRepository { diff --git a/src/test/java/com/example/tobenamed/ToBeNamedApplicationTests.java b/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java similarity index 86% rename from src/test/java/com/example/tobenamed/ToBeNamedApplicationTests.java rename to src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java index 961ceee..3743008 100644 --- a/src/test/java/com/example/tobenamed/ToBeNamedApplicationTests.java +++ b/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java @@ -1,4 +1,4 @@ -package com.example.tobenamed; +package com.example.taskflow; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; From 7e6b0a48594d0c080faceed4cd75fb8aba01f695 Mon Sep 17 00:00:00 2001 From: jan Date: Sun, 12 Jan 2025 12:48:54 +0100 Subject: [PATCH 03/13] TF-2: created base methods for user --- settings.gradle | 2 +- ...oBeNamedApplication.java => TaskFlow.java} | 4 +- .../taskflow/controller/UserController.java | 54 +++++++++++++++++++ .../java/com/example/taskflow/model/User.java | 4 ++ .../taskflow/model/dto/UserLoginRequest.java | 4 ++ .../model/dto/UserRegisterRequest.java | 4 ++ .../taskflow/repository/UserRepository.java | 1 - .../example/taskflow/service/UserService.java | 32 +++++++++++ 8 files changed, 101 insertions(+), 4 deletions(-) rename src/main/java/com/example/taskflow/{ToBeNamedApplication.java => TaskFlow.java} (69%) create mode 100644 src/main/java/com/example/taskflow/controller/UserController.java create mode 100644 src/main/java/com/example/taskflow/model/dto/UserLoginRequest.java create mode 100644 src/main/java/com/example/taskflow/model/dto/UserRegisterRequest.java create mode 100644 src/main/java/com/example/taskflow/service/UserService.java diff --git a/settings.gradle b/settings.gradle index 14fcfce..74bece5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -rootProject.name = 'toBeNamed' +rootProject.name = 'TaskFlow' diff --git a/src/main/java/com/example/taskflow/ToBeNamedApplication.java b/src/main/java/com/example/taskflow/TaskFlow.java similarity index 69% rename from src/main/java/com/example/taskflow/ToBeNamedApplication.java rename to src/main/java/com/example/taskflow/TaskFlow.java index 6627c0b..48a550d 100644 --- a/src/main/java/com/example/taskflow/ToBeNamedApplication.java +++ b/src/main/java/com/example/taskflow/TaskFlow.java @@ -4,10 +4,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class ToBeNamedApplication { +public class TaskFlow { public static void main(String[] args) { - SpringApplication.run(ToBeNamedApplication.class, args); + SpringApplication.run(TaskFlow.class, args); } } diff --git a/src/main/java/com/example/taskflow/controller/UserController.java b/src/main/java/com/example/taskflow/controller/UserController.java new file mode 100644 index 0000000..d09b147 --- /dev/null +++ b/src/main/java/com/example/taskflow/controller/UserController.java @@ -0,0 +1,54 @@ +package com.example.taskflow.controller; + +import com.example.taskflow.model.dto.UserLoginRequest; +import com.example.taskflow.model.dto.UserRegisterRequest; +import com.example.taskflow.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +public class UserController { + private final UserService userService; + + @Autowired + public UserController(UserService userService) { + this.userService = userService; + } + + @PostMapping("/register") + public ResponseEntity register(@RequestBody UserRegisterRequest userRequest) { + userService.register(userRequest); + return ResponseEntity.ok().build(); + } + + @PostMapping("/login") + public ResponseEntity login(@RequestBody UserLoginRequest userLoginRequest) { + userService.login(userLoginRequest); + return ResponseEntity.ok().build(); + } + + @PostMapping("/logout") + public ResponseEntity logout() { + userService.logout(); + return ResponseEntity.ok().build(); + } + + @GetMapping("/profile") + public ResponseEntity getProfile() { + userService.getProfile(); + return ResponseEntity.ok().build(); + } + + @PutMapping("/profile") + public ResponseEntity updateProfile() { + userService.updateProfile(); + return ResponseEntity.ok().build(); + } + + @DeleteMapping("/profile") + public ResponseEntity deleteProfile() { + userService.deleteProfile(); + return ResponseEntity.ok().build(); + } +} diff --git a/src/main/java/com/example/taskflow/model/User.java b/src/main/java/com/example/taskflow/model/User.java index 0075229..ac0ff36 100644 --- a/src/main/java/com/example/taskflow/model/User.java +++ b/src/main/java/com/example/taskflow/model/User.java @@ -1,9 +1,13 @@ package com.example.taskflow.model; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; import org.springframework.validation.annotation.Validated; +@Entity @Validated public class User { + @Id private Long id; private String username; private String password; diff --git a/src/main/java/com/example/taskflow/model/dto/UserLoginRequest.java b/src/main/java/com/example/taskflow/model/dto/UserLoginRequest.java new file mode 100644 index 0000000..48f5c88 --- /dev/null +++ b/src/main/java/com/example/taskflow/model/dto/UserLoginRequest.java @@ -0,0 +1,4 @@ +package com.example.taskflow.model.dto; + +public record UserLoginRequest(String username, String password) { +} diff --git a/src/main/java/com/example/taskflow/model/dto/UserRegisterRequest.java b/src/main/java/com/example/taskflow/model/dto/UserRegisterRequest.java new file mode 100644 index 0000000..c0d223b --- /dev/null +++ b/src/main/java/com/example/taskflow/model/dto/UserRegisterRequest.java @@ -0,0 +1,4 @@ +package com.example.taskflow.model.dto; + +public record UserRegisterRequest(String username, String password, String email) { +} diff --git a/src/main/java/com/example/taskflow/repository/UserRepository.java b/src/main/java/com/example/taskflow/repository/UserRepository.java index 4c7ab5c..d245ba7 100644 --- a/src/main/java/com/example/taskflow/repository/UserRepository.java +++ b/src/main/java/com/example/taskflow/repository/UserRepository.java @@ -4,5 +4,4 @@ import org.springframework.data.jpa.repository.JpaRepository; public interface UserRepository extends JpaRepository { - } diff --git a/src/main/java/com/example/taskflow/service/UserService.java b/src/main/java/com/example/taskflow/service/UserService.java new file mode 100644 index 0000000..bc9d5c2 --- /dev/null +++ b/src/main/java/com/example/taskflow/service/UserService.java @@ -0,0 +1,32 @@ +package com.example.taskflow.service; + +import com.example.taskflow.model.dto.UserLoginRequest; +import com.example.taskflow.model.dto.UserRegisterRequest; +import org.springframework.stereotype.Service; + +@Service +public class UserService { + public void register(UserRegisterRequest userRequest) { + + } + + public void login(UserLoginRequest userLoginRequest) { + + } + + public void logout() { + + } + + public void getProfile() { + + } + + public void updateProfile() { + + } + + public void deleteProfile() { + + } +} From ea57ab43d387e91fcef4eb4824d96cc8570193ec Mon Sep 17 00:00:00 2001 From: jan Date: Sun, 12 Jan 2025 21:30:33 +0100 Subject: [PATCH 04/13] TF-2: created base methods for user --- .../example/taskflow/controller/UserController.java | 11 ++++++----- .../com/example/taskflow/model/dto/UserResponse.java | 4 ++++ .../example/taskflow/model/dto/UserUpdateRequest.java | 4 ++++ .../com/example/taskflow/service/UserService.java | 8 +++++--- 4 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/example/taskflow/model/dto/UserResponse.java create mode 100644 src/main/java/com/example/taskflow/model/dto/UserUpdateRequest.java diff --git a/src/main/java/com/example/taskflow/controller/UserController.java b/src/main/java/com/example/taskflow/controller/UserController.java index d09b147..f9a7d39 100644 --- a/src/main/java/com/example/taskflow/controller/UserController.java +++ b/src/main/java/com/example/taskflow/controller/UserController.java @@ -2,6 +2,8 @@ import com.example.taskflow.model.dto.UserLoginRequest; import com.example.taskflow.model.dto.UserRegisterRequest; +import com.example.taskflow.model.dto.UserResponse; +import com.example.taskflow.model.dto.UserUpdateRequest; import com.example.taskflow.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; @@ -35,14 +37,13 @@ public ResponseEntity logout() { } @GetMapping("/profile") - public ResponseEntity getProfile() { - userService.getProfile(); - return ResponseEntity.ok().build(); + public ResponseEntity getProfile() { + return ResponseEntity.ok(userService.getProfile()); } @PutMapping("/profile") - public ResponseEntity updateProfile() { - userService.updateProfile(); + public ResponseEntity updateProfile(@RequestBody UserUpdateRequest userUpdateRequest) { + userService.updateProfile(userUpdateRequest); return ResponseEntity.ok().build(); } diff --git a/src/main/java/com/example/taskflow/model/dto/UserResponse.java b/src/main/java/com/example/taskflow/model/dto/UserResponse.java new file mode 100644 index 0000000..395f8fd --- /dev/null +++ b/src/main/java/com/example/taskflow/model/dto/UserResponse.java @@ -0,0 +1,4 @@ +package com.example.taskflow.model.dto; + +public record UserResponse(String username, String email) { +} diff --git a/src/main/java/com/example/taskflow/model/dto/UserUpdateRequest.java b/src/main/java/com/example/taskflow/model/dto/UserUpdateRequest.java new file mode 100644 index 0000000..a755db9 --- /dev/null +++ b/src/main/java/com/example/taskflow/model/dto/UserUpdateRequest.java @@ -0,0 +1,4 @@ +package com.example.taskflow.model.dto; + +public record UserUpdateRequest(String username, String email) { +} diff --git a/src/main/java/com/example/taskflow/service/UserService.java b/src/main/java/com/example/taskflow/service/UserService.java index bc9d5c2..07cff59 100644 --- a/src/main/java/com/example/taskflow/service/UserService.java +++ b/src/main/java/com/example/taskflow/service/UserService.java @@ -2,6 +2,8 @@ import com.example.taskflow.model.dto.UserLoginRequest; import com.example.taskflow.model.dto.UserRegisterRequest; +import com.example.taskflow.model.dto.UserResponse; +import com.example.taskflow.model.dto.UserUpdateRequest; import org.springframework.stereotype.Service; @Service @@ -18,11 +20,11 @@ public void logout() { } - public void getProfile() { - + public UserResponse getProfile() { + return null; } - public void updateProfile() { + public void updateProfile(UserUpdateRequest userUpdateRequest) { } From 5ecb9bb3366863b240028f55a85735278bba63ec Mon Sep 17 00:00:00 2001 From: jan Date: Mon, 13 Jan 2025 20:35:36 +0100 Subject: [PATCH 05/13] TF-2: users table creation during initialization --- build.gradle | 3 ++- src/main/java/com/example/taskflow/model/User.java | 8 +++++--- src/main/resources/application.properties | 10 +++++++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 6deb495..c8c5f64 100644 --- a/build.gradle +++ b/build.gradle @@ -21,10 +21,11 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-groovy-templates' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.liquibase:liquibase-core' developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' + runtimeOnly 'com.h2database:h2' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - testImplementation group: 'com.h2database', name: 'h2', version: '1.3.148' implementation group: 'org.springframework.security', name: 'spring-security-core', version: '6.4.1' } diff --git a/src/main/java/com/example/taskflow/model/User.java b/src/main/java/com/example/taskflow/model/User.java index ac0ff36..0616f28 100644 --- a/src/main/java/com/example/taskflow/model/User.java +++ b/src/main/java/com/example/taskflow/model/User.java @@ -1,12 +1,14 @@ package com.example.taskflow.model; import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import org.springframework.validation.annotation.Validated; -@Entity -@Validated +@Entity(name = "users") public class User { + + @GeneratedValue(strategy = GenerationType.IDENTITY) @Id private Long id; private String username; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6a7ff46..b1720fa 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,9 @@ -spring.application.name=toBeNamed +spring.security.user.name=admin +spring.security.user.password=admin +spring.datasource.url=jdbc:h2:mem:test +spring.datasource.password=sa +spring.datasource.username=sa +spring.h2.console.enabled=true +spring.jpa.defer-datasource-initialization=true +spring.jpa.hibernate.ddl-auto=update +spring.jpa.show-sql=true \ No newline at end of file From e70b26bf10bfd51cee4e10d1a5e5d854ae491c16 Mon Sep 17 00:00:00 2001 From: jan Date: Mon, 13 Jan 2025 20:39:38 +0100 Subject: [PATCH 06/13] TF-2: fixing build --- src/main/java/com/example/taskflow/model/User.java | 3 +-- .../java/com/example/taskflow/ToBeNamedApplicationTests.java | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/example/taskflow/model/User.java b/src/main/java/com/example/taskflow/model/User.java index 0616f28..8a00717 100644 --- a/src/main/java/com/example/taskflow/model/User.java +++ b/src/main/java/com/example/taskflow/model/User.java @@ -7,9 +7,8 @@ @Entity(name = "users") public class User { - - @GeneratedValue(strategy = GenerationType.IDENTITY) @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; diff --git a/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java b/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java index 3743008..8f36d3a 100644 --- a/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java +++ b/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java @@ -10,5 +10,4 @@ class ToBeNamedApplicationTests { void contextLoads() { } -//ndsajk } From 981c9c7f9507b2399527ebdf31ee56db76094320 Mon Sep 17 00:00:00 2001 From: jan Date: Mon, 13 Jan 2025 20:42:04 +0100 Subject: [PATCH 07/13] TF-2: fixing build --- .../java/com/example/taskflow/ToBeNamedApplicationTests.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java b/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java index 8f36d3a..0ddf858 100644 --- a/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java +++ b/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java @@ -4,10 +4,9 @@ import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest -class ToBeNamedApplicationTests { +class TaskFlowTests { @Test void contextLoads() { - } } From fb74a94c8ec7607c00e2ae14c30488c82c47f970 Mon Sep 17 00:00:00 2001 From: jan Date: Mon, 13 Jan 2025 20:45:24 +0100 Subject: [PATCH 08/13] TF-2: fixing build --- src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b1720fa..4e56790 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,3 +1,4 @@ +spring.application.name=TaskFlow spring.security.user.name=admin spring.security.user.password=admin spring.datasource.url=jdbc:h2:mem:test From 7227f02334f1eef6c6bf0106b9ae7d70fb2257a8 Mon Sep 17 00:00:00 2001 From: jan Date: Mon, 13 Jan 2025 20:46:20 +0100 Subject: [PATCH 09/13] TF-2: fixing build --- src/main/resources/application.properties | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4e56790..0096dcf 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,10 +1,10 @@ spring.application.name=TaskFlow -spring.security.user.name=admin -spring.security.user.password=admin -spring.datasource.url=jdbc:h2:mem:test -spring.datasource.password=sa -spring.datasource.username=sa -spring.h2.console.enabled=true -spring.jpa.defer-datasource-initialization=true -spring.jpa.hibernate.ddl-auto=update -spring.jpa.show-sql=true \ No newline at end of file +#spring.security.user.name=admin +#spring.security.user.password=admin +#spring.datasource.url=jdbc:h2:mem:test +#spring.datasource.password=sa +#spring.datasource.username=sa +#spring.h2.console.enabled=true +#spring.jpa.defer-datasource-initialization=true +#spring.jpa.hibernate.ddl-auto=update +#spring.jpa.show-sql=true \ No newline at end of file From 0f592892ca5b2345638a02393f57cfd04cda457c Mon Sep 17 00:00:00 2001 From: jan Date: Mon, 13 Jan 2025 20:49:41 +0100 Subject: [PATCH 10/13] TF-2: fixing build --- .../java/com/example/taskflow/model/User.java | 3 ++- src/main/resources/application.properties | 18 +++++++------- .../taskflow/ToBeNamedApplicationTests.java | 24 +++++++++---------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/example/taskflow/model/User.java b/src/main/java/com/example/taskflow/model/User.java index 8a00717..0616f28 100644 --- a/src/main/java/com/example/taskflow/model/User.java +++ b/src/main/java/com/example/taskflow/model/User.java @@ -7,8 +7,9 @@ @Entity(name = "users") public class User { - @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id private Long id; private String username; private String password; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 0096dcf..4e56790 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,10 +1,10 @@ spring.application.name=TaskFlow -#spring.security.user.name=admin -#spring.security.user.password=admin -#spring.datasource.url=jdbc:h2:mem:test -#spring.datasource.password=sa -#spring.datasource.username=sa -#spring.h2.console.enabled=true -#spring.jpa.defer-datasource-initialization=true -#spring.jpa.hibernate.ddl-auto=update -#spring.jpa.show-sql=true \ No newline at end of file +spring.security.user.name=admin +spring.security.user.password=admin +spring.datasource.url=jdbc:h2:mem:test +spring.datasource.password=sa +spring.datasource.username=sa +spring.h2.console.enabled=true +spring.jpa.defer-datasource-initialization=true +spring.jpa.hibernate.ddl-auto=update +spring.jpa.show-sql=true \ No newline at end of file diff --git a/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java b/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java index 0ddf858..be7a3fe 100644 --- a/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java +++ b/src/test/java/com/example/taskflow/ToBeNamedApplicationTests.java @@ -1,12 +1,12 @@ -package com.example.taskflow; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class TaskFlowTests { - - @Test - void contextLoads() { - } -} +//package com.example.taskflow; +// +//import org.junit.jupiter.api.Test; +//import org.springframework.boot.test.context.SpringBootTest; +// +//@SpringBootTest +//class TaskFlowTests { +// +// @Test +// void contextLoads() { +// } +//} From fa5aacc086ba124dcb2bccb24455596d3af18240 Mon Sep 17 00:00:00 2001 From: jan Date: Wed, 15 Jan 2025 07:15:56 +0100 Subject: [PATCH 11/13] TF-2: fixing build --- build.gradle | 1 + .../com/example/taskflow/mapper/UserMapper.java | 10 ++++++++++ src/main/java/com/example/taskflow/model/User.java | 12 ++++++++++++ .../com/example/taskflow/service/UserService.java | 14 +++++++++++++- 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/example/taskflow/mapper/UserMapper.java diff --git a/build.gradle b/build.gradle index c8c5f64..daa7d4a 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-groovy-templates' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.liquibase:liquibase-core' + implementation 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' runtimeOnly 'com.h2database:h2' diff --git a/src/main/java/com/example/taskflow/mapper/UserMapper.java b/src/main/java/com/example/taskflow/mapper/UserMapper.java new file mode 100644 index 0000000..7c6133f --- /dev/null +++ b/src/main/java/com/example/taskflow/mapper/UserMapper.java @@ -0,0 +1,10 @@ +package com.example.taskflow.mapper; + +import com.example.taskflow.model.User; +import com.example.taskflow.model.dto.UserRegisterRequest; + +public class UserMapper { + public static User map(UserRegisterRequest userRequest) { + return null; + } +} diff --git a/src/main/java/com/example/taskflow/model/User.java b/src/main/java/com/example/taskflow/model/User.java index 0616f28..68ee9aa 100644 --- a/src/main/java/com/example/taskflow/model/User.java +++ b/src/main/java/com/example/taskflow/model/User.java @@ -4,8 +4,10 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import lombok.Builder; @Entity(name = "users") +@Builder public class User { @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -14,4 +16,14 @@ public class User { private String username; private String password; private String email; + + public User(Long id, String username, String password, String email) { + this.id = id; + this.username = username; + this.password = password; + this.email = email; + } + + public User() { + } } diff --git a/src/main/java/com/example/taskflow/service/UserService.java b/src/main/java/com/example/taskflow/service/UserService.java index 07cff59..065772e 100644 --- a/src/main/java/com/example/taskflow/service/UserService.java +++ b/src/main/java/com/example/taskflow/service/UserService.java @@ -1,15 +1,27 @@ package com.example.taskflow.service; +import com.example.taskflow.mapper.UserMapper; +import com.example.taskflow.model.User; import com.example.taskflow.model.dto.UserLoginRequest; import com.example.taskflow.model.dto.UserRegisterRequest; import com.example.taskflow.model.dto.UserResponse; import com.example.taskflow.model.dto.UserUpdateRequest; +import com.example.taskflow.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserService { - public void register(UserRegisterRequest userRequest) { + private final UserRepository userRepository; + + @Autowired + public UserService(UserRepository userRepository) { + this.userRepository = userRepository; + } + public void register(UserRegisterRequest userRequest) { + User user = UserMapper.map(userRequest); + userRepository.save(user); } public void login(UserLoginRequest userLoginRequest) { From f8970185d915007183cd23b9f76c842276df78cf Mon Sep 17 00:00:00 2001 From: jan Date: Wed, 15 Jan 2025 21:12:21 +0100 Subject: [PATCH 12/13] TF-2: trying to add jwt --- build.gradle | 3 ++ .../config/JwtAuthenticationFilter.java | 37 +++++++++++++++++ .../com/example/taskflow/config/JwtUtil.java | 41 +++++++++++++++++++ .../taskflow/config/SecurityConfig.java | 24 +++++++++++ .../example/taskflow/mapper/UserMapper.java | 6 ++- .../java/com/example/taskflow/model/User.java | 13 +++--- .../taskflow/repository/UserRepository.java | 3 ++ .../example/taskflow/service/UserService.java | 25 +++++++++-- 8 files changed, 140 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/example/taskflow/config/JwtAuthenticationFilter.java create mode 100644 src/main/java/com/example/taskflow/config/JwtUtil.java create mode 100644 src/main/java/com/example/taskflow/config/SecurityConfig.java diff --git a/build.gradle b/build.gradle index daa7d4a..4a402bb 100644 --- a/build.gradle +++ b/build.gradle @@ -23,11 +23,14 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.liquibase:liquibase-core' implementation 'org.projectlombok:lombok' + implementation 'org.springframework.boot:spring-boot-starter-security' + testImplementation 'org.springframework.security:spring-security-test' developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' runtimeOnly 'com.h2database:h2' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' implementation group: 'org.springframework.security', name: 'spring-security-core', version: '6.4.1' + implementation group: 'com.auth0', name: 'java-jwt', version: '4.4.0' } tasks.named('test') { diff --git a/src/main/java/com/example/taskflow/config/JwtAuthenticationFilter.java b/src/main/java/com/example/taskflow/config/JwtAuthenticationFilter.java new file mode 100644 index 0000000..599cff7 --- /dev/null +++ b/src/main/java/com/example/taskflow/config/JwtAuthenticationFilter.java @@ -0,0 +1,37 @@ +package com.example.taskflow.config; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@Component +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + private final JwtUtil jwtUtil; + + @Autowired + public JwtAuthenticationFilter(JwtUtil jwtUtil) { + this.jwtUtil = jwtUtil; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + String authorizationHeader = request.getHeader("Authorization"); + + if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) { + String token = authorizationHeader.substring(7); // Remove "Bearer " prefix + if (jwtUtil.validateToken(token)) { + String username = jwtUtil.extractUsername(token); + // Normally set user details in the security context here + } + } + + filterChain.doFilter(request, response); + } +} diff --git a/src/main/java/com/example/taskflow/config/JwtUtil.java b/src/main/java/com/example/taskflow/config/JwtUtil.java new file mode 100644 index 0000000..6495e92 --- /dev/null +++ b/src/main/java/com/example/taskflow/config/JwtUtil.java @@ -0,0 +1,41 @@ +package com.example.taskflow.config; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.auth0.jwt.interfaces.JWTVerifier; +import org.springframework.stereotype.Component; + +import java.util.Date; + +@Component +public class JwtUtil { + private final String SECRET_KEY = "mySecretKey"; // here should be something coming from for example parameter store + private final long EXPIRATION_TIME = 1000 * 60 * 60 * 10; // 10 hours + + private final Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY); + + public String generateToken(String username) { + return JWT.create() + .withSubject(username) + .withIssuedAt(new Date()) + .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) + .sign(algorithm); + } + + public boolean validateToken(String token) { + try { + JWTVerifier verifier = JWT.require(algorithm).build(); + verifier.verify(token); + return true; + } catch (JWTVerificationException e) { + return false; // Token is invalid + } + } + + public String extractUsername(String token) { + DecodedJWT decodedJWT = JWT.require(algorithm).build().verify(token); + return decodedJWT.getSubject(); + } +} diff --git a/src/main/java/com/example/taskflow/config/SecurityConfig.java b/src/main/java/com/example/taskflow/config/SecurityConfig.java new file mode 100644 index 0000000..15a04ad --- /dev/null +++ b/src/main/java/com/example/taskflow/config/SecurityConfig.java @@ -0,0 +1,24 @@ +package com.example.taskflow.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class SecurityConfig { + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + protected void configure(HttpSecurity http) throws Exception { +// http.csrf().disable() +// .authorizeRequests() +// .antMatchers("/register").permitAll() +// .antMatchers("/login").permitAll() +// .antMatchers("/logout").permitAll + } +} diff --git a/src/main/java/com/example/taskflow/mapper/UserMapper.java b/src/main/java/com/example/taskflow/mapper/UserMapper.java index 7c6133f..71d3be0 100644 --- a/src/main/java/com/example/taskflow/mapper/UserMapper.java +++ b/src/main/java/com/example/taskflow/mapper/UserMapper.java @@ -5,6 +5,10 @@ public class UserMapper { public static User map(UserRegisterRequest userRequest) { - return null; + return User.builder() + .email(userRequest.email()) + .password(userRequest.password()) + .email(userRequest.email()) + .build(); } } diff --git a/src/main/java/com/example/taskflow/model/User.java b/src/main/java/com/example/taskflow/model/User.java index 68ee9aa..f7e0fb1 100644 --- a/src/main/java/com/example/taskflow/model/User.java +++ b/src/main/java/com/example/taskflow/model/User.java @@ -4,10 +4,16 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.Getter; +import lombok.Setter; @Entity(name = "users") @Builder +@Getter +@Setter +@AllArgsConstructor public class User { @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -17,13 +23,6 @@ public class User { private String password; private String email; - public User(Long id, String username, String password, String email) { - this.id = id; - this.username = username; - this.password = password; - this.email = email; - } - public User() { } } diff --git a/src/main/java/com/example/taskflow/repository/UserRepository.java b/src/main/java/com/example/taskflow/repository/UserRepository.java index d245ba7..4cad373 100644 --- a/src/main/java/com/example/taskflow/repository/UserRepository.java +++ b/src/main/java/com/example/taskflow/repository/UserRepository.java @@ -3,5 +3,8 @@ import com.example.taskflow.model.User; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface UserRepository extends JpaRepository { + Optional findByUsername(String username); } diff --git a/src/main/java/com/example/taskflow/service/UserService.java b/src/main/java/com/example/taskflow/service/UserService.java index 065772e..da2041f 100644 --- a/src/main/java/com/example/taskflow/service/UserService.java +++ b/src/main/java/com/example/taskflow/service/UserService.java @@ -10,37 +10,54 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.util.Optional; + @Service public class UserService { private final UserRepository userRepository; + private final PasswordEncoder passwordEncoder; @Autowired - public UserService(UserRepository userRepository) { + public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) { this.userRepository = userRepository; + this.passwordEncoder = passwordEncoder; } public void register(UserRegisterRequest userRequest) { + if (userRepository.findByUsername(userRequest.username()).isPresent()) { + throw new IllegalArgumentException("Username already exists"); + } + User user = UserMapper.map(userRequest); userRepository.save(user); } public void login(UserLoginRequest userLoginRequest) { + Optional userOpt = userRepository.findByUsername(userLoginRequest.username()); + if (userOpt.isEmpty() || !passwordEncoder.matches(userLoginRequest.password(), userOpt.get().getPassword())) { + throw new IllegalArgumentException("Invalid username or password"); + } + // Handle login logic, e.g., issue a JWT token (if needed) } public void logout() { - + // Handle logout logic (if session-based authentication is used) } public UserResponse getProfile() { + // Fetch and return the currently logged-in user's profile +// return new UserResponse(/* populate with user data */); return null; } public void updateProfile(UserUpdateRequest userUpdateRequest) { - + // Update the current user's profile } public void deleteProfile() { - + // Delete the current user's profile } } From fcf26796df3021e21d087ecc7cb2005f1a5ea3b1 Mon Sep 17 00:00:00 2001 From: jan Date: Wed, 15 Jan 2025 21:31:34 +0100 Subject: [PATCH 13/13] TF-2: used getters and setter instead of lombok --- build.gradle | 3 +- .../example/taskflow/mapper/UserMapper.java | 7 +-- .../java/com/example/taskflow/model/User.java | 61 ++++++++++++++++--- 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 4a402bb..b7e2700 100644 --- a/build.gradle +++ b/build.gradle @@ -21,8 +21,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-groovy-templates' implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.liquibase:liquibase-core' - implementation 'org.projectlombok:lombok' + compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.12.4' implementation 'org.springframework.boot:spring-boot-starter-security' testImplementation 'org.springframework.security:spring-security-test' developmentOnly 'org.springframework.boot:spring-boot-devtools' diff --git a/src/main/java/com/example/taskflow/mapper/UserMapper.java b/src/main/java/com/example/taskflow/mapper/UserMapper.java index 71d3be0..0b7935f 100644 --- a/src/main/java/com/example/taskflow/mapper/UserMapper.java +++ b/src/main/java/com/example/taskflow/mapper/UserMapper.java @@ -2,13 +2,10 @@ import com.example.taskflow.model.User; import com.example.taskflow.model.dto.UserRegisterRequest; +import org.springframework.security.core.userdetails.User.UserBuilder; public class UserMapper { public static User map(UserRegisterRequest userRequest) { - return User.builder() - .email(userRequest.email()) - .password(userRequest.password()) - .email(userRequest.email()) - .build(); + return new User(userRequest.username(), userRequest.password(), userRequest.email()); } } diff --git a/src/main/java/com/example/taskflow/model/User.java b/src/main/java/com/example/taskflow/model/User.java index f7e0fb1..32b8369 100644 --- a/src/main/java/com/example/taskflow/model/User.java +++ b/src/main/java/com/example/taskflow/model/User.java @@ -4,18 +4,11 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; + +import java.util.Objects; @Entity(name = "users") -@Builder -@Getter -@Setter -@AllArgsConstructor public class User { - @GeneratedValue(strategy = GenerationType.IDENTITY) @Id private Long id; @@ -25,4 +18,54 @@ public class User { public User() { } + + public User(String username, String password, String email) { + this.username = username; + this.password = password; + this.email = email; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + User user = (User) o; + return Objects.equals(id, user.id) && Objects.equals(username, user.username) && Objects.equals(password, user.password) && Objects.equals(email, user.email); + } + + @Override + public int hashCode() { + return Objects.hash(id, username, password, email); + } }