diff --git a/pom.xml b/pom.xml index 2b199f6..829b223 100644 --- a/pom.xml +++ b/pom.xml @@ -52,6 +52,10 @@ org.springframework.boot spring-boot-starter-data-jpa + + spring-boot-starter-validation + org.springframework.boot + org.springframework.boot spring-boot-starter-security diff --git a/src/main/kotlin/uk/co/neviyn/projectplanner/Entities.kt b/src/main/kotlin/uk/co/neviyn/projectplanner/Entities.kt index 7d0a57d..9b53cfb 100644 --- a/src/main/kotlin/uk/co/neviyn/projectplanner/Entities.kt +++ b/src/main/kotlin/uk/co/neviyn/projectplanner/Entities.kt @@ -13,12 +13,19 @@ import javax.persistence.JoinTable import javax.persistence.ManyToMany import javax.persistence.ManyToOne import javax.persistence.OneToMany +import javax.validation.constraints.Email +import javax.validation.constraints.NotBlank @Entity open class User( + @field:NotBlank(message = "Username is required") + @Column(unique = true) open var username: String = "INVALID", + @field:NotBlank(message = "Email address is required") + @field:Email(message = "Email address invalid") open var email: String = "INVALID", @JsonIgnore + @field:NotBlank(message = "Password is required") open var password: String = "INVALID", @ManyToMany(cascade = [CascadeType.ALL]) @JsonIgnore @@ -29,7 +36,11 @@ open class User( ) open var projects: MutableSet = mutableSetOf(), @Id @GeneratedValue(strategy = GenerationType.IDENTITY) open var id: Long? = null -) +) { + override fun toString(): String { + return "User(username='$username', email='$email', password='$password', id=$id)" + } +} @Entity open class Project( diff --git a/src/main/kotlin/uk/co/neviyn/projectplanner/HtmlController.kt b/src/main/kotlin/uk/co/neviyn/projectplanner/HtmlController.kt index 3903690..d87dc6f 100644 --- a/src/main/kotlin/uk/co/neviyn/projectplanner/HtmlController.kt +++ b/src/main/kotlin/uk/co/neviyn/projectplanner/HtmlController.kt @@ -8,6 +8,7 @@ import org.springframework.stereotype.Controller import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.ui.Model +import org.springframework.validation.BindingResult import org.springframework.web.bind.annotation.ModelAttribute import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody @@ -18,6 +19,7 @@ import org.springframework.web.server.ResponseStatusException import java.time.Instant import javax.persistence.EntityManager import javax.transaction.Transactional +import javax.validation.Valid @Controller @@ -37,7 +39,8 @@ class HtmlController @Autowired constructor(val userRepository: UserRepository, } @PostMapping("/register") - fun register(@ModelAttribute newUser: User) : String { + fun register(@Valid @ModelAttribute("user_details") newUser: User, bindingResult: BindingResult): String { + if (bindingResult.hasErrors()) return "register" newUser.password = passwordEncoder().encode(newUser.password) userRepository.save(newUser) return "login" @@ -59,15 +62,14 @@ class HtmlController @Autowired constructor(val userRepository: UserRepository, @PostMapping("/profile") @Transactional - fun updateLoggedInUser(@ModelAttribute userData: DisplayUser, @AuthenticationPrincipal userDetails: CustomUserDetails, model: Model) : String { - if(userData.id == userDetails.user.id!! && passwordEncoder().matches(userData.oldPassword, userDetails.password)) { + fun updateLoggedInUser(@Valid @ModelAttribute userData: DisplayUser, @AuthenticationPrincipal userDetails: CustomUserDetails, model: Model): String { + if (userData.id == userDetails.user.id!! && passwordEncoder().matches(userData.oldPassword, userDetails.password)) { val user = userDetails.user user.email = userData.email - if(userData.password.isNotEmpty()) user.password = passwordEncoder().encode(userData.password) + if (userData.password.isNotEmpty()) user.password = passwordEncoder().encode(userData.password) userRepository.save(user) model.addAttribute("message", "Your profile has been updated") - } - else{ + } else { model.addAttribute("error", "Incorrect existing password") } model.addAttribute("userData", DisplayUser(userData.id, userData.username, userData.email, userData.password, "")) diff --git a/src/main/kotlin/uk/co/neviyn/projectplanner/Requests.kt b/src/main/kotlin/uk/co/neviyn/projectplanner/Requests.kt index b6f9527..9897f6c 100644 --- a/src/main/kotlin/uk/co/neviyn/projectplanner/Requests.kt +++ b/src/main/kotlin/uk/co/neviyn/projectplanner/Requests.kt @@ -1,17 +1,46 @@ package uk.co.neviyn.projectplanner import java.time.Instant +import javax.validation.constraints.NotBlank +import javax.validation.constraints.PastOrPresent +import javax.validation.constraints.Positive -data class DisplayUser(val id: Long, val username: String, val email: String, val password: String, val oldPassword: String) +data class DisplayUser( + @field:Positive val id: Long, + val username: String, + val email: String, + val password: String, + @field:NotBlank val oldPassword: String +) -data class NewProject(val title: String) +data class NewProject( + @field:NotBlank val title: String +) -data class NewEvent(val title: String, val description: String, val start: Instant, val end: Instant) +data class NewEvent( + @field:NotBlank val title: String, + val description: String, + val start: Instant, + val end: Instant +) -data class EditedEvent(val id: Long, val title: String, val description: String, val start: Instant, val end: Instant) +data class EditedEvent( + @field:Positive val id: Long, + val title: String, + val description: String, + val start: Instant, + val end: Instant) -data class EventID(val id: Long) +data class EventID( + @field:Positive val id: Long +) -data class FlatComment(val created: Instant, val comment: String, val username: String) +data class FlatComment( + @field:PastOrPresent val created: Instant, + @field:NotBlank val comment: String, + @field:NotBlank val username: String +) -data class NewComment(val comment: String) \ No newline at end of file +data class NewComment( + @field:NotBlank val comment: String +) \ No newline at end of file diff --git a/src/main/resources/db/migration/V1_0__Database_Init.sql b/src/main/resources/db/migration/V1_0__Database_Init.sql index 3213006..5a37f3e 100644 --- a/src/main/resources/db/migration/V1_0__Database_Init.sql +++ b/src/main/resources/db/migration/V1_0__Database_Init.sql @@ -3,25 +3,51 @@ create schema if not exists projectplanner; create table if not exists projectplanner."user" ( id bigserial not null - constraint user_pk - primary key, - username varchar(50) not null, - email varchar(255) not null, - password varchar(255) not null -); + constraint + user_pk + primary + key, + username + varchar +( + 50 +) not null, + email varchar +( + 255 +) not null, + password varchar +( + 255 +) not null + ); -create unique index if not exists user_id_uindex +create +unique index if not exists user_id_uindex on projectplanner."user" (id); +create +unique index if not exists user_username_uindex + ON projectplanner."user" (username); + create table if not exists projectplanner.project ( - id bigserial not null - constraint project_pk - primary key, - title text not null + id + bigserial + not + null + constraint + project_pk + primary + key, + title + text + not + null ); -create unique index if not exists project_id_uindex +create +unique index if not exists project_id_uindex on projectplanner.project (id); create table if not exists projectplanner.team diff --git a/src/main/resources/templates/register.html b/src/main/resources/templates/register.html index 10f84e8..040df67 100644 --- a/src/main/resources/templates/register.html +++ b/src/main/resources/templates/register.html @@ -12,30 +12,29 @@
-
-
- Please enter an email address. +
Email Error
-
- Please enter a username. +
Username + Error
-
- Please enter a password. +
Password + Error
@@ -43,26 +42,5 @@
- \ No newline at end of file