Skip to content

Commit dd5f0c8

Browse files
authored
feat(user-roles): adds userRoles recipe support (#38)
* feat(user-roles): adds some user role queries and functions * adds TODOs, removes unnecessary comment * query fixs * removes comment * fixs * adds getRoles function * fix: renames addRoleToPermission function (#39) * feat: adds functions for setting a role for a user and retriving user roles (#40) * adds functions for setting a role for a user and retriving user roles * fixs * fix: updates plugin interface functions (#42) * feat: adds doesRoleExist_transaction and deleteUserRole_transaction (#41) * feat: adds doesRoleExist_transaction and deleteUserRole_transaction * updates doesRoleExist_Transaction with FOR UPDATE * feat: adds getUsersForRoleAPI functions (#43) * feat: adds RemovePermissionsFromRoleAPI (#44) * feat: adds getRolesForPermissionAPI function (#45) * feat: adds deleteAllRolesForUser functions (#46) * chore: updates (#47) * updates * fixs * updates CHANGELOG.md
1 parent 7c64e22 commit dd5f0c8

File tree

7 files changed

+450
-4
lines changed

7 files changed

+450
-4
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
99

10+
## [1.16.0] - 2022-05-05
11+
- Adds support for UserRoles recipe
12+
1013
## [1.15.0] - 2022-03-04
1114

1215
- Adds support for the new usermetadata recipe

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ plugins {
22
id 'java-library'
33
}
44

5-
version = "1.15.0"
5+
version = "1.16.0"
66

77
repositories {
88
mavenCentral()

pluginInterfaceSupported.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"_comment": "contains a list of plugin interfaces branch names that this core supports",
33
"versions": [
4-
"2.13"
4+
"2.14"
55
]
66
}

src/main/java/io/supertokens/storage/postgresql/Start.java

Lines changed: 176 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
import io.supertokens.pluginInterface.thirdparty.exception.DuplicateThirdPartyUserException;
5050
import io.supertokens.pluginInterface.thirdparty.sqlStorage.ThirdPartySQLStorage;
5151
import io.supertokens.pluginInterface.usermetadata.sqlStorage.UserMetadataSQLStorage;
52+
import io.supertokens.pluginInterface.userroles.exception.DuplicateUserRoleMappingException;
53+
import io.supertokens.pluginInterface.userroles.exception.UnknownRoleException;
54+
import io.supertokens.pluginInterface.userroles.sqlStorage.UserRolesSQLStorage;
5255
import io.supertokens.storage.postgresql.config.Config;
5356
import io.supertokens.storage.postgresql.config.PostgreSQLConfig;
5457
import io.supertokens.storage.postgresql.output.Logging;
@@ -67,7 +70,7 @@
6770
import java.util.List;
6871

6972
public class Start implements SessionSQLStorage, EmailPasswordSQLStorage, EmailVerificationSQLStorage,
70-
ThirdPartySQLStorage, JWTRecipeSQLStorage, PasswordlessSQLStorage, UserMetadataSQLStorage {
73+
ThirdPartySQLStorage, JWTRecipeSQLStorage, PasswordlessSQLStorage, UserMetadataSQLStorage, UserRolesSQLStorage {
7174

7275
private static final Object appenderLock = new Object();
7376
public static boolean silent = false;
@@ -179,6 +182,7 @@ public <T> T startTransaction(TransactionLogic<T> logic, TransactionIsolationLev
179182
if (exceptionMessage == null) {
180183
exceptionMessage = "";
181184
}
185+
182186
// see: https://github.com/supertokens/supertokens-postgresql-plugin/pull/3
183187

184188
// We set this variable to the current (or cause) exception casted to
@@ -1442,4 +1446,175 @@ public int deleteUserMetadata(String userId) throws StorageQueryException {
14421446
throw new StorageQueryException(e);
14431447
}
14441448
}
1449+
1450+
@Override
1451+
public void addRoleToUser(String userId, String role)
1452+
throws StorageQueryException, UnknownRoleException, DuplicateUserRoleMappingException {
1453+
1454+
try {
1455+
UserRolesQueries.addRoleToUser(this, userId, role);
1456+
} catch (SQLException e) {
1457+
if (e instanceof PSQLException) {
1458+
PostgreSQLConfig config = Config.getConfig(this);
1459+
ServerErrorMessage serverErrorMessage = ((PSQLException) e).getServerErrorMessage();
1460+
if (isForeignKeyConstraintError(serverErrorMessage, config.getUserRolesTable(), "role")) {
1461+
throw new UnknownRoleException();
1462+
}
1463+
if (isPrimaryKeyError(serverErrorMessage, config.getUserRolesTable())) {
1464+
throw new DuplicateUserRoleMappingException();
1465+
}
1466+
}
1467+
throw new StorageQueryException(e);
1468+
}
1469+
1470+
}
1471+
1472+
@Override
1473+
public String[] getRolesForUser(String userId) throws StorageQueryException {
1474+
try {
1475+
return UserRolesQueries.getRolesForUser(this, userId);
1476+
} catch (SQLException e) {
1477+
throw new StorageQueryException(e);
1478+
}
1479+
}
1480+
1481+
@Override
1482+
public String[] getUsersForRole(String role) throws StorageQueryException {
1483+
try {
1484+
return UserRolesQueries.getUsersForRole(this, role);
1485+
} catch (SQLException e) {
1486+
throw new StorageQueryException(e);
1487+
}
1488+
}
1489+
1490+
@Override
1491+
public String[] getPermissionsForRole(String role) throws StorageQueryException {
1492+
try {
1493+
return UserRolesQueries.getPermissionsForRole(this, role);
1494+
} catch (SQLException e) {
1495+
throw new StorageQueryException(e);
1496+
}
1497+
}
1498+
1499+
@Override
1500+
public String[] getRolesThatHavePermission(String permission) throws StorageQueryException {
1501+
try {
1502+
return UserRolesQueries.getRolesThatHavePermission(this, permission);
1503+
} catch (SQLException e) {
1504+
throw new StorageQueryException(e);
1505+
}
1506+
}
1507+
1508+
@Override
1509+
public boolean deleteRole(String role) throws StorageQueryException {
1510+
try {
1511+
return UserRolesQueries.deleteRole(this, role);
1512+
} catch (SQLException e) {
1513+
throw new StorageQueryException(e);
1514+
}
1515+
}
1516+
1517+
@Override
1518+
public String[] getRoles() throws StorageQueryException {
1519+
try {
1520+
return UserRolesQueries.getRoles(this);
1521+
} catch (SQLException e) {
1522+
throw new StorageQueryException(e);
1523+
}
1524+
}
1525+
1526+
@Override
1527+
public boolean doesRoleExist(String role) throws StorageQueryException {
1528+
try {
1529+
return UserRolesQueries.doesRoleExist(this, role);
1530+
} catch (SQLException e) {
1531+
throw new StorageQueryException(e);
1532+
}
1533+
}
1534+
1535+
@Override
1536+
public int deleteAllRolesForUser(String userId) throws StorageQueryException {
1537+
try {
1538+
return UserRolesQueries.deleteAllRolesForUser(this, userId);
1539+
} catch (SQLException e) {
1540+
throw new StorageQueryException(e);
1541+
}
1542+
}
1543+
1544+
@Override
1545+
public boolean deleteRoleForUser_Transaction(TransactionConnection con, String userId, String role)
1546+
throws StorageQueryException {
1547+
Connection sqlCon = (Connection) con.getConnection();
1548+
1549+
try {
1550+
return UserRolesQueries.deleteRoleForUser_Transaction(this, sqlCon, userId, role);
1551+
} catch (SQLException e) {
1552+
throw new StorageQueryException(e);
1553+
}
1554+
}
1555+
1556+
@Override
1557+
public boolean createNewRoleOrDoNothingIfExists_Transaction(TransactionConnection con, String role)
1558+
throws StorageQueryException {
1559+
Connection sqlCon = (Connection) con.getConnection();
1560+
1561+
try {
1562+
return UserRolesQueries.createNewRoleOrDoNothingIfExists_Transaction(this, sqlCon, role);
1563+
} catch (SQLException e) {
1564+
throw new StorageQueryException(e);
1565+
}
1566+
}
1567+
1568+
@Override
1569+
public void addPermissionToRoleOrDoNothingIfExists_Transaction(TransactionConnection con, String role,
1570+
String permission) throws StorageQueryException, UnknownRoleException {
1571+
Connection sqlCon = (Connection) con.getConnection();
1572+
try {
1573+
UserRolesQueries.addPermissionToRoleOrDoNothingIfExists_Transaction(this, sqlCon, role, permission);
1574+
} catch (SQLException e) {
1575+
if (e instanceof PSQLException) {
1576+
PostgreSQLConfig config = Config.getConfig(this);
1577+
ServerErrorMessage serverErrorMessage = ((PSQLException) e).getServerErrorMessage();
1578+
if (isForeignKeyConstraintError(serverErrorMessage, config.getUserRolesPermissionsTable(), "role")) {
1579+
throw new UnknownRoleException();
1580+
}
1581+
}
1582+
1583+
throw new StorageQueryException(e);
1584+
}
1585+
}
1586+
1587+
@Override
1588+
public boolean deletePermissionForRole_Transaction(TransactionConnection con, String role, String permission)
1589+
throws StorageQueryException {
1590+
Connection sqlCon = (Connection) con.getConnection();
1591+
try {
1592+
return UserRolesQueries.deletePermissionForRole_Transaction(this, sqlCon, role, permission);
1593+
} catch (SQLException e) {
1594+
throw new StorageQueryException(e);
1595+
}
1596+
}
1597+
1598+
@Override
1599+
public int deleteAllPermissionsForRole_Transaction(TransactionConnection con, String role)
1600+
throws StorageQueryException {
1601+
1602+
Connection sqlCon = (Connection) con.getConnection();
1603+
try {
1604+
return UserRolesQueries.deleteAllPermissionsForRole_Transaction(this, sqlCon, role);
1605+
} catch (SQLException e) {
1606+
throw new StorageQueryException(e);
1607+
}
1608+
}
1609+
1610+
@Override
1611+
public boolean doesRoleExist_Transaction(TransactionConnection con, String role) throws StorageQueryException {
1612+
Connection sqlCon = (Connection) con.getConnection();
1613+
try {
1614+
return UserRolesQueries.doesRoleExist_transaction(this, sqlCon, role);
1615+
} catch (SQLException e) {
1616+
throw new StorageQueryException(e);
1617+
}
1618+
}
1619+
14451620
}

src/main/java/io/supertokens/storage/postgresql/config/PostgreSQLConfig.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,18 @@ public String getUserMetadataTable() {
281281
return addSchemaAndPrefixToTableName("user_metadata");
282282
}
283283

284+
public String getRolesTable() {
285+
return addSchemaAndPrefixToTableName("roles");
286+
}
287+
288+
public String getUserRolesPermissionsTable() {
289+
return addSchemaAndPrefixToTableName("role_permissions");
290+
}
291+
292+
public String getUserRolesTable() {
293+
return addSchemaAndPrefixToTableName("user_roles");
294+
}
295+
284296
private String addSchemaAndPrefixToTableName(String tableName) {
285297
String name = tableName;
286298
if (!postgresql_table_names_prefix.trim().equals("")) {

src/main/java/io/supertokens/storage/postgresql/queries/GeneralQueries.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,26 @@ public static void createTablesIfNotExists(Start start) throws SQLException, Sto
194194
getInstance(start).addState(CREATING_NEW_TABLE, null);
195195
update(start, getQueryToCreateUserMetadataTable(start), NO_OP_SETTER);
196196
}
197+
198+
if (!doesTableExists(start, Config.getConfig(start).getRolesTable())) {
199+
getInstance(start).addState(CREATING_NEW_TABLE, null);
200+
update(start, UserRolesQueries.getQueryToCreateRolesTable(start), NO_OP_SETTER);
201+
}
202+
203+
if (!doesTableExists(start, Config.getConfig(start).getUserRolesPermissionsTable())) {
204+
getInstance(start).addState(CREATING_NEW_TABLE, null);
205+
update(start, UserRolesQueries.getQueryToCreateRolePermissionsTable(start), NO_OP_SETTER);
206+
// index
207+
update(start, UserRolesQueries.getQueryToCreateRolePermissionsPermissionIndex(start), NO_OP_SETTER);
208+
}
209+
210+
if (!doesTableExists(start, Config.getConfig(start).getUserRolesTable())) {
211+
getInstance(start).addState(CREATING_NEW_TABLE, null);
212+
update(start, UserRolesQueries.getQueryToCreateUserRolesTable(start), NO_OP_SETTER);
213+
// index
214+
update(start, UserRolesQueries.getQueryToCreateUserRolesRoleIndex(start), NO_OP_SETTER);
215+
}
216+
197217
} catch (Exception e) {
198218
if (e.getMessage().contains("schema") && e.getMessage().contains("does not exist")
199219
&& numberOfRetries < 1) {
@@ -237,7 +257,9 @@ public static void deleteAllTables(Start start) throws SQLException, StorageQuer
237257
+ "," + getConfig(start).getJWTSigningKeysTable() + ","
238258
+ getConfig(start).getPasswordlessCodesTable() + ","
239259
+ getConfig(start).getPasswordlessDevicesTable() + ","
240-
+ getConfig(start).getPasswordlessUsersTable() + "," + getConfig(start).getUserMetadataTable();
260+
+ getConfig(start).getPasswordlessUsersTable() + "," + getConfig(start).getUserMetadataTable() + ","
261+
+ getConfig(start).getRolesTable() + "," + getConfig(start).getUserRolesPermissionsTable() + ","
262+
+ getConfig(start).getUserRolesTable();
241263
update(start, DROP_QUERY, NO_OP_SETTER);
242264
}
243265
}

0 commit comments

Comments
 (0)