Skip to content
This repository has been archived by the owner on Jul 24, 2023. It is now read-only.

Representative demo app for password auth #69

Merged
merged 1 commit into from
Aug 26, 2017
Merged

Conversation

iainmcgin
Copy link
Member

Simple two activity demo app for password authentication.

This also has some conflated changes (apologies), which relax our Javadoc validation as I intend to switch it to Markdown based doc comments, like in AppAuth.

@iainmcgin iainmcgin requested a review from dxslly August 9, 2017 22:03
Simple two activity demo app for password authentication.
@codecov-io
Copy link

codecov-io commented Aug 10, 2017

Codecov Report

Merging #69 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff            @@
##             master      #69   +/-   ##
=========================================
  Coverage     70.94%   70.94%           
  Complexity      436      436           
=========================================
  Files            58       58           
  Lines          2437     2437           
  Branches        241      241           
=========================================
  Hits           1729     1729           
  Misses          641      641           
  Partials         67       67

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 315c11f...c80bf6c. Read the comment docs.

* Indicates whether a progress bar should be displayed to the user, while an asynchronous
* request is made.
*/
public final ObservableBoolean loading = new ObservableBoolean(true);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: rename isLoading

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compromise: renamed to showLoading (to make it clear that this impacts the UI). Generally I prefer to reserve "is" prefixes for boolean getter methods.

/**
* Whether the password entry field should be displayed at this time.
*/
public final ObservableBoolean showPasswordField = new ObservableBoolean(false);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: rename to shouldShowpasswordField

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving as showPasswordField for consistency with showLoading.

* Whether to show a generic error message to the user - this happens when requests fail
* in a way that we cannot recover from, other than asking the user to potentially try again.
*/
public final ObservableBoolean errorOccurred = new ObservableBoolean(false);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: rename to hasErrorOccurred

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renaming to showError


doManualAuthentication(
R.string.enter_email_prompt,
null);
Copy link
Collaborator

@dxslly dxslly Aug 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: add comment with param name, similarly for other non-obvious parameters.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

.setDisplayName(displayName)
.setDisplayPicture(displayPicture)
.setPassword(hintPassword)
.build());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened a issue to add a utlity transformer for this operation here: #71

public UserRepository(@NonNull OpenYoloDemoApplication application) {
mUserDatabase = Room.databaseBuilder(application, UserDatabase.class, "userdb")
.build();
mSharedPrefs = application.getSharedPreferences("authInfo", Context.MODE_PRIVATE);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Move inline strings to constants.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

setCurrentUserEmail(null);
}

private String getCurrentUserEmail() {
Copy link
Collaborator

@dxslly dxslly Aug 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To stay consistent add @Nullable annotation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

boolean isExistingAccount(@NonNull String email);

/**
* Attempts to create and persist a new user account account with the specified properties.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document that returned boolean signals success/failure.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@NonNull String password);

/**
* Attempts to authenticate an existing user with the provided credentials.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (userPassword.isEmpty()) {
authPrompt.set(getResourceString(R.string.existing_account_enter_password));
showPasswordField.set(true);
} else if (mUserDataSource.authWithPassword(userEmail, userPassword)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Avoid side effects in conditional expression. Similarly for if conditional below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

/**
* A base class for use by view models that utilize Android data binding.
*/
public abstract class ObservableViewModel extends AndroidViewModel implements Observable {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind explaining why you are using this base class?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to be able to bind a value in a layout, it must be an Observable. AndroidViewModel is not an observable, so I had to create a subclass which implements this to allow data binding. As this composition of view model and observable is reusable (it never really changes from view to view), it was worth creating a base type for extension by my other views, rather than extending AndroidViewModel and copying this implementation into every type.

* Specifies the navigator for use in communicating with the activity environment.
*/
@MainThread
public void setNavigator(@NonNull MainNavigator navigator) {
Copy link
Collaborator

@dxslly dxslly Aug 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation (https://developer.android.com/reference/android/arch/lifecycle/ViewModel.html) I found suggests a ViewModel should "scary bold text" never have a reference it's associated activity. It looks like that's what you're doing here. IMO it seems nice to have the business logic of transitions in here. It's not clear why that divide is made. Any idea why they suggest avoiding this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's to avoid leaking activity references, but I've copied the pattern here from their own architecture component demos:

https://github.com/googlesamples/android-architecture/blob/dev-todo-mvvm-live/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/tasks/TaskItemViewModel.java#L43

However, they do hold it in a weak reference to avoid leaks, so I'll at least have to fix that.

@dxslly dxslly merged commit 50a16bf into openid:master Aug 26, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants