mirror of https://github.com/hykilpikonna/AquaDX
[O] Unwrap spaghetti code
parent
1e606f8b85
commit
4c3aafd266
|
@ -3,6 +3,7 @@ package icu.samnyan.aqua.net
|
||||||
import ext.*
|
import ext.*
|
||||||
import icu.samnyan.aqua.net.db.AquaNetUser
|
import icu.samnyan.aqua.net.db.AquaNetUser
|
||||||
import icu.samnyan.aqua.net.db.AquaNetUserRepo
|
import icu.samnyan.aqua.net.db.AquaNetUserRepo
|
||||||
|
import icu.samnyan.aqua.net.utils.GeoIP
|
||||||
import icu.samnyan.aqua.net.utils.TurnstileService
|
import icu.samnyan.aqua.net.utils.TurnstileService
|
||||||
import jakarta.servlet.http.HttpServletRequest
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder
|
import org.springframework.security.crypto.password.PasswordEncoder
|
||||||
|
@ -15,7 +16,8 @@ import org.springframework.web.bind.annotation.RestController
|
||||||
class UserRegistrar(
|
class UserRegistrar(
|
||||||
val userRepo: AquaNetUserRepo,
|
val userRepo: AquaNetUserRepo,
|
||||||
val hasher: PasswordEncoder,
|
val hasher: PasswordEncoder,
|
||||||
val turnstileService: TurnstileService
|
val turnstileService: TurnstileService,
|
||||||
|
val geoIP: GeoIP
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* Register a new user
|
* Register a new user
|
||||||
|
@ -23,8 +25,10 @@ class UserRegistrar(
|
||||||
@PostMapping("/register")
|
@PostMapping("/register")
|
||||||
suspend fun register(@RP username: Str, @RP email: Str, @RP password: Str,
|
suspend fun register(@RP username: Str, @RP email: Str, @RP password: Str,
|
||||||
@RP turnstile: Str?, request: HttpServletRequest) {
|
@RP turnstile: Str?, request: HttpServletRequest) {
|
||||||
|
val ip = geoIP.getIP(request)
|
||||||
|
|
||||||
// Check captcha
|
// Check captcha
|
||||||
if (!turnstileService.validate(turnstile, request)) 400 > "Invalid captcha"
|
if (!turnstileService.validate(turnstile, ip)) 400 > "Invalid captcha"
|
||||||
|
|
||||||
// Check if email is valid
|
// Check if email is valid
|
||||||
if (!email.isValidEmail()) 400 > "Invalid email"
|
if (!email.isValidEmail()) 400 > "Invalid email"
|
||||||
|
@ -47,12 +51,14 @@ class UserRegistrar(
|
||||||
if (password.length < 8) 400 > "Password too short"
|
if (password.length < 8) 400 > "Password too short"
|
||||||
|
|
||||||
// GeoIP check to infer country
|
// GeoIP check to infer country
|
||||||
|
val country = geoIP.getCountry(ip)
|
||||||
|
|
||||||
val u = AquaNetUser(username = username, email = email, pwHash = hasher.encode(password),
|
val u = AquaNetUser(username = username, email = email, pwHash = hasher.encode(password),
|
||||||
regTime = millis(), lastLogin = millis())
|
regTime = millis(), lastLogin = millis(), country = country)
|
||||||
async { userRepo.save(u) }
|
async { userRepo.save(u) }
|
||||||
|
|
||||||
|
// TODO: Send confirmation email
|
||||||
|
|
||||||
200 > "User created"
|
200 > "User created"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,9 @@ package icu.samnyan.aqua.net.utils
|
||||||
|
|
||||||
import com.maxmind.geoip2.DatabaseReader
|
import com.maxmind.geoip2.DatabaseReader
|
||||||
import ext.Bool
|
import ext.Bool
|
||||||
|
import ext.Str
|
||||||
import jakarta.annotation.PostConstruct
|
import jakarta.annotation.PostConstruct
|
||||||
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
|
@ -16,9 +18,8 @@ import java.nio.file.Files
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConfigurationProperties(prefix = "aqua-net.geoip")
|
@ConfigurationProperties(prefix = "aqua-net.geoip")
|
||||||
class GeoIPProperties {
|
class GeoIPProperties {
|
||||||
var enable: Bool = false
|
var geoLitePath: Str = "data/GeoLite2-Country.mmdb"
|
||||||
|
var ipHeader: Str = ""
|
||||||
lateinit var geoLitePath: String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@ -30,8 +31,6 @@ class GeoIP(
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
fun onLoad() {
|
fun onLoad() {
|
||||||
if (!props.enable) return
|
|
||||||
|
|
||||||
// Check path exists
|
// Check path exists
|
||||||
if (!File(props.geoLitePath).exists()) {
|
if (!File(props.geoLitePath).exists()) {
|
||||||
log.error("GeoIP Service is enabled but GeoLite2 database is not found, trying to download from GitHub.")
|
log.error("GeoIP Service is enabled but GeoLite2 database is not found, trying to download from GitHub.")
|
||||||
|
@ -47,25 +46,33 @@ class GeoIP(
|
||||||
}
|
}
|
||||||
|
|
||||||
geoLite = DatabaseReader.Builder(File(props.geoLitePath)).build()
|
geoLite = DatabaseReader.Builder(File(props.geoLitePath)).build()
|
||||||
|
selfTest()
|
||||||
|
log.info("GeoIP Service Enabled")
|
||||||
|
}
|
||||||
|
|
||||||
// Self test
|
/**
|
||||||
|
* Test the connection of the GeoIP service on startup
|
||||||
|
*/
|
||||||
|
fun selfTest() {
|
||||||
try {
|
try {
|
||||||
getCountry("1.1.1.1")
|
getCountry("1.1.1.1")
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error("GeoIP Service Self Test Failed", e)
|
log.error("GeoIP Service Self Test Failed", e)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("GeoIP Service Enabled")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the IP address from a request
|
||||||
|
*/
|
||||||
|
fun getIP(request: HttpServletRequest): Str =
|
||||||
|
if (props.ipHeader.isEmpty()) request.remoteAddr else request.getHeader(props.ipHeader) ?: request.remoteAddr
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the country code from an IP address
|
* Get the country code from an IP address
|
||||||
*/
|
*/
|
||||||
fun getCountry(ip: String): String
|
fun getCountry(ip: Str): Str
|
||||||
{
|
{
|
||||||
if (!props.enable) return ""
|
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
geoLite.country(InetAddress.getByName(ip)).country.isoCode
|
geoLite.country(InetAddress.getByName(ip)).country.isoCode
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
@ -19,8 +19,6 @@ class TurnstileProperties {
|
||||||
var enable: Bool = false
|
var enable: Bool = false
|
||||||
|
|
||||||
lateinit var secret: Str
|
lateinit var secret: Str
|
||||||
|
|
||||||
lateinit var ipHeader: Str
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@ -28,12 +26,10 @@ class TurnstileService(val props: TurnstileProperties) {
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Outcome(val success: Boolean)
|
data class Outcome(val success: Boolean)
|
||||||
|
|
||||||
suspend fun validate(captcha: Str?, request: HttpServletRequest): Boolean {
|
suspend fun validate(captcha: Str?, ip: Str): Boolean {
|
||||||
if (!props.enable) return true
|
if (!props.enable) return true
|
||||||
if (captcha == null) return false
|
if (captcha == null) return false
|
||||||
|
|
||||||
val ip = request.getHeader(props.ipHeader) ?: request.remoteAddr
|
|
||||||
|
|
||||||
val outcome: Outcome = HTTP.post("https://challenges.cloudflare.com/turnstile/v0/siteverify") {
|
val outcome: Outcome = HTTP.post("https://challenges.cloudflare.com/turnstile/v0/siteverify") {
|
||||||
setBody(
|
setBody(
|
||||||
FormDataContent(Parameters.build {
|
FormDataContent(Parameters.build {
|
||||||
|
|
Loading…
Reference in New Issue