Skip to content

Commit

Permalink
Add native auth to MSAL test app (#2001)
Browse files Browse the repository at this point in the history
### For MSAL team:
In order to let the native auth team execute (manual) release tests, an
application is needed that supports the various use flows that are part
of the release tests.

Changes:
- The existing MSAL test app is extended with a Native Auth section,
which is accessed from the side menu.
- Updated CODEOWNERS to reflect native auth ownership of the newly added
classes.

### For native auth team:
Changes compared to previous versions of this application:
- Sign up attributes are no longer hardcoded to `country` and `city`,
but taken dynamically from the UI (through new key and value text
fields).
- AttributesRequired` state will navigate to the new, generic
AttributesFragment. Logs need to be checked for details about which
attributes are required, and thus which keys need to be supplied.
- `CodeFragment` displays API's `channel`, `sentTo` and `codeLength`
fields, which can now be used for validation for correct behaviour.

Note:
This application is not in a state where it can be used as a
CI-generated artefact by the native auth team. Developers using this
application will need to change the config JSON file and update it to
one of several tenant configurations, recompile and run it. Support for
native auth in the Labs environment is needed to make this application
usable as a CI-generated artefact. Once Labs support is added, the
native auth screens will need config selection UI, similar to the
Fragment dedicated to testing `acquireToken()`.
  • Loading branch information
SammyO authored Jan 24, 2024
1 parent aad08a3 commit 1f146d0
Show file tree
Hide file tree
Showing 35 changed files with 3,234 additions and 2 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
msal/src/main/java/com/microsoft/identity/nativeauth/ @AzureAD/NativeAuthTeam
msal/src/test/java/com/microsoft/identity/nativeauth/ @AzureAD/NativeAuthTeam
msal/src/androidTest/java/com/microsoft/identity/nativeauth/ @AzureAD/NativeAuthTeam
msal/testapps/testapp/src/main/java/com/microsoft/identity/client/testapp/nativeauth @AzureAD/NativeAuthTeam

# If you are interested in reviewing or getting notified of changes in a particular area
# Please add your alias against that specific path below
Expand Down
11 changes: 10 additions & 1 deletion testapps/testapp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@

apply plugin: 'com.android.application'

def msalVersion = "5.0.0"
apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

def msalVersion = "5.+"

if (project.hasProperty("distMsalVersion")) {
msalVersion = distMsalVersion
Expand Down Expand Up @@ -83,6 +87,9 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
buildFeatures {
viewBinding true
}
lintOptions {
abortOnError false
}
Expand Down Expand Up @@ -111,6 +118,8 @@ dependencies {
localImplementation project(':msal')
distImplementation "com.microsoft.identity.client:msal:${msalVersion}"
implementation "com.google.code.gson:gson:$rootProject.ext.gsonVersion"
implementation "androidx.constraintlayout:constraintlayout:$rootProject.ext.constraintLayoutVersion"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.ext.kotlinXCoroutinesVersion"
implementation "androidx.appcompat:appcompat:$rootProject.ext.appCompatVersion"
implementation "androidx.legacy:legacy-support-v4:$rootProject.ext.legacySupportV4Version"
implementation "com.google.android.material:material:$rootProject.ext.materialVersion"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,12 @@ public enum AuthScheme {
BEARER,
POP
}

/**
* Constants used in native auth flows.
*/
public static final String STATE = "state";
public static final String CODE_LENGTH = "code_length";
public static final String SENT_TO = "sent_to";
public static final String CHANNEL = "channel";
}
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ public boolean onNavigationItemSelected(final MenuItem item) {
return false;
}
fragment = new AcquireTokenFragment();
} else if ( menuItemId == R.id.nav_native) {
if (getCurrentFragment() instanceof NativeAuthFragment){
return false;
}
fragment = new NativeAuthFragment();
} else if (menuItemId == R.id.nav_result) {
if (getCurrentFragment() instanceof ResultFragment){
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (c) Microsoft Corporation.
// All rights reserved.
//
// This code is licensed under the MIT License.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package com.microsoft.identity.client.testapp

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.microsoft.identity.client.testapp.nativeauth.AuthClient
import com.microsoft.identity.client.testapp.nativeauth.EmailAttributeSignUpFragment
import com.microsoft.identity.client.testapp.nativeauth.EmailPasswordSignInSignUpFragment
import com.microsoft.identity.client.testapp.nativeauth.EmailSignInSignUpFragment
import com.microsoft.identity.client.testapp.nativeauth.PasswordResetFragment

/**
* Fragment used for starting various native auth flows.
*/
class NativeAuthFragment : Fragment() {
companion object {
private val TAG = MainActivity::class.java.simpleName
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.fragment_native, container, false)

AuthClient.initialize(requireContext())

val emailSignInSignUpFragment = EmailSignInSignUpFragment()
val emailPasswordSignInSignUpFragment = EmailPasswordSignInSignUpFragment()
val emailAttributeSignUpFragment = EmailAttributeSignUpFragment()
val passwordResetFragment = PasswordResetFragment()

val bottomNavigationView = view.findViewById<BottomNavigationView>(R.id.bottom_navigation_view)

setFragment(emailSignInSignUpFragment, R.string.title_email_oob_sisu)

bottomNavigationView.setOnNavigationItemSelectedListener {
when (it.itemId) {
R.id.email_oob_sisu -> setFragment(emailSignInSignUpFragment, R.string.title_email_oob_sisu)
R.id.email_password_sisu -> setFragment(emailPasswordSignInSignUpFragment, R.string.title_email_password_sisu)
R.id.email_attribute_sisu -> setFragment(emailAttributeSignUpFragment, R.string.title_email_attribute_oob_sisu)
R.id.email_oob_sspr -> setFragment(passwordResetFragment, R.string.title_email_oob_sspr)
}
true
}

return view
}

private fun setFragment(fragment: Fragment, title: Int) {
(this.context as AppCompatActivity).supportFragmentManager.beginTransaction().apply {
replace(R.id.scenario_fragment, fragment)
commit()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation.
// All rights reserved.
//
// This code is licensed under the MIT License.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package com.microsoft.identity.client.testapp.nativeauth

import android.app.Application
import android.content.Context
import com.microsoft.identity.client.PublicClientApplication
import com.microsoft.identity.client.testapp.R
import com.microsoft.identity.nativeauth.INativeAuthPublicClientApplication

/**
* Utility for managing MSAL SDK instance INativeAuthPublicClientApplication.
*/
object AuthClient : Application() {
private lateinit var authClient: INativeAuthPublicClientApplication

fun getAuthClient(): INativeAuthPublicClientApplication {
return authClient
}

fun initialize(context: Context) {
authClient = PublicClientApplication.createNativeAuthPublicClientApplication(
context,
R.raw.msal_config_native
)
}
}
Loading

0 comments on commit 1f146d0

Please sign in to comment.