-
Notifications
You must be signed in to change notification settings - Fork 455
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) [NAN-677] enforce cap when calling nangoauth #1950
(feat) [NAN-677] enforce cap when calling nangoauth #1950
Conversation
…ers' into khaliq/nan-677-enforce-cap-when-calling-nangoauth
…ers' into khaliq/nan-677-enforce-cap-when-calling-nangoauth
providerConfigKey: string, | ||
environment_id: number | ||
): Promise<({ connections: { connection_id: string }[] } & SyncConfig & ProviderConfig)[]> { | ||
const result = await schema() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to get another pair of eyes on this query to improve it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you only want connection with syncs? I feel like it's harder to explain to customers but whatever :D
Isn't something like this enough? I'm not sure why you selected that much stuff from the table
SELECT
COUNT(1)
FROM
_nango_connections
JOIN _nango_syncs ON _nango_syncs.nango_connection_id = _nango_connections.id AND _nango_syncs.deleted = FALSE
WHERE
environment_id = 2
AND provider_config_key = 'github-demo'
AND _nango_syncs.deleted = FALSE;
and if it's only 3 connections ever
SELECT
COUNT(1)
FROM
_nango_connections
WHERE
environment_id = 2
AND provider_config_key = 'github-demo'
AND _nango_syncs.deleted = FALSE;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SELECT
COUNT(1)
FROM
_nango_connections
JOIN _nango_syncs ON _nango_syncs.nango_connection_id = _nango_connections.id AND _nango_syncs.deleted = FALSE
WHERE
environment_id = 2
AND provider_config_key = 'github-demo'
AND _nango_syncs.deleted = FALSE;
Thanks, that query would work nicely but at some point I would like to move away from storing the provider_config_key
in the connections table and instead rely on the config_id
there which relates back to the _nango_configs
table. As a result of the provider_config_key
being stored in the connections table a user can't edit a provider_config_key if there are connections are attached to it. Happy to discuss that more if you want?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This give you all connections with active syncs or actions for a provider.
SELECT
conn.id
FROM
_nango_configs AS configs
JOIN _nango_connections AS conn ON configs.id = conn.config_id
AND conn.deleted = FALSE
JOIN _nango_sync_configs AS syncs ON syncs.nango_config_id = configs.id
AND syncs.deleted = FALSE
AND syncs.active = TRUE
WHERE
configs.environment_id = 2
AND configs.provider_config_key = 'github-demo'
AND configs.deleted = FALSE
GROUP BY
conn.id
HAVING
COUNT(syncs.id) > 0;
then res.length >= 3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this doesn't give me what I want either
SELECT
conn.id
FROM
nango._nango_configs AS configs
JOIN nango._nango_connections AS conn ON configs.id = conn.config_id
AND conn.deleted = FALSE
JOIN nango._nango_sync_configs AS syncs ON syncs.nango_config_id = configs.id
AND syncs.deleted = FALSE
AND syncs.active = TRUE
WHERE
configs.environment_id = 2
AND configs.unique_key = 'unauthenticated'
AND configs.deleted = FALSE
GROUP BY
conn.id
HAVING
COUNT(syncs.id) > 0;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah indeed, I realized that _nango_sync_configs
are per config not per connection and _nango_syncs
are per connection but do not contain actions :/
I guess you got the right one then!
@@ -559,6 +559,13 @@ export class NangoError extends Error { | |||
this.message = `Missing an account name for account login/signup.`; | |||
break; | |||
|
|||
case 'resource_capped': | |||
this.status = 400; | |||
// TODO docs link |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pending from Bastien.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small review, not tested
providerConfigKey: string, | ||
environment_id: number | ||
): Promise<({ connections: { connection_id: string }[] } & SyncConfig & ProviderConfig)[]> { | ||
const result = await schema() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you only want connection with syncs? I feel like it's harder to explain to customers but whatever :D
Isn't something like this enough? I'm not sure why you selected that much stuff from the table
SELECT
COUNT(1)
FROM
_nango_connections
JOIN _nango_syncs ON _nango_syncs.nango_connection_id = _nango_connections.id AND _nango_syncs.deleted = FALSE
WHERE
environment_id = 2
AND provider_config_key = 'github-demo'
AND _nango_syncs.deleted = FALSE;
and if it's only 3 connections ever
SELECT
COUNT(1)
FROM
_nango_connections
WHERE
environment_id = 2
AND provider_config_key = 'github-demo'
AND _nango_syncs.deleted = FALSE;
|
||
const { accountId, environmentId } = response; | ||
|
||
const account = await accountService.getAccountById(accountId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are making more queries to the db on each request by adding a middleware which is doing something similar to the access.middleware
, ie: fetching the account and environment from the db. Can we fetch the account.is_capped
as part of the access.middleware
and save it into the res.locals
like we do with accountId
and environmentId
so it can be access down the line by controllers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea in theory, but the issue is that the value of is_capped
can change via the api and then the value stored in the res.locals
is stale and potentially inaccurate. Since the user changing the is_capped
setting is different than the user who has the capping nor not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
res.locals
is only stored for the current request if that's your worry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, but still this is making it more complicated than it needs since right now the only controller it goes through is the connection.controller
when it is imported. If it went into the access.middleware
instead of the capping.middleware
then the logic to check the cap would need to go through:
oauth.controller
unauth.controller
apiAuth.controller
appStoreController
import type { Result } from '../utils/result.js'; | ||
import { resultOk, resultErr } from '../utils/result.js'; | ||
import { NangoError } from '../utils/error.js'; | ||
|
||
export const connectionCreationStartCapCheck = async ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need a new function? Can we not call syncService.getSyncsByProviderConfigKey
and count the connections?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That method would be good, but we need both to check against syncs and actions.
…rect values via the API
…-enforce-cap-when-calling-nangoauth
@bodinsamuel are you good with this one? A few other tasks rely on this one so is semi blocking but not a huge issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sure we can improve it later 👌🏻
## Describe your changes Builds on #1950 ## Issue ticket number and link NAN-676 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is:
Describe your changes
Add check when creating a new connection and importing a connection to see if the account has reached the cap.
Issue ticket number and link
NAN-680
Checklist before requesting a review (skip if just adding/editing APIs & templates)