-
Notifications
You must be signed in to change notification settings - Fork 481
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
SNOW-1825621 OAuth code flow support #2135
base: main
Are you sure you want to change the base?
SNOW-1825621 OAuth code flow support #2135
Conversation
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!
A couple over-arching thoughts:
- I only really looked at the security semantics, we should have additional reviewers for the Pythonic HTTP bits.
- Ideally we find some way to add automated tests for this flow. Do we have browser automation testing, for example, that we could use to build an integration test?
logger = logging.getLogger(__name__) | ||
|
||
|
||
class AuthHttpServer: |
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 assume we have this to avoid taking additional dependencies in the driver?
(As we move to introduce additional forms of CSP-specific authentication I suspect we'll want to introduce dependencies on the various CSP libraries, which is in part why I ask.)
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.
Yes, I copied this code all from externalbrowser auth. So it's tried and tested given that I have made no mistakes. I didn't feel like I needed to introduce any dependencies for this OAuth implementation and I'm not sure I'd have time to really investigate different options anymore. I'd like to leave this up to the new owners of the library if you don't mind
fields=fields, | ||
) | ||
try: | ||
self._oauth_token = json.loads(resp.data)["access_token"] |
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.
at some point we'll also have to content with refresh_token coming back, I expect
can the driver be used to establish multiple sessions using the same credentials? (if so we might also need to handle the case where the access token has expired and we need to retrieve a new one, either via the refresh token if it's available or via the full browser flow)
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, it cannot. Users can manually feed the same credentials to the connector, but we discard the information required to create a session in reset_secrets
method once we consume them.
":".join(origin_line.split(":")[1:]).strip(), | ||
) | ||
|
||
def _process_options( |
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.
there are a lot of mechanics shared with the external browser flow that I wonder might be better hoisted somewhere common?
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.
Yes, I started sharing code between the two, but I didn't plan on touching externalbrowser code in this PR. I'd like to touch that in the near future. Once this code is verified to work properly. I've filed a follow-up Jira for this effort. If you would like me to close do this in this PR please let me know, but otherwise we could pick this up in a bit.
We do this manually when we mess with the authentication code, otherwise we just don't touch these pieces of the code and we don't test them. None of them have any dependencies outside of std lib, so there's no need to |
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.
Broadly LGTM modulo a few minor comments!
We should have the "new owners" take a look too. This is complex and sensitive enough that I think it benefits from additional eyes.
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.
Nice! Stamped.
I'd really love more eyes on this, however. Can we perhaps involve the team taking over this driver to take a second look? There's enough security-sensitive handling here that more than one reviewer is ~necessary.
"client_id": self.client_id, | ||
"redirect_uri": self.redirect_uri, | ||
} | ||
if self.client_secret: |
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 still expecting that we'll remove this from the body since it appears in the header?
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 provide some testing? I think it can be done pretty easily. We could inject fake/mock webbrowser object and access token request? The fake web browser could do a redirect call immediately (extracted from the url).
Please answer these questions before submitting your pull requests. Thanks!
What GitHub issue is this PR addressing? Make sure that there is an accompanying issue to your PR.
Fixes SNOW-1825621
Fill out the following pre-review checklist:
Please describe how your code solves the related issue.
In this PR I add support for OUath authorization code flow. It's very similar to external browser authentication, but it uses oauth and more options are more better for users.
This change has been tested manually, as it's fairly complicated to setup and we don't do unit tests for the different authentication methods.
(Optional) PR for stored-proc connector: Not applicable