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

feat: multitenancy dashboard #220

Merged
merged 7 commits into from
Jul 9, 2024
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
28 changes: 14 additions & 14 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,17 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [7.1.0]

- Compatible with plugin interface version 6.2
- Adds implementation for a new method `getConfigFieldsInfo` to fetch the plugin config fields.
- Adds `null` state for `firstFactors` and `providers` by adding `is_first_factors_null`
and `is_third_party_providers_null` fields in `tenant_configs` table
- Adds `DashboardInfo` annotations to the config properties in `PostgreSQLConfig`
- Adds `null` state for `firstFactors` by adding `is_first_factors_null` field in `tenant_configs` table. The value of
this column is only applicable when there are no entries in the `tenant_first_factors` table for the tenant.

### Migration

```sql
ALTER TABLE tenant_configs ADD COLUMN IF NOT EXISTS is_first_factors_null BOOLEAN DEFAULT TRUE;
ALTER TABLE tenant_configs ADD COLUMN IF NOT EXISTS is_third_party_providers_null BOOLEAN DEFAULT TRUE;

ALTER TABLE tenant_configs ALTER COLUMN is_first_factors_null DROP DEFAULT;
ALTER TABLE tenant_configs ALTER COLUMN is_third_party_providers_null DROP DEFAULT;
```

## [7.0.1] - 2024-04-17
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

import io.supertokens.pluginInterface.exceptions.StorageQueryException;
import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException;
import io.supertokens.pluginInterface.multitenancy.*;
import io.supertokens.pluginInterface.multitenancy.TenantConfig;
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
import io.supertokens.pluginInterface.multitenancy.ThirdPartyConfig;
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.storage.postgresql.Start;
import io.supertokens.storage.postgresql.config.Config;
Expand All @@ -32,8 +34,8 @@
import java.sql.SQLException;
import java.util.HashMap;

import static io.supertokens.storage.postgresql.QueryExecutorTemplate.update;
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 MultitenancyQueries {
Expand All @@ -52,7 +54,6 @@ static String getQueryToCreateTenantConfigsTable(Start start) {
+ "passwordless_enabled BOOLEAN,"
+ "third_party_enabled BOOLEAN,"
+ "is_first_factors_null BOOLEAN,"
+ "is_third_party_providers_null BOOLEAN,"
+ "CONSTRAINT " + Utils.getConstraintName(schema, tenantConfigsTable, null, "pkey") +
" PRIMARY KEY (connection_uri_domain, app_id, tenant_id)"
+ ");";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,13 @@ public static TenantConfigSQLHelper.TenantConfigRowMapper getInstance(ThirdParty
public TenantConfig map(ResultSet result) throws StorageQueryException {
try {
boolean isFirstFactorsNull = result.getBoolean("is_first_factors_null");
boolean isThirdPartyProvidersNull = result.getBoolean("is_third_party_providers_null");
return new TenantConfig(
new TenantIdentifier(result.getString("connection_uri_domain"), result.getString("app_id"),
result.getString("tenant_id")),
new EmailPasswordConfig(result.getBoolean("email_password_enabled")),
new ThirdPartyConfig(
result.getBoolean("third_party_enabled"),
providers.length == 0 && isThirdPartyProvidersNull ? null : providers),
providers),
new PasswordlessConfig(result.getBoolean("passwordless_enabled")),
firstFactors.length == 0 && isFirstFactorsNull ? null : firstFactors,
requiredSecondaryFactors.length == 0 ? null : requiredSecondaryFactors,
Expand All @@ -82,7 +81,7 @@ public static TenantConfig[] selectAll(Start start,
throws SQLException, StorageQueryException {
String QUERY = "SELECT connection_uri_domain, app_id, tenant_id, core_config,"
+ " email_password_enabled, passwordless_enabled, third_party_enabled, "
+ " is_first_factors_null, is_third_party_providers_null FROM "
+ " is_first_factors_null FROM "
+ getConfig(start).getTenantConfigsTable() + ";";

TenantConfig[] tenantConfigs = execute(start, QUERY, pst -> {
Expand Down Expand Up @@ -121,8 +120,8 @@ public static void create(Start start, Connection sqlCon, TenantConfig tenantCon
String QUERY = "INSERT INTO " + getConfig(start).getTenantConfigsTable()
+ "(connection_uri_domain, app_id, tenant_id, core_config,"
+ " email_password_enabled, passwordless_enabled, third_party_enabled,"
+ " is_first_factors_null, is_third_party_providers_null)"
+ " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ " is_first_factors_null)"
+ " VALUES(?, ?, ?, ?, ?, ?, ?, ?)";

update(sqlCon, QUERY, pst -> {
pst.setString(1, tenantConfig.tenantIdentifier.getConnectionUriDomain());
Expand All @@ -133,7 +132,6 @@ public static void create(Start start, Connection sqlCon, TenantConfig tenantCon
pst.setBoolean(6, tenantConfig.passwordlessConfig.enabled);
pst.setBoolean(7, tenantConfig.thirdPartyConfig.enabled);
pst.setBoolean(8, tenantConfig.firstFactors == null);
pst.setBoolean(9, tenantConfig.thirdPartyConfig.providers == null);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,12 @@ public void storageInstanceIsReusedAcrossTenants()
StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()));

Assert.assertEquals(
Config.getConfig(new TenantIdentifier(null, null, null), process.getProcess()).getAccessTokenValidity(),
Config.getConfig(new TenantIdentifier(null, null, null), process.getProcess())
.getAccessTokenValidityInMillis(),
(long) 3600 * 1000);

Assert.assertEquals(Config.getConfig(new TenantIdentifier(null, "abc", null), process.getProcess())
.getAccessTokenValidity(),
.getAccessTokenValidityInMillis(),
(long) 3601 * 1000);

Assert.assertEquals(
Expand Down Expand Up @@ -238,11 +239,12 @@ public void storageInstanceIsReusedAcrossTenantsComplex()
StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()));

Assert.assertEquals(
Config.getConfig(new TenantIdentifier(null, null, null), process.getProcess()).getAccessTokenValidity(),
Config.getConfig(new TenantIdentifier(null, null, null), process.getProcess())
.getAccessTokenValidityInMillis(),
(long) 3600 * 1000);

Assert.assertEquals(Config.getConfig(new TenantIdentifier(null, "abc", null), process.getProcess())
.getAccessTokenValidity(),
.getAccessTokenValidityInMillis(),
(long) 3601 * 1000);

Assert.assertEquals(
Expand Down Expand Up @@ -454,11 +456,12 @@ public void newStorageIsNotCreatedWhenSameTenantIsAdded()
existingStorage);

Assert.assertEquals(
Config.getConfig(new TenantIdentifier(null, null, null), process.getProcess()).getAccessTokenValidity(),
Config.getConfig(new TenantIdentifier(null, null, null), process.getProcess())
.getAccessTokenValidityInMillis(),
(long) 3600 * 1000);

Assert.assertEquals(Config.getConfig(new TenantIdentifier(null, "abc", null), process.getProcess())
.getAccessTokenValidity(),
.getAccessTokenValidityInMillis(),
(long) 3601 * 1000);

Assert.assertEquals(
Expand Down
Loading