init commit

This commit is contained in:
Barney
2022-05-23 11:28:48 +08:00
commit f211314443
18 changed files with 693 additions and 0 deletions
@@ -0,0 +1,17 @@
package com.ray650128
import com.ray650128.database.DatabaseFactory
import io.ktor.server.application.*
import com.ray650128.plugins.*
fun main(args: Array<String>): Unit =
io.ktor.server.netty.EngineMain.main(args)
@Suppress("unused") // application.conf references the main function. This annotation prevents the IDE from marking it as unused.
fun Application.module() {
DatabaseFactory.init()
DatabaseFactory.createTable()
configureRouting()
configureSerialization()
configureSecurity()
}
@@ -0,0 +1,31 @@
package com.ray650128.database
import com.ray650128.entity.Users
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.transactions.transaction
object DatabaseFactory {
fun init() {
Database.connect(hikari())
}
fun createTable(){
transaction {
SchemaUtils.create(Users)
}
}
private fun hikari(): HikariDataSource {
val config = HikariConfig()
config.driverClassName = "com.mysql.cj.jdbc.Driver"
config.jdbcUrl = "jdbc:mysql://www.ray650128.com:3306/test_db"
config.username = "root"
config.password = "650128"
config.validate()
return HikariDataSource(config)
}
}
@@ -0,0 +1,16 @@
package com.ray650128.entity
import org.jetbrains.exposed.dao.id.LongIdTable
import org.jetbrains.exposed.sql.Table.Dual.default
import org.jetbrains.exposed.sql.Table.Dual.long
import org.jetbrains.exposed.sql.Table.Dual.uniqueIndex
import org.jetbrains.exposed.sql.Table.Dual.varchar
object Users : LongIdTable() {
var name = varchar("name", 50)
var account = varchar("account", 255).uniqueIndex()
var password = varchar("password", 255)
var token = varchar("token", 255).default("")
var createTime = long("createTime")
var updateTime = long("updateTime")
}
@@ -0,0 +1,11 @@
package com.ray650128.model
data class User(
var id: Long,
var name: String,
var account: String,
var password: String,
var token: String,
var createTime: Long,
var updateTime: Long
)
@@ -0,0 +1,16 @@
package com.ray650128.plugins
import io.ktor.server.routing.*
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.request.*
fun Application.configureRouting() {
routing {
get("/") {
call.respondText("Hello World!")
}
}
}
@@ -0,0 +1,32 @@
package com.ray650128.plugins
import io.ktor.server.auth.*
import io.ktor.util.*
import io.ktor.server.auth.jwt.*
import com.auth0.jwt.JWT
import com.auth0.jwt.JWTVerifier
import com.auth0.jwt.algorithms.Algorithm
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.request.*
fun Application.configureSecurity() {
authentication {
jwt {
val jwtAudience = this@configureSecurity.environment.config.property("jwt.audience").getString()
realm = this@configureSecurity.environment.config.property("jwt.realm").getString()
verifier(
JWT
.require(Algorithm.HMAC256("secret"))
.withAudience(jwtAudience)
.withIssuer(this@configureSecurity.environment.config.property("jwt.domain").getString())
.build()
)
validate { credential ->
if (credential.payload.audience.contains(jwtAudience)) JWTPrincipal(credential.payload) else null
}
}
}
}
@@ -0,0 +1,21 @@
package com.ray650128.plugins
import io.ktor.serialization.gson.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.request.*
import io.ktor.server.routing.*
fun Application.configureSerialization() {
install(ContentNegotiation) {
gson {
}
}
routing {
get("/json/gson") {
call.respond(mapOf("hello" to "world"))
}
}
}
@@ -0,0 +1,53 @@
package com.ray650128.repository
import com.ray650128.entity.Users
import com.ray650128.model.User
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
class UserRepository {
suspend fun add(data: User) {
transaction {
Users.insert {
it[account] = data.account
it[password] = data.password
it[createTime] = System.currentTimeMillis()
it[updateTime] = System.currentTimeMillis()
}
}
}
suspend fun update(data: User) {
transaction {
Users.update {
it[name] = data.name
it[token] = data.token
it[updateTime] = System.currentTimeMillis()
}
}
}
suspend fun get(): List<User> {
val data = withContext(Dispatchers.IO) {
transaction {
Users.selectAll().orderBy(Users.id, SortOrder.DESC).mapNotNull {
toUser(it)
}.toList()
}
}
return data
}
private fun toUser(row: ResultRow): User =
User(
id = row[Users.id].value,
name = row[Users.name],
account = row[Users.account],
password = row[Users.password],
token = row[Users.token],
createTime = row[Users.createTime],
updateTime = row[Users.updateTime]
)
}
+14
View File
@@ -0,0 +1,14 @@
ktor {
deployment {
port = 8080
port = ${?PORT}
}
application {
modules = [ com.ray650128.ApplicationKt.module ]
}
}
jwt {
domain = "https://jwt-provider-domain/"
audience = "jwt-audience"
realm = "ktor sample app"
}
+12
View File
@@ -0,0 +1,12 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="trace">
<appender-ref ref="STDOUT"/>
</root>
<logger name="org.eclipse.jetty" level="INFO"/>
<logger name="io.netty" level="INFO"/>
</configuration>
@@ -0,0 +1,33 @@
package com.ray650128
import io.ktor.server.routing.*
import io.ktor.http.*
import io.ktor.serialization.gson.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.auth.*
import io.ktor.util.*
import io.ktor.server.auth.jwt.*
import com.auth0.jwt.JWT
import com.auth0.jwt.JWTVerifier
import com.auth0.jwt.algorithms.Algorithm
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.request.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import kotlin.test.*
import io.ktor.server.testing.*
import com.ray650128.plugins.*
class ApplicationTest {
@Test
fun testRoot() = testApplication {
application {
configureRouting()
}
client.get("/").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals("Hello World!", bodyAsText())
}
}
}