Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Replace TotpNotEnabledError with UnknownUserIdTotpError #133

Merged
merged 7 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

- Replace `TotpNotEnabledError` with `UnknownUserIdTotpError`.
- Support for MFA recipe

## [5.0.0] - 2023-09-19
Expand Down
74 changes: 53 additions & 21 deletions src/main/java/io/supertokens/storage/postgresql/Start.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@
import io.supertokens.pluginInterface.jwt.exceptions.DuplicateKeyIdException;
import io.supertokens.pluginInterface.jwt.sqlstorage.JWTRecipeSQLStorage;
import io.supertokens.pluginInterface.mfa.MfaStorage;
import io.supertokens.pluginInterface.multitenancy.AppIdentifier;
import io.supertokens.pluginInterface.multitenancy.MultitenancyStorage;
import io.supertokens.pluginInterface.multitenancy.TenantConfig;
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
import io.supertokens.pluginInterface.multitenancy.*;
import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateClientTypeException;
import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateTenantException;
import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateThirdPartyIdException;
Expand All @@ -72,8 +69,8 @@
import io.supertokens.pluginInterface.totp.TOTPStorage;
import io.supertokens.pluginInterface.totp.TOTPUsedCode;
import io.supertokens.pluginInterface.totp.exception.DeviceAlreadyExistsException;
import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException;
import io.supertokens.pluginInterface.totp.exception.UnknownDeviceException;
import io.supertokens.pluginInterface.totp.exception.UnknownTotpUserIdException;
import io.supertokens.pluginInterface.totp.exception.UsedCodeAlreadyExistsException;
import io.supertokens.pluginInterface.totp.sqlStorage.TOTPSQLStorage;
import io.supertokens.pluginInterface.useridmapping.UserIdMapping;
Expand Down Expand Up @@ -833,12 +830,13 @@ public void addInfoToNonAuthRecipesBasedOnUserId(TenantIdentifier tenantIdentifi
} else if (className.equals(TOTPStorage.class.getName())) {
try {
TOTPDevice device = new TOTPDevice(userId, "testDevice", "secret", 0, 30, false);
TOTPQueries.createDevice(this, tenantIdentifier.toAppIdentifier(), device);
this.startTransaction(con -> {
try {
long now = System.currentTimeMillis();
Connection sqlCon = (Connection) con.getConnection();
TOTPQueries.createDevice_Transaction(this, sqlCon, tenantIdentifier.toAppIdentifier(), device);
TOTPQueries.insertUsedCode_Transaction(this,
(Connection) con.getConnection(), tenantIdentifier,
sqlCon, tenantIdentifier,
new TOTPUsedCode(userId, "123456", true, 1000 + now, now));
} catch (SQLException e) {
throw new StorageTransactionLogicException(e);
Expand Down Expand Up @@ -1339,7 +1337,7 @@ public int countUsersEnabledTotpAndActiveSince(AppIdentifier appIdentifier, long
throw new StorageQueryException(e);
}
}

@Override
public int countUsersEnabledMfa(AppIdentifier appIdentifier) throws StorageQueryException {
try {
Expand Down Expand Up @@ -2633,26 +2631,60 @@ public void revokeExpiredSessions() throws StorageQueryException {
}

// TOTP recipe:
@TestOnly
@Override
public void createDevice(AppIdentifier appIdentifier, TOTPDevice device)
throws StorageQueryException, DeviceAlreadyExistsException, TenantOrAppNotFoundException {
throws DeviceAlreadyExistsException, TenantOrAppNotFoundException, StorageQueryException {
try {
TOTPQueries.createDevice(this, appIdentifier, device);
startTransaction(con -> {
try {
createDevice_Transaction(con, new AppIdentifier(null, null), device);
} catch (DeviceAlreadyExistsException | TenantOrAppNotFoundException e) {
throw new StorageTransactionLogicException(e);
}
return null;
});
} catch (StorageTransactionLogicException e) {
Exception actualException = e.actualException;
if (e.actualException instanceof DeviceAlreadyExistsException) {
throw (DeviceAlreadyExistsException) e.actualException;
} else if (e.actualException instanceof TenantOrAppNotFoundException) {
throw (TenantOrAppNotFoundException) e.actualException;
} else if (e.actualException instanceof StorageQueryException) {
throw (StorageQueryException) e.actualException;
}
}
}

@Override
public TOTPDevice createDevice_Transaction(TransactionConnection con, AppIdentifier appIdentifier, TOTPDevice device)
throws StorageQueryException, DeviceAlreadyExistsException, TenantOrAppNotFoundException {
Connection sqlCon = (Connection) con.getConnection();
try {
TOTPQueries.createDevice_Transaction(this, sqlCon, appIdentifier, device);
return device;
} catch (SQLException e) {
Exception actualException = e;

if (actualException instanceof PSQLException) {
ServerErrorMessage errMsg = ((PSQLException) actualException).getServerErrorMessage();

if (isPrimaryKeyError(errMsg, Config.getConfig(this).getTotpUserDevicesTable())) {
throw new DeviceAlreadyExistsException();
throw new DeviceAlreadyExistsException();
} else if (isForeignKeyConstraintError(errMsg, Config.getConfig(this).getTotpUsersTable(), "app_id")) {
throw new TenantOrAppNotFoundException(appIdentifier);
throw new TenantOrAppNotFoundException(appIdentifier);
}

}
throw new StorageQueryException(e);
}
}

throw new StorageQueryException(e.actualException);
@Override
public TOTPDevice getDeviceByName_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId, String deviceName) throws StorageQueryException {
Connection sqlCon = (Connection) con.getConnection();
try {
return TOTPQueries.getDeviceByName_Transaction(this, sqlCon, appIdentifier, userId, deviceName);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
}

Expand Down Expand Up @@ -2706,8 +2738,8 @@ public boolean removeUser(TenantIdentifier tenantIdentifier, String userId)

@Override
public void updateDeviceName(AppIdentifier appIdentifier, String userId, String oldDeviceName, String newDeviceName)
throws StorageQueryException, DeviceAlreadyExistsException,
UnknownDeviceException {
throws StorageQueryException,
UnknownDeviceException, DeviceAlreadyExistsException {
try {
int updatedCount = TOTPQueries.updateDeviceName(this, appIdentifier, userId, oldDeviceName, newDeviceName);
if (updatedCount == 0) {
Expand All @@ -2717,7 +2749,7 @@ public void updateDeviceName(AppIdentifier appIdentifier, String userId, String
if (e instanceof PSQLException) {
ServerErrorMessage errMsg = ((PSQLException) e).getServerErrorMessage();
if (isPrimaryKeyError(errMsg, Config.getConfig(this).getTotpUserDevicesTable())) {
throw new DeviceAlreadyExistsException();
throw new DeviceAlreadyExistsException();
}
}
throw new StorageQueryException(e);
Expand Down Expand Up @@ -2748,7 +2780,7 @@ public TOTPDevice[] getDevices_Transaction(TransactionConnection con, AppIdentif
@Override
public void insertUsedCode_Transaction(TransactionConnection con, TenantIdentifier tenantIdentifier,
TOTPUsedCode usedCodeObj)
throws StorageQueryException, TotpNotEnabledException, UsedCodeAlreadyExistsException,
throws StorageQueryException, UnknownTotpUserIdException, UsedCodeAlreadyExistsException,
TenantOrAppNotFoundException {
Connection sqlCon = (Connection) con.getConnection();
try {
Expand All @@ -2760,7 +2792,7 @@ public void insertUsedCode_Transaction(TransactionConnection con, TenantIdentifi
throw new UsedCodeAlreadyExistsException();
} else if (isForeignKeyConstraintError(err, Config.getConfig(this).getTotpUsedCodesTable(),
"user_id")) {
throw new TotpNotEnabledException();
throw new UnknownTotpUserIdException();
} else if (isForeignKeyConstraintError(err, Config.getConfig(this).getTotpUsedCodesTable(), "tenant_id")) {
throw new TenantOrAppNotFoundException(tenantIdentifier);
}
Expand Down Expand Up @@ -2790,7 +2822,7 @@ public int removeExpiredCodes(TenantIdentifier tenantIdentifier, long expiredBef
throw new StorageQueryException(e);
}
}

// MFA recipe:
@Override
public boolean enableFactor(TenantIdentifier tenantIdentifier, String userId, String factor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,22 +134,27 @@ private static int insertDevice_Transaction(Start start, Connection con, AppIden
});
}

public static void createDevice(Start start, AppIdentifier appIdentifier, TOTPDevice device)
throws StorageQueryException, StorageTransactionLogicException {
start.startTransaction(con -> {
Connection sqlCon = (Connection) con.getConnection();

try {
insertUser_Transaction(start, sqlCon, appIdentifier, device.userId);
insertDevice_Transaction(start, sqlCon, appIdentifier, device);
sqlCon.commit();
} catch (SQLException e) {
throw new StorageTransactionLogicException(e);
}
public static void createDevice_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, TOTPDevice device)
throws SQLException, StorageQueryException {
insertUser_Transaction(start, sqlCon, appIdentifier, device.userId);
insertDevice_Transaction(start, sqlCon, appIdentifier, device);
}

public static TOTPDevice getDeviceByName_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String userId, String deviceName)
throws SQLException, StorageQueryException {
String QUERY = "SELECT * FROM " + Config.getConfig(start).getTotpUserDevicesTable()
+ " WHERE app_id = ? AND user_id = ? AND device_name = ? FOR UPDATE;";

return execute(sqlCon, QUERY, pst -> {
pst.setString(1, appIdentifier.getAppId());
pst.setString(2, userId);
pst.setString(3, deviceName);
}, result -> {
if (result.next()) {
return TOTPDeviceRowMapper.getInstance().map(result);
}
return null;
});
return;
}

public static int markDeviceAsVerified(Start start, AppIdentifier appIdentifier, String userId, String deviceName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import io.supertokens.pluginInterface.sqlStorage.SQLStorage.TransactionIsolationLevel;
import io.supertokens.pluginInterface.totp.TOTPDevice;
import io.supertokens.pluginInterface.totp.TOTPUsedCode;
import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException;
import io.supertokens.pluginInterface.totp.exception.UnknownTotpUserIdException;
import io.supertokens.pluginInterface.totp.exception.UsedCodeAlreadyExistsException;
import io.supertokens.pluginInterface.totp.sqlStorage.TOTPSQLStorage;
import io.supertokens.storageLayer.StorageLayer;
Expand Down Expand Up @@ -294,7 +294,7 @@ public void testConcurrentDeleteAndUpdate() throws Exception {
try {
totpStorage.insertUsedCode_Transaction(con, new TenantIdentifier(null, null, null), code);
totpStorage.commitTransaction(con);
} catch (TotpNotEnabledException | UsedCodeAlreadyExistsException e) {
} catch (UnknownTotpUserIdException | UsedCodeAlreadyExistsException e) {
// This should not happen
throw new StorageTransactionLogicException(e);
} catch (TenantOrAppNotFoundException e) {
Expand Down Expand Up @@ -456,7 +456,7 @@ public void testConcurrentDeleteAndInsert() throws Exception {
try {
totpStorage.insertUsedCode_Transaction(con, new TenantIdentifier(null, null, null), code);
totpStorage.commitTransaction(con);
} catch (TotpNotEnabledException | UsedCodeAlreadyExistsException e) {
} catch (UnknownTotpUserIdException | UsedCodeAlreadyExistsException e) {
// This should not happen
throw new StorageTransactionLogicException(e);
} catch (TenantOrAppNotFoundException e) {
Expand Down Expand Up @@ -559,7 +559,7 @@ public void testConcurrentDeleteAndInsert() throws Exception {
TOTPUsedCode code2 = new TOTPUsedCode("user", "1234", false, nextDay, now + 1);
try {
totpStorage.insertUsedCode_Transaction(con, new TenantIdentifier(null, null, null), code2);
} catch (TotpNotEnabledException | UsedCodeAlreadyExistsException e) {
} catch (UnknownTotpUserIdException | UsedCodeAlreadyExistsException e) {
// This should not happen
throw new StorageTransactionLogicException(e);
} catch (TenantOrAppNotFoundException e) {
Expand All @@ -574,7 +574,7 @@ public void testConcurrentDeleteAndInsert() throws Exception {
} catch (StorageTransactionLogicException e) {
Exception e2 = e.actualException;

if (e2 instanceof TotpNotEnabledException) {
if (e2 instanceof UnknownTotpUserIdException) {
t2Failed.set(true);
}
} catch (StorageQueryException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.pluginInterface.totp.TOTPDevice;
import io.supertokens.pluginInterface.totp.TOTPUsedCode;
import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException;
import io.supertokens.pluginInterface.totp.exception.UnknownTotpUserIdException;
import io.supertokens.pluginInterface.totp.exception.UsedCodeAlreadyExistsException;
import io.supertokens.pluginInterface.totp.sqlStorage.TOTPSQLStorage;
import io.supertokens.storageLayer.StorageLayer;
Expand Down Expand Up @@ -54,15 +54,15 @@ public static void insertUsedCodeUtil(TOTPSQLStorage storage, TOTPUsedCode usedC
storage.insertUsedCode_Transaction(con, new TenantIdentifier(null, null, null), usedCode);
storage.commitTransaction(con);
return null;
} catch (TotpNotEnabledException | UsedCodeAlreadyExistsException e) {
} catch (UnknownTotpUserIdException | UsedCodeAlreadyExistsException e) {
throw new StorageTransactionLogicException(e);
} catch (TenantOrAppNotFoundException e) {
throw new IllegalStateException(e);
}
});
} catch (StorageTransactionLogicException e) {
Exception actual = e.actualException;
if (actual instanceof TotpNotEnabledException || actual instanceof UsedCodeAlreadyExistsException) {
if (actual instanceof UnknownTotpUserIdException || actual instanceof UsedCodeAlreadyExistsException) {
throw actual;
} else {
throw e;
Expand Down
Loading