-
Notifications
You must be signed in to change notification settings - Fork 335
Fix feature flag defaults #4265
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
Merged
Merged
Changes from 10 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
a800afe
Add failing test for flag default issue
pcapriotti bf93047
Disallow empty download location
pcapriotti fcb7ec6
Test empty download location
pcapriotti f18bb78
Fix mls migration defaults
pcapriotti 491483c
Configure enforceFileDownloadLocation on CI
pcapriotti b98ac55
Split feature flag test module
pcapriotti 4ef6567
Add global defAllFeatures
pcapriotti e77dd7d
Simplify checkPatch
pcapriotti a39a860
Test non-member access to features
pcapriotti cc4ba11
Add CHANGELOG entry
pcapriotti 33c355e
Fix enforceFileDownloadLocation config in chart
pcapriotti 1910afe
Add comment
pcapriotti File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Fix feature flag default calculation for `mlsMigration` and `enforceFileDownloadLocation` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| module Test.FeatureFlags.AppLock where | ||
|
|
||
| import qualified Data.Aeson as A | ||
| import Test.FeatureFlags.Util | ||
| import Testlib.Prelude | ||
|
|
||
| testPatchAppLock :: (HasCallStack) => App () | ||
| testPatchAppLock = do | ||
| checkPatch OwnDomain "appLock" | ||
| $ object ["lockStatus" .= "locked"] | ||
| checkPatch OwnDomain "appLock" | ||
| $ object ["status" .= "disabled"] | ||
| checkPatch OwnDomain "appLock" | ||
| $ object ["lockStatus" .= "locked", "status" .= "disabled"] | ||
| checkPatch OwnDomain "appLock" | ||
| $ object | ||
| [ "lockStatus" .= "unlocked", | ||
| "config" | ||
| .= object | ||
| [ "enforceAppLock" .= True, | ||
| "inactivityTimeoutSecs" .= A.Number 120 | ||
| ] | ||
| ] | ||
| checkPatch OwnDomain "appLock" | ||
| $ object | ||
| [ "config" | ||
| .= object | ||
| [ "enforceAppLock" .= True, | ||
| "inactivityTimeoutSecs" .= A.Number 240 | ||
| ] | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| module Test.FeatureFlags.ClassifiedDomains where | ||
|
|
||
| import SetupHelpers | ||
| import Test.FeatureFlags.Util | ||
| import Testlib.Prelude | ||
|
|
||
| testClassifiedDomainsEnabled :: (HasCallStack) => App () | ||
| testClassifiedDomainsEnabled = do | ||
| (_, tid, m : _) <- createTeam OwnDomain 2 | ||
| expected <- enabled & setField "config.domains" ["example.com"] | ||
| checkFeature "classifiedDomains" m tid expected | ||
|
|
||
| testClassifiedDomainsDisabled :: (HasCallStack) => App () | ||
| testClassifiedDomainsDisabled = do | ||
| withModifiedBackend def {galleyCfg = setField "settings.featureFlags.classifiedDomains" (object ["status" .= "disabled", "config" .= object ["domains" .= ["example.com"]]])} $ \domain -> do | ||
| (_, tid, m : _) <- createTeam domain 2 | ||
| expected <- disabled & setField "config.domains" ["example.com"] | ||
| checkFeature "classifiedDomains" m tid expected |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| module Test.FeatureFlags.ConferenceCalling where | ||
|
|
||
| import Test.FeatureFlags.Util | ||
| import Testlib.Prelude | ||
|
|
||
| testPatchConferenceCalling :: (HasCallStack) => App () | ||
| testPatchConferenceCalling = do | ||
| checkPatch OwnDomain "conferenceCalling" | ||
| $ object ["lockStatus" .= "locked"] | ||
| checkPatch OwnDomain "conferenceCalling" | ||
| $ object ["status" .= "disabled"] | ||
| checkPatch OwnDomain "conferenceCalling" | ||
| $ object ["lockStatus" .= "locked", "status" .= "disabled"] | ||
| checkPatch OwnDomain "conferenceCalling" | ||
| $ object | ||
| [ "lockStatus" .= "unlocked", | ||
| "config" .= object ["useSFTForOneToOneCalls" .= toJSON True] | ||
| ] | ||
|
|
||
| testConferenceCalling :: (HasCallStack) => APIAccess -> App () | ||
| testConferenceCalling access = do | ||
| runFeatureTests OwnDomain access | ||
| $ mkFeatureTests "conferenceCalling" | ||
| & addUpdate (confCalling def {sft = toJSON True}) | ||
| & addUpdate (confCalling def {sft = toJSON False}) | ||
| & addInvalidUpdate (confCalling def {sft = toJSON (0 :: Int)}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| module Test.FeatureFlags.DigitalSignatures where | ||
|
|
||
| import SetupHelpers | ||
| import Test.FeatureFlags.Util | ||
| import Testlib.Prelude | ||
|
|
||
| testPatchDigitalSignatures :: (HasCallStack) => App () | ||
| testPatchDigitalSignatures = checkPatch OwnDomain "digitalSignatures" enabled | ||
|
|
||
| testDigitalSignaturesInternal :: (HasCallStack) => App () | ||
| testDigitalSignaturesInternal = do | ||
| (alice, tid, _) <- createTeam OwnDomain 0 | ||
| withWebSocket alice $ \ws -> do | ||
| setFlag InternalAPI ws tid "digitalSignatures" disabled | ||
| setFlag InternalAPI ws tid "digitalSignatures" enabled |
55 changes: 55 additions & 0 deletions
55
integration/test/Test/FeatureFlags/EnforceFileDownloadLocation.hs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| module Test.FeatureFlags.EnforceFileDownloadLocation where | ||
|
|
||
| import qualified API.GalleyInternal as Internal | ||
| import SetupHelpers | ||
| import Test.FeatureFlags.Util | ||
| import Testlib.Prelude | ||
|
|
||
| testPatchEnforceFileDownloadLocation :: (HasCallStack) => App () | ||
| testPatchEnforceFileDownloadLocation = do | ||
| checkPatch OwnDomain "enforceFileDownloadLocation" | ||
| $ object ["lockStatus" .= "unlocked"] | ||
| checkPatch OwnDomain "enforceFileDownloadLocation" | ||
| $ object ["status" .= "enabled"] | ||
| checkPatch OwnDomain "enforceFileDownloadLocation" | ||
| $ object ["lockStatus" .= "unlocked", "status" .= "enabled"] | ||
| checkPatch OwnDomain "enforceFileDownloadLocation" | ||
| $ object ["lockStatus" .= "locked", "config" .= object []] | ||
| checkPatch OwnDomain "enforceFileDownloadLocation" | ||
| $ object ["config" .= object ["enforcedDownloadLocation" .= "/tmp"]] | ||
|
|
||
| do | ||
| (user, tid, _) <- createTeam OwnDomain 0 | ||
| bindResponse | ||
| ( Internal.patchTeamFeature | ||
| user | ||
| tid | ||
| "enforceFileDownloadLocation" | ||
| (object ["config" .= object ["enforcedDownloadLocation" .= ""]]) | ||
| ) | ||
| $ \resp -> do | ||
| resp.status `shouldMatchInt` 400 | ||
| resp.json %. "label" `shouldMatch` "empty-download-location" | ||
|
|
||
| testEnforceDownloadLocation :: (HasCallStack) => APIAccess -> App () | ||
| testEnforceDownloadLocation access = do | ||
| mkFeatureTests | ||
| "enforceFileDownloadLocation" | ||
| & addUpdate | ||
| ( object | ||
| [ "status" .= "enabled", | ||
| "config" .= object ["enforcedDownloadLocation" .= "/tmp"] | ||
| ] | ||
| ) | ||
| & addUpdate | ||
| (object ["status" .= "disabled", "config" .= object []]) | ||
| & addInvalidUpdate | ||
| ( object | ||
| [ "status" .= "enabled", | ||
| "config" | ||
| .= object | ||
| [ "enforcedDownloadLocation" .= object [] | ||
| ] | ||
| ] | ||
| ) | ||
| & runFeatureTests OwnDomain access |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| module Test.FeatureFlags.FileSharing where | ||
|
|
||
| import Test.FeatureFlags.Util | ||
| import Testlib.Prelude | ||
|
|
||
| testPatchFileSharing :: (HasCallStack) => App () | ||
| testPatchFileSharing = checkPatch OwnDomain "fileSharing" disabled | ||
|
|
||
| testFileSharing :: (HasCallStack) => APIAccess -> App () | ||
| testFileSharing access = | ||
| mkFeatureTests "fileSharing" | ||
| & addUpdate disabled | ||
| & addUpdate enabled | ||
| & runFeatureTests OwnDomain access |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| module Test.FeatureFlags.GuestLinks where | ||
|
|
||
| import Test.FeatureFlags.Util | ||
| import Testlib.Prelude | ||
|
|
||
| testConversationGuestLinks :: (HasCallStack) => APIAccess -> App () | ||
| testConversationGuestLinks access = | ||
| mkFeatureTests "conversationGuestLinks" | ||
| & addUpdate disabled | ||
| & addUpdate enabled | ||
| & runFeatureTests OwnDomain access | ||
|
|
||
| testPatchGuestLinks :: (HasCallStack) => App () | ||
| testPatchGuestLinks = checkPatch OwnDomain "conversationGuestLinks" disabled |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| module Test.FeatureFlags.LegalHold where | ||
|
|
||
| import qualified API.Galley as Public | ||
| import qualified API.GalleyInternal as Internal | ||
| import Control.Monad.Codensity (Codensity (runCodensity)) | ||
| import Control.Monad.Reader | ||
| import SetupHelpers | ||
| import Test.FeatureFlags.Util | ||
| import Testlib.Prelude | ||
| import Testlib.ResourcePool (acquireResources) | ||
|
|
||
| testLegalholdDisabledByDefault :: (HasCallStack) => App () | ||
| testLegalholdDisabledByDefault = do | ||
| let put uid tid st = Internal.setTeamFeatureConfig uid tid "legalhold" (object ["status" .= st]) >>= assertSuccess | ||
| let patch uid tid st = Internal.setTeamFeatureStatus uid tid "legalhold" st >>= assertSuccess | ||
| forM_ [put, patch] $ \setFeatureStatus -> do | ||
| withModifiedBackend | ||
| def {galleyCfg = setField "settings.featureFlags.legalhold" "disabled-by-default"} | ||
| $ \domain -> do | ||
| (owner, tid, m : _) <- createTeam domain 2 | ||
| nonMember <- randomUser domain def | ||
| assertForbidden =<< Public.getTeamFeature nonMember tid "legalhold" | ||
| -- Test default | ||
| checkFeature "legalhold" m tid disabled | ||
| -- Test override | ||
| setFeatureStatus owner tid "enabled" | ||
| checkFeature "legalhold" owner tid enabled | ||
| setFeatureStatus owner tid "disabled" | ||
| checkFeature "legalhold" owner tid disabled | ||
|
|
||
| -- always disabled | ||
| testLegalholdDisabledPermanently :: (HasCallStack) => App () | ||
| testLegalholdDisabledPermanently = do | ||
| let cfgLhDisabledPermanently = | ||
| def | ||
| { galleyCfg = setField "settings.featureFlags.legalhold" "disabled-permanently" | ||
| } | ||
| cfgLhDisabledByDefault = | ||
| def | ||
| { galleyCfg = setField "settings.featureFlags.legalhold" "disabled-by-default" | ||
| } | ||
| resourcePool <- asks (.resourcePool) | ||
| runCodensity (acquireResources 1 resourcePool) $ \[testBackend] -> do | ||
| let domain = testBackend.berDomain | ||
|
|
||
| -- Happy case: DB has no config for the team | ||
| runCodensity (startDynamicBackend testBackend cfgLhDisabledPermanently) $ \_ -> do | ||
| (owner, tid, _) <- createTeam domain 1 | ||
| checkFeature "legalhold" owner tid disabled | ||
| assertStatus 403 =<< Internal.setTeamFeatureStatus domain tid "legalhold" "enabled" | ||
| assertStatus 403 =<< Internal.setTeamFeatureConfig domain tid "legalhold" (object ["status" .= "enabled"]) | ||
|
|
||
| -- Interesting case: The team had LH enabled before backend config was | ||
| -- changed to disabled-permanently | ||
| (owner, tid) <- runCodensity (startDynamicBackend testBackend cfgLhDisabledByDefault) $ \_ -> do | ||
| (owner, tid, _) <- createTeam domain 1 | ||
| checkFeature "legalhold" owner tid disabled | ||
| assertSuccess =<< Internal.setTeamFeatureStatus domain tid "legalhold" "enabled" | ||
| checkFeature "legalhold" owner tid enabled | ||
| pure (owner, tid) | ||
|
|
||
| runCodensity (startDynamicBackend testBackend cfgLhDisabledPermanently) $ \_ -> do | ||
| checkFeature "legalhold" owner tid disabled | ||
|
|
||
| -- enabled if team is allow listed, disabled in any other case | ||
| testLegalholdWhitelistTeamsAndImplicitConsent :: (HasCallStack) => App () | ||
| testLegalholdWhitelistTeamsAndImplicitConsent = do | ||
| let cfgLhWhitelistTeamsAndImplicitConsent = | ||
| def | ||
| { galleyCfg = setField "settings.featureFlags.legalhold" "whitelist-teams-and-implicit-consent" | ||
| } | ||
| cfgLhDisabledByDefault = | ||
| def | ||
| { galleyCfg = setField "settings.featureFlags.legalhold" "disabled-by-default" | ||
| } | ||
| resourcePool <- asks (.resourcePool) | ||
| runCodensity (acquireResources 1 resourcePool) $ \[testBackend] -> do | ||
| let domain = testBackend.berDomain | ||
|
|
||
| -- Happy case: DB has no config for the team | ||
| (owner, tid) <- runCodensity (startDynamicBackend testBackend cfgLhWhitelistTeamsAndImplicitConsent) $ \_ -> do | ||
| (owner, tid, _) <- createTeam domain 1 | ||
| checkFeature "legalhold" owner tid disabled | ||
| Internal.legalholdWhitelistTeam tid owner >>= assertSuccess | ||
| checkFeature "legalhold" owner tid enabled | ||
|
|
||
| -- Disabling it doesn't work | ||
| assertStatus 403 =<< Internal.setTeamFeatureStatus domain tid "legalhold" "disabled" | ||
| assertStatus 403 =<< Internal.setTeamFeatureConfig domain tid "legalhold" (object ["status" .= "disabled"]) | ||
| checkFeature "legalhold" owner tid enabled | ||
| pure (owner, tid) | ||
|
|
||
| -- Interesting case: The team had LH disabled before backend config was | ||
| -- changed to "whitelist-teams-and-implicit-consent". It should still show | ||
| -- enabled when the config gets changed. | ||
| runCodensity (startDynamicBackend testBackend cfgLhDisabledByDefault) $ \_ -> do | ||
| checkFeature "legalhold" owner tid disabled | ||
| assertSuccess =<< Internal.setTeamFeatureStatus domain tid "legalhold" "disabled" | ||
| checkFeature "legalhold" owner tid disabled | ||
|
|
||
| runCodensity (startDynamicBackend testBackend cfgLhWhitelistTeamsAndImplicitConsent) $ \_ -> do | ||
| checkFeature "legalhold" owner tid enabled | ||
|
|
||
| testExposeInvitationURLsToTeamAdminConfig :: (HasCallStack) => App () | ||
| testExposeInvitationURLsToTeamAdminConfig = do | ||
| let cfgExposeInvitationURLsTeamAllowlist tids = | ||
| def | ||
| { galleyCfg = setField "settings.exposeInvitationURLsTeamAllowlist" tids | ||
| } | ||
| resourcePool <- asks (.resourcePool) | ||
| runCodensity (acquireResources 1 resourcePool) $ \[testBackend] -> do | ||
| let domain = testBackend.berDomain | ||
|
|
||
| let testNoAllowlistEntry = runCodensity (startDynamicBackend testBackend $ cfgExposeInvitationURLsTeamAllowlist ([] :: [String])) $ \_ -> do | ||
| (owner, tid, _) <- createTeam domain 1 | ||
| checkFeature "exposeInvitationURLsToTeamAdmin" owner tid disabledLocked | ||
| -- here we get a response with HTTP status 200 and feature status unchanged (disabled), which we find weird, but we're just testing the current behavior | ||
| -- a team that is not in the allow list cannot enable the feature, it will always be disabled and locked | ||
| -- even though the internal API request to enable it succeeds | ||
| assertSuccess =<< Internal.setTeamFeatureStatus domain tid "exposeInvitationURLsToTeamAdmin" "enabled" | ||
| checkFeature "exposeInvitationURLsToTeamAdmin" owner tid disabledLocked | ||
| -- however, a request to the public API will fail | ||
| assertStatus 409 =<< Public.setTeamFeatureConfig owner tid "exposeInvitationURLsToTeamAdmin" (object ["status" .= "enabled"]) | ||
| assertSuccess =<< Internal.setTeamFeatureStatus domain tid "exposeInvitationURLsToTeamAdmin" "disabled" | ||
| pure (owner, tid) | ||
|
|
||
| -- Happy case: DB has no config for the team | ||
| (owner, tid) <- testNoAllowlistEntry | ||
|
|
||
| -- Interesting case: The team is in the allow list | ||
| runCodensity (startDynamicBackend testBackend $ cfgExposeInvitationURLsTeamAllowlist [tid]) $ \_ -> do | ||
| -- when the team is in the allow list the lock status is implicitly unlocked | ||
| checkFeature "exposeInvitationURLsToTeamAdmin" owner tid disabled | ||
| assertSuccess =<< Internal.setTeamFeatureStatus domain tid "exposeInvitationURLsToTeamAdmin" "enabled" | ||
| checkFeature "exposeInvitationURLsToTeamAdmin" owner tid enabled | ||
| assertSuccess =<< Internal.setTeamFeatureStatus domain tid "exposeInvitationURLsToTeamAdmin" "disabled" | ||
| checkFeature "exposeInvitationURLsToTeamAdmin" owner tid disabled | ||
| assertSuccess =<< Internal.setTeamFeatureStatus domain tid "exposeInvitationURLsToTeamAdmin" "enabled" | ||
| checkFeature "exposeInvitationURLsToTeamAdmin" owner tid enabled | ||
|
|
||
| -- Interesting case: The team had the feature enabled but is not in allow list | ||
| void testNoAllowlistEntry |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.