Skip to content

OAuth - request the token via REST API #19

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

Merged
merged 6 commits into from
Jun 25, 2025
Merged

Conversation

AdamGrzybkowski
Copy link
Contributor

Description

This PR adds the logic for requesting the user's Token via WP REST API after the app receives the code from the OAuth flow.

Some new stuff that's introduced:

  • The :foundations module. This is the place for the lowest-level types that we will share between the modules. One example could be a custom Result type that should be common for all the modules.
  • The :userComponent module. This is the place for user-related domain/data stuff. At this point, we only do the auth, but I believe this is also the place where we can put stuff like getting the user profile.

Let me know what you think about it 🙏

There are no tests, the error handling is not done, but I don't want this PR to grow, so I would rather do this stuff separately, once we have the full OAuth flow completed.

Testing Steps

  1. Launch the app and login.
  2. You can verify that the app won't crash with a network error (wrong OAuth setup, for example), but in general, the error handling is not there except for not crashing and showing a Toast.
  3. Verify the success flow - you can monitor the network and see if it works.

@AdamGrzybkowski AdamGrzybkowski added the enhancement New feature or request label Jun 25, 2025
Comment on lines +35 to +39
buildConfigField(
"String",
"OAUTH_CLIENT_SECRET",
"\"${properties["oauth.clientSecret"]?.toString() ?: ""}\"",
)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remember to add this to your local.properties

Comment on lines 12 to 21
HttpClient(OkHttp) {
install(ContentNegotiation) {
json(
Json {
ignoreUnknownKeys = true
}
)
}
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can configure more stuff here, so we don't have to repeat it in each request, but let's do that as we need it. This is also the place to configure stuff like network loggers if we need to in the future.

Comment on lines +11 to +12
factoryOf(::RealAuthRepository) { bind<AuthRepository>() }
factoryOf(::WordPressClient)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't see a reason that those should be singletons. WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

Agree. We are preserving data in those instances, so no need for a singleton. 👌

clientSecret: String,
redirectUri: String,
clientId: String
): Result<String> = withContext(dispatcherProvider.io) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Standard Result for now - but I want to introduce our own type for better error types, rather than exceptions.

Copy link
Contributor

@hamorillo hamorillo left a comment

Choose a reason for hiding this comment

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

Works as described. I can see the access_token when reviewing the network requests.

I left a comment about DI and modules that could be worth discussing before approving it.

There are no tests, the error handling is not done, but I don't want this PR to grow, so I would rather do this stuff separately, once we have the full OAuth flow completed.

Sounds good. I would also include in those tests the Koin.Modules ones. :)

}

@Composable
internal fun LoginScreen(
Copy link
Contributor

Choose a reason for hiding this comment

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

Preview in this class no longer works, as Koin won't be initialized. We could use KoinAppApplicationPreview:

@Preview
@Composable
private fun LoginScreenPreview() {
    KoinApplicationPreview(application = { modules(loginUiModule) }) {
        LoginScreen(
            onLoggedIn = { },
        )
    }
}

However, if you try that code, it will fail because it doesn't know how to resolve dispatcherModule.

dispatcherModule is being defined in the app module, so DispatcherProvider will be available everywhere in the app when needed. However, thinking in isolated modules, appmodule doesn't require :foundations. It's only required by loginUI.

I wonder if dispatcherModule should be defined in foundations and refactor a bit the dependencies.

Something like this:
adam/GRA-199...hamorillo/GRA-199-refactor-dispatcher

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should be fixed now. I didn't update the test to use the proper composable that doesn't rely on ViewModel, but rather on a ui state class.

Comment on lines +11 to +12
factoryOf(::RealAuthRepository) { bind<AuthRepository>() }
factoryOf(::WordPressClient)
Copy link
Contributor

Choose a reason for hiding this comment

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

Agree. We are preserving data in those instances, so no need for a singleton. 👌

@AdamGrzybkowski AdamGrzybkowski merged commit f195ea6 into trunk Jun 25, 2025
8 checks passed
@AdamGrzybkowski AdamGrzybkowski deleted the adam/GRA-199 branch June 25, 2025 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants