Clean Citizen entities
Change plainPassword to just password Add request Input for /login
This commit is contained in:
@@ -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?
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user