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

Allow to send headers to proxied documents #42

Merged
merged 4 commits into from
Jan 11, 2023
Merged

Conversation

marcospri
Copy link
Member

@marcospri marcospri commented Dec 20, 2022

For:

Testing

Follow the instructions over: hypothesis/lms#4792

@marcospri marcospri marked this pull request as ready for review December 21, 2022 11:51
@marcospri marcospri changed the title [WIP]Secret headers Allow to send headers to proxied PDFs Dec 21, 2022
@marcospri marcospri changed the title Allow to send headers to proxied PDFs Allow to send headers to proxied documents Dec 21, 2022
src/h_vialib/client.py Outdated Show resolved Hide resolved
@@ -56,7 +57,10 @@ def __init__(self, secret, service_url=None, html_service_url=None):
"via.external_link_mode": "new-tab",
}

def url_for(self, url, content_type=None, options=None, blocked_for=None):
# pylint:disable=too-many-arguments
Copy link
Member Author

Choose a reason for hiding this comment

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

I reckon this might keep growing and have a similar interface to requests.request.

Not a problem IMO.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍

src/h_vialib/client.py Show resolved Hide resolved
src/h_vialib/secure/secrets.py Outdated Show resolved Hide resolved
src/h_vialib/secure/secrets.py Outdated Show resolved Hide resolved

return json.loads(self._decrypt(aes_iv, cipher))

def _decrypt(self, aes_iv, encrypted) -> bytes:
Copy link
Member Author

Choose a reason for hiding this comment

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

Making these private. We might need them in the future but as this is a library we want to keep the interface under control.

Copy link
Contributor

Choose a reason for hiding this comment

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

So the existing SecureToken and SecureURL classes aren't appropriate for this use-case? I guess not because it looks like SecureURL only signs the URL doesn't encrypt it.

I wonder if we should rename some of these classes, to clarify what they do and don't do? For example perhaps SecureURL should be SignedURL if it just signs and doesn't encrypt. I think SecureSecrets encrypts a dict but doesn't sign it, so perhaps EncryptedDict?

I think we should probably stop using the words "secret" and "secure" because it's not clear exactly what they mean, and maybe instead say "signed" and "encrypted".

Copy link
Member Author

Choose a reason for hiding this comment

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

EncryptedDict is a better name 👍.

Copy link
Member Author

Choose a reason for hiding this comment

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

I wrote this as EncryptedDict but from the callers perspetive it looked like it was as dict subclass supporting encryption. It didn't feel right.

I renamed the class to a more explicit Encryption and keep the method names.

tests/unit/h_vialib/secure/secrets_test.py Outdated Show resolved Hide resolved
Copy link
Contributor

@seanh seanh left a comment

Choose a reason for hiding this comment

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

Posting some initial questions. I want to come back and take a closer look at the crypto code in here when I have more time, just to double-check...

.cookiecutter/includes/setuptools/install_requires Outdated Show resolved Hide resolved
src/h_vialib/client.py Outdated Show resolved Hide resolved
Comment on lines +61 to +63
def url_for(
self, url, content_type=None, options=None, blocked_for=None, headers=None
):
Copy link
Contributor

Choose a reason for hiding this comment

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

headers are only supported by certain Via endpoints, right? The ones that proxy in Python, not the ones that proxy in NGINX. Are there some url's where url_for(url, headers=my_headers) will return a URL containing headers that Via will actually ignore because it's going to proxy that URL through NGINX?

Copy link
Member Author

Choose a reason for hiding this comment

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

will return a URL containing headers that Via will actually ignore because it's going to proxy that URL through NGINX?

Yes, all HTML ones and pdfs not proxied by python (so all of them except one drive and d2l ones).

Applying the headers to everything will be a big tasks (not sure even if possible without writing nginx lua code).

Maybe we could just explain the limitation on the method's docstring?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added a comment about this. Not ideal but naming this headers_for_python_proxing is not better.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we could make Via throw some sort of "not implemented" error if any headers are passed to it and it would have proxied the request through NGINX rather than through Python?


return json.loads(self._decrypt(aes_iv, cipher))

def _decrypt(self, aes_iv, encrypted) -> bytes:
Copy link
Contributor

Choose a reason for hiding this comment

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

So the existing SecureToken and SecureURL classes aren't appropriate for this use-case? I guess not because it looks like SecureURL only signs the URL doesn't encrypt it.

I wonder if we should rename some of these classes, to clarify what they do and don't do? For example perhaps SecureURL should be SignedURL if it just signs and doesn't encrypt. I think SecureSecrets encrypts a dict but doesn't sign it, so perhaps EncryptedDict?

I think we should probably stop using the words "secret" and "secure" because it's not clear exactly what they mean, and maybe instead say "signed" and "encrypted".

@marcospri marcospri force-pushed the secret-headers branch 2 times, most recently from edb9587 to 2aa15de Compare January 9, 2023 10:08
.cookiecutter/includes/setuptools/install_requires Outdated Show resolved Hide resolved
def __init__(self, secret: bytes):
self._secret = secret.ljust(32)[:32]

def encrypt_dict(self, payload: dict) -> str:
Copy link
Member Author

Choose a reason for hiding this comment

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

Using JWE simplified this a lot.

src/h_vialib/secure/token.py Outdated Show resolved Hide resolved
tests/unit/h_vialib/secure/token_test.py Outdated Show resolved Hide resolved
tests/unit/h_vialib/secure/token_test.py Outdated Show resolved Hide resolved
@marcospri marcospri changed the base branch from main to replace-jwt-library January 9, 2023 10:18
@marcospri marcospri requested a review from seanh January 9, 2023 10:35
Copy link
Contributor

@seanh seanh left a comment

Choose a reason for hiding this comment

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

This all looks good to me. Made a comment below about potentially wanting to make Via (not h-vialib) error if headers are sent for an NGINX or Via HTML-proxied URL where headers aren't supported

@@ -56,7 +57,10 @@ def __init__(self, secret, service_url=None, html_service_url=None):
"via.external_link_mode": "new-tab",
}

def url_for(self, url, content_type=None, options=None, blocked_for=None):
# pylint:disable=too-many-arguments
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Comment on lines +61 to +63
def url_for(
self, url, content_type=None, options=None, blocked_for=None, headers=None
):
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we could make Via throw some sort of "not implemented" error if any headers are passed to it and it would have proxied the request through NGINX rather than through Python?

Allows to encrypt dictionaries using AES and encode both the cipher text
and IV in a base64 encoded string.
Take an optional `headers` parameters which wild be sent AES encoded
over the wire to Via.
Instead of our own mix of base64,AES,iv... just use JWE for the same
functionality.
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.

2 participants