-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
✨ Source Facebook-Marketing: Add Selectable Auth (with migration & tests) #38304
base: master
Are you sure you want to change the base?
Conversation
…anges to solve build issues, and changes to solve unit testing issues.
…e config. Updated version to reflect Airbyte versioning standard (this use case is a major version upgrade due to configuration of credentials needed to be changed)
…ebook-marketing-selectable-auth
…ebook-marketing-selectable-auth' into JohnMikkelsonOvative/feature-facebook-marketing-selectable-auth
…eting-selectable-auth
…eting-selectable-auth
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 1 Ignored Deployment
|
cristina.mariscal seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
@cmm-airbyte We need to update the config in the GSM for the change to work, I believe. |
I haven't check the change but it shouldn't be if the change is non-breaking with the config migration |
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'll test manually tomorrow morning but I don't see obvious issues with the code
@@ -44,6 +44,9 @@ data: | |||
- "ads_insights_region" | |||
- "ads_insights_dma" | |||
- "ads_insights_action_product_id" | |||
3.0.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.
What makes it breaking if we have the config migration? Does that mean that the user will have to opt-in on that change?
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.
no, I was just guessing this because the PR cannot be directly reverted. I can do only a 2.2.0 version increment. WDYT?
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 think 2.2.0 makes sense, yes! We should still document that the config format changes but there is a migration for backward compatibility but none for forward compatiblity
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.
great. Thanks Max!
""" | ||
credentials = config.get("credentials", None) | ||
return credentials is None or ( | ||
"access_token" not in credentials and not ("client_id" in credentials and "client_id" in credentials) |
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 condition feels hard to maintain. If something adds a new auth method, they will need to know that they have to update an old migration script
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.
mmm.. I think if there is a new change, an iteration over this migration will be required. isn't 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.
Let's take the following scenario: on the 2025-01-04, a developer is doing the work to add username/password as an authentication mechanism. To do so, they update the spec to have credentials.username
and credentials.password
and configure the authenticator properly in the source.py. Now, this condition will always be triggered which means that the GSM secrets and the database entries will be updated on every operation of the connector. For the source in practice, I don't think it changes that much but I fear that those updates on the platform or GSM side could create issues in the long run. Hence, I would try to make the condition specific to this update. Is there a case where only credentials
not being present wouldn't be enough to trigger this migration?
Note if we keep the condition as-is: the "client_id" in credentials and "client_id" in credentials
part of the condition should probably be "client_id" in credentials and "client_secret" in credentials
Starting from `3.0.0`, the `client_id`, `client_secret` and `access_token` will be placed at `credentials` path. | ||
""" | ||
|
||
message_repository: MessageRepository = InMemoryMessageRepository() |
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 field is useless right now. We can just do print(create_connector_config_control_message(migrated_config).json(exclude_unset=True))
message_repository: MessageRepository = InMemoryMessageRepository() | ||
|
||
@classmethod | ||
def should_migrate(cls, config: Mapping[str, Any]) -> bool: |
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.
It feels like this should be private as it is only used internally. What do you think? The same comment applies to transform
, modify_and_save
and emit_control_message
def transform(cls, config: Mapping[str, Any]) -> Mapping[str, Any]: | ||
# transform the config | ||
config["credentials"] = {} | ||
if "client_id" in config: |
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.
Set the type here so we can distinguish which type of authentication
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.
If client_id
and client_secret
are not defined, we should use the auth Service
title = "Authenticate via Facebook Marketing (Oauth)" | ||
discriminator = "auth_type" | ||
|
||
auth_type: Literal["Client"] = Field("Client", const=True) |
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 probably needs an access_token
…m-airbyte/fb_oauth
…m-airbyte/fb_oauth
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.
Can you confirm that the case I mentioned in the _should_migrate
method is covered or not?
"airbyte_secret": true, | ||
"type": "string" | ||
"credentials": { | ||
"title": "authentication credentials", |
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.
Why does this differ from spec.py
? https://github.com/airbytehq/airbyte/pull/38304/files#diff-465a935c5dc0fc41f783e4f82ca3ba4bacf4d0dd97065fa273d7a7bdad94ac9bR33
> False, otherwise. | ||
""" | ||
credentials = config.get("credentials", None) | ||
return credentials is None or ( |
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 think this condition needs to change with the new release process. At first, we wanted to release both the platform and the source at the same time. This meant that we only had to bother about the migration once as:
- Before the update, access_token would be at the root but source would migrate this to
credentials.access_token
- After the update:
- when configuring the source, the access_token would be on
credentials.access_token
- when logging in through oauth, the platform would set the access_token would be on
credentials.access_token
- when configuring the source, the access_token would be on
However, our new plan have those releases split. This means that we will have a state where the source is updated but not the platform. In this case, we could have the following steps:
- The source is updated
- The migration happens so
access_token
is moved tocredentials.access_token
- A user does oauth, the access token is set to
access_token
- Given this condition, there will be
credentials.access_token
and we won't leverage the new token from oauth
I think the condition here should just be "is there an access token on the root level". Does that make sense?
…m-airbyte/fb_oauth
What
The Source Facebook Marketing Connector does not allow for choosing between providing an access token or using oauth, it only allows for users to define a source connection by following an oauth flow. This does not allow for use-cases in which a large organization may provision an access token to be used to authenticate to the Facebook Marketing data, rather than giving a user's personal Facebook account access.
How
The
spec
defines acredentials
field that is a union between newly createdOAuthCredentials
andServiceAccountCredentials
. This allows for the user to select between using the Oauth flow and inserting Service Account Credentials.Review guide
User Impact
The user is able to select between using the Oauth flow and inserting Service Account Credentials when setting up the Facebook Marketing Source.
Can this PR be safely reverted and rolled back?
Source PR here: #37625