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

feat(server): add support for multiple auth tokens via env vars #339

Merged
merged 4 commits into from
Aug 24, 2024

Conversation

nydragon
Copy link
Contributor

@nydragon nydragon commented Aug 22, 2024

Description

Add support for reading a list of newline separated tokens from a file
which path is being supplied through the following environment
variables:

  • AUTH_FILE
  • DELETE_FILE

Also add support for setting environment variables inside of fixtures through the optional custom_env function.

Also describe this new functionality in the readme.

Motivation and Context

Need a way to supply multiple auth token akin to AUTH_TOKEN due to agenix behaviour.

closes #338

How Has This Been Tested?

Added UTs for file content parsing. File reading has not received any UT, but has been manually tested.

Changelog Entry

Added

  • Multiple authentication and deletion token parsing via a file to which AUTH_FILE and DELETION_FILE point. This file needs to be a newline separated list of strings. Whitespace is discarded.

Types of Changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (no code change)
  • Refactor (refactoring production code)
  • Other

Checklist:

  • My code follows the code style of this project.
  • I have updated the documentation accordingly.
  • I have formatted the code with rustfmt.
  • I checked the lints with clippy.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Copy link
Collaborator

@tessus tessus left a comment

Choose a reason for hiding this comment

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

Thanks for this PR. LGTM (unless I missed some Rust specific optimization I am not aware of, since I am not a Rust expert).

@tessus
Copy link
Collaborator

tessus commented Aug 22, 2024

Oh, could you add a test to the fixtures as well?

@nydragon
Copy link
Contributor Author

Thanks for this PR. LGTM (unless I missed some Rust specific optimization I am not aware of, since I am not a Rust expert).

I was wondering if it would be better to .trim() the entire file or the individual lines after splitting (current behaviour).

entire file -> calls trim once instead of n of lines time
on every line -> allows the end user to be "sloppy", ie trailing whitepace, empty lines etc

@nydragon
Copy link
Contributor Author

Oh, could you add a test to the fixtures as well?

Sure! I didn't see an option to set env vars tho... Did i miss something?

@tessus
Copy link
Collaborator

tessus commented Aug 22, 2024

I was wondering if it would be better to .trim() the entire file or the individual lines after splitting (current behaviour).

One would have to run perf tests for the difference, but I doubt it is huge for a small to medium sized file with tokens.
Personally I like the current behavior better, since you took care of a few edge cases as well.

The only workflow optimization I can think of is that the file is not read and parsed every time a request is made, but only when the config is read or reloaded via refresh_rate.

If you want to try that, please go ahead.

@tessus
Copy link
Collaborator

tessus commented Aug 22, 2024

Sure! I didn't see an option to set env vars tho... Did i miss something?

No, you are correct.

@orhun are you ok with adding another hook to add env vars to the fixtures?

e.g. in test.sh:

rp_env {
  export ENV=bla
}

and then we only need in the test_fixtutes.sh:

run_fixture() {
  cd "$FIXTURE_DIR/$1" || exit 1
  source "test.sh"
  rp_env
  NO_COLOR=1 CONFIG=config.toml "$PROJECT_DIR/target/debug/rustypaste" &
  ..
  ..

P.S.: Hmm, since the test.sh scripts are not run but sourced, we might have to unset the exported var in teardown, although that is run in a subshell, which means we would also have to use another hook e.g. rp_env_teardown.

@nydragon
Copy link
Contributor Author

I was wondering if it would be better to .trim() the entire file or the individual lines after splitting (current behaviour).

One would have to run perf tests for the difference, but I doubt it is huge for a small to medium sized file with tokens. Personally I like the current behavior better, since you took care of a few edge cases as well.

The only workflow optimization I can think of is that the file is not read and parsed every time a request is made, but only when the config is read or reloaded via refresh_rate.

If you want to try that, please go ahead.

That'd make definitely sense! I was a bit surprised to see that get_tokens is called on every request. Why is that? Wouldn't it be enough to just call the function periodically according to refresh_rate?

@tessus
Copy link
Collaborator

tessus commented Aug 22, 2024

That'd make definitely sense! I was a bit surprised to see that get_tokens is called on every request. Why is that? Wouldn't it be enough to just call the function periodically according to refresh_rate?

This is a good question. I think it developed this way. At the beginning there was only one token in the config file and one env var. I added the multiple tokens and delete tokens, and then it was refactored by somebody else to be used as a middleware with web grants.
In all these stages only the config was referenced (not the file read) and the ENV vars read, thus no real overhead.

Copy link
Owner

@orhun orhun 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! We can simplify it a bit :)

src/config.rs Outdated Show resolved Hide resolved
src/config.rs Outdated Show resolved Hide resolved
src/config.rs Outdated Show resolved Hide resolved
src/config.rs Outdated Show resolved Hide resolved
src/config.rs Outdated Show resolved Hide resolved
@orhun
Copy link
Owner

orhun commented Aug 22, 2024

are you ok with adding another hook to add env vars to the fixtures?

Hmm, yeah, if it is not much of a hassle. Bash is annoying.

I was a bit surprised to see that get_tokens is called on every request. Why is that?

We use a library called actix_web_grants which works by adding a middleware and then you can simply protect your endpoints with an annotation.

.wrap(GrantsMiddleware::with_extractor(extract_tokens))

#[actix_web_grants::protect("TokenType::Delete", ty = TokenType, error = unauthorized_error)]

Implemented in #199

That is why extract_tokens is called on every request since there is a guard. We can maybe cache some parts to make it more performant.

Wouldn't it be enough to just call the function periodically according to refresh_rate?

That means we need to store the tokens somewhere (probably in memory) and that's not how the grants library works.

@nydragon
Copy link
Contributor Author

Alright, thank you for the explanation, should I then leave out the improvements mentioned by tessus (#339 (comment))?

I'll also add the env handling to the fixture script.

@nydragon
Copy link
Contributor Author

Should be all good now:

  • added fixture for the file based authentication process
  • added fixture for the file based deletion process
  • added env var setting through the rp_env function, teardown is handled by putting run_fixture into a subshell
  • applied code review requests

@orhun orhun requested review from tessus and orhun August 23, 2024 08:36
fixtures/README.md Outdated Show resolved Hide resolved
fixtures/README.md Outdated Show resolved Hide resolved
fixtures/test-fixtures.sh Outdated Show resolved Hide resolved
fixtures/test-fixtures.sh Outdated Show resolved Hide resolved
…a single fixture

Define the custom_env function in your fixture to set environment variables.
@nydragon
Copy link
Contributor Author

Applied all requests

Copy link
Collaborator

@tessus tessus left a comment

Choose a reason for hiding this comment

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

Great, thanks.

One last thing. Could you please update the README in the fixtures dir?

Can you please add the new function to the file format?

@nydragon
Copy link
Contributor Author

@tessus
Copy link
Collaborator

tessus commented Aug 23, 2024

Thanks, I missed it. All good then! I think it is ready to be merged.

src/lib.rs Outdated Show resolved Hide resolved
Add support for reading a list of newline separated tokens from a file
which path is being supplied through the following environment
variables:

- AUTH_FILE
- DELETE_FILE
…error

- add fixture for auth file testing
- add fixture for delete file texting
- expiring-file-upload would sometimes fail, so I increased the sleep
duration
Copy link
Owner

@orhun orhun left a comment

Choose a reason for hiding this comment

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

Perfect, thanks!

@orhun orhun changed the title Add support of multiple auth tokens via env vars feat(server): add support for multiple auth tokens via env vars Aug 24, 2024
@orhun orhun merged commit 5d71dbd into orhun:master Aug 24, 2024
9 checks passed
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.

Loading Auth Tokens from a file
3 participants