-
Couldn't load subscription status.
- Fork 298
Bulk User Import API #174
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
Bulk User Import API #174
Conversation
* Removed the deprecated FirebaseCredential API * Removing the deprecated Task API
* Dropping support for GAE 7 * Removed GaeThreadFactory, GaeExecutorService and RevivingScheduledExecutor * Removed the deprecated FirebaseCredential API * Removing GAE java7 related APIs (GaeThreadFactory, RevivingScheduledExecutor) * Removed GaePlatform implementation * Added FirebaseScheduledExecutor * Updated documentation * Some minor nits from code reviews * Calling super method in DefaultRunLoop executor
* Dropping support for GAE 7 * Removed GaeThreadFactory, GaeExecutorService and RevivingScheduledExecutor * Removed the deprecated FirebaseCredential API * Removing GAE java7 related APIs (GaeThreadFactory, RevivingScheduledExecutor) * Removed GaePlatform implementation * Added FirebaseScheduledExecutor * Updated documentation * Removing LogWrapper API * Removing PrefixedLogger * Removing test config file * Updated CHANGELOG * Minor clean ups pointed out in the code review
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 pretty much LGTM. I mostly compared it to the API approval doc and it looks like 2600 lines of sound code.
Thanks for adding these exhaustive tests!
| | ||
| if (hasPassword) { | ||
| checkArgument(options != null && options.getHash() != null, | ||
| "UserImportHash option is required when at least one user has a 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.
I would suggest that you explain how the UserImportHash can be set here:
"UserImportHash option is required when at least one user has a password. Provide a UserImportHash via UserImportOptions.withHash()."
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.
Done
| * @return This builder. | ||
| */ | ||
| public Builder addUserProvider(@NonNull UserProvider provider) { | ||
| this.userProviders.add(provider); |
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 you explain to me (and maybe everyone in the comment) what the intended use for this is? How does it interact with the other fields in this builder, especially the overlapping ones?
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.
Done
| * @return A non-null {@link UserImportOptions}. | ||
| */ | ||
| public UserImportOptions build() { | ||
| return new UserImportOptions(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.
Add verification here that the hash is not null.
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.
Done
| | ||
| Map<String, Object> getProperties() { | ||
| ImmutableMap.Builder<String, Object> properties = ImmutableMap.builder(); | ||
| if (hash != null) { |
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 can mark hash @nonnull and remove this check.
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.
Done
| /** | ||
| * Returns the number of users that were imported successfully. | ||
| * | ||
| * @return an integer (possibly zero). |
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.
Here an below: You should update this to describe that the number represents. It's already clear that you are returning an integer.
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.
Done
| BasicHash(String name, Builder builder) { | ||
| super(name); | ||
| checkArgument(builder.rounds >= 0 && builder.rounds <= 120000, | ||
| "A non-empty key is required for HMAC algorithms"); |
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 error message doesn't match what it is verifying.
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.
Fixed
| * Firebase Auth. See {@link StandardScrypt} for the standard Scrypt algorithm. Can be used as an | ||
| * instance of {@link com.google.firebase.auth.UserImportHash} when importing users. | ||
| */ | ||
| public final class Scrypt extends UserImportHash { |
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 make this inherit BasicHash and re-use setRounds()? On that note, should BasicHash be renamed to better reflect what it does?
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 seems there are 5 types of hash algorithms that we need to support:
- HMAC hashes
- MD5, SHA, PBKDF etc
- Scrypt
- StandardScrypt
- Bcrypt
I refer to the 2nd category as basic hashes for the lack of a better name. I think it makes sense to not have Scrypt extend from BasicHash (the allowed integer ranges are different). But I'm certainly open to calling BasicHash something else. 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.
What do you think of making BasicHash a "RepeatableHash" interface? You will have to verify the range in each implementing class, but it's a nicely named interface and would convey some property about the hash functions that adhere to 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.
Thanks for the suggestion. I renamed BasicHash to RepeatableHash, and passed range interval as constructor parameters. This enables us to reuse it in Scrypt as well.
| import com.google.api.client.util.Key; | ||
| import java.util.List; | ||
| | ||
| public class UploadAccountResponse { |
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 add a some JavaDoc snippet, even for internal classes.
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.
Done
| UserRecord savedUser = auth.getUserAsync(randomId).get(); | ||
| assertEquals(userEmail, savedUser.getEmail()); | ||
| String idToken = signInWithPassword(userEmail, "password"); | ||
| assertTrue(!Strings.isNullOrEmpty(idToken)); |
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.
assertFalse
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.
Done
| FirebaseAuth.getInstance().importUsersAsync(users); | ||
| fail("No error thrown for missing hash option"); | ||
| } catch (IllegalArgumentException expected) { | ||
| // expected |
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 verify the error message. That will also make it super obvious what this test is verifying.
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.
Done
| @schmidt-sebastian thanks for the thorough review. Addressed pretty much all the comments, and left one follow up question (about renaming |
| checkArgument(builder.rounds >= 0 && builder.rounds <= 120000, | ||
| "Rounds value must be between 0 and 120000 (inclusive)."); | ||
| checkArgument(builder.rounds >= min && builder.rounds <= max, | ||
| "Rounds value must be between %s and %s (inclusive).", min, max); |
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.
Make this "%d".
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.
| import com.google.common.collect.ImmutableMap; | ||
| import com.google.firebase.auth.UserImportHash; | ||
| import java.util.Map; | ||
| |
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 you add a short class comment here?
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.
Done
Introduces the following new APIs for importing users to Firebase Auth in bulk (1000 users per API call):
Also add the
UserImportHashandUserImportResultAPIs.go/firebase-admin-user-import