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 org.joda.time.DateTime
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class User(
|
class UserForCreate(
|
||||||
id: UUID = UUID.randomUUID(),
|
id: UUID = UUID.randomUUID(),
|
||||||
username: String,
|
username: String,
|
||||||
|
override val password: String,
|
||||||
blockedAt: DateTime? = null,
|
blockedAt: DateTime? = null,
|
||||||
override var plainPassword: String? = null,
|
roles: List<Roles> = emptyList()
|
||||||
override var roles: List<Roles> = emptyList()
|
) : User(id, username, blockedAt, roles),
|
||||||
) : UserFull,
|
UserWithPasswordI
|
||||||
UserBasic(id, username, blockedAt),
|
|
||||||
|
open class User(
|
||||||
|
id: UUID = UUID.randomUUID(),
|
||||||
|
var username: String,
|
||||||
|
var blockedAt: DateTime? = null,
|
||||||
|
var roles: List<Roles> = emptyList()
|
||||||
|
) : UserRef(id),
|
||||||
EntityCreatedAt by EntityCreatedAtImp(),
|
EntityCreatedAt by EntityCreatedAtImp(),
|
||||||
EntityUpdatedAt by EntityUpdatedAtImp()
|
EntityUpdatedAt by EntityUpdatedAtImp()
|
||||||
|
|
||||||
@Deprecated("")
|
interface UserWithPasswordI {
|
||||||
open class UserBasic(
|
val id: UUID
|
||||||
id: UUID = UUID.randomUUID(),
|
val password: String
|
||||||
override var username: String,
|
}
|
||||||
override var blockedAt: DateTime? = null
|
|
||||||
) : UserBasicI, UserRef(id)
|
class UserWithPassword(
|
||||||
|
id: UUID,
|
||||||
|
override val password: String,
|
||||||
|
) : UserWithPasswordI,
|
||||||
|
UserRef(id)
|
||||||
|
|
||||||
open class UserRef(
|
open class UserRef(
|
||||||
id: UUID = UUID.randomUUID()
|
id: UUID = UUID.randomUUID()
|
||||||
@@ -37,18 +48,6 @@ interface UserI : UuidEntityI, Principal {
|
|||||||
enum class Roles { ROLE_USER, ROLE_ADMIN }
|
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 {
|
interface UserForAuthI : UserI {
|
||||||
var roles: List<Roles>
|
var roles: List<Roles>
|
||||||
var blockedAt: DateTime?
|
var blockedAt: DateTime?
|
||||||
|
|||||||
@@ -4,19 +4,18 @@ import fr.postgresjson.connexion.Requester
|
|||||||
import fr.postgresjson.repository.RepositoryI
|
import fr.postgresjson.repository.RepositoryI
|
||||||
import io.ktor.auth.UserPasswordCredential
|
import io.ktor.auth.UserPasswordCredential
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import fr.dcproject.component.auth.User as UserEntity
|
|
||||||
|
|
||||||
class UserRepository(override var requester: Requester) : RepositoryI {
|
class UserRepository(override var requester: Requester) : RepositoryI {
|
||||||
fun findByCredentials(credentials: UserPasswordCredential): UserEntity? {
|
fun findByCredentials(credentials: UserPasswordCredential): User? {
|
||||||
return requester
|
return requester
|
||||||
.getFunction("check_user")
|
.getFunction("check_user")
|
||||||
.selectOne(
|
.selectOne(
|
||||||
"username" to credentials.name,
|
"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
|
return requester
|
||||||
.getFunction("find_user_by_id")
|
.getFunction("find_user_by_id")
|
||||||
.selectOne(
|
.selectOne(
|
||||||
@@ -24,13 +23,13 @@ class UserRepository(override var requester: Requester) : RepositoryI {
|
|||||||
) ?: throw UserNotFound(id)
|
) ?: throw UserNotFound(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun insert(user: UserEntity): UserEntity? {
|
fun insert(user: User): User? {
|
||||||
return requester
|
return requester
|
||||||
.getFunction("insert_user")
|
.getFunction("insert_user")
|
||||||
.selectOne("resource" to user)
|
.selectOne("resource" to user)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun changePassword(user: UserFull) {
|
fun changePassword(user: UserWithPassword) {
|
||||||
requester
|
requester
|
||||||
.getFunction("change_user_password")
|
.getFunction("change_user_password")
|
||||||
.sendQuery("resource" to user)
|
.sendQuery("resource" to user)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.exc.MismatchedInputException
|
|||||||
import fr.dcproject.common.utils.receiveOrBadRequest
|
import fr.dcproject.common.utils.receiveOrBadRequest
|
||||||
import fr.dcproject.component.auth.UserRepository
|
import fr.dcproject.component.auth.UserRepository
|
||||||
import fr.dcproject.component.auth.jwt.makeToken
|
import fr.dcproject.component.auth.jwt.makeToken
|
||||||
|
import fr.dcproject.component.auth.routes.Login.LoginRequest.Input
|
||||||
import io.ktor.application.call
|
import io.ktor.application.call
|
||||||
import io.ktor.auth.UserPasswordCredential
|
import io.ktor.auth.UserPasswordCredential
|
||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
@@ -17,12 +18,20 @@ import io.ktor.routing.Route
|
|||||||
@KtorExperimentalLocationsAPI
|
@KtorExperimentalLocationsAPI
|
||||||
object Login {
|
object Login {
|
||||||
@Location("/login")
|
@Location("/login")
|
||||||
class LoginRequest
|
class LoginRequest {
|
||||||
|
data class Input(
|
||||||
|
val username: String,
|
||||||
|
val password: String,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun Route.authLogin(userRepo: UserRepository) {
|
fun Route.authLogin(userRepo: UserRepository) {
|
||||||
post<LoginRequest> {
|
post<LoginRequest> {
|
||||||
try {
|
try {
|
||||||
val credentials = call.receiveOrBadRequest<UserPasswordCredential>()
|
val credentials = call.receiveOrBadRequest<Input>().run {
|
||||||
|
UserPasswordCredential(username, password)
|
||||||
|
}
|
||||||
|
|
||||||
userRepo.findByCredentials(credentials)?.let { user ->
|
userRepo.findByCredentials(credentials)?.let { user ->
|
||||||
call.respondText(user.makeToken())
|
call.respondText(user.makeToken())
|
||||||
} ?: call.respond(HttpStatusCode.BadRequest, "Username not exist or password is wrong")
|
} ?: 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 com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException
|
||||||
import fr.dcproject.common.utils.receiveOrBadRequest
|
import fr.dcproject.common.utils.receiveOrBadRequest
|
||||||
import fr.dcproject.component.auth.User
|
import fr.dcproject.component.auth.User
|
||||||
|
import fr.dcproject.component.auth.UserForCreate
|
||||||
import fr.dcproject.component.auth.UserI
|
import fr.dcproject.component.auth.UserI
|
||||||
import fr.dcproject.component.auth.jwt.makeToken
|
import fr.dcproject.component.auth.jwt.makeToken
|
||||||
import fr.dcproject.component.auth.routes.Register.RegisterRequest.Input
|
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.CitizenI
|
||||||
import fr.dcproject.component.citizen.CitizenRepository
|
import fr.dcproject.component.citizen.CitizenRepository
|
||||||
import io.ktor.application.call
|
import io.ktor.application.call
|
||||||
@@ -39,21 +40,21 @@ object Register {
|
|||||||
)
|
)
|
||||||
data class User(
|
data class User(
|
||||||
val username: String,
|
val username: String,
|
||||||
val plainPassword: String? = null
|
val password: String
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Route.authRegister(citizenRepo: CitizenRepository) {
|
fun Route.authRegister(citizenRepo: CitizenRepository) {
|
||||||
fun Input.toCitizen(): Citizen = Citizen(
|
fun Input.toCitizen(): CitizenForCreate = CitizenForCreate(
|
||||||
name = CitizenI.Name(name.firstName, name.lastName, name.civility),
|
name = CitizenI.Name(name.firstName, name.lastName, name.civility),
|
||||||
birthday = birthday,
|
birthday = birthday,
|
||||||
email = email,
|
email = email,
|
||||||
followAnonymous = followAnonymous,
|
followAnonymous = followAnonymous,
|
||||||
voteAnonymous = voteAnonymous,
|
voteAnonymous = voteAnonymous,
|
||||||
user = User(
|
user = UserForCreate(
|
||||||
username = user.username,
|
username = user.username,
|
||||||
plainPassword = user.plainPassword,
|
password = user.password,
|
||||||
roles = listOf(UserI.Roles.ROLE_USER)
|
roles = listOf(UserI.Roles.ROLE_USER)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package fr.dcproject.component.citizen
|
package fr.dcproject.component.citizen
|
||||||
|
|
||||||
import fr.dcproject.component.auth.User
|
import fr.dcproject.component.auth.User
|
||||||
|
import fr.dcproject.component.auth.UserForCreate
|
||||||
import fr.dcproject.component.auth.UserI
|
import fr.dcproject.component.auth.UserI
|
||||||
import fr.dcproject.component.auth.UserRef
|
import fr.dcproject.component.auth.UserRef
|
||||||
import fr.dcproject.component.citizen.CitizenI.Name
|
import fr.dcproject.component.citizen.CitizenI.Name
|
||||||
@@ -14,6 +15,18 @@ import fr.postgresjson.entity.UuidEntityI
|
|||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
import java.util.UUID
|
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(
|
class Citizen(
|
||||||
override val id: UUID = UUID.randomUUID(),
|
override val id: UUID = UUID.randomUUID(),
|
||||||
override val name: Name,
|
override val name: Name,
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ class CitizenRepository(override var requester: Requester) : RepositoryI {
|
|||||||
"search" to search
|
"search" to search
|
||||||
)
|
)
|
||||||
|
|
||||||
fun upsert(citizen: CitizenFull): Citizen? = requester
|
fun upsert(citizen: Citizen): Citizen? = requester
|
||||||
.getFunction("upsert_citizen")
|
.getFunction("upsert_citizen")
|
||||||
.selectOne("resource" to citizen)
|
.selectOne("resource" to citizen)
|
||||||
|
|
||||||
fun insertWithUser(citizen: CitizenFull): Citizen? = requester
|
fun insertWithUser(citizen: CitizenForCreate): Citizen? = requester
|
||||||
.getFunction("insert_citizen_with_user")
|
.getFunction("insert_citizen_with_user")
|
||||||
.selectOne("resource" to citizen)
|
.selectOne("resource" to citizen)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package fr.dcproject.component.citizen.routes
|
|||||||
import fr.dcproject.common.security.assert
|
import fr.dcproject.common.security.assert
|
||||||
import fr.dcproject.common.utils.receiveOrBadRequest
|
import fr.dcproject.common.utils.receiveOrBadRequest
|
||||||
import fr.dcproject.component.auth.UserRepository
|
import fr.dcproject.component.auth.UserRepository
|
||||||
|
import fr.dcproject.component.auth.UserWithPassword
|
||||||
import fr.dcproject.component.auth.citizen
|
import fr.dcproject.component.auth.citizen
|
||||||
import fr.dcproject.component.auth.citizenOrNull
|
import fr.dcproject.component.auth.citizenOrNull
|
||||||
import fr.dcproject.component.citizen.CitizenAccessControl
|
import fr.dcproject.component.citizen.CitizenAccessControl
|
||||||
@@ -31,8 +32,12 @@ object ChangeMyPassword {
|
|||||||
ac.assert { canChangePassword(it.citizen, citizenOrNull) }
|
ac.assert { canChangePassword(it.citizen, citizenOrNull) }
|
||||||
val content = call.receiveOrBadRequest<ChangePasswordCitizenRequest.Input>()
|
val content = call.receiveOrBadRequest<ChangePasswordCitizenRequest.Input>()
|
||||||
userRepository.findByCredentials(UserPasswordCredential(citizen.user.username, content.oldPassword)) ?: throw BadRequestException("Bad Password")
|
userRepository.findByCredentials(UserPasswordCredential(citizen.user.username, content.oldPassword)) ?: throw BadRequestException("Bad Password")
|
||||||
citizen.user.plainPassword = content.newPassword
|
userRepository.changePassword(
|
||||||
userRepository.changePassword(citizen.user)
|
UserWithPassword(
|
||||||
|
citizen.user.id,
|
||||||
|
content.newPassword,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
call.respond(HttpStatusCode.Created)
|
call.respond(HttpStatusCode.Created)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1330,7 +1330,7 @@ components:
|
|||||||
- $ref: '#/components/schemas/UserBase'
|
- $ref: '#/components/schemas/UserBase'
|
||||||
- type: object
|
- type: object
|
||||||
properties:
|
properties:
|
||||||
plain_password:
|
password:
|
||||||
type: string
|
type: string
|
||||||
required: true
|
required: true
|
||||||
example:
|
example:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ create or replace function change_user_password(resource json) returns void lang
|
|||||||
$$
|
$$
|
||||||
begin
|
begin
|
||||||
update "user"
|
update "user"
|
||||||
set password = crypt(resource->>'plain_password', gen_salt('bf', 8))
|
set password = crypt(resource->>'password', gen_salt('bf', 8))
|
||||||
where id = (resource->>'id')::uuid;
|
where id = (resource->>'id')::uuid;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
create or replace function check_user(in username text, in plain_password text, out resource json) language plpgsql as
|
create or replace function check_user(in _username text, in _password text, out resource json) language plpgsql as
|
||||||
$$
|
$$
|
||||||
declare
|
|
||||||
_username alias for username;
|
|
||||||
begin
|
begin
|
||||||
select
|
select
|
||||||
case when count(u) = 1
|
case when count(u) = 1
|
||||||
@@ -10,7 +8,7 @@ begin
|
|||||||
into resource
|
into resource
|
||||||
from "user" as u
|
from "user" as u
|
||||||
where u.username = lower(_username)
|
where u.username = lower(_username)
|
||||||
and u.password = crypt(plain_password, u.password)
|
and u.password = crypt(_password, u.password)
|
||||||
group by u;
|
group by u;
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ begin
|
|||||||
select
|
select
|
||||||
coalesce(t.id, uuid_generate_v4()),
|
coalesce(t.id, uuid_generate_v4()),
|
||||||
t.username,
|
t.username,
|
||||||
crypt(resource->>'plain_password', gen_salt('bf', 8)),
|
crypt(resource->>'password', gen_salt('bf', 8)),
|
||||||
case when t.blocked_at is not null then now() else null end,
|
case when t.blocked_at is not null then now() else null end,
|
||||||
t.roles
|
t.roles
|
||||||
from json_populate_record(null::"user", resource) t
|
from json_populate_record(null::"user", resource) t
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import fr.dcproject.common.utils.toUUID
|
|||||||
import fr.dcproject.component.article.ArticleForUpdate
|
import fr.dcproject.component.article.ArticleForUpdate
|
||||||
import fr.dcproject.component.article.ArticleForView
|
import fr.dcproject.component.article.ArticleForView
|
||||||
import fr.dcproject.component.article.ArticleRepository
|
import fr.dcproject.component.article.ArticleRepository
|
||||||
|
import fr.dcproject.component.auth.UserForCreate
|
||||||
import fr.dcproject.component.citizen.Citizen
|
import fr.dcproject.component.citizen.Citizen
|
||||||
|
import fr.dcproject.component.citizen.CitizenForCreate
|
||||||
import fr.dcproject.component.citizen.CitizenI
|
import fr.dcproject.component.citizen.CitizenI
|
||||||
import fr.dcproject.component.citizen.CitizenRepository
|
import fr.dcproject.component.citizen.CitizenRepository
|
||||||
import fr.dcproject.component.comment.article.CommentArticleRepository
|
import fr.dcproject.component.comment.article.CommentArticleRepository
|
||||||
@@ -16,7 +18,6 @@ import org.joda.time.DateTime
|
|||||||
import org.koin.test.KoinTest
|
import org.koin.test.KoinTest
|
||||||
import org.koin.test.get
|
import org.koin.test.get
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import fr.dcproject.component.auth.User as UserEntity
|
|
||||||
|
|
||||||
class ArticleSteps : En, KoinTest {
|
class ArticleSteps : En, KoinTest {
|
||||||
init {
|
init {
|
||||||
@@ -57,16 +58,16 @@ class ArticleSteps : En, KoinTest {
|
|||||||
} else {
|
} else {
|
||||||
val first = "firstName" + UUID.randomUUID().toString()
|
val first = "firstName" + UUID.randomUUID().toString()
|
||||||
val last = "lastName" + UUID.randomUUID().toString()
|
val last = "lastName" + UUID.randomUUID().toString()
|
||||||
Citizen(
|
CitizenForCreate(
|
||||||
birthday = DateTime.now(),
|
birthday = DateTime.now(),
|
||||||
name = CitizenI.Name(
|
name = CitizenI.Name(
|
||||||
first,
|
first,
|
||||||
last
|
last
|
||||||
),
|
),
|
||||||
email = "$first@fakeemail.com",
|
email = "$first@fakeemail.com",
|
||||||
user = UserEntity(username = username, plainPassword = "azerty")
|
user = UserForCreate(username = username, password = "azerty")
|
||||||
).also {
|
).let {
|
||||||
get<CitizenRepository>().insertWithUser(it)
|
get<CitizenRepository>().insertWithUser(it) ?: error("Unable to create User")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package steps
|
package steps
|
||||||
|
|
||||||
import fr.dcproject.component.auth.User
|
import fr.dcproject.component.auth.UserForCreate
|
||||||
import fr.dcproject.component.citizen.Citizen
|
import fr.dcproject.component.citizen.CitizenForCreate
|
||||||
import fr.dcproject.component.citizen.CitizenI
|
import fr.dcproject.component.citizen.CitizenI
|
||||||
import fr.dcproject.component.citizen.CitizenRepository
|
import fr.dcproject.component.citizen.CitizenRepository
|
||||||
import io.cucumber.datatable.DataTable
|
import io.cucumber.datatable.DataTable
|
||||||
@@ -40,12 +40,12 @@ class CitizenSteps : En, KoinTest {
|
|||||||
val id: UUID = id ?: params?.get("id")?.let { UUID.fromString(it) } ?: UUID.randomUUID()
|
val id: UUID = id ?: params?.get("id")?.let { UUID.fromString(it) } ?: UUID.randomUUID()
|
||||||
val email = params?.get("email") ?: ("$firstName-$lastName".toLowerCase()) + "@dc-project.fr"
|
val email = params?.get("email") ?: ("$firstName-$lastName".toLowerCase()) + "@dc-project.fr"
|
||||||
|
|
||||||
val user = User(
|
val user = UserForCreate(
|
||||||
id = id,
|
id = id,
|
||||||
username = "$firstName-$lastName".toLowerCase(),
|
username = "$firstName-$lastName".toLowerCase(),
|
||||||
plainPassword = "azerty"
|
password = "azerty",
|
||||||
)
|
)
|
||||||
val citizen = Citizen(
|
val citizen = CitizenForCreate(
|
||||||
id = id,
|
id = id,
|
||||||
name = CitizenI.Name(firstName, lastName),
|
name = CitizenI.Name(firstName, lastName),
|
||||||
email = email,
|
email = email,
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package steps
|
|||||||
|
|
||||||
import fr.dcproject.common.utils.toUUID
|
import fr.dcproject.common.utils.toUUID
|
||||||
import fr.dcproject.component.article.ArticleRef
|
import fr.dcproject.component.article.ArticleRef
|
||||||
|
import fr.dcproject.component.auth.UserForCreate
|
||||||
import fr.dcproject.component.citizen.Citizen
|
import fr.dcproject.component.citizen.Citizen
|
||||||
|
import fr.dcproject.component.citizen.CitizenForCreate
|
||||||
import fr.dcproject.component.citizen.CitizenI
|
import fr.dcproject.component.citizen.CitizenI
|
||||||
import fr.dcproject.component.citizen.CitizenRepository
|
import fr.dcproject.component.citizen.CitizenRepository
|
||||||
import fr.dcproject.component.citizen.CitizenWithUserI
|
import fr.dcproject.component.citizen.CitizenWithUserI
|
||||||
@@ -18,7 +20,6 @@ import org.joda.time.DateTime
|
|||||||
import org.koin.test.KoinTest
|
import org.koin.test.KoinTest
|
||||||
import org.koin.test.get
|
import org.koin.test.get
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import fr.dcproject.component.auth.User as UserEntity
|
|
||||||
|
|
||||||
class ConstitutionSteps : En, KoinTest {
|
class ConstitutionSteps : En, KoinTest {
|
||||||
init {
|
init {
|
||||||
@@ -55,16 +56,16 @@ class ConstitutionSteps : En, KoinTest {
|
|||||||
} else {
|
} else {
|
||||||
val first = "firstName" + UUID.randomUUID().toString()
|
val first = "firstName" + UUID.randomUUID().toString()
|
||||||
val last = "lastName" + UUID.randomUUID().toString()
|
val last = "lastName" + UUID.randomUUID().toString()
|
||||||
Citizen(
|
CitizenForCreate(
|
||||||
birthday = DateTime.now(),
|
birthday = DateTime.now(),
|
||||||
name = CitizenI.Name(
|
name = CitizenI.Name(
|
||||||
first,
|
first,
|
||||||
last
|
last
|
||||||
),
|
),
|
||||||
email = "$first@fakeemail.com",
|
email = "$first@fakeemail.com",
|
||||||
user = UserEntity(username = username, plainPassword = "azerty")
|
user = UserForCreate(username = username, password = "azerty")
|
||||||
).also {
|
).let {
|
||||||
get<CitizenRepository>().insertWithUser(it)
|
get<CitizenRepository>().insertWithUser(it) ?: error("Unable to create User")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package steps
|
package steps
|
||||||
|
|
||||||
import fr.dcproject.common.utils.toUUID
|
import fr.dcproject.common.utils.toUUID
|
||||||
import fr.dcproject.component.auth.User
|
import fr.dcproject.component.auth.UserForCreate
|
||||||
import fr.dcproject.component.citizen.Citizen
|
import fr.dcproject.component.citizen.CitizenForCreate
|
||||||
import fr.dcproject.component.citizen.CitizenI
|
import fr.dcproject.component.citizen.CitizenI
|
||||||
import fr.dcproject.component.citizen.CitizenRef
|
import fr.dcproject.component.citizen.CitizenRef
|
||||||
import fr.dcproject.component.citizen.CitizenRepository
|
import fr.dcproject.component.citizen.CitizenRepository
|
||||||
@@ -39,17 +39,17 @@ class WorkgroupSteps : En, KoinTest {
|
|||||||
get<CitizenRepository>().findByUsername(it.toLowerCase().replace(' ', '-'))
|
get<CitizenRepository>().findByUsername(it.toLowerCase().replace(' ', '-'))
|
||||||
} ?: run {
|
} ?: run {
|
||||||
val username = "paul-langevin".toLowerCase() + UUID.randomUUID()
|
val username = "paul-langevin".toLowerCase() + UUID.randomUUID()
|
||||||
val user = User(
|
val user = UserForCreate(
|
||||||
username = username,
|
username = username,
|
||||||
plainPassword = "azerty"
|
password = "azerty",
|
||||||
)
|
)
|
||||||
Citizen(
|
CitizenForCreate(
|
||||||
name = CitizenI.Name("Paul", "Langevin"),
|
name = CitizenI.Name("Paul", "Langevin"),
|
||||||
email = "$username@dc-project.fr",
|
email = "$username@dc-project.fr",
|
||||||
birthday = DateTime.now(),
|
birthday = DateTime.now(),
|
||||||
user = user
|
user = user
|
||||||
).also {
|
).let {
|
||||||
get<CitizenRepository>().insertWithUser(it)
|
get<CitizenRepository>().insertWithUser(it) ?: error("Unable to create User")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
@auth
|
@auth
|
||||||
Feature: Auth routes
|
Feature: Auth routes
|
||||||
|
|
||||||
Scenario: The route for create citizen must response a 200 and return object
|
Scenario: I can resiter
|
||||||
When I send a POST request to "/register" with body:
|
When I send a POST request to "/register" with body:
|
||||||
"""
|
"""
|
||||||
{
|
{
|
||||||
@@ -9,7 +9,7 @@ Feature: Auth routes
|
|||||||
"birthday": "2001-01-01",
|
"birthday": "2001-01-01",
|
||||||
"user":{
|
"user":{
|
||||||
"username": "george-junior",
|
"username": "george-junior",
|
||||||
"plain_password": "azerty"
|
"password": "azerty"
|
||||||
},
|
},
|
||||||
"email": "george-junior@gmail.com"
|
"email": "george-junior@gmail.com"
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,7 @@ Feature: Auth routes
|
|||||||
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.
|
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Scenario: The route for create citizen must response a 400 and return object
|
Scenario: I cannot create user if no username was sent
|
||||||
When I send a POST request to "/register" with body:
|
When I send a POST request to "/register" with body:
|
||||||
"""
|
"""
|
||||||
{
|
{
|
||||||
@@ -28,18 +28,19 @@ Feature: Auth routes
|
|||||||
"birthday": "2001-01-01",
|
"birthday": "2001-01-01",
|
||||||
"user":{
|
"user":{
|
||||||
"username": "",
|
"username": "",
|
||||||
"plain_password": ""
|
"password": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
Then the response status code should be 400
|
Then the response status code should be 400
|
||||||
|
|
||||||
Scenario: The route for create citizen must response a 200 and return object
|
Scenario: I can login with username and password
|
||||||
|
The route for create citizen must response a 200 and return object
|
||||||
Given I have citizen Niels Bohr
|
Given I have citizen Niels Bohr
|
||||||
When I send a POST request to "/login" with body:
|
When I send a POST request to "/login" with body:
|
||||||
"""
|
"""
|
||||||
{
|
{
|
||||||
"name": "niels-bohr",
|
"username": "niels-bohr",
|
||||||
"password": "azerty"
|
"password": "azerty"
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
@citizen
|
@citizen
|
||||||
Feature: citizens routes
|
Feature: citizens routes
|
||||||
|
|
||||||
Scenario: The route for get citizens must response a 200
|
Scenario: I can get Citizens informations
|
||||||
Given I have citizen Jean Perrin with ID "5267a5c6-af42-4a02-aa2b-6b71d2e43973"
|
Given I have citizen Jean Perrin with ID "5267a5c6-af42-4a02-aa2b-6b71d2e43973"
|
||||||
And I am authenticated as Jean Perrin
|
And I am authenticated as Jean Perrin
|
||||||
When I send a GET request to "/citizens"
|
When I send a GET request to "/citizens"
|
||||||
Then the response status code should be 200
|
Then the response status code should be 200
|
||||||
|
|
||||||
Scenario: The route for get one citizen must response a 200 and return citizen
|
Scenario: I can get specific Citizen informations
|
||||||
Given I have citizen Linus Pauling with ID "47a05c0f-7329-46c3-a7d0-325db37e9114"
|
Given I have citizen Linus Pauling with ID "47a05c0f-7329-46c3-a7d0-325db37e9114"
|
||||||
Given I am authenticated as Linus Pauling
|
Given I am authenticated as Linus Pauling
|
||||||
When I send a GET request to "/citizens/47a05c0f-7329-46c3-a7d0-325db37e9114"
|
When I send a GET request to "/citizens/47a05c0f-7329-46c3-a7d0-325db37e9114"
|
||||||
@@ -15,7 +15,7 @@ Feature: citizens routes
|
|||||||
And the response should contain object:
|
And the response should contain object:
|
||||||
| id | 47a05c0f-7329-46c3-a7d0-325db37e9114 |
|
| id | 47a05c0f-7329-46c3-a7d0-325db37e9114 |
|
||||||
|
|
||||||
Scenario: Can get connected citizen
|
Scenario: I can get my citizen informations when I was connected
|
||||||
Given I have citizen Henri Becquerel with ID "47356809-c8ef-4649-8b99-1c5cb9886d38"
|
Given I have citizen Henri Becquerel with ID "47356809-c8ef-4649-8b99-1c5cb9886d38"
|
||||||
And I am authenticated as Henri Becquerel
|
And I am authenticated as Henri Becquerel
|
||||||
When I send a GET request to "/citizens/current"
|
When I send a GET request to "/citizens/current"
|
||||||
@@ -24,7 +24,7 @@ Feature: citizens routes
|
|||||||
| id | 47356809-c8ef-4649-8b99-1c5cb9886d38 |
|
| id | 47356809-c8ef-4649-8b99-1c5cb9886d38 |
|
||||||
|
|
||||||
@online
|
@online
|
||||||
Scenario: Can be connect with Passwordless auth
|
Scenario: I can be connect with Passwordless auth
|
||||||
Given I have citizen
|
Given I have citizen
|
||||||
| id | c606110c-ff0e-4d09-a79e-74632d7bf7bd |
|
| id | c606110c-ff0e-4d09-a79e-74632d7bf7bd |
|
||||||
| email | fabrice.lecomte.be@gmail.com |
|
| email | fabrice.lecomte.be@gmail.com |
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ declare
|
|||||||
wrong_citizen json;
|
wrong_citizen json;
|
||||||
_user_id uuid := fixture_user();
|
_user_id uuid := fixture_user();
|
||||||
created_citizen json := '{"name": {"first_name":"George", "last_name":"MICHEL"}, "birthday": "2001-01-01", "email":"george.michel@gmail.com"}';
|
created_citizen json := '{"name": {"first_name":"George", "last_name":"MICHEL"}, "birthday": "2001-01-01", "email":"george.michel@gmail.com"}';
|
||||||
created_citizen_with_user json := '{"name": {"first_name":"George", "last_name":"MICHEL"}, "birthday": "2001-01-01", "email":"george.michel2@gmail.com", "user":{"username": "george junior", "plain_password": "azerty", "roles": ["ROLE_USER"]}}';
|
created_citizen_with_user json := '{"name": {"first_name":"George", "last_name":"MICHEL"}, "birthday": "2001-01-01", "email":"george.michel2@gmail.com", "user":{"username": "george junior", "password": "azerty", "roles": ["ROLE_USER"]}}';
|
||||||
selected_citizen json;
|
selected_citizen json;
|
||||||
begin
|
begin
|
||||||
created_citizen := jsonb_set(created_citizen::jsonb, '{user}'::text[], jsonb_build_object('id', _user_id::text), true)::json;
|
created_citizen := jsonb_set(created_citizen::jsonb, '{user}'::text[], jsonb_build_object('id', _user_id::text), true)::json;
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ declare
|
|||||||
created_user json;
|
created_user json;
|
||||||
begin
|
begin
|
||||||
if (name = 'george') then
|
if (name = 'george') then
|
||||||
created_user = '{"username": "george", "plain_password": "azerty", "roles": ["ROLE_USER"]}';
|
created_user = '{"username": "george", "password": "azerty", "roles": ["ROLE_USER"]}';
|
||||||
elseif (name = 'john') then
|
elseif (name = 'john') then
|
||||||
created_user = '{"username": "john", "plain_password": "qwerty", "roles": ["ROLE_USER"]}';
|
created_user = '{"username": "john", "password": "qwerty", "roles": ["ROLE_USER"]}';
|
||||||
elseif (name = 'tesla') then
|
elseif (name = 'tesla') then
|
||||||
created_user = '{"username": "tesla", "plain_password": "azerty", "roles": ["ROLE_USER"]}';
|
created_user = '{"username": "tesla", "password": "azerty", "roles": ["ROLE_USER"]}';
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
select insert_user(created_user) into created_user;
|
select insert_user(created_user) into created_user;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
do
|
do
|
||||||
$$
|
$$
|
||||||
declare
|
declare
|
||||||
created_user json := '{"username": "george", "plain_password": "azerty", "roles": ["ROLE_USER"]}';
|
created_user json := '{"username": "george", "password": "azerty", "roles": ["ROLE_USER"]}';
|
||||||
created_user2 json := '{"username": "george2", "plain_password": "azerty", "roles": ["ROLE_USER"]}';
|
created_user2 json := '{"username": "george2", "password": "azerty", "roles": ["ROLE_USER"]}';
|
||||||
_citizen_id uuid;
|
_citizen_id uuid;
|
||||||
_citizen_id2 uuid;
|
_citizen_id2 uuid;
|
||||||
created_citizen json := $json$
|
created_citizen json := $json$
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
do
|
do
|
||||||
$$
|
$$
|
||||||
declare
|
declare
|
||||||
created_user json := '{"username": "george", "plain_password": "azerty", "roles": ["ROLE_USER"]}';
|
created_user json := '{"username": "george", "password": "azerty", "roles": ["ROLE_USER"]}';
|
||||||
user_with_other_password json;
|
user_with_other_password json;
|
||||||
selected_user json;
|
selected_user json;
|
||||||
exist_user json;
|
exist_user json;
|
||||||
@@ -26,7 +26,7 @@ begin
|
|||||||
assert exist_user->>'password' is null, format('the function check_user must not be return the password, %s is return', exist_user::text);
|
assert exist_user->>'password' is null, format('the function check_user must not be return the password, %s is return', exist_user::text);
|
||||||
|
|
||||||
-- test change password
|
-- test change password
|
||||||
user_with_other_password = jsonb_set(created_user::jsonb, '{plain_password}', '"qwerty"'::jsonb);
|
user_with_other_password = jsonb_set(created_user::jsonb, '{password}', '"qwerty"'::jsonb);
|
||||||
perform change_user_password(user_with_other_password);
|
perform change_user_password(user_with_other_password);
|
||||||
select check_user('george', 'qwerty') into exist_user;
|
select check_user('george', 'qwerty') into exist_user;
|
||||||
assert exist_user->>'username' = 'george', format('the function change_user_password must change password: %s', exist_user::text);
|
assert exist_user->>'username' = 'george', format('the function change_user_password must change password: %s', exist_user::text);
|
||||||
|
|||||||
Reference in New Issue
Block a user