-
Notifications
You must be signed in to change notification settings - Fork 72
[#935] Auth with recovery code #1049
base: master
Are you sure you want to change the base?
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.
We think it's a good idea to change the HTTP status to a more meaningful.
def assert_successful(success): | ||
self.assertEqual(success, 'Done!') | ||
def assert_error_response(_): | ||
self.assertEqual(500, request.responseCode) |
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.
Hey,
@thaissiqueira and me think that in case of validation error the best HTTP status is 400 (bad request), not 500.
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.
good call!
self.assertFalse(self.resource._validate_password('12345678', '1234')) | ||
|
||
def test_validate_password_failed_by_length(self): | ||
self.assertFalse(self.resource._validate_password('1234', '1234')) |
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.
Why did you remove these tests?
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.
same as above, please have a look at #1047 (comment)
@@ -44,7 +43,8 @@ def assert_200_when_user_logged_in(_): | |||
def test_post_returns_successfully(self): | |||
request = DummyRequest(['/account-recovery']) | |||
request.method = 'POST' | |||
self.resource._handle_post = MagicMock(return_value=defer.succeed(None)) | |||
request.content = MagicMock() | |||
request.content.getvalue.return_value = '{"password": "12345678", "confirmPassword": "12345678"}' |
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.
Did you stop mocking POST handler in order to test it?
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.
please have a look at #1047 (comment)
@@ -43,6 +43,7 @@ export class NewPasswordForm extends React.Component { | |||
submitHandler = (event) => { | |||
event.preventDefault(); | |||
submitForm(event, '/account-recovery', { | |||
username: this.props.username, |
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.
Did you check if it works if the user adds username with domain?
pageInstance = page.instance(); | ||
|
||
expect(pageInstance.state.username).toEqual(''); | ||
}); |
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.
Should it return an error in case of username is empty?
What exactly this test is testing? Is it testing if the code can handle empty querystring or it's just one more test case?
@@ -1,10 +1,16 @@ | |||
import queryString from 'query-string'; | |||
import browser from 'helpers/browser'; | |||
|
|||
export const hasQueryParameter = (param) => { | |||
const decodedUri = decodeURIComponent(window.location.search.substring(1)); | |||
return !(decodedUri.split('&').indexOf(param) < 0); | |||
}; |
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.
These observations are not really from this PR, but does this method still need these handmade parsing after adding that js library to parse querystring?
4d7a38a
to
60f9cfb
Compare
60f9cfb
to
e8f2fe6
Compare
e8f2fe6
to
20ae5e6
Compare
@@ -39,6 +39,8 @@ def update_recovery_code(self): | |||
try: | |||
code = self._soledad.create_recovery_code() | |||
response = yield self._bonafide_session.update_recovery_code(code) | |||
log.info('recovery code updated') | |||
log.info(response) |
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.
Is this just for testing purposes? should we be committing logging that we don't know what it could say about the user, or if the formatting breaks, or anything of the kind?
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.
You're right, @anikarni
That was committed by mistake!
service/pixelated/authentication.py
Outdated
@@ -27,37 +28,41 @@ | |||
|
|||
|
|||
class Authenticator(object): | |||
def __init__(self, leap_provider): | |||
def __init__(self, leap_provider, recovery=False): |
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.
Is this supposed to be a boolean? Can we either rename the variable to make it clear, or not set it to False?
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 changed the variable to recovery_session
and it is a boolean indeed.
Do you think it's clearer now, @anikarni ?
elif failure.type is UnauthorizedLogin: | ||
request.setResponseCode(UNAUTHORIZED) | ||
else: | ||
request.setResponseCode(INTERNAL_SERVER_ERROR) |
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 we map these in a dict or somehting of the kind? There would be a lot of ifs if we continue down this path. We could also resuse it, as this is already used elsewhere.
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.
Also, shouldn't this be used in common with authentication/login errors
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.
hey @anikarni
I extracted this response code flow to the common parent BaseResource
and it should be easier for adding new exceptions. I noticed however that the LoginResource
doesn't apply these response codes, since its implementation redirects to /login?auth-error
, overriding any previous code to 302. I think this refactoring is still valuable though. Please take a look.
@@ -73,15 +85,24 @@ def error_response(failure): | |||
def _get_post_form(self, request): | |||
return json.loads(request.content.getvalue()) | |||
|
|||
def _validate_empty_fields(self, username, user_code): | |||
if not username or not user_code: | |||
raise EmptyFieldsError('The user entered an empty username or empty usercode') |
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.
"emtyp user recovery code"
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.
📝
559d816
to
dbb3c90
Compare
No description provided.