Clean Citizen entities

Change plainPassword to just password
Add request Input for /login
This commit is contained in:
2021-02-09 00:39:26 +01:00
parent 905330a722
commit dcf35eaccd
21 changed files with 114 additions and 87 deletions

View File

@@ -11,23 +11,34 @@ import io.ktor.auth.Principal
import org.joda.time.DateTime
import java.util.UUID
class User(
class UserForCreate(
id: UUID = UUID.randomUUID(),
username: String,
override val password: String,
blockedAt: DateTime? = null,
override var plainPassword: String? = null,
override var roles: List<Roles> = emptyList()
) : UserFull,
UserBasic(id, username, blockedAt),
roles: List<Roles> = emptyList()
) : User(id, username, blockedAt, roles),
UserWithPasswordI
open class User(
id: UUID = UUID.randomUUID(),
var username: String,
var blockedAt: DateTime? = null,
var roles: List<Roles> = emptyList()
) : UserRef(id),
EntityCreatedAt by EntityCreatedAtImp(),
EntityUpdatedAt by EntityUpdatedAtImp()
@Deprecated("")
open class UserBasic(
id: UUID = UUID.randomUUID(),
override var username: String,
override var blockedAt: DateTime? = null
) : UserBasicI, UserRef(id)
interface UserWithPasswordI {
val id: UUID
val password: String
}
class UserWithPassword(
id: UUID,
override val password: String,
) : UserWithPasswordI,
UserRef(id)
open class UserRef(
id: UUID = UUID.randomUUID()
@@ -37,18 +48,6 @@ interface UserI : UuidEntityI, Principal {
enum class Roles { ROLE_USER, ROLE_ADMIN }
}
@Deprecated("")
interface UserBasicI : UserI {
var username: String
var blockedAt: DateTime?
}
@Deprecated("")
interface UserFull : UserBasicI, EntityCreatedAt, EntityUpdatedAt {
var plainPassword: String?
var roles: List<Roles>
}
interface UserForAuthI : UserI {
var roles: List<Roles>
var blockedAt: DateTime?

View File

@@ -4,19 +4,18 @@ import fr.postgresjson.connexion.Requester
import fr.postgresjson.repository.RepositoryI
import io.ktor.auth.UserPasswordCredential
import java.util.UUID
import fr.dcproject.component.auth.User as UserEntity
class UserRepository(override var requester: Requester) : RepositoryI {
fun findByCredentials(credentials: UserPasswordCredential): UserEntity? {
fun findByCredentials(credentials: UserPasswordCredential): User? {
return requester
.getFunction("check_user")
.selectOne(
"username" to credentials.name,
"plain_password" to credentials.password
"password" to credentials.password
)
}
fun findById(id: UUID): UserEntity {
fun findById(id: UUID): User {
return requester
.getFunction("find_user_by_id")
.selectOne(
@@ -24,13 +23,13 @@ class UserRepository(override var requester: Requester) : RepositoryI {
) ?: throw UserNotFound(id)
}
fun insert(user: UserEntity): UserEntity? {
fun insert(user: User): User? {
return requester
.getFunction("insert_user")
.selectOne("resource" to user)
}
fun changePassword(user: UserFull) {
fun changePassword(user: UserWithPassword) {
requester
.getFunction("change_user_password")
.sendQuery("resource" to user)

View File

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.exc.MismatchedInputException
import fr.dcproject.common.utils.receiveOrBadRequest
import fr.dcproject.component.auth.UserRepository
import fr.dcproject.component.auth.jwt.makeToken
import fr.dcproject.component.auth.routes.Login.LoginRequest.Input
import io.ktor.application.call
import io.ktor.auth.UserPasswordCredential
import io.ktor.http.HttpStatusCode
@@ -17,12 +18,20 @@ import io.ktor.routing.Route
@KtorExperimentalLocationsAPI
object Login {
@Location("/login")
class LoginRequest
class LoginRequest {
data class Input(
val username: String,
val password: String,
)
}
fun Route.authLogin(userRepo: UserRepository) {
post<LoginRequest> {
try {
val credentials = call.receiveOrBadRequest<UserPasswordCredential>()
val credentials = call.receiveOrBadRequest<Input>().run {
UserPasswordCredential(username, password)
}
userRepo.findByCredentials(credentials)?.let { user ->
call.respondText(user.makeToken())
} ?: call.respond(HttpStatusCode.BadRequest, "Username not exist or password is wrong")

View File

@@ -3,10 +3,11 @@ package fr.dcproject.component.auth.routes
import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException
import fr.dcproject.common.utils.receiveOrBadRequest
import fr.dcproject.component.auth.User
import fr.dcproject.component.auth.UserForCreate
import fr.dcproject.component.auth.UserI
import fr.dcproject.component.auth.jwt.makeToken
import fr.dcproject.component.auth.routes.Register.RegisterRequest.Input
import fr.dcproject.component.citizen.Citizen
import fr.dcproject.component.citizen.CitizenForCreate
import fr.dcproject.component.citizen.CitizenI
import fr.dcproject.component.citizen.CitizenRepository
import io.ktor.application.call
@@ -39,21 +40,21 @@ object Register {
)
data class User(
val username: String,
val plainPassword: String? = null
val password: String
)
}
}
fun Route.authRegister(citizenRepo: CitizenRepository) {
fun Input.toCitizen(): Citizen = Citizen(
fun Input.toCitizen(): CitizenForCreate = CitizenForCreate(
name = CitizenI.Name(name.firstName, name.lastName, name.civility),
birthday = birthday,
email = email,
followAnonymous = followAnonymous,
voteAnonymous = voteAnonymous,
user = User(
user = UserForCreate(
username = user.username,
plainPassword = user.plainPassword,
password = user.password,
roles = listOf(UserI.Roles.ROLE_USER)
)
)

View File

@@ -1,6 +1,7 @@
package fr.dcproject.component.citizen
import fr.dcproject.component.auth.User
import fr.dcproject.component.auth.UserForCreate
import fr.dcproject.component.auth.UserI
import fr.dcproject.component.auth.UserRef
import fr.dcproject.component.citizen.CitizenI.Name
@@ -14,6 +15,18 @@ import fr.postgresjson.entity.UuidEntityI
import org.joda.time.DateTime
import java.util.UUID
class CitizenForCreate(
val name: Name,
val email: String,
val birthday: DateTime,
val voteAnonymous: Boolean = true,
val followAnonymous: Boolean = true,
override val user: UserForCreate,
id: UUID = UUID.randomUUID(),
) : CitizenI,
CitizenRefWithUser(id, user),
EntityCreatedAt by EntityCreatedAtImp()
class Citizen(
override val id: UUID = UUID.randomUUID(),
override val name: Name,

View File

@@ -40,11 +40,11 @@ class CitizenRepository(override var requester: Requester) : RepositoryI {
"search" to search
)
fun upsert(citizen: CitizenFull): Citizen? = requester
fun upsert(citizen: Citizen): Citizen? = requester
.getFunction("upsert_citizen")
.selectOne("resource" to citizen)
fun insertWithUser(citizen: CitizenFull): Citizen? = requester
fun insertWithUser(citizen: CitizenForCreate): Citizen? = requester
.getFunction("insert_citizen_with_user")
.selectOne("resource" to citizen)
}

View File

@@ -3,6 +3,7 @@ package fr.dcproject.component.citizen.routes
import fr.dcproject.common.security.assert
import fr.dcproject.common.utils.receiveOrBadRequest
import fr.dcproject.component.auth.UserRepository
import fr.dcproject.component.auth.UserWithPassword
import fr.dcproject.component.auth.citizen
import fr.dcproject.component.auth.citizenOrNull
import fr.dcproject.component.citizen.CitizenAccessControl
@@ -31,8 +32,12 @@ object ChangeMyPassword {
ac.assert { canChangePassword(it.citizen, citizenOrNull) }
val content = call.receiveOrBadRequest<ChangePasswordCitizenRequest.Input>()
userRepository.findByCredentials(UserPasswordCredential(citizen.user.username, content.oldPassword)) ?: throw BadRequestException("Bad Password")
citizen.user.plainPassword = content.newPassword
userRepository.changePassword(citizen.user)
userRepository.changePassword(
UserWithPassword(
citizen.user.id,
content.newPassword,
)
)
call.respond(HttpStatusCode.Created)
}