Skip to content

Commit a02fcbe

Browse files
committed
Add password to user
1 parent 7415f0e commit a02fcbe

15 files changed

Lines changed: 168 additions & 17 deletions

File tree

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,15 @@ Seed is a RESTful API template.
55
`docker-compose -f docker-compose.yml up -d`
66

77
Make sure your .env variables are properly set in your IDE before running the app.
8+
9+
## Password Encryption
10+
11+
This application uses BCrypt for password encryption. All passwords are automatically encrypted before being stored in the database.
12+
13+
### Features:
14+
- **Automatic Encryption**: Passwords are encrypted using BCrypt when creating users
15+
- **Secure Hashing**: BCrypt provides salt and cost factor for enhanced security
16+
- **Password Verification**: Built-in methods to verify passwords during login
17+
18+
### Security Configuration
19+
The application includes a `SecurityConfig` that disables default Spring Security authentication while keeping BCrypt available for password encoding.

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ dependencies {
2323
implementation("org.springframework.boot:spring-boot-starter")
2424
implementation("org.springframework.boot:spring-boot-starter-web")
2525
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
26+
implementation("org.springframework.boot:spring-boot-starter-security")
2627
implementation("org.jetbrains.kotlin:kotlin-reflect")
2728
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
2829
runtimeOnly("org.postgresql:postgresql")

src/main/kotlin/studio/vitr/seed/adapter/UserAdapter.kt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,23 @@ import org.springframework.stereotype.Component
44
import studio.vitr.seed.constants.Properties.ID
55
import studio.vitr.seed.errors.InvalidParameter
66
import studio.vitr.seed.model.User
7-
import studio.vitr.seed.model.api.UserRequest
7+
import studio.vitr.seed.model.api.CreateUserRequest
88
import studio.vitr.seed.model.api.UserResponse
9+
import studio.vitr.seed.service.PasswordEncoderService
910

1011
@Component
11-
class UserAdapter {
12+
class UserAdapter(
13+
private val passwordEncoderService: PasswordEncoderService
14+
) {
1215

13-
fun toUser(request: UserRequest) = User(
14-
githubUserId = request.githubUserId
16+
fun toUser(r: CreateUserRequest) = User(
17+
email = r.email,
18+
password = passwordEncoderService.encodePassword(r.password),
1519
)
1620

17-
fun toUserResponse(user: User) = UserResponse(
18-
id = user.id ?: throw InvalidParameter(ID),
19-
githubUserId = user.githubUserId,
20-
createdAt = user.createdAt,
21+
fun toUserResponse(u: User) = UserResponse(
22+
id = u.id ?: throw InvalidParameter(ID),
23+
email = u.email,
24+
createdAt = u.createdAt,
2125
)
2226
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package studio.vitr.seed.config
2+
3+
import org.springframework.context.annotation.Bean
4+
import org.springframework.context.annotation.Configuration
5+
import org.springframework.security.config.annotation.web.builders.HttpSecurity
6+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
7+
import org.springframework.security.web.SecurityFilterChain
8+
9+
@Configuration
10+
@EnableWebSecurity
11+
class SecurityConfig {
12+
13+
@Bean
14+
fun filterChain(http: HttpSecurity): SecurityFilterChain = http
15+
.csrf { it.disable() }
16+
.authorizeHttpRequests { it.anyRequest().permitAll() }
17+
.build()
18+
}

src/main/kotlin/studio/vitr/seed/controller/UserController.kt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import org.springframework.web.bind.annotation.*
44
import studio.vitr.seed.adapter.UserAdapter
55
import studio.vitr.seed.constants.Properties.USER
66
import studio.vitr.seed.errors.NotFound
7-
import studio.vitr.seed.model.api.UserRequest
7+
import studio.vitr.seed.model.api.CreateUserRequest
8+
import studio.vitr.seed.model.api.PasswordVerificationRequest
9+
import studio.vitr.seed.model.api.PasswordVerificationResponse
810
import studio.vitr.seed.service.UserService
911
import java.util.UUID
1012

@@ -25,10 +27,19 @@ class UserController(
2527
?: throw NotFound(USER, userId.toString())
2628

2729
@PostMapping
28-
fun createUser(@RequestBody request: UserRequest) = userAdapter
30+
fun createUser(@RequestBody request: CreateUserRequest) = userAdapter
2931
.toUser(request)
3032
.let { userService.create(it) }
3133

3234
@DeleteMapping("/{userId}")
3335
fun deleteUser(@PathVariable userId: UUID) = userService.delete(userId)
34-
}
36+
37+
@PostMapping("/{userId}/verify-password")
38+
fun verifyPassword(
39+
@PathVariable userId: UUID,
40+
@RequestBody request: PasswordVerificationRequest
41+
): PasswordVerificationResponse {
42+
val isValid = userService.verifyPassword(userId, request.password)
43+
return PasswordVerificationResponse(isValid = isValid)
44+
}
45+
}

src/main/kotlin/studio/vitr/seed/model/User.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ import jakarta.persistence.GenerationType.UUID as UUIDX
1212
data class User(
1313
@Id @GeneratedValue(strategy = UUIDX) val id: UUID? = null,
1414
val email: String,
15+
val password: String,
1516
val createdAt: Long = System.currentTimeMillis(),
1617
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package studio.vitr.seed.model.api
2+
3+
class CreateUserRequest(
4+
val email: String,
5+
val password: String,
6+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package studio.vitr.seed.model.api
2+
3+
data class PasswordVerificationRequest(
4+
val password: String
5+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package studio.vitr.seed.model.api
2+
3+
data class PasswordVerificationResponse(
4+
val isValid: Boolean
5+
)

src/main/kotlin/studio/vitr/seed/model/api/UserRequest.kt

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)