Skip to content

Commit

Permalink
fix: mfa stats (#170)
Browse files Browse the repository at this point in the history
* fix: mfa stats

* fix: pr comments
  • Loading branch information
sattvikc authored Nov 1, 2023
1 parent 6ebaa47 commit dba89ba
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 82 deletions.
56 changes: 18 additions & 38 deletions src/main/java/io/supertokens/storage/postgresql/Start.java
Original file line number Diff line number Diff line change
Expand Up @@ -1319,44 +1319,6 @@ public int countUsersActiveSince(AppIdentifier appIdentifier, long time) throws
}
}

@Override
public int countUsersEnabledTotp(AppIdentifier appIdentifier) throws StorageQueryException {
try {
return ActiveUsersQueries.countUsersEnabledTotp(this, appIdentifier);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
}

@Override
public int countUsersEnabledTotpAndActiveSince(AppIdentifier appIdentifier, long time)
throws StorageQueryException {
try {
return ActiveUsersQueries.countUsersEnabledTotpAndActiveSince(this, appIdentifier, time);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
}

@Override
public int countUsersEnabledMfa(AppIdentifier appIdentifier) throws StorageQueryException {
try {
return ActiveUsersQueries.countUsersEnabledMfa(this, appIdentifier);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
}

@Override
public int countUsersEnabledMfaAndActiveSince(AppIdentifier appIdentifier, long time)
throws StorageQueryException {
try {
return ActiveUsersQueries.countUsersEnabledMfaAndActiveSince(this, appIdentifier, time);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
}

@Override
public void deleteUserActive_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId)
throws StorageQueryException {
Expand Down Expand Up @@ -3037,4 +2999,22 @@ public UserIdMapping[] getUserIdMapping_Transaction(TransactionConnection con, A
throw new StorageQueryException(e);
}
}

@Override
public int getUsersCountWithMoreThanOneLoginMethodOrTOTPEnabled(AppIdentifier appIdentifier) throws StorageQueryException {
try {
return GeneralQueries.getUsersCountWithMoreThanOneLoginMethodOrTOTPEnabled(this, appIdentifier);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
}

@Override
public int countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(AppIdentifier appIdentifier, long sinceTime) throws StorageQueryException {
try {
return ActiveUsersQueries.countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(this, appIdentifier, sinceTime);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import static io.supertokens.storage.postgresql.QueryExecutorTemplate.execute;
import static io.supertokens.storage.postgresql.QueryExecutorTemplate.update;
import static io.supertokens.storage.postgresql.config.Config.getConfig;

public class ActiveUsersQueries {
static String getQueryToCreateUserLastActiveTable(Start start) {
Expand Down Expand Up @@ -51,9 +52,10 @@ public static int countUsersActiveSince(Start start, AppIdentifier appIdentifier

public static int countUsersActiveSinceAndHasMoreThanOneLoginMethod(Start start, AppIdentifier appIdentifier, long sinceTime)
throws SQLException, StorageQueryException {
// TODO: Active users are present only on public tenant and MFA users may be present on different storages
String QUERY = "SELECT count(1) as c FROM ("
+ " SELECT count(user_id) as num_login_methods, app_id, primary_or_recipe_user_id"
+ " FROM " + Config.getConfig(start).getUsersTable()
+ " FROM " + Config.getConfig(start).getAppIdToUserIdTable()
+ " WHERE primary_or_recipe_user_id IN ("
+ " SELECT user_id FROM " + Config.getConfig(start).getUserLastActiveTable()
+ " WHERE app_id = ? AND last_active_time >= ?"
Expand All @@ -71,48 +73,6 @@ public static int countUsersActiveSinceAndHasMoreThanOneLoginMethod(Start start,
});
}

public static int countUsersEnabledTotp(Start start, AppIdentifier appIdentifier)
throws SQLException, StorageQueryException {
String QUERY = "SELECT COUNT(*) as total FROM " + Config.getConfig(start).getTotpUsersTable()
+ " WHERE app_id = ?";

return execute(start, QUERY, pst -> {
pst.setString(1, appIdentifier.getAppId());
}, result -> {
if (result.next()) {
return result.getInt("total");
}
return 0;
});
}

public static int countUsersEnabledTotpAndActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime)
throws SQLException, StorageQueryException {
String QUERY =
"SELECT COUNT(*) as total FROM " + Config.getConfig(start).getTotpUsersTable() + " AS totp_users "
+ "INNER JOIN " + Config.getConfig(start).getUserLastActiveTable() + " AS user_last_active "
+ "ON totp_users.user_id = user_last_active.user_id "
+ "WHERE user_last_active.app_id = ? AND user_last_active.last_active_time >= ?";

return execute(start, QUERY, pst -> {
pst.setString(1, appIdentifier.getAppId());
pst.setLong(2, sinceTime);
}, result -> {
if (result.next()) {
return result.getInt("total");
}
return 0;
});
}

public static int countUsersEnabledMfa(Start start, AppIdentifier appIdentifier) throws SQLException, StorageQueryException {
return 0; // TODO
}

public static int countUsersEnabledMfaAndActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime) throws SQLException, StorageQueryException {
return 0; // TODO
}

public static int updateUserLastActive(Start start, AppIdentifier appIdentifier, String userId)
throws SQLException, StorageQueryException {
String QUERY = "INSERT INTO " + Config.getConfig(start).getUserLastActiveTable()
Expand Down Expand Up @@ -160,4 +120,41 @@ public static void deleteUserActive_Transaction(Connection con, Start start, App
pst.setString(2, userId);
});
}

public static int countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime)
throws SQLException, StorageQueryException {
// TODO: Active users are present only on public tenant and MFA users may be present on different storages
String QUERY =
"SELECT COUNT (DISTINCT user_id) as c FROM ("
+ " (" // users with more than one login method
+ " SELECT primary_or_recipe_user_id AS user_id FROM ("
+ " SELECT COUNT(user_id) as num_login_methods, app_id, primary_or_recipe_user_id"
+ " FROM " + getConfig(start).getAppIdToUserIdTable()
+ " WHERE app_id = ? AND primary_or_recipe_user_id IN ("
+ " SELECT user_id FROM " + getConfig(start).getUserLastActiveTable()
+ " WHERE app_id = ? AND last_active_time >= ?"
+ " )"
+ " GROUP BY (app_id, primary_or_recipe_user_id)"
+ " ) AS nloginmethods"
+ " WHERE num_login_methods > 1"
+ " ) UNION (" // TOTP users
+ " SELECT user_id FROM " + getConfig(start).getTotpUsersTable()
+ " WHERE app_id = ? AND user_id IN ("
+ " SELECT user_id FROM " + getConfig(start).getUserLastActiveTable()
+ " WHERE app_id = ? AND last_active_time >= ?"
+ " )"
+ " )"
+ ") AS all_users";

return execute(start, QUERY, pst -> {
pst.setString(1, appIdentifier.getAppId());
pst.setString(2, appIdentifier.getAppId());
pst.setLong(3, sinceTime);
pst.setString(4, appIdentifier.getAppId());
pst.setString(5, appIdentifier.getAppId());
pst.setLong(6, sinceTime);
}, result -> {
return result.next() ? result.getInt("c") : 0;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1711,7 +1711,7 @@ public static int getUsersCountWithMoreThanOneLoginMethod(Start start, AppIdenti
throws SQLException, StorageQueryException {
String QUERY = "SELECT COUNT (1) as c FROM ("
+ " SELECT COUNT(user_id) as num_login_methods "
+ " FROM " + getConfig(start).getUsersTable()
+ " FROM " + getConfig(start).getAppIdToUserIdTable()
+ " WHERE app_id = ? "
+ " GROUP BY (app_id, primary_or_recipe_user_id) "
+ ") as nloginmethods WHERE num_login_methods > 1";
Expand All @@ -1723,6 +1723,32 @@ public static int getUsersCountWithMoreThanOneLoginMethod(Start start, AppIdenti
});
}

public static int getUsersCountWithMoreThanOneLoginMethodOrTOTPEnabled(Start start, AppIdentifier appIdentifier)
throws SQLException, StorageQueryException {
String QUERY =
"SELECT COUNT (DISTINCT user_id) as c FROM ("
+ " (" // Users with number of login methods > 1
+ " SELECT primary_or_recipe_user_id AS user_id FROM ("
+ " SELECT COUNT(user_id) as num_login_methods, app_id, primary_or_recipe_user_id"
+ " FROM " + getConfig(start).getAppIdToUserIdTable()
+ " WHERE app_id = ? "
+ " GROUP BY (app_id, primary_or_recipe_user_id)"
+ " ) AS nloginmethods"
+ " WHERE num_login_methods > 1"
+ " ) UNION (" // TOTP users
+ " SELECT user_id FROM " + getConfig(start).getTotpUsersTable()
+ " WHERE app_id = ?"
+ " )"
+ ") AS all_users";

return execute(start, QUERY, pst -> {
pst.setString(1, appIdentifier.getAppId());
pst.setString(2, appIdentifier.getAppId());
}, result -> {
return result.next() ? result.getInt("c") : 0;
});
}

public static boolean checkIfUsesAccountLinking(Start start, AppIdentifier appIdentifier)
throws SQLException, StorageQueryException {
String QUERY = "SELECT 1 FROM "
Expand Down

0 comments on commit dba89ba

Please sign in to comment.