-
Notifications
You must be signed in to change notification settings - Fork 155
Refactor GoogleAuthenticatorChallenge to allow for setting code along with challenge. #1244
Changes from all commits
e51d1ef
9fd6639
499553e
4f8b706
5e88bfe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| /* | ||
| * Copyright 2017 Stormpath, Inc. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package com.stormpath.sdk.challenge.google; | ||
|
|
||
| import com.stormpath.sdk.challenge.CreateChallengeRequest; | ||
|
|
||
| /** | ||
| * A Google Authenticator specific create challenge request | ||
| * | ||
| * Google Authenticator challenges can validate a code at the same time that the challenge is created. | ||
| * | ||
| * @since 1.4.0 | ||
| */ | ||
| public interface GoogleAuthenticatorCreateChallengeRequest extends CreateChallengeRequest {} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing Javadoc. In particular both a short description and the version are important since it is an interface in the api module |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| /* | ||
| * Copyright 2017 Stormpath, Inc. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package com.stormpath.sdk.challenge.google; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing license
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addressed |
||
|
|
||
| import com.stormpath.sdk.challenge.CreateChallengeRequestBuilder; | ||
|
|
||
| /** | ||
| * A builder to construct {@link GoogleAuthenticatorCreateChallengeRequest}s Google Authenticator specific create challenge requests. | ||
| * | ||
| * Google Authenticator can both create the challenge and set the code in one API call. | ||
| * See {@link com.stormpath.sdk.factor.google.GoogleAuthenticatorFactor} | ||
| * | ||
| * @since 1.4.0 | ||
| */ | ||
| public interface GoogleAuthenticatorCreateChallengeRequestBuilder extends CreateChallengeRequestBuilder<GoogleAuthenticatorChallenge> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing Javadoc in the class and in the method. Both a short description and the version are important since it is an interface in the api module
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this class still needed?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mrioan - I think so. There are two supported ways to validate a challenge on the backend - by hitting the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but, maybe not - looking |
||
|
|
||
| /** | ||
| * @param code to be used to validate the challenge for the {@link com.stormpath.sdk.factor.google.GoogleAuthenticatorFactor} | ||
| * @return GoogleAuthenticatorCreateChallengeRequestBuilder for method chaining with the builder pattern | ||
| */ | ||
| GoogleAuthenticatorCreateChallengeRequestBuilder withCode(String code); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,8 +22,16 @@ | |
| * A {@code GoogleAuthenticatorFactor} is a Factor that represents a two-step verification services using | ||
| * the Time-based One-time Password Algorithm (TOTP) and HMAC-based One-time Password Algorithm (HOTP), | ||
| * for authenticating users of mobile applications by Google. | ||
| * When issuing a challenge via an GoogleAuthenticatorFactor, a code is sent to the Google Authenticator app, | ||
| * and the user can enter the received code back into the system to verify/complete the challenge. | ||
| * <p/> | ||
| * The TOTP algorithm determines the next valid code without the requirement for any communication between server and | ||
| * TOTP client. | ||
| * <p/> | ||
| * As such, the challenge can be created with the code at the same time: | ||
| * <p/> | ||
| * | ||
| * <pre> | ||
| * GoogleAuthenticatorChallenge challenge = googleAuthenticatorFactor.createChallenge(code); | ||
| * </pre> | ||
| * | ||
| * @since 1.1.0 | ||
| */ | ||
|
|
@@ -80,4 +88,13 @@ public interface GoogleAuthenticatorFactor<T extends GoogleAuthenticatorChalleng | |
| * @return the base64QRImage. | ||
| */ | ||
| String getBase64QrImage(); | ||
|
|
||
| /** | ||
| * | ||
| * @param code The code to validate the challenge that is created. With Google Authenticator, you can create a | ||
| * challenge and validate it all in one call. | ||
| * @return the {@link GoogleAuthenticatorChallenge} | ||
| * @since 1.4.0 | ||
| */ | ||
| GoogleAuthenticatorChallenge createChallenge(String code); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,7 +31,7 @@ | |
| public abstract class AbstractChallenge<T extends Factor, R extends Enum> extends AbstractInstanceResource implements Challenge<T,R> { | ||
|
|
||
| public static final EnumProperty<Enum> STATUS = new EnumProperty<>("status", Enum.class); | ||
| static final StringProperty CODE = new StringProperty("code"); | ||
| public static final StringProperty CODE = new StringProperty("code"); | ||
| static final ResourceReference<Account> ACCOUNT = new ResourceReference<>("account", Account.class); | ||
| static final ResourceReference<? extends Factor> FACTOR = new ResourceReference<>("factor", Factor.class); | ||
| public static final DateProperty CREATED_AT = new DateProperty("createdAt"); | ||
|
|
@@ -92,16 +92,11 @@ public Challenge setFactor(T factor) { | |
| @Override | ||
| public boolean validate(String code) { | ||
| Assert.notNull(code, "code can not be null."); | ||
| setCode(code); | ||
| setProperty(CODE, code); | ||
| Challenge returnedChallenge = getDataStore().create(getHref(), this); | ||
| if ((returnedChallenge.getStatus()).name().equals("SUCCESS")) { | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| protected Challenge setCode(String code) { | ||
| setProperty(CODE, code); | ||
| return this; | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did we remove the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before this PR, that method was only used in one place in the validate method, and in two places in tests which should not have had access to that protected method anyway. So there was no need for it. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,7 +27,7 @@ | |
| /** | ||
| * @since 1.1.0 | ||
| */ | ||
| public class DefaultGoogleAuthenticatorChallenge extends AbstractChallenge<GoogleAuthenticatorFactor, GoogleAuthenticatorChallengeStatus> implements GoogleAuthenticatorChallenge{ | ||
| public class DefaultGoogleAuthenticatorChallenge extends AbstractChallenge<GoogleAuthenticatorFactor, GoogleAuthenticatorChallengeStatus> implements GoogleAuthenticatorChallenge { | ||
|
|
||
| static final Map<String, Property> PROPERTY_DESCRIPTORS = AbstractChallenge.PROPERTY_DESCRIPTORS; | ||
|
|
||
|
|
@@ -53,4 +53,9 @@ public GoogleAuthenticatorChallengeStatus getStatus() { | |
| } | ||
| return GoogleAuthenticatorChallengeStatus.valueOf(value.toUpperCase()); | ||
| } | ||
|
|
||
| @Override | ||
| public void setCode(String code) { | ||
| setProperty(CODE, code); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method could have stayed in the Abstract Class, no?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above. There is no reason for a code to be set on an SMS challenge outside of the validate method.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But doesn't the snippet above post to the sms challenge with a code in the body? That means it is supported on the API.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mrafiei - Previously, the interface didn't support calling What I am saying is that with GA, you can algorithmically know the code, which is how the TOTP app gives it to you, so it makes sense to be able to create the challenge and submit the code all in one shot. With SMS, you can't know the code (from an end-user perspective) until you've received the text. I will dig into the spec in Jira/Confluence some more, but am I missing something here?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mrafiei POSTing to a challenge href with a code is indeed supported by the REST API, and that is what is mirrored by the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dogeared Its correct what you stated above, my only thing is since it is supported on the REST API we should also support it for Sms challenges on SDK side to be consistent. |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| /* | ||
| * Copyright 2017 Stormpath, Inc. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package com.stormpath.sdk.impl.challenge.google; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing license
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addressed |
||
|
|
||
| import com.stormpath.sdk.challenge.Challenge; | ||
| import com.stormpath.sdk.challenge.ChallengeOptions; | ||
| import com.stormpath.sdk.challenge.google.GoogleAuthenticatorCreateChallengeRequest; | ||
| import com.stormpath.sdk.impl.challenge.DefaultCreateChallengeRequest; | ||
|
|
||
| /** | ||
| * @since 1.4.0 | ||
| */ | ||
| public class DefaultGoogleAuthenticatorCreateChallengeRequest extends DefaultCreateChallengeRequest implements GoogleAuthenticatorCreateChallengeRequest { | ||
|
|
||
| public DefaultGoogleAuthenticatorCreateChallengeRequest(Challenge challenge, ChallengeOptions options) { | ||
| super(challenge, options); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| /* | ||
| * Copyright 2017 Stormpath, Inc. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package com.stormpath.sdk.impl.challenge.google; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing license
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. adressed |
||
|
|
||
| import com.stormpath.sdk.challenge.google.GoogleAuthenticatorCreateChallengeRequest; | ||
| import com.stormpath.sdk.challenge.google.GoogleAuthenticatorChallenge; | ||
| import com.stormpath.sdk.challenge.google.GoogleAuthenticatorCreateChallengeRequestBuilder; | ||
| import com.stormpath.sdk.impl.challenge.DefaultCreateChallengeRequestBuilder; | ||
|
|
||
| /** | ||
| * @since 1.4.0 | ||
| */ | ||
| public class DefaultGoogleAuthenticatorCreateChallengeRequestBuilder extends DefaultCreateChallengeRequestBuilder<GoogleAuthenticatorChallenge> implements GoogleAuthenticatorCreateChallengeRequestBuilder { | ||
|
|
||
| public DefaultGoogleAuthenticatorCreateChallengeRequestBuilder(GoogleAuthenticatorChallenge challenge) { | ||
| super(challenge); | ||
| } | ||
|
|
||
| @Override | ||
| public GoogleAuthenticatorCreateChallengeRequestBuilder withCode(String code) { | ||
| challenge.setCode(code); | ||
| return this; | ||
| } | ||
|
|
||
| @Override | ||
| public GoogleAuthenticatorCreateChallengeRequest build() { | ||
| return new DefaultGoogleAuthenticatorCreateChallengeRequest(challenge, options); | ||
| } | ||
| } | ||
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.
Missing license header
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.
addressed.