[M] Move services to components package

This commit is contained in:
Azalea
2024-02-19 03:07:32 -05:00
parent 2cb5b18975
commit e962baaf48
6 changed files with 7 additions and 9 deletions

View File

@@ -1,75 +0,0 @@
package icu.samnyan.aqua.net.utils
import ext.Bool
import ext.Str
import icu.samnyan.aqua.net.db.AquaNetUser
import jakarta.annotation.PostConstruct
import org.simplejavamail.api.mailer.Mailer
import org.simplejavamail.email.EmailBuilder
import org.simplejavamail.springsupport.SimpleJavaMailSpringSupport
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import
import org.springframework.stereotype.Service
@Configuration
@ConfigurationProperties(prefix = "aqua-net.email")
class EmailProperties {
var enable: Bool = false
lateinit var senderName: Str
lateinit var senderAddr: Str
}
/**
* Email service. All email related operations should be placed here.
*
* Library Documentation: https://www.simplejavamail.org/
*/
@Service
@Import(SimpleJavaMailSpringSupport::class)
class EmailService(
val mailer: Mailer,
val props: EmailProperties,
) {
val log: Logger = LoggerFactory.getLogger(EmailService::class.java)
/**
* Test the connection of the email service on startup
*/
@PostConstruct
fun testConnection() {
if (!props.enable) return
try {
mailer.testConnection()
log.info("Email Service Connected")
} catch (e: Exception) {
log.error("Email Service Connection Failed", e)
}
}
/**
* Send a confirmation email to the user
*/
fun confirmationEmail(user: AquaNetUser) {
}
fun testEmail(addr: Str, name: Str) {
if (!props.enable) return
log.info("Sending test email to $addr")
mailer.sendMail(EmailBuilder.startingBlank()
.from(props.senderName, props.senderAddr)
.to(name, addr)
.withSubject("Test Email")
.withPlainText("This is a test email to check if AquaNet Email Works").buildEmail()).thenRun {
log.info("Test email sent to $addr")
}
}
}

View File

@@ -1,89 +0,0 @@
package icu.samnyan.aqua.net.utils
import com.maxmind.geoip2.DatabaseReader
import com.maxmind.geoip2.exception.AddressNotFoundException
import ext.Bool
import ext.Str
import jakarta.annotation.PostConstruct
import jakarta.servlet.http.HttpServletRequest
import org.slf4j.LoggerFactory
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Service
import java.io.File
import java.net.InetAddress
import java.net.URL
import java.nio.file.Files
@Configuration
@ConfigurationProperties(prefix = "aqua-net.geoip")
class GeoIPProperties {
var geoLitePath: Str = "data/GeoLite2-Country.mmdb"
var ipHeader: Str = ""
}
@Service
class GeoIP(
val props: GeoIPProperties
) {
val log = LoggerFactory.getLogger(GeoIP::class.java)!!
lateinit var geoLite: DatabaseReader
@PostConstruct
fun onLoad() {
// Check path exists
if (!File(props.geoLitePath).exists()) {
log.error("GeoIP Service is enabled but GeoLite2 database is not found, trying to download from GitHub.")
// Download from GitHub
try {
log.info("Downloading GeoLite2 database to ${props.geoLitePath}")
URL("https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdb").openStream()
.use { Files.copy(it, File(props.geoLitePath).toPath()) }
} catch (e: Exception) {
log.error("Failed to download GeoLite2 database", e)
throw e
}
}
geoLite = DatabaseReader.Builder(File(props.geoLitePath)).build()
selfTest()
log.info("GeoIP Service Enabled")
}
/**
* Test the connection of the GeoIP service on startup
*/
fun selfTest() {
try {
// Test with Google's IP
getCountry("172.217.165.14")
} catch (e: Exception) {
log.error("GeoIP Service Self Test Failed", e)
throw e
}
}
/**
* 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
*/
fun getCountry(ip: Str): Str
{
return try {
val ipa = InetAddress.getByName(ip)
geoLite.country(ipa)?.country?.isoCode ?: ""
}
catch (e: AddressNotFoundException) { "" }
catch (e: Exception) {
log.error("Failed to get country from IP $ip", e)
""
}
}
}

View File

@@ -1,61 +0,0 @@
package icu.samnyan.aqua.net.utils
import ext.Str
import icu.samnyan.aqua.net.db.AquaNetUser
import icu.samnyan.aqua.net.db.AquaNetUserRepo
import io.jsonwebtoken.JwtParser
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.security.Keys
import jakarta.annotation.PostConstruct
import org.slf4j.LoggerFactory
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Service
import java.util.*
import javax.crypto.SecretKey
@Configuration
@ConfigurationProperties(prefix = "aqua-net.jwt")
class JWTProperties {
var secret: Str = "Open Sesame!"
}
@Service
class JWT(
val props: JWTProperties,
val userRepo: AquaNetUserRepo
) {
val log = LoggerFactory.getLogger(JWT::class.java)!!
lateinit var key: SecretKey
lateinit var parser: JwtParser
@PostConstruct
fun onLoad() {
// Check secret
if (props.secret == "Open Sesame!") {
log.warn("USING DEFAULT JWT SECRET, PLEASE SET aqua-net.jwt IN CONFIGURATION")
}
// Initialize key
key = Keys.hmacShaKeyFor(props.secret.toByteArray())
// Create parser
parser = Jwts.parser()
.verifyWith(key)
.build()
log.info("JWT Service Enabled")
}
fun gen(user: AquaNetUser): Str = Jwts.builder().header()
.keyId("aqua-net")
.and()
.subject(user.auId.toString())
.issuedAt(Date())
.signWith(key)
.compact()
fun parse(token: Str): AquaNetUser? =
userRepo.findByAuId(parser.parseSignedClaims(token).payload.subject.toLong())
}

View File

@@ -1,46 +0,0 @@
package icu.samnyan.aqua.net.utils
import ext.Bool
import ext.HTTP
import ext.Str
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.client.request.forms.*
import io.ktor.http.*
import jakarta.servlet.http.HttpServletRequest
import kotlinx.serialization.Serializable
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Service
@Configuration
@ConfigurationProperties(prefix = "aqua-net.turnstile")
class TurnstileProperties {
var enable: Bool = false
lateinit var secret: Str
}
@Service
class TurnstileService(val props: TurnstileProperties) {
@Serializable
data class Outcome(val success: Boolean)
suspend fun validate(captcha: Str?, ip: Str): Boolean {
if (!props.enable) return true
if (captcha == null) return false
val outcome: Outcome = HTTP.post("https://challenges.cloudflare.com/turnstile/v0/siteverify") {
setBody(
FormDataContent(Parameters.build {
append("secret", props.secret)
append("response", captcha)
append("remoteip", ip)
})
)
}.body()
return outcome.success
}
}