@@ -3,12 +3,13 @@ package org.kotatsu.resources
3
3
import org.kotatsu.database
4
4
import org.kotatsu.model.user.*
5
5
import org.kotatsu.model.users
6
- import org.kotatsu.util.md5
7
6
import org.kotatsu.util.withRetry
8
7
import org.ktorm.dsl.eq
9
8
import org.ktorm.dsl.insertAndGenerateKey
10
9
import org.ktorm.entity.find
11
10
import org.ktorm.entity.singleOrNull
11
+ import org.kotatsu.util.PasswordHasher
12
+ import org.kotatsu.util.md5
12
13
13
14
suspend fun getOrCreateUser (request : AuthRequest , allowNewRegister : Boolean ): UserInfo ? = withRetry {
14
15
require(request.password.length in 2 .. 24 ) {
@@ -17,16 +18,38 @@ suspend fun getOrCreateUser(request: AuthRequest, allowNewRegister: Boolean): Us
17
18
require(request.email.length in 5 .. 320 && ' @' in request.email) {
18
19
" Invalid email address"
19
20
}
20
- val passDigest = request.password.md5()
21
+
21
22
val user = database.users.find { (it.email eq request.email) }
23
+
22
24
when {
23
- user == null && allowNewRegister -> registerUser(request, passDigest)
25
+ user == null && allowNewRegister -> {
26
+ val bcryptHash = PasswordHasher .hash(request.password)
27
+ registerUser(request, bcryptHash)
28
+ }
24
29
user == null -> null
25
- user.passwordHash == passDigest -> user.toUserInfo()
26
- else -> null
30
+ else -> {
31
+ val storedHash = user.passwordHash
32
+
33
+ when {
34
+ PasswordHasher .isArgon2Hash(storedHash) -> {
35
+ if (PasswordHasher .verify(request.password, storedHash)) {
36
+ user.toUserInfo()
37
+ } else null
38
+ }
39
+ else -> { // MD5 legacy
40
+ if (storedHash == request.password.md5()) {
41
+ // Upgrade to bcrypt
42
+ user.passwordHash = PasswordHasher .hash(request.password)
43
+ user.flushChanges()
44
+ user.toUserInfo()
45
+ } else null
46
+ }
47
+ }
48
+ }
27
49
}
28
50
}
29
51
52
+
30
53
private fun registerUser (request : AuthRequest , passwordDigest : String ): UserInfo ? {
31
54
val userId = database.insertAndGenerateKey(UsersTable ) {
32
55
set(it.email, request.email)
0 commit comments