Can login with SSO & change Password

This commit is contained in:
2019-10-09 21:57:56 +02:00
parent 20416ce108
commit a6f25bcbb2
16 changed files with 197 additions and 41 deletions

View File

@@ -3,13 +3,19 @@ package fr.dcproject.routes
import com.fasterxml.jackson.databind.exc.MismatchedInputException
import fr.dcproject.JwtConfig
import fr.dcproject.entity.User
import fr.dcproject.messages.SsoManager
import fr.dcproject.routes.AuthPaths.LoginRequest
import fr.dcproject.routes.AuthPaths.RegisterRequest
import fr.dcproject.routes.AuthPaths.SsoRequest
import io.ktor.application.call
import io.ktor.auth.UserPasswordCredential
import io.ktor.features.BadRequestException
import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location
import io.ktor.locations.post
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.response.respondText
import io.ktor.routing.Route
import io.ktor.util.KtorExperimentalAPI
@@ -21,12 +27,19 @@ import fr.dcproject.repository.User as UserRepository
object AuthPaths {
@Location("/login") class LoginRequest
@Location("/register") class RegisterRequest
@Location("/sso") class SsoRequest {
data class Content(val email: String, val url: String)
}
}
@KtorExperimentalLocationsAPI
@KtorExperimentalAPI
fun Route.auth(userRepo: UserRepository, citizenRepo: CitizenRepository) {
post <AuthPaths.LoginRequest> {
fun Route.auth(
userRepo: UserRepository,
citizenRepo: CitizenRepository,
ssoManager: SsoManager
) {
post <LoginRequest> {
try {
val credentials = call.receive<UserPasswordCredential>()
val user = userRepo.findByCredentials(credentials) ?: throw BadRequestException("Username not exist or password is wrong")
@@ -36,11 +49,18 @@ fun Route.auth(userRepo: UserRepository, citizenRepo: CitizenRepository) {
}
}
post <AuthPaths.RegisterRequest> {
post <RegisterRequest> {
val citizen = call.receive<CitizenEntity>()
citizen.user?.roles = listOf(User.Roles.ROLE_USER)
val created = citizenRepo.insertWithUser(citizen)?.user ?: throw BadRequestException("Bad request")
call.respondText(JwtConfig.makeToken(created))
}
post<SsoRequest> {
val content = call.receive<SsoRequest.Content>()
ssoManager.sendMail(content.email, content.url)
call.respond(HttpStatusCode.NoContent)
}
}

View File

@@ -2,46 +2,71 @@ package fr.dcproject.routes
import fr.dcproject.citizen
import fr.dcproject.entity.Citizen
import fr.dcproject.routes.CitizenPaths.ChangePasswordCitizenRequest
import fr.dcproject.routes.CitizenPaths.CitizenRequest
import fr.dcproject.routes.CitizenPaths.CitizensRequest
import fr.dcproject.routes.CitizenPaths.CurrentCitizenRequest
import fr.dcproject.security.voter.CitizenVoter.Action.CHANGE_PASSWORD
import fr.dcproject.security.voter.CitizenVoter.Action.VIEW
import fr.dcproject.security.voter.assertCan
import fr.postgresjson.repository.RepositoryI
import fr.postgresjson.repository.RepositoryI.Direction
import io.ktor.application.call
import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location
import io.ktor.locations.get
import io.ktor.locations.put
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.routing.Route
import fr.dcproject.repository.Citizen as CitizenRepository
import fr.dcproject.repository.User as UserRepository
@KtorExperimentalLocationsAPI
object CitizenPaths {
@Location("/citizens") class CitizensRequest(page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: RepositoryI.Direction? = null, val search: String? = null) {
@Location("/citizens") class CitizensRequest(page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: Direction? = null, val search: String? = null) {
val page: Int = if (page < 1) 1 else page
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
}
@Location("/citizens/{citizen}") class CitizenRequest(val citizen: Citizen)
@Location("/citizens/current") class CurrentCitizenRequest
@Location("/citizens/{citizen}/follows/articles") class CitizenFollowArticleRequest(val citizen: Citizen)
@Location("/citizens/{citizen}/follows/constitutions") class CitizenFollowConstitutionRequest(val citizen: Citizen)
@Location("/citizens/{citizen}/password/change") class ChangePasswordCitizenRequest(val citizen: Citizen) {
data class Content(val password: String)
}
}
@KtorExperimentalLocationsAPI
fun Route.citizen(repo: CitizenRepository) {
get<CitizenPaths.CitizensRequest> {
fun Route.citizen(
repo: CitizenRepository,
userRepository: UserRepository
) {
get<CitizensRequest> {
val citizens = repo.find(it.page, it.limit, it.sort, it.direction, it.search)
assertCan(VIEW, citizens.result)
call.respond(citizens)
}
get<CitizenPaths.CitizenRequest> {
get<CitizenRequest> {
assertCan(VIEW, it.citizen)
call.respond(it.citizen)
}
get<CitizenPaths.CurrentCitizenRequest> {
get<CurrentCitizenRequest> {
assertCan(VIEW, citizen)
call.respond(citizen)
}
put<ChangePasswordCitizenRequest> {
assertCan(CHANGE_PASSWORD, it.citizen)
val content = call.receive<ChangePasswordCitizenRequest.Content>()
val user = it.citizen.user ?: error("Citizen must have User")
user.plainPassword = content.password
userRepository.changePassword(user)
call.respond(HttpStatusCode.Created)
}
}