From bd214f04238cf3dc814edbfd2d70b0bfd14e6bae Mon Sep 17 00:00:00 2001 From: Raymond Yang Date: Tue, 16 May 2023 13:48:09 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4Dto(=E9=9B=A3=E7=94=A8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 1 + src/main/kotlin/com/ray650128/Application.kt | 12 +++++-- src/main/kotlin/com/ray650128/JwtConfig.kt | 4 +-- .../ray650128/extension/MaterialExtension.kt | 28 --------------- .../com/ray650128/extension/UserExtension.kt | 25 -------------- .../com/ray650128/model/dto/MaterialDto.kt | 16 --------- .../kotlin/com/ray650128/model/dto/UserDto.kt | 15 -------- .../com/ray650128/model/pojo/Material.kt | 13 ++++--- .../kotlin/com/ray650128/model/pojo/User.kt | 11 +++--- .../ray650128/plugins/ArMaterialRouting.kt | 34 +++++++------------ .../com/ray650128/plugins/UserRouting.kt | 24 ++++++------- .../com/ray650128/service/MaterialService.kt | 27 ++++++--------- .../com/ray650128/service/UserService.kt | 4 +-- 13 files changed, 62 insertions(+), 152 deletions(-) delete mode 100644 src/main/kotlin/com/ray650128/extension/MaterialExtension.kt delete mode 100644 src/main/kotlin/com/ray650128/extension/UserExtension.kt delete mode 100644 src/main/kotlin/com/ray650128/model/dto/MaterialDto.kt delete mode 100644 src/main/kotlin/com/ray650128/model/dto/UserDto.kt diff --git a/build.gradle.kts b/build.gradle.kts index eaaf67b..8cccf44 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -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") diff --git a/src/main/kotlin/com/ray650128/Application.kt b/src/main/kotlin/com/ray650128/Application.kt index fee2959..53b7ac7 100644 --- a/src/main/kotlin/com/ray650128/Application.kt +++ b/src/main/kotlin/com/ray650128/Application.kt @@ -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 } diff --git a/src/main/kotlin/com/ray650128/JwtConfig.kt b/src/main/kotlin/com/ray650128/JwtConfig.kt index 9ecea4a..db08d90 100644 --- a/src/main/kotlin/com/ray650128/JwtConfig.kt +++ b/src/main/kotlin/com/ray650128/JwtConfig.kt @@ -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) diff --git a/src/main/kotlin/com/ray650128/extension/MaterialExtension.kt b/src/main/kotlin/com/ray650128/extension/MaterialExtension.kt deleted file mode 100644 index 1a8b5ce..0000000 --- a/src/main/kotlin/com/ray650128/extension/MaterialExtension.kt +++ /dev/null @@ -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 - ) \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/extension/UserExtension.kt b/src/main/kotlin/com/ray650128/extension/UserExtension.kt deleted file mode 100644 index 0d50a36..0000000 --- a/src/main/kotlin/com/ray650128/extension/UserExtension.kt +++ /dev/null @@ -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 - ) \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/model/dto/MaterialDto.kt b/src/main/kotlin/com/ray650128/model/dto/MaterialDto.kt deleted file mode 100644 index 7f5981d..0000000 --- a/src/main/kotlin/com/ray650128/model/dto/MaterialDto.kt +++ /dev/null @@ -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? = null, - var createAt: Long? = null, - var updatedAt: Long? = null -): Principal \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/model/dto/UserDto.kt b/src/main/kotlin/com/ray650128/model/dto/UserDto.kt deleted file mode 100644 index ed5bb58..0000000 --- a/src/main/kotlin/com/ray650128/model/dto/UserDto.kt +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/model/pojo/Material.kt b/src/main/kotlin/com/ray650128/model/pojo/Material.kt index 9abe5aa..0ac5921 100644 --- a/src/main/kotlin/com/ray650128/model/pojo/Material.kt +++ b/src/main/kotlin/com/ray650128/model/pojo/Material.kt @@ -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? = null, - var ownerId: Id? = null, + @Contextual var _id: Id = newId(), + @Contextual var ownerId: Id? = null, var name: String, - var path: String, - var contentType: String, + var path: String? = null, + var contentType: String? = null, var fileTag: ArrayList? = null, var createAt: Long? = null, var updatedAt: Long? = null diff --git a/src/main/kotlin/com/ray650128/model/pojo/User.kt b/src/main/kotlin/com/ray650128/model/pojo/User.kt index 650c4db..8548144 100644 --- a/src/main/kotlin/com/ray650128/model/pojo/User.kt +++ b/src/main/kotlin/com/ray650128/model/pojo/User.kt @@ -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? = null, + @Contextual val _id: Id? = newId(), val account: String, val password: String, var name: String? = null, var token: String? = null, var createAt: Long? = null, var updatedAt: Long? = null -) \ No newline at end of file +): Principal \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/plugins/ArMaterialRouting.kt b/src/main/kotlin/com/ray650128/plugins/ArMaterialRouting.kt index 85e5a14..26a6575 100644 --- a/src/main/kotlin/com/ray650128/plugins/ArMaterialRouting.kt +++ b/src/main/kotlin/com/ray650128/plugins/ArMaterialRouting.kt @@ -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()?.account ?: run { + val user = call.authentication.principal() ?: 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()?.account ?: run { - call.sendUnauthorized() - return@post - } - val user = userService.findByAccount(account) ?: run { + val user = call.authentication.principal() ?: 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()?.account ?: run { + call.authentication.principal() ?: run { call.sendUnauthorized() return@put } - val body = call.receive() + val body = call.receive() 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()?.account ?: run { + call.authentication.principal() ?: run { call.sendUnauthorized() return@delete } diff --git a/src/main/kotlin/com/ray650128/plugins/UserRouting.kt b/src/main/kotlin/com/ray650128/plugins/UserRouting.kt index ceb2299..82f89b7 100644 --- a/src/main/kotlin/com/ray650128/plugins/UserRouting.kt +++ b/src/main/kotlin/com/ray650128/plugins/UserRouting.kt @@ -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() + val request = call.receive() 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() + val request = call.receive() 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()?.account ?: run { + val account = call.authentication.principal()?.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() - val user = userRequest.toUser() - val updatedSuccessfully = service.updateById(id, user) + val userRequest = call.receive() + val updatedSuccessfully = service.updateById(id, userRequest) if (updatedSuccessfully) { call.respond(HttpStatusCode.NoContent) } else { diff --git a/src/main/kotlin/com/ray650128/service/MaterialService.kt b/src/main/kotlin/com/ray650128/service/MaterialService.kt index 6126c3b..81a2e43 100644 --- a/src/main/kotlin/com/ray650128/service/MaterialService.kt +++ b/src/main/kotlin/com/ray650128/service/MaterialService.kt @@ -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() + private val materialCollection = database.getCollection() - fun create(user: Material): Id? { - userCollection.insertOne(user) - return user.id + fun create(material: Material): Id { + materialCollection.insertOne(material) + return material._id } - fun findAll(): List = userCollection.find().toList() - fun findById(id: String): Material? { val bsonId: Id = ObjectId(id).toId() - return userCollection.findOne(Material::id eq bsonId) + return materialCollection.findOne(Material::_id eq bsonId) } fun findByOwnerId(ownerId: String): List { val bsonId: Id = ObjectId(ownerId).toId() - return userCollection.find(Material::ownerId eq bsonId).toList() - } - - fun findByName(name: String): List { - 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 } } \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/service/UserService.kt b/src/main/kotlin/com/ray650128/service/UserService.kt index f17bec2..a725612 100644 --- a/src/main/kotlin/com/ray650128/service/UserService.kt +++ b/src/main/kotlin/com/ray650128/service/UserService.kt @@ -12,14 +12,14 @@ class UserService { fun create(user: User): Id? { userCollection.insertOne(user) - return user.id + return user._id } fun findAll(): List = userCollection.find().toList() fun findById(id: String): User? { val bsonId: Id = ObjectId(id).toId() - return userCollection.findOne(User::id eq bsonId) + return userCollection.findOne(User::_id eq bsonId) } fun findByName(name: String): List {