-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #406 from ForgeRock/SDKS-3079
SDKS-3079 Replace deprecated onActivityResult with ActivityResultContract
- Loading branch information
Showing
13 changed files
with
378 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
forgerock-auth/src/main/java/org/forgerock/android/auth/AppAuthFragment2.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* Copyright (c) 2024 ForgeRock. All rights reserved. | ||
* | ||
* This software may be modified and distributed under the terms | ||
* of the MIT license. See the LICENSE file for details. | ||
*/ | ||
package org.forgerock.android.auth | ||
|
||
import android.content.Intent | ||
import android.os.Bundle | ||
import androidx.annotation.RestrictTo | ||
import androidx.fragment.app.Fragment | ||
import androidx.fragment.app.FragmentActivity | ||
import androidx.fragment.app.FragmentManager | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import net.openid.appauth.AuthorizationResponse | ||
import org.forgerock.android.auth.centralize.BrowserLauncher | ||
import org.forgerock.android.auth.centralize.Launcher | ||
|
||
private const val PENDING = "pending" | ||
|
||
/** | ||
* Headless Fragment to receive callback result from AppAuth library | ||
*/ | ||
@RestrictTo(RestrictTo.Scope.LIBRARY) | ||
class AppAuthFragment2 : Fragment() { | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
val state: MutableStateFlow<Intent?> = MutableStateFlow(null) | ||
val delegate = | ||
registerForActivityResult(AuthorizeContract()) { | ||
state.value = it | ||
} | ||
|
||
val pending = savedInstanceState?.getBoolean(PENDING, false) ?: false | ||
|
||
BrowserLauncher.init(Launcher(delegate, state, pending)) | ||
} | ||
|
||
override fun onSaveInstanceState(outState: Bundle) { | ||
outState.putBoolean(PENDING, true) | ||
super.onSaveInstanceState(outState) | ||
} | ||
|
||
override fun onDestroy() { | ||
super.onDestroy() | ||
BrowserLauncher.reset() | ||
} | ||
|
||
companion object { | ||
val TAG: String = AppAuthFragment2::class.java.name | ||
|
||
/** | ||
* Initialize the Fragment to receive AppAuth callback event. | ||
*/ | ||
@Synchronized | ||
@JvmStatic | ||
fun launch(activity: FragmentActivity, browser: FRUser.Browser) { | ||
val fragmentManager: FragmentManager = activity.supportFragmentManager | ||
var current = fragmentManager.findFragmentByTag(TAG) as? AppAuthFragment2 | ||
if (current == null) { | ||
current = AppAuthFragment2() | ||
fragmentManager.beginTransaction().add(current, TAG).commitNow() | ||
} | ||
|
||
BrowserLauncher.authorize(browser, object : FRListener<AuthorizationResponse> { | ||
override fun onSuccess(result: AuthorizationResponse) { | ||
reset(activity, current) | ||
browser.listener.onSuccess(result) | ||
} | ||
|
||
override fun onException(e: Exception) { | ||
reset(activity, current) | ||
browser.listener.onException(e) | ||
} | ||
|
||
/** | ||
* Once receive the result, reset state. | ||
*/ | ||
private fun reset(activity: FragmentActivity, fragment: Fragment?) { | ||
activity.runOnUiThread { | ||
BrowserLauncher.reset() | ||
} | ||
fragment?.let { | ||
activity.runOnUiThread { | ||
fragmentManager.beginTransaction().remove(it).commitNow() | ||
} | ||
} | ||
} | ||
}) | ||
|
||
|
||
} | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
forgerock-auth/src/main/java/org/forgerock/android/auth/AuthorizeContract.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright (c) 2024 ForgeRock. All rights reserved. | ||
* | ||
* This software may be modified and distributed under the terms | ||
* of the MIT license. See the LICENSE file for details. | ||
*/ | ||
|
||
package org.forgerock.android.auth | ||
|
||
import android.content.Context | ||
import android.content.Intent | ||
import android.net.Uri | ||
import androidx.activity.result.contract.ActivityResultContract | ||
import androidx.browser.customtabs.CustomTabsIntent | ||
import net.openid.appauth.AppAuthConfiguration | ||
import net.openid.appauth.AuthorizationRequest | ||
import net.openid.appauth.AuthorizationService | ||
import org.forgerock.android.auth.FRUser.Browser | ||
|
||
/** | ||
* This class is an implementation of the ActivityResultContract. | ||
* It is used to handle the OAuth2 authorization process. | ||
*/ | ||
internal class AuthorizeContract : ActivityResultContract<Browser, Intent?>() { | ||
override fun createIntent( | ||
context: Context, | ||
input: Browser, | ||
): Intent { | ||
val configurer: AppAuthConfigurer = input.appAuthConfigurer | ||
val oAuth2Client = Config.getInstance().oAuth2Client | ||
|
||
val configuration = configurer.authorizationServiceConfigurationSupplier.get() | ||
val authRequestBuilder = | ||
AuthorizationRequest.Builder( | ||
configuration, | ||
oAuth2Client.clientId, | ||
oAuth2Client.responseType, | ||
Uri.parse(oAuth2Client.redirectUri), | ||
).setScope(oAuth2Client.scope) | ||
|
||
//Allow caller to override Authorization Request setting | ||
configurer.authorizationRequestBuilder.accept(authRequestBuilder) | ||
val authorizationRequest = authRequestBuilder.build() | ||
|
||
//Allow caller to override AppAuth default setting | ||
val appAuthConfigurationBuilder = AppAuthConfiguration.Builder() | ||
configurer.appAuthConfigurationBuilder.accept(appAuthConfigurationBuilder) | ||
val authorizationService = AuthorizationService(context, appAuthConfigurationBuilder.build()) | ||
|
||
//Allow caller to override custom tabs default setting | ||
val intentBuilder: CustomTabsIntent.Builder = | ||
authorizationService.createCustomTabsIntentBuilder(authorizationRequest.toUri()) | ||
configurer.customTabsIntentBuilder.accept(intentBuilder) | ||
|
||
val request = authRequestBuilder.build() | ||
val service = AuthorizationService(context, AppAuthConfiguration.DEFAULT) | ||
return service.getAuthorizationRequestIntent(request, intentBuilder.build()) | ||
} | ||
|
||
override fun parseResult( | ||
resultCode: Int, | ||
intent: Intent?, | ||
): Intent? { | ||
return intent | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.