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: Changes for multitenancy dashboard #963

Merged
merged 40 commits into from
May 24, 2024
Merged

Conversation

prateek3255
Copy link
Contributor

Summary of change

  • Adds an API to fetch the list of core config properties

Related issues

N/A

Test Plan

N/A

Documentation changes

N/A

Checklist for important updates

  • Changelog has been updated
    • If there are any db schema changes, mention those changes clearly
  • coreDriverInterfaceSupported.json file has been updated (if needed)
  • pluginInterfaceSupported.json file has been updated (if needed)
  • Changes to the version if needed
    • In build.gradle
  • If added a new paid feature, edit the getPaidFeatureStats function in FeatureFlag.java file
  • Had installed and ran the pre-commit hook
  • If there are new dependencies that have been added in build.gradle, please make sure to add them
    in implementationDependencies.json.
  • Update function getValidFields in io/supertokens/config/CoreConfig.java if new aliases were added for any core config (similar to the access_token_signing_key_update_interval config alias).
  • Issue this PR against the latest non released version branch.
    • To know which one it is, run find the latest released tag (git tag) in the format vX.Y.Z, and then find the
      latest branch (git branch --all) whose X.Y is greater than the latest released tag.
    • If no such branch exists, then create one from the latest released branch.
  • If added a foreign key constraint on app_id_to_user_id table, make sure to delete from this table when deleting the user as well if deleteUserIdMappingToo is false.

Remaining TODOs for this PR

  • Update the API to return all property values and more information about properties like if they can be updated across apps, are config YAML only or are protected because of SaaS

* Add an API to fetch the coreConfig properties

* Update changelog

* Include plugin configs as well

* Remove core_config_result from the final output

* Hide protected config

* Fix formatting changes

* Add tests to ensure that the properties are same in the config and core config file

* Match descriptions from devConfig.yaml as well

* Refactor CoreConfig to return ConfigFieldInfo objects

* Refactor enum property validation

* Refactor move storage fields to API

* Refactor getConfigFieldsInfo method and update CoreConfigListAPI

* Add test to check protected properties are not present when saas secret is set

* Add comments wherever necessary
@prateek3255 prateek3255 changed the title Feat/multitenancy dashboard feat: Add API to fetch core config properties Mar 18, 2024
@sattvikc sattvikc changed the title feat: Add API to fetch core config properties feat: Changes for multitenancy dashboard May 2, 2024
## Unreleased

- Add a new core API for fetching all the core properties

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

schema changes + migration of schema + changes to multi tenancy + changes to how you configure a tenant

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Release prep at the end

Comment on lines 161 to 174
if (getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_1)) {
// if using first factors as a way to enable/disable recipes but the tenant was already created using an
// old CDI, we automatically enable the recipes to make things work seamlessly
if (hasFirstFactors && firstFactors != null) {
if (List.of(firstFactors).contains("emailpassword") && emailPasswordEnabled == null) {
emailPasswordEnabled = true;
}
if (List.of(firstFactors).contains("thirdparty") && thirdPartyEnabled == null) {
thirdPartyEnabled = true;
}
if ((List.of(firstFactors).contains("otp-email") || List.of(firstFactors).contains("otp-phone") || List.of(firstFactors).contains("link-email") || List.of(firstFactors).contains("link-phone")) && passwordlessEnabled == null) {
passwordlessEnabled = true;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think by default, all these enabled booleans have to be empty anyway for >= 5.1 CDI! Why is this being done?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should just set all to true in this if block

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do the if should be

  • (>= 5.1 cdi && emailPasswordEnabled == null) => emailPasswordEnabled = true

same thing for third party and passwordless

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no that might bring in un-intended side effects if the tenant is being updated with something else, like coreConfig only. This is specifically to handle tenants created using older CDI, and now updating enabled recipes using the firstFactors array.

);
if (useFirstFactorsFromStaticIfEmpty == null) {
useFirstFactorsFromStaticIfEmpty = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have to make this true for public tenant right? I think you need to refactor this whole thing to be more easy to read. Have separate branches in logic for if you are working with public tenant vs not, and what version of CDI it is. The code right now is very hard to follow and understand.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, it will be true if firstFactors is not passed at all. Whenever firstFactors is set, we set this boolean to false. Because this means that user want's to use that value for the tenant.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done refactoring

Comment on lines 87 to 93
if (getVersionFromRequest(req).lesserThan(SemVer.v5_1)) {
result.get("thirdParty").getAsJsonObject().remove("useThirdPartyProvidersFromStaticConfigIfEmpty");
result.remove("useFirstFactorsFromStaticConfigIfEmpty");
}

if (getVersionFromRequest(req).lesserThan(SemVer.v5_0)) {
result.remove("firstFactors");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should make the toJson function only do this logic? Otherwise it is easy to miss doing this

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 101 to 109
if (getVersionFromRequest(req).lesserThan(SemVer.v5_1)) {
tenantConfigJson.remove("useFirstFactorsFromStaticConfigIfEmpty");
tenantConfigJson.get("thirdParty").getAsJsonObject().remove("useThirdPartyProvidersFromStaticConfigIfEmpty");
}

if (getVersionFromRequest(req).lesserThan(SemVer.v5_0)) {
tenantConfigJson.remove("firstFactors");
tenantConfigJson.remove("requiredSecondaryFactors");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should make the toJson function only do this logic? Otherwise it is easy to miss doing this

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 69 to 77
if (getVersionFromRequest(req).lesserThan(SemVer.v5_1)) {
tenantConfigJson.remove("useFirstFactorsFromStaticConfigIfEmpty");
tenantConfigJson.get("thirdParty").getAsJsonObject().remove("useThirdPartyProvidersFromStaticConfigIfEmpty");
}

if (getVersionFromRequest(req).lesserThan(SemVer.v5_0)) {
tenantConfigJson.remove("firstFactors");
tenantConfigJson.remove("requiredSecondaryFactors");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should make the toJson function only do this logic? Otherwise it is easy to miss doing this

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -112,9 +113,12 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
tenantConfig.emailPasswordConfig,
new ThirdPartyConfig(
tenantConfig.thirdPartyConfig.enabled,
getVersionFromRequest(req).lesserThan(SemVer.v5_1) ?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why checking version here? The value of useThirdPartyProvidersFromStaticConfigIfEmpty should be already set correctly based on when it was created.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but when add/update/delete thirdParty config, we should set it to false for CDI >= 5.1. otherwise, preserve the older state

@@ -81,9 +82,13 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
config.tenantIdentifier,
config.emailPasswordConfig,
new ThirdPartyConfig(
config.thirdPartyConfig.enabled, newProviders.toArray(new ThirdPartyConfig.Provider[0])),
config.thirdPartyConfig.enabled,
getVersionFromRequest(req).lesserThan(SemVer.v5_1) ?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why checking version here? The value of useThirdPartyProvidersFromStaticConfigIfEmpty should be already set correctly based on when it was created.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but when add/update/delete thirdParty config, we should set it to false for CDI >= 5.1. otherwise, preserve the older state

@sattvikc sattvikc self-assigned this May 7, 2024
@sattvikc sattvikc changed the base branch from 9.0 to 9.1 May 24, 2024 10:36
@sattvikc sattvikc marked this pull request as ready for review May 24, 2024 10:37
@sattvikc sattvikc merged commit 563a90a into 9.1 May 24, 2024
4 of 6 checks passed
@sattvikc sattvikc deleted the feat/multitenancy-dashboard branch May 24, 2024 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants