移除Dto(難用)

This commit is contained in:
Raymond Yang 2023-05-16 13:48:09 +08:00
parent 8999ab3272
commit bd214f0423
13 changed files with 62 additions and 152 deletions

View File

@ -31,6 +31,7 @@ dependencies {
testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
implementation("org.litote.kmongo:kmongo:$kmongo_version")
implementation("org.litote.kmongo:kmongo-id-serialization:$kmongo_version")
implementation("io.ktor:ktor-server-auth-jvm:$ktor_version")
implementation("io.ktor:ktor-server-auth-jwt-jvm:$ktor_version")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0")

View File

@ -1,8 +1,9 @@
package com.ray650128
import com.ray650128.model.dto.UserDto
import com.ray650128.model.pojo.User
import com.ray650128.plugins.configureUserRouting
import com.ray650128.plugins.configureArMaterialRouting
import com.ray650128.service.UserService
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
@ -10,20 +11,25 @@ import io.ktor.server.auth.jwt.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.plugins.contentnegotiation.*
import kotlinx.serialization.json.Json
import org.litote.kmongo.id.serialization.IdKotlinXSerializationModule
fun main() {
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
install(ContentNegotiation) {
json()
json(
Json { serializersModule = IdKotlinXSerializationModule }
)
}
install(Authentication) {
jwt {
verifier(JwtConfig.verifier)
realm = JwtConfig.myRealm
validate {
val service = UserService()
val name = it.payload.getClaim("account").asString()
if (name != null) {
UserDto(account = name, password = "")
service.findByAccount(name)
} else {
null
}

View File

@ -3,7 +3,7 @@ package com.ray650128
import com.auth0.jwt.JWT
import com.auth0.jwt.JWTVerifier
import com.auth0.jwt.algorithms.Algorithm
import com.ray650128.model.dto.UserDto
import com.ray650128.model.pojo.User
import java.util.*
object JwtConfig {
@ -21,7 +21,7 @@ object JwtConfig {
/**
* Produce a token for this combination of name and password
*/
fun generateToken(user: UserDto): String = JWT.create()
fun generateToken(user: User): String = JWT.create()
.withSubject("Authentication")
.withIssuer(issuer)
.withClaim("account", user.account)

View File

@ -1,28 +0,0 @@
package com.ray650128.extension
import com.ray650128.model.dto.MaterialDto
import com.ray650128.model.dto.UserDto
import com.ray650128.model.pojo.Material
import com.ray650128.model.pojo.User
fun Material.toDto(): MaterialDto =
MaterialDto(
id = this.id.toString(),
ownerId = this.ownerId.toString(),
name = this.name,
path = this.path,
contentType = this.contentType,
fileTag = this.fileTag,
createAt = this.createAt,
updatedAt = this.updatedAt
)
fun MaterialDto.toMaterial(): Material =
Material(
name = this.name,
path = this.path,
contentType = this.contentType,
fileTag = this.fileTag,
createAt = this.createAt,
updatedAt = this.updatedAt
)

View File

@ -1,25 +0,0 @@
package com.ray650128.extension
import com.ray650128.model.dto.UserDto
import com.ray650128.model.pojo.User
fun User.toDto(): UserDto =
UserDto(
id = this.id.toString(),
account = this.account,
password = this.password,
name = this.name,
token = this.token,
createAt = this.createAt,
updatedAt = this.updatedAt
)
fun UserDto.toUser(): User =
User(
account = this.account,
password = this.password,
name = this.name,
token = this.token,
createAt = this.createAt,
updatedAt = this.updatedAt
)

View File

@ -1,16 +0,0 @@
package com.ray650128.model.dto
import io.ktor.server.auth.*
import kotlinx.serialization.Serializable
@Serializable
data class MaterialDto(
val id: String? = null,
var ownerId: String? = null,
var name: String,
val path: String,
val contentType: String,
var fileTag: ArrayList<String>? = null,
var createAt: Long? = null,
var updatedAt: Long? = null
): Principal

View File

@ -1,15 +0,0 @@
package com.ray650128.model.dto
import io.ktor.server.auth.*
import kotlinx.serialization.Serializable
@Serializable
data class UserDto(
val id: String? = null,
val account: String,
val password: String,
val name: String? = null,
var token: String? = null,
var createAt: Long? = null,
var updatedAt: Long? = null
): Principal

View File

@ -1,14 +1,17 @@
package com.ray650128.model.pojo
import org.bson.codecs.pojo.annotations.BsonId
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
import org.litote.kmongo.Id
import org.litote.kmongo.newId
@Serializable
data class Material(
@BsonId var id: Id<Material>? = null,
var ownerId: Id<User>? = null,
@Contextual var _id: Id<Material> = newId(),
@Contextual var ownerId: Id<User>? = null,
var name: String,
var path: String,
var contentType: String,
var path: String? = null,
var contentType: String? = null,
var fileTag: ArrayList<String>? = null,
var createAt: Long? = null,
var updatedAt: Long? = null

View File

@ -1,15 +1,18 @@
package com.ray650128.model.pojo
import org.bson.codecs.pojo.annotations.BsonId
import io.ktor.server.auth.*
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
import org.litote.kmongo.Id
import org.litote.kmongo.newId
@Serializable
data class User(
@BsonId
val id: Id<User>? = null,
@Contextual val _id: Id<User>? = newId(),
val account: String,
val password: String,
var name: String? = null,
var token: String? = null,
var createAt: Long? = null,
var updatedAt: Long? = null
)
): Principal

View File

@ -2,10 +2,9 @@ package com.ray650128.plugins
import com.ray650128.extension.*
import com.ray650128.model.ErrorResponse
import com.ray650128.model.dto.MaterialDto
import com.ray650128.model.dto.UserDto
import com.ray650128.model.pojo.Material
import com.ray650128.model.pojo.NewMaterial
import com.ray650128.model.pojo.User
import com.ray650128.service.MaterialService
import com.ray650128.service.UserService
import io.ktor.http.content.*
@ -45,24 +44,16 @@ fun Application.configureArMaterialRouting() {
route("/v1") {
route("/materials") {
get {
val account = call.authentication.principal<UserDto>()?.account ?: run {
val user = call.authentication.principal<User>() ?: run {
call.sendUnauthorized()
return@get
}
val user = userService.findByAccount(account) ?: run {
call.sendUnauthorized()
return@get
}
val list = materialService.findByOwnerId(user.id.toString())
call.sendSuccess(list.map(Material::toDto))
val list = materialService.findByOwnerId(user._id.toString())
call.sendSuccess(list)
}
post("/upload") {
val account = call.authentication.principal<UserDto>()?.account ?: run {
call.sendUnauthorized()
return@post
}
val user = userService.findByAccount(account) ?: run {
val user = call.authentication.principal<User>() ?: run {
call.sendUnauthorized()
return@post
}
@ -102,7 +93,8 @@ fun Application.configureArMaterialRouting() {
}
}
val tmpMaterial = MaterialDto(
val tmpMaterial = Material(
ownerId = user._id!!,
name = if (params == null) {
part.originalFileName!!
} else {
@ -111,9 +103,7 @@ fun Application.configureArMaterialRouting() {
path = "/upload/$name",
contentType = "${part.contentType}",
createAt = System.currentTimeMillis()
).toMaterial().apply {
ownerId = user.id!!
}
)
materialId = materialService.create(tmpMaterial).toString()
}
@ -123,7 +113,7 @@ fun Application.configureArMaterialRouting() {
part.dispose()
}
if (materialId != null) {
val data = materialService.findById(materialId!!)?.toDto()
val data = materialService.findById(materialId!!)
call.sendSuccess(data)
} else {
call.sendBadRequest(ErrorResponse("Add material fail."))
@ -131,11 +121,11 @@ fun Application.configureArMaterialRouting() {
}
put("/{id}") {
call.authentication.principal<UserDto>()?.account ?: run {
call.authentication.principal<User>() ?: run {
call.sendUnauthorized()
return@put
}
val body = call.receive<MaterialDto>()
val body = call.receive<Material>()
val id = call.parameters["id"].toString()
val material = materialService.findById(id) ?: run {
call.sendNotFound()
@ -151,7 +141,7 @@ fun Application.configureArMaterialRouting() {
}
delete("/{id}") {
call.authentication.principal<UserDto>()?.account ?: run {
call.authentication.principal<User>() ?: run {
call.sendUnauthorized()
return@delete
}

View File

@ -2,7 +2,6 @@ package com.ray650128.plugins
import com.ray650128.JwtConfig
import com.ray650128.extension.*
import com.ray650128.model.dto.UserDto
import com.ray650128.model.ErrorResponse
import com.ray650128.model.pojo.LoginResult
import com.ray650128.model.pojo.User
@ -21,13 +20,13 @@ fun Application.configureUserRouting() {
route("/api") {
route("/v1") {
post("/register") {
val request = call.receive<UserDto>()
val request = call.receive<User>()
if (service.findByAccount(request.account) != null) {
call.sendBadRequest(ErrorResponse("User has existed."))
return@post
}
val newToken = JwtConfig.generateToken(request)
val user = request.toUser().apply {
val user = request.apply {
token = newToken
createAt = System.currentTimeMillis()
}
@ -38,7 +37,7 @@ fun Application.configureUserRouting() {
}
post("/login") {
val request = call.receive<UserDto>()
val request = call.receive<User>()
val user = service.findByLoginInfo(request.account, request.password)
if (user != null) {
var token = user.token
@ -46,7 +45,7 @@ fun Application.configureUserRouting() {
token = JwtConfig.generateToken(request)
user.token = token
user.updatedAt = System.currentTimeMillis()
service.updateById(user.id.toString(), user)
service.updateById(user._id.toString(), user)
}
call.sendSuccess(LoginResult(request.account, token!!))
} else {
@ -56,7 +55,7 @@ fun Application.configureUserRouting() {
authenticate {
post("/logout") {
val account = call.authentication.principal<UserDto>()?.account ?: run {
val account = call.authentication.principal<User>()?.account ?: run {
call.sendUnauthorized()
return@post
}
@ -68,35 +67,34 @@ fun Application.configureUserRouting() {
token = null
updatedAt = System.currentTimeMillis()
}
service.updateById(user.id.toString(), user)
service.updateById(user._id.toString(), user)
call.sendSuccess(null)
}
}
}
get {
val peopleList = service.findAll().map(User::toDto)
val peopleList = service.findAll()
call.respond(peopleList)
}
get("/{id}") {
val id = call.parameters["id"].toString()
service.findById(id)
?.let { foundPerson -> call.respond(foundPerson.toDto()) }
?.let { foundPerson -> call.respond(foundPerson) }
?: call.sendNotFound()
}
get("/search") {
val name = call.request.queryParameters["name"].toString()
val foundPeople = service.findByName(name).map(User::toDto)
val foundPeople = service.findByName(name)
call.respond(foundPeople)
}
put("/{id}") {
val id = call.parameters["id"].toString()
val userRequest = call.receive<UserDto>()
val user = userRequest.toUser()
val updatedSuccessfully = service.updateById(id, user)
val userRequest = call.receive<User>()
val updatedSuccessfully = service.updateById(id, userRequest)
if (updatedSuccessfully) {
call.respond(HttpStatusCode.NoContent)
} else {

View File

@ -9,34 +9,27 @@ import org.litote.kmongo.id.toId
class MaterialService {
private val client = KMongo.createClient("mongodb://www.ray650128.com:27017")
private val database = client.getDatabase("ar_system")
private val userCollection = database.getCollection<Material>()
private val materialCollection = database.getCollection<Material>()
fun create(user: Material): Id<Material>? {
userCollection.insertOne(user)
return user.id
fun create(material: Material): Id<Material> {
materialCollection.insertOne(material)
return material._id
}
fun findAll(): List<Material> = userCollection.find().toList()
fun findById(id: String): Material? {
val bsonId: Id<Material> = ObjectId(id).toId()
return userCollection.findOne(Material::id eq bsonId)
return materialCollection.findOne(Material::_id eq bsonId)
}
fun findByOwnerId(ownerId: String): List<Material> {
val bsonId: Id<User> = ObjectId(ownerId).toId()
return userCollection.find(Material::ownerId eq bsonId).toList()
}
fun findByName(name: String): List<Material> {
val caseSensitiveTypeSafeFilter = Material::name regex name
return userCollection.find(caseSensitiveTypeSafeFilter).toList()
return materialCollection.find(Material::ownerId eq bsonId).toList()
}
fun updateById(id: String, request: Material): Boolean =
findById(id)?.let { user ->
val updateResult = userCollection.replaceOne(
user.copy(
findById(id)?.let { material ->
val updateResult = materialCollection.replaceOne(
material.copy(
name = request.name,
updatedAt = request.updatedAt
)
@ -45,7 +38,7 @@ class MaterialService {
} ?: false
fun deleteById(id: String): Boolean {
val deleteResult = userCollection.deleteOneById(ObjectId(id))
val deleteResult = materialCollection.deleteOneById(ObjectId(id))
return deleteResult.deletedCount == 1L
}
}

View File

@ -12,14 +12,14 @@ class UserService {
fun create(user: User): Id<User>? {
userCollection.insertOne(user)
return user.id
return user._id
}
fun findAll(): List<User> = userCollection.find().toList()
fun findById(id: String): User? {
val bsonId: Id<User> = ObjectId(id).toId()
return userCollection.findOne(User::id eq bsonId)
return userCollection.findOne(User::_id eq bsonId)
}
fun findByName(name: String): List<User> {