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

Implement AUTO_REFRESH_MAX_TTL to limit total token lifetime when AUTO_REFRESH = True. #366

Merged
merged 4 commits into from
Sep 30, 2024

Conversation

christian-oudard
Copy link
Contributor

Refs #311

Copy link
Collaborator

@johnraz johnraz left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the contribution, I have a few comments 😉

docs/settings.md Outdated Show resolved Hide resolved
knox/auth.py Outdated

# Do not auto-renew tokens past AUTO_REFRESH_MAX_TTL.
if knox_settings.AUTO_REFRESH_MAX_TTL is not None:
new_expiry = min(new_expiry, auth_token.created + knox_settings.AUTO_REFRESH_MAX_TTL)
Copy link
Collaborator

Choose a reason for hiding this comment

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

There is quite some indirection here, I think that rather than abusing the expiry value we should raise a clear error that says auto refresh has been « exhausted »

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess I don't understand the library enough to get what needs to be different here. This seems to me like an elegant solution to not extending the maximum time since creation date. Is there a different exception or http code or something you want to return to the user instead?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would like the error message to clearly state that the token couldn’t be auto refreshed due to the max ttl being reached yes.

While this code would work, it would be quite hard to understand what happened.

Remember the Zen of Python: explicit is better than implicit 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, but the current design deletes token objects once they expire. The error message does not currently distinguish between tokens that never existed and ones that once existed then expired. According to the docstring of authenticate_credentials: "Tokens that have expired will be deleted and skipped", using _cleanup_token.

So I think it's on you to provide a mechanism to explicitly distinguish these things.

Copy link
Collaborator

@johnraz johnraz Sep 6, 2024

Choose a reason for hiding this comment

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

This is not really true.

Nothing prevents us from raising something like AutoRefreshMaxTTLExpired here and handling the exception in authenticate_credentials in order to return a specific error message with exceptions.AuthenticationFailed.

Marking the token has expired and letting it continue its life until it reaches another step of the flow feels wrong to me, really.

Edit: To clarify, I think that adding more potential mechanism for failure / expiration requires more care - this is why building on top of the current behavior is going to make things hard to follow IMHO.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Reading the code again I realize we actually don’t want an error here as the authentication passed … Then I guess adding a log message stating that the max ttl was reached would be better already.

And maybe for the longer game we should review the way this is designed: decide if a token should be refreshed at the time we identify it is actually expired - this would give us more room for raising appropriate errors but this is definitely outside of the scope of this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Totally fine adding a log message, but there is currently no logging whatsoever in the project, so I would wait for you or one of the other main developers to add that before trying to do it myself. My client is already using our fork of this in its current state, so I'm going to stop working on this PR for now. Please feel free to do anything you need to to merge this into the main codebase.

Copy link
Collaborator

Choose a reason for hiding this comment

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

AFAIK logging configuration is handled by Django.

To add a log line here you can just follow the usual way:

logger = logging.getLogger(__name__)

and then use the logger accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a log message when the expiry is capped by AUTO_REFRESH_MAX_TTL.

tests/tests.py Outdated Show resolved Hide resolved
self.assertEqual(new_expiry.replace(tzinfo=None), expected_expiry,
"Expiry time should have been extended to {} but is {}."
.format(expected_expiry, new_expiry))

Copy link
Collaborator

Choose a reason for hiding this comment

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

This test is ok but I think we need to demonstrate the use case from an http standpoint: status code, error message etc in case auto refresh is not allowed anymore

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe I wasn’t clear in my previous comment but can you add the call that actually fails due to the expired token ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added an http request to the test and showed that it fails.

Copy link
Collaborator

@johnraz johnraz left a comment

Choose a reason for hiding this comment

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

Looks good to me, can you look into why you have a pre-commit related commit in your PR?

After that is solved we should be good to merge 😁

@giovannicimolin maybe you want to give this a check too?

@christian-oudard
Copy link
Contributor Author

christian-oudard commented Sep 23, 2024

can you look into why you have a pre-commit related commit in your PR?

This was apparently created by the copied CI system on my fork. It was a linting fix. All it does is rearrange the order of some imports.

Please merge this whenever you like.

@christian-oudard
Copy link
Contributor Author

Any predictions when you'll be able to merge this?

@johnraz
Copy link
Collaborator

johnraz commented Sep 26, 2024

When @giovannicimolin will have free time to review so no, there is no specific timeline

@eranrund
Copy link

Looking forward to seeing this merged :) Thank you!

Copy link
Contributor

@giovannicimolin giovannicimolin left a comment

Choose a reason for hiding this comment

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

👍

Nice addition! Looks good to go

@johnraz Thanks for the heavy lifting here!

@giovannicimolin giovannicimolin merged commit a3dfcba into jazzband:develop Sep 30, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants