-
Notifications
You must be signed in to change notification settings - Fork 1
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
Add signInWithNewPassword GraphQL API #291
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #291 +/- ##
==========================================
+ Coverage 66.21% 66.87% +0.66%
==========================================
Files 68 68
Lines 13011 13259 +248
==========================================
+ Hits 8615 8867 +252
+ Misses 4396 4392 -4 ☔ View full report in Codecov by Sentry. |
CHANGELOG.md
Outdated
@@ -68,6 +68,9 @@ Versioning](https://semver.org/spec/v2.0.0.html). | |||
- Added a `language` field to the `Account`. Consequently, the `account` and | |||
`accountList` API responses now include this field. The `insertAccount` and | |||
`updateAccount` GraphQL API endpoints are also updated to support the field. | |||
- Added `common_sign-in_logic` to handle `sign-in` GraphQL API logic. |
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 is not necessary because the method is not for users.
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'll delete it.
src/graphql/account.rs
Outdated
/// - Authenticates with the given username and password. | ||
/// - If the `last_signin_time` value of the `account` is `None`, the operation will fail, and | ||
/// it should be guided to call common_sign_in_logic. |
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.
Since this is an open method to users, we need to fulfill the Rust documentation according to the convention
ed652fa
to
97ffb90
Compare
src/graphql/account.rs
Outdated
/// }"# | ||
/// ``` | ||
/// | ||
/// # Returns |
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 usually don't mention returning values in a separate section. You can refer to the standard library to check how to write the Rust documentation.
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'll delete 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.
If you deleted that part, that’s not what I meant. I just wanted to say that the return values should be mentioned according to the Rust documentation convention, like this:
///
/// Returns blah blah blah
///
- The title,
# Returns
, is not necessary. - The sentence starts with
Returns
, a third-person singular verb.
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'll be careful.
src/graphql/account.rs
Outdated
@@ -420,6 +400,96 @@ impl AccountMutation { | |||
} | |||
} | |||
|
|||
async fn common_sign_in_logic( |
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 method doesn't seem to behave consistently. Its behavior depends on is_update_password
, which is the only differing argument between the two callers. In other words, this method is not the common part between the two callers. When we extract the common part, it should be identical across all participants.
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.
If there were any reason to keep this, it should have at least a different name rather than "common".
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.
What do you think of the function name below?
sign_in_logic_by_update_password
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.
It would be better to explicitly outline the process in both methods, sign_in
and sign_in_with_new_password
.
I suggest the following pseudocode:
sign_in
- Check the password
- Check if there was no previous sign-in
- Check the IP address
- Check the number of parallel sessions
- Sign in
sign_in_with_new_password
- Check the password
- Check the IP address
- Check the number of parallel sessions
- Change the password
- Sign in
While revealing this skeleton in both methods, we need to extract the common parts as separate methods.
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 want to point out we need to check the password first. The information about whether the user is signing in for the first time or again, whether the number of sessions exceeds the limit, or whether the IP address is valid, is so confidential that it should not be accessible to anyone who has not provided the correct password. The original code was not properly implemented in this regard.
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.
While revealing this skeleton in both methods, we need to extract the common parts as separate methods.
The common part might involve validating the IP address and the number of sessions.
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 considered splitting the function because it is responsible for so many functions, but there is a lot of overlap, so we made it into one function.
As you mentioned above, we will refactor the checking part by splitting it into functions and calling them.
a5c9935
to
5548e55
Compare
src/graphql/account.rs
Outdated
@@ -641,6 +742,7 @@ fn initial_credential() -> anyhow::Result<types::Account> { | |||
None, | |||
None, | |||
)?; | |||
initial_account.update_last_signin_time(); |
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.
Could you explain why you put this?
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 is the part set to satisfy the existing test case.
There is also a part where admin/admin does not affect the part you are currently using when running for the first time.
In the future, I thought of the expected behavior of creating a new account after logging in with the admin account, and requesting password change when attempting to log in with the created account.
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 don't quite understand. Could you elaborate on what you answered?
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 initial_credential
seems to create the first admin account and immediately set its sign-in time. This makes it pointless to alter sign_in
to check the last sign-in time. What do you think?
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 part has been restored to its original state.
CHANGELOG.md
Outdated
@@ -68,6 +68,7 @@ Versioning](https://semver.org/spec/v2.0.0.html). | |||
- Added a `language` field to the `Account`. Consequently, the `account` and | |||
`accountList` API responses now include this field. The `insertAccount` and | |||
`updateAccount` GraphQL API endpoints are also updated to support the field. | |||
- Added `signInWithNewPassword` GraphQL API for signing in with a new password. |
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 is a new API, so should be included in the section "Added".
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.
Since the signIn
has been changed, it should be documented.
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'll change it.
e72ae31
to
6ebe11b
Compare
CHANGELOG.md
Outdated
@@ -68,6 +69,7 @@ Versioning](https://semver.org/spec/v2.0.0.html). | |||
- Added a `language` field to the `Account`. Consequently, the `account` and | |||
`accountList` API responses now include this field. The `insertAccount` and | |||
`updateAccount` GraphQL API endpoints are also updated to support the field. | |||
- Added logic to check the `lastSigninTime` value in the `signIn` GraphQL API. |
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 think we need to document how the new logic works, as well as the fact that it has changed, because in this case, the new behavior is the primary concern for users.
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.
Added content.
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.
The key point is that this API rejects a user's access if it is their first attempt. Therefore, it's not enough to simply mention checking the lastSigninTime
. Additionally, the word "logic" seems unnecessary. I suggest:
- Changed the
signIn
to reject the first sign-in attempt unless it is done through the newsignInWithNewPassword
API.
In this case, "Changed" or "Updated" is preferred over "Added" because the behavior of the API has actually changed from the user's perspective. Also, the word "reject" or any similar one should be included to convey the key point.
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 will delete the explanation below and change it to the sentence you suggested.
"Apply a requirement for a password change upon the initial signIn
."
e4320fd
to
acbb168
Compare
When reseting the admin's password, we need to reset the |
fb6cc77
to
17d7dc0
Compare
src/graphql/account.rs
Outdated
/// ```ignore | ||
/// r#"mutation { | ||
/// signInWithNewPassword(username: "user", password: "pw", newPassword: "pw2") { | ||
/// token | ||
/// } | ||
/// }"# | ||
/// ``` |
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 don't need to present the signatures of GraphQL APIs in the code because users can not only infer them on their own but also check them in the GraphQL playground.
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'll delete it.
src/graphql/account.rs
Outdated
/// If the `signIn` GraphQL API response is the error message "a password change is | ||
/// required to proceed", you can call the `signInWithNewPassword` GraphQL API. |
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 don't think this part is necessary because it seems to repeat what was mentioned right above.
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.
The part I think is unnecessary:
/// If the `signIn` GraphQL API response is the error message "a password change is
/// required to proceed", you can call the `signInWithNewPassword` GraphQL API.
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'll delete it.
src/graphql/account.rs
Outdated
/// | ||
/// # Errors | ||
/// | ||
/// An error message (`String`) if any of the checks fail or an error occurs during the process. |
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 suggest:
/// # Errors
///
/// Returns `Err` if the password is invalid, this is the first sign-in attempt, the access doesn't originate from a permitted IP address, or the number of sessions exceeds the maximum limit.
The style where the sentence starts with a third-person singular verb is a convention in Rust documentation. Additionally, it would be better to specify exactly the cases where errors occur.
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'll change it.
@sehkone I know we are still in pr-review stage for this PR, but I think merging PR would require implement new UX flow and design in the client side. So I would like to suggest in advance, that we might merge this PR after we release the upcoming review-web version. |
Yes. I won't merge this until what is required is done. |
17d7dc0
to
8912b70
Compare
Close #14 Changed `sign-in` GraphQL API logic. - Returns `Err` if `last_signin_time` of `account` is `None`.
8912b70
to
a743b94
Compare
Close #14
Changed
sign-in
GraphQL API logic.Err
iflast_signin_time
ofaccount
isNone
.