-
Notifications
You must be signed in to change notification settings - Fork 40
Implement (most of the) MFA support for Okta. #14
base: master
Are you sure you want to change the base?
Conversation
Codecov Report
@@ Coverage Diff @@
## master #14 +/- ##
==========================================
- Coverage 98.1% 96.14% -1.97%
==========================================
Files 5 5
Lines 317 441 +124
Branches 42 72 +30
==========================================
+ Hits 311 424 +113
- Misses 3 4 +1
- Partials 3 13 +10
Continue to review full report at Codecov.
|
Just a note that although this code does work on its own, it doesn't work with AWS CLI because the latter consumes all output received from the running authentication process. If you try to use this enhancement with AWS CLI, it appears to stall but it is actually waiting for the user to specify which MFA action to take. My initial thought was to use sys.stderr to output the prompts but the existing awsprocesscreds code uses getpass.getpass to get the user's password and that works - apparently by writing to sys.stdout. Also, it looks like botocore might not allow stderr to be used either: aws/aws-cli#3057 So ... not sure how to proceed. I don't know if this is something that needs to be altered in awsprocesscreds or if aws-cli needs a cleaner way of getting the results back from awsprocesscreds so that the user can be allowed to interact with awsprocesscreds? |
In the absence of botocore not handling stderr at the moment, I've created a separate branch on my code - revised_prompting. This uses getpass to provide all of the prompting which gets around the problem that the user can't see the output. If the repo maintainers would prefer that version, I'll merge it into the PR. |
Hey @pcolmer I've patched master w/ your changes and rolled this into a docker image for beta testing, however a select group of individuals with Google Authenticator seem to not get prompted for an MFA token, any suggestions? |
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 looks pretty good! Thanks for the pr! Could you please add in tests (and adjust the existing ones which are apparently not valid)?
@rprashad You may want to take a look at https://github.com/pcolmer/awsprocesscreds/tree/revised_prompting instead of the commit I'm referencing in this PR. It takes a different approach to prompt the users due to a limitation in botocore. (I've now merged revised_prompting into my master branch. The CI build is failing because of the new tests I've added but the code works :) ). |
Fix prompting and improve tests
@JordonPhillips I'm going to need some help with writing the tests. I'm getting really stuck on how to properly handle the input and output in the tests. As you'll see from the CI build, one of the tests is failing under Python 3 because of how pytest handles input, but it passes on my computer. To make matters worse, I've commented out one of the tests I was working on (test_process_mfa_totp) because the test process is hanging on waiting for input even though I'm re-using an approach that has worked in a different test. I'm more than happy to put the effort into writing the tests but I'm hitting a brick wall here and just don't know what to do next. |
@pcolmer I took a quick look on the test results. Have you considered mocking saml#get_response() in the test? This is the recommended approach as described here pytest-dev/pytest#1598 (comment) |
fwiw, just tested @pcolmer fork and it works great with MFA... would love to see this supported upstream!
|
@JordonPhillips anything blocking this pr? would be great to have MFA support for okta via credential_process! |
@lorengordon I think the main thing blocking this PR is the lack of tests to run against the code I added. I frankly haven't had the time to write the tests lately and the maintainer won't accept the PR with such a poor code coverage. Also, it looks like some of the tests are actually failing for some reason so that in itself is a blocker. I do want to get this code to a state where it is acceptable to the maintainers - I am just struggling to find the time but I will try and carve some out from somewhere. |
@pcolmer I can understand that. If it would help, we can commit some time starting maybe next month to get this done (need to close out other tasks first). Would just like some indication from a maintainer (@JordonPhillips) that if we get tests passing and improve coverage that the work would get merged and released (if not, would rather not spend the time). |
@lorengordon certainly @JordonPhillips comment on Apr 6 suggests that, tests aside, the code would seem to be acceptable. I have started looking at the tests again. The biggest challenge I have is that I've not written many Python tests before so trying to mock/patch routines is proving to be quite a stumbling block. I've tried @itaifrenkel suggestion but that doesn't work against the code. Part of the problem is that the input function is within the class and therefore the patching has to be done against the class instance, I believe, rather than against the class itself. Like I said, a bit of a newbie so lots of fumbling going on. I'm going to review the other tests to see what they are doing; another part of the problem is that so much time has passed that I'm partly forgetting what I've written and what was already there … my thinking being that I can look at what was already there to try and learn from it. Such fun :) |
A small progress report … I've got past the input testing now. Currently stuck on the TOTP testing because I can't get the responses (mocking) library to react the way it seems to be documented for dynamic responses. I've raised an issue on that repo to try and get some help with that as I just can't see what I'm doing wrong. |
Tests have been written and the Travis CI build now passes. The CodeCov report hasn't been updated but coverage is now 94% for saml.py. |
@pcolmer Played around with this more as a user today and there are a couple things that feel a little odd...
Entering a passcode is echoed, so it seems it should be possible to echo the response at that prompt.
|
@lorengordon thanks for the feedback and code inspection. I'm a bit torn over the MFA push and SMS changes, to be honest, partly because I wanted to provide feedback to the user as to what is happening and there is a limitation in the current Boto library where it "swallows" anything sent to stdout and stderr (boto/botocore#1348). This is why I'm using For SMS, it can be somewhat mitigated by swapping the call to For MFA Push, I do think the user needs to know that Finally, thanks for the suggested change from |
@pcolmer I suppose I feel like when I answer the prompt for the authentication type, that if I choose push or sms, then I am expecting the notification/text to be sent immediately. As it is,
Hanging is exactly what it does now that I find confusing. It is not clear that I must press RETURN again for some reason to get the notification. I actually did make the suggested changes locally, and it worked perfectly. |
@lorengordon the problem with removing those prompts, though, is that the user has no indication of what the script is doing. Suppose they haven't realised that their device hasn't got a signal to receive SMS or Internet access to receive Push? Yes, the code works perfectly without the prompts but I do feel it is less informative to the user. Also, are you testing this code by running it directly or by calling it from within AWS CLI? The reason why Basically the link between AWS CLI and I can try rewording the prompts to see if that makes it clearer? |
Oh, quite right! I was testing execution directly for the sake of expediency. Sorry! 🤕 Rewording the prompts would help I think. Maybe: "Press RETURN when you are ready to request the SMS text message" |
Actually, for SMS, changing this line to use
Using it looks like this:
|
OK - I've updated the user prompting code and I've also restructured some of the code in order to allow me to get a higher coverage with the tests. I'll see if I can get the coverage any higher. |
Tested and looks great, nice work! |
@JordonPhillips can you please let me know if anything further needs to be done for this PR in order to facilitate getting it merged into the base branch? Or is this repo dead? I find it a bit concerning that it hasn't been touched since it was announced at last year's re:Invent. Is that because the functionality is going to be folded into CLI 2? I want to push ahead with adopting Okta for federated authentication inside my company but I can't until the MFA support is there. This PR needs to be merged for that to happen, or for AWS to provide their own alternative code for MFA support. Thanks. |
@pcolmer If Amazon isn't going to maintain this project, perhaps someone (maybe you or I) could fork it and maintain it instead? |
@lorengordon I agree that that would seem to be the sensible way forward … but I would prefer it if someone from Amazon could categorically state what is happening with this repo. Is it dead? It is being subsumed into CLI 2? I'm happy to maintain my own contribution but my coding skills are not strong enough to maintain the whole repo, I'm afraid. |
This project isn't all that active, and we have experience publishing packages to PyPi and generating self-contained executables. I don't expect it would be much of a burden to maintain (famous last words). I'll talk with our team and explore the code base, and if we don't hear back from @JordonPhillips, we may be able to take it on. Or perhaps, another option would be to add a compatible credential_process outputter to another project, and maybe okta support as well: |
Just a little bit of feedback on the other potential projects:
I'll try and find the time for a closer look at awscli-login. |
Hi @pcolmer, any chance you might be able to resolve the new conflicts? |
Hi @lorengordon, all sorted. |
Using @pcolmer fork I am having issues. I am able to get a token, but I get a SAML error and it does not prompt me for MFA. `C:>awsprocesscreds-saml -e -u -p okta -a |
@livt0ride Maybe try using |
Issue #13
I've extended the Okta authenticator to recognise the response from Okta that indicates at least one MFA is active and to act accordingly.
I have not been able to code for the hardware tokens (e.g. RSA) as I don't have one to test the code against. The implemented factors have been tested.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.