From c9494341bf1a1b4bb5f8cc17271fcfafbe833c73 Mon Sep 17 00:00:00 2001 From: benzuzu Date: Tue, 15 Aug 2023 19:35:59 -0400 Subject: [PATCH] Add TokenKey and TokenType classes --- .../mskcc/cbio/oncokb/domain/TokenKey.java | 125 ++++++++++++++++++ .../oncokb/domain/enumeration/TokenType.java | 30 +++++ 2 files changed, 155 insertions(+) create mode 100644 src/main/java/org/mskcc/cbio/oncokb/domain/TokenKey.java create mode 100644 src/main/java/org/mskcc/cbio/oncokb/domain/enumeration/TokenType.java diff --git a/src/main/java/org/mskcc/cbio/oncokb/domain/TokenKey.java b/src/main/java/org/mskcc/cbio/oncokb/domain/TokenKey.java new file mode 100644 index 000000000..201a37139 --- /dev/null +++ b/src/main/java/org/mskcc/cbio/oncokb/domain/TokenKey.java @@ -0,0 +1,125 @@ +package org.mskcc.cbio.oncokb.domain; + +import java.util.Optional; +import java.util.UUID; +import java.util.zip.CRC32; + +import org.mskcc.cbio.oncokb.domain.enumeration.TokenType; +import org.mskcc.cbio.oncokb.service.SlackService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Object to store api key strings in manipulatable format. + * + * Created by Benjamin Xu on 08/15/2023. + */ + +public class TokenKey { + + private static final Logger log = LoggerFactory.getLogger(TokenKey.class); + + private TokenType type; + private String randomString; + private String checksum; + + private static final int PREFIX_LENGTH = 4; + private static final int RANDOM_STRING_LENGTH = 32; + private static final int CHECKSUM_LENGTH = 8; + + public static TokenKey randomKey(TokenType type) { + TokenKey tokenKey = new TokenKey(); + tokenKey.setTokenType(type); + tokenKey.setRandomString(UUID.randomUUID()); + return tokenKey; + } + + public static Optional fromString(String key) { + String[] separatedKey = key.split("_"); + + // Check that the input is in the right format + if (separatedKey.length != 2 + || separatedKey[0].length() != PREFIX_LENGTH + || separatedKey[1].length() != RANDOM_STRING_LENGTH + CHECKSUM_LENGTH) { + log.warn("Attempted to generate TokenKey from invalid string."); + return Optional.empty(); + } + + TokenType inputKeyType = TokenType.getTokenTypeFromPrefix(separatedKey[0]); + + // Check that the input prefix is valid + if (inputKeyType == null) { + log.warn("Attempted to generate TokenKey from invalid string (bad prefix)."); + return Optional.empty(); + } + + String inputRandomString = separatedKey[1].substring(0, 32); + + // Check that the input randomString satisfies character set + if (!inputRandomString.matches("[0-9a-f]+")) { + log.warn("Attempted to generate TokenKey from invalid string (bad randomString)."); + return Optional.empty(); + } + + String inputCheckSum = separatedKey[1].substring(32); + + // Check that the input checksum is valid + if (!inputCheckSum.equals(calculateChecksum(inputRandomString))) { + log.warn("Attempted to generate TokenKey from invalid string (bad checksum)."); + return Optional.empty(); + } + + TokenKey tokenKey = new TokenKey(); + tokenKey.setTokenType(inputKeyType); + tokenKey.setRandomString(inputRandomString); + return Optional.of(tokenKey); + } + + public TokenType getTokenType() { + return type; + } + + public void setTokenType(TokenType type) { + this.type = type; + } + + public String getRandomString() { + return randomString; + } + + public void setRandomString(String randomString) { + // Assert the string is 32 characters + if (randomString == null || randomString.length() != 32) { + log.warn("Attempted to modify TokenKey from invalid string. TokenKey modification skipped."); + return; + } + this.randomString = randomString; + + // Set checksum + setChecksum(); + } + + public void setRandomString(UUID uuid) { + // Convert UUID to 32 character string + randomString = uuid.toString().replace("-",""); + + // Set checksum + setChecksum(); + } + + private void setChecksum() { + CRC32 crc32 = new CRC32(); + crc32.update(randomString.getBytes()); + checksum = String.format("%08x", crc32.getValue()); + } + + private static String calculateChecksum(String randomString) { + CRC32 crc32 = new CRC32(); + crc32.update(randomString.getBytes()); + return String.format("%08x", crc32.getValue()); + } + + public String toString() { + return type.getPrefix() + randomString + checksum; + } +} diff --git a/src/main/java/org/mskcc/cbio/oncokb/domain/enumeration/TokenType.java b/src/main/java/org/mskcc/cbio/oncokb/domain/enumeration/TokenType.java new file mode 100644 index 000000000..63f36da2f --- /dev/null +++ b/src/main/java/org/mskcc/cbio/oncokb/domain/enumeration/TokenType.java @@ -0,0 +1,30 @@ +package org.mskcc.cbio.oncokb.domain.enumeration; + +/** + * The TokenType enumeration. + */ +public enum TokenType { + PERSONAL("okbp") + // Not yet implemented + , SERVICE("okbs") + , WEB("okbw"); + + String prefix; + + TokenType(String prefix) { + this.prefix = prefix; + } + + public String getPrefix() { + return prefix; + } + + public static TokenType getTokenTypeFromPrefix(String prefix) { + for (TokenType type : TokenType.values()) { + if (type.getPrefix().equals(prefix)) { + return type; + } + } + return null; + } +}