From 6a16e5534da4b4e393dd45e89670e2991110e110 Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Thu, 22 Feb 2024 17:29:13 -0500 Subject: [PATCH] [+] Sanitize card id when creating card --- .../icu/samnyan/aqua/net/CardController.kt | 12 +++++-- .../aqua/sega/general/service/CardService.kt | 33 +++++++++++++++++-- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/main/java/icu/samnyan/aqua/net/CardController.kt b/src/main/java/icu/samnyan/aqua/net/CardController.kt index 941811ac..1fbaadfc 100644 --- a/src/main/java/icu/samnyan/aqua/net/CardController.kt +++ b/src/main/java/icu/samnyan/aqua/net/CardController.kt @@ -47,15 +47,21 @@ class CardController( // Check if the user's card limit is reached if (u.cards.size >= props.linkCardLimit) 400 - "Card limit reached" - // Check if the card is already bound + // Try to look up the card val card = cardService.tryLookup(cardId) + + // If no card is found, create a new card if (card == null) { + // Ensure the format of the card ID is correct + val id = cardService.sanitizeCardId(cardId) + // Create a new card - val newCard = cardService.registerByAccessCode(cardId) - cardRepository.save(newCard) + cardService.registerByAccessCode(id, u) return SUCCESS } + + // If card is already bound if (card.aquaUser != null) 400 - "Card already bound to another user" // Bind the card diff --git a/src/main/java/icu/samnyan/aqua/sega/general/service/CardService.kt b/src/main/java/icu/samnyan/aqua/sega/general/service/CardService.kt index 9b55819f..42052118 100644 --- a/src/main/java/icu/samnyan/aqua/sega/general/service/CardService.kt +++ b/src/main/java/icu/samnyan/aqua/sega/general/service/CardService.kt @@ -1,5 +1,7 @@ package icu.samnyan.aqua.sega.general.service +import ext.minus +import icu.samnyan.aqua.net.db.AquaNetUser import icu.samnyan.aqua.sega.general.dao.CardRepository import icu.samnyan.aqua.sega.general.model.Card import org.springframework.stereotype.Service @@ -12,7 +14,9 @@ import kotlin.jvm.optionals.getOrNull * @author samnyan (privateamusement@protonmail.com) */ @Service -class CardService(val cardRepo: CardRepository) { +class CardService { + lateinit var cardRepo: CardRepository + /** * Find a card by External ID * @param extId External ID @@ -40,11 +44,13 @@ class CardService(val cardRepo: CardRepository) { * @param accessCode String represent of an access code * @return a new registered Card */ - fun registerByAccessCode(accessCode: String): Card = cardRepo.save(Card().apply { + @JvmOverloads + fun registerByAccessCode(accessCode: String, user: AquaNetUser? = null): Card = cardRepo.save(Card().apply { luid = accessCode extId = randExtID() registerTime = LocalDateTime.now() accessTime = registerTime + aquaUser = user }) /** @@ -80,7 +86,28 @@ class CardService(val cardRepo: CardRepository) { return null } - fun randExtID(lower: Long = 0, upper: Long = 99999999): Long { + /** + * Sanitize user input for card ID + * + * This is strictly stricter than the `tryLookup` method, as it only accepts valid Felica IDm and AIME access code. + * + * @param id String represent of a card ID (e.g. Felica IDm, AIME access code) + */ + fun sanitizeCardId(id: String): String { + // Felica + if (":" in id) + return id.replace(":", "").lowercase().toLongOrNull(16)?.toString()?.padStart(20, '0') + ?: (400 - "Invalid card ID") + + // Access Code + else if (" " in id && id.length == 24) + return id.replace(" ", "") + .also { if (it.any { c -> !c.isDigit() }) 400 - "Invalid card ID" } + + else 400 - "Invalid card ID" + } + + fun randExtID(lower: Long = 0, upper: Long = 1e9.toLong() - 1): Long { var eid = ThreadLocalRandom.current().nextLong(lower, upper) while (cardRepo.findByExtId(eid).isPresent) { eid = ThreadLocalRandom.current().nextLong(lower, upper)