From 1b79eba4a4c55a1e96b376def90ad55f74085d4a Mon Sep 17 00:00:00 2001 From: Henrik Lepson Date: Mon, 8 Nov 2021 19:07:30 +0200 Subject: [PATCH 1/4] MOB-23 setup for post request done, parameter viewModel added --- .../mobileauthapp/AuthFragment.kt | 16 +++++-- .../mobileauthapp/HomeFragment.kt | 29 ++++++++++-- .../mobileauthapp/PinFragment.kt | 2 +- .../mobileauthapp/ResultFragment.kt | 46 +++++++++++++++++-- .../model/ParametersViewModel.kt | 28 +++++++++++ .../mobileauthapp/network/Response.kt | 9 ---- .../mobileauthapp/network/TokenApiService.kt | 7 +-- .../mobileauthapp/network/TokenItem.kt | 9 ++++ .../com/example/testmobileapp/MainActivity.kt | 6 ++- 9 files changed, 123 insertions(+), 29 deletions(-) create mode 100644 MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/model/ParametersViewModel.kt delete mode 100644 MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/Response.kt create mode 100644 MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenItem.kt diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/AuthFragment.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/AuthFragment.kt index cb97a5a..cb4be72 100644 --- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/AuthFragment.kt +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/AuthFragment.kt @@ -16,8 +16,10 @@ import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs import com.tarkvaraprojekt.mobileauthapp.NFC.Comms import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentAuthBinding +import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel import java.lang.Exception +import kotlin.system.exitProcess /** * Fragment that asks the user to detect the ID card with mobile NFC chip. @@ -28,6 +30,8 @@ class AuthFragment : Fragment() { private val viewModel: SmartCardViewModel by activityViewModels() + private val intentParameters: ParametersViewModel by activityViewModels() + private var binding: FragmentAuthBinding? = null private val args: CanFragmentArgs by navArgs() @@ -126,9 +130,15 @@ class AuthFragment : Fragment() { if (args.reading) { findNavController().navigate(R.id.action_authFragment_to_homeFragment) } else { - val resultIntent = Intent() - requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent) - requireActivity().finish() + if (!args.mobile) { + //Currently for some reason the activity is not killed entirely. Must be looked into further. + requireActivity().finish() + exitProcess(0) + } else { + val resultIntent = Intent() + requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent) + requireActivity().finish() + } } } diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt index e53cd54..4057307 100644 --- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt @@ -6,11 +6,14 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding +import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel +import java.lang.Exception /** * HomeFragment is only shown to the user when then the user launches the application. When the application @@ -23,6 +26,8 @@ class HomeFragment : Fragment() { private val viewModel: SmartCardViewModel by activityViewModels() + private val intentParams: ParametersViewModel by activityViewModels() + private var binding: FragmentHomeBinding? = null override fun onCreateView( @@ -39,12 +44,28 @@ class HomeFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initialChecks() - var mobile = false - if (requireActivity().intent.data?.getQueryParameter("arg1") != null) { - mobile = true + var auth = false + if (requireActivity().intent.data?.getQueryParameter("action") != null) { + // Currently we only support authentication not signing. + auth = true } - val auth = requireActivity().intent.getBooleanExtra("auth", false) + val mobile = requireActivity().intent.getBooleanExtra("mobile", false) if (auth || mobile){ + try { + if (mobile) { + // We use !! because we want an exception when something is not right. + intentParams.setChallenge(requireActivity().intent.getStringExtra("challenge")!!) + intentParams.setAuthUrl(requireActivity().intent.getStringExtra("authUrl")!!) + } else { //Website + intentParams.setChallenge(requireActivity().intent.data!!.getQueryParameter("challenge")!!) + intentParams.setAuthUrl(requireActivity().intent.data!!.getQueryParameter("authUrl")!!) + } + } catch (e: Exception) { + // There was a problem with parameters, which means that authentication is not possible. + val resultIntent = Intent() + requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent) + requireActivity().finish() + } goToTheNextFragment(true, mobile) } binding!!.beginButton.setOnClickListener { goToTheNextFragment() } diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/PinFragment.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/PinFragment.kt index 3248ef0..d6a78a4 100644 --- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/PinFragment.kt +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/PinFragment.kt @@ -30,7 +30,7 @@ class PinFragment : Fragment() { // saving = true means that the user must be returned to the settings menu // reading = true means that we are reading information from the ID card that does // not require PIN 1 so it is not necessary to ask it. - private val args: CanFragmentArgs by navArgs() + private val args: PinFragmentArgs by navArgs() override fun onCreateView( inflater: LayoutInflater, diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/ResultFragment.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/ResultFragment.kt index 9d01c8f..8c61a02 100644 --- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/ResultFragment.kt +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/ResultFragment.kt @@ -11,7 +11,14 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.navArgs import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentResultBinding +import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel +import com.tarkvaraprojekt.mobileauthapp.network.TokenApi +import com.tarkvaraprojekt.mobileauthapp.network.TokenItem +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlin.system.exitProcess /** * ResultFragment is used to create a JWT and to send response to the website/application @@ -20,11 +27,11 @@ import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel */ class ResultFragment : Fragment() { - private val viewModel: SmartCardViewModel by activityViewModels() + private val paramsModel: ParametersViewModel by activityViewModels() private var binding: FragmentResultBinding? = null - private val args: CanFragmentArgs by navArgs() + private val args: ResultFragmentArgs by navArgs() override fun onCreateView( inflater: LayoutInflater, @@ -38,15 +45,44 @@ class ResultFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding!!.resultBackButton.setOnClickListener { - if (!args.mobile) { + if (args.mobile) { createResponse() } } } - private fun createResponse() { + /** + * Makes a POST request to the backend server with a tokenItem + */ + fun postToken() { + val tokenData = TokenItem( + paramsModel.token, + paramsModel.challenge + ) + CoroutineScope(Dispatchers.Default).launch { + val response = TokenApi.retrofitService.postToken(tokenData) + if (response.isSuccessful) { + //Success scenario here + } else { + //Failure scenario here + if (args.mobile) { + createResponse(false) + } else { + //Currently for some reason the activity is not killed entirely. Must be looked into further. + requireActivity().finish() + exitProcess(0) + } + } + } + } + + /** + * Only used when the MobileAuthApp was launched by an app. Not for website use. + */ + private fun createResponse(success: Boolean = true) { + val responseCode = if (success) AppCompatActivity.RESULT_OK else AppCompatActivity.RESULT_CANCELED val resultIntent = Intent() - requireActivity().setResult(AppCompatActivity.RESULT_OK, resultIntent) + requireActivity().setResult(responseCode, resultIntent) requireActivity().finish() } diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/model/ParametersViewModel.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/model/ParametersViewModel.kt new file mode 100644 index 0000000..fbfea09 --- /dev/null +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/model/ParametersViewModel.kt @@ -0,0 +1,28 @@ +package com.tarkvaraprojekt.mobileauthapp.model + +import androidx.lifecycle.ViewModel +import com.tarkvaraprojekt.mobileauthapp.network.TokenItem + +class ParametersViewModel: ViewModel() { + + private var _challenge: String = "" + val challenge get() = _challenge + + private var _authUrl: String = "" + val authUrl get() = _authUrl + + private var _token: String = "" + val token get() = _token + + fun setChallenge(newChallenge: String) { + _challenge = newChallenge + } + + fun setAuthUrl(newAuthUrl: String) { + _authUrl = newAuthUrl + } + + fun setToken(newToken: String) { + _token = newToken + } +} \ No newline at end of file diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/Response.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/Response.kt deleted file mode 100644 index 199b913..0000000 --- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/Response.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.tarkvaraprojekt.mobileauthapp.network - -/** - * Placeholder ResponseItem. - */ -data class ResponseItem ( - val data1: Int, - val data2: Int, -) \ No newline at end of file diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenApiService.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenApiService.kt index aa08490..649c048 100644 --- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenApiService.kt +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenApiService.kt @@ -22,12 +22,9 @@ private val retrofit = Retrofit.Builder().addConverterFactory(MoshiConverterFact .baseUrl(BASE_URL).build() interface TokenApiService { - @GET("something") - suspend fun getData(): ResponseItem - @Headers("Content-Type: application/json") - @POST("posts") - suspend fun addData(@Body data: ResponseItem): Response + @POST("authentication") + suspend fun postToken(@Body data: TokenItem): Response } object TokenApi { diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenItem.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenItem.kt new file mode 100644 index 0000000..b7bb0c1 --- /dev/null +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenItem.kt @@ -0,0 +1,9 @@ +package com.tarkvaraprojekt.mobileauthapp.network + +/** + * TokenItem for making POST request. + */ +data class TokenItem ( + val token: String, + val challenge: String, +) \ No newline at end of file diff --git a/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt b/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt index 8d9e9e0..785fde9 100644 --- a/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt +++ b/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt @@ -44,8 +44,10 @@ class MainActivity : AppCompatActivity() { private fun launchAuth(arg: String = "nothing") { val launchIntent = Intent() launchIntent.setClassName("com.tarkvaraprojekt.mobileauthapp", "com.tarkvaraprojekt.mobileauthapp.MainActivity") - launchIntent.putExtra("auth", true) - launchIntent.putExtra("nonce", arg) // Currently nothing + launchIntent.putExtra("action", "auth") + launchIntent.putExtra("challenge", "challengerValue") + launchIntent.putExtra("authUrl", "authUrl is here") + launchIntent.putExtra("mobile", true) authLauncher.launch(launchIntent) } From f0c7ab96bb0dc39e62ae1e4865892b0546ec66ee Mon Sep 17 00:00:00 2001 From: Henrik Lepson Date: Mon, 8 Nov 2021 20:22:33 +0200 Subject: [PATCH 2/4] MOB-23 MOB-41 small fixes related to HTTP --- .../com/tarkvaraprojekt/mobileauthapp/AuthFragment.kt | 4 ++-- .../com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt | 4 +++- .../mobileauthapp/model/ParametersViewModel.kt | 1 - .../mobileauthapp/network/TokenApiService.kt | 2 +- .../java/com/example/testmobileapp/MainActivity.kt | 10 +++++++--- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/AuthFragment.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/AuthFragment.kt index cb4be72..fa5de12 100644 --- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/AuthFragment.kt +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/AuthFragment.kt @@ -55,9 +55,9 @@ class AuthFragment : Fragment() { override fun onTick(p0: Long) { timeRemaining-- if (timeRemaining == 0) { - binding!!.timeCounter.text = getString(R.string.no_time) + binding?.timeCounter?.text = getString(R.string.no_time) } else { - binding!!.timeCounter.text = getString(R.string.time_left, timeRemaining) + binding?.timeCounter?.text = getString(R.string.time_left, timeRemaining) } } diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt index 4057307..e79c402 100644 --- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt @@ -57,8 +57,10 @@ class HomeFragment : Fragment() { intentParams.setChallenge(requireActivity().intent.getStringExtra("challenge")!!) intentParams.setAuthUrl(requireActivity().intent.getStringExtra("authUrl")!!) } else { //Website + // Currently the test website won't send the authUrl parameter + //Log.i("intentDebugging", requireActivity().intent.data.toString()) intentParams.setChallenge(requireActivity().intent.data!!.getQueryParameter("challenge")!!) - intentParams.setAuthUrl(requireActivity().intent.data!!.getQueryParameter("authUrl")!!) + //intentParams.setAuthUrl(requireActivity().intent.data!!.getQueryParameter("authUrl")!!) } } catch (e: Exception) { // There was a problem with parameters, which means that authentication is not possible. diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/model/ParametersViewModel.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/model/ParametersViewModel.kt index fbfea09..0a76f1d 100644 --- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/model/ParametersViewModel.kt +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/model/ParametersViewModel.kt @@ -1,7 +1,6 @@ package com.tarkvaraprojekt.mobileauthapp.model import androidx.lifecycle.ViewModel -import com.tarkvaraprojekt.mobileauthapp.network.TokenItem class ParametersViewModel: ViewModel() { diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenApiService.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenApiService.kt index 649c048..56ad1c1 100644 --- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenApiService.kt +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/network/TokenApiService.kt @@ -23,7 +23,7 @@ private val retrofit = Retrofit.Builder().addConverterFactory(MoshiConverterFact interface TokenApiService { @Headers("Content-Type: application/json") - @POST("authentication") + @POST("auth/authentication") suspend fun postToken(@Body data: TokenItem): Response } diff --git a/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt b/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt index 785fde9..e2876db 100644 --- a/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt +++ b/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt @@ -35,13 +35,14 @@ class MainActivity : AppCompatActivity() { } binding.loginOptionNfcButton.setOnClickListener { launchAuth() } + //binding.loginOptionNfcButton.setOnClickListener { getData() } } /** * Method that creates an intent to launch the MobileAuthApp */ - private fun launchAuth(arg: String = "nothing") { + private fun launchAuth(challenge: String = "challenge", authUrl: String = "authUrl") { val launchIntent = Intent() launchIntent.setClassName("com.tarkvaraprojekt.mobileauthapp", "com.tarkvaraprojekt.mobileauthapp.MainActivity") launchIntent.putExtra("action", "auth") @@ -56,14 +57,17 @@ class MainActivity : AppCompatActivity() { * Ion library is used as it is very convenient for making simple GET requests. */ private fun getData() { - val url = "real-address-here" + // Enter the server endpoint address to here + val baseUrl = "enter-base-url-here" + val url = "$baseUrl/auth/challenge" Ion.with(applicationContext) .load(url) .asJsonObject() .setCallback { _, result -> try { // Get data from the result and call launchAuth method - launchAuth() + val challenge = result.asJsonObject["nonce"].toString() + launchAuth(challenge, baseUrl) } catch (e: Exception) { Log.i("GETrequest", "was unsuccessful") } From d60cecdd2677540e8b9d9e6324c1f773fae637da Mon Sep 17 00:00:00 2001 From: Henrik Lepson Date: Mon, 8 Nov 2021 20:26:17 +0200 Subject: [PATCH 3/4] forgot to remove dummy values --- .../src/main/java/com/example/testmobileapp/MainActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt b/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt index e2876db..4184aad 100644 --- a/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt +++ b/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt @@ -46,8 +46,8 @@ class MainActivity : AppCompatActivity() { val launchIntent = Intent() launchIntent.setClassName("com.tarkvaraprojekt.mobileauthapp", "com.tarkvaraprojekt.mobileauthapp.MainActivity") launchIntent.putExtra("action", "auth") - launchIntent.putExtra("challenge", "challengerValue") - launchIntent.putExtra("authUrl", "authUrl is here") + launchIntent.putExtra("challenge", challenge) + launchIntent.putExtra("authUrl", authUrl) launchIntent.putExtra("mobile", true) authLauncher.launch(launchIntent) } From c51f0e42778ef370c3d8d2a2616b435a67811911 Mon Sep 17 00:00:00 2001 From: Henrik Lepson <56916788+Henrik895@users.noreply.github.com> Date: Mon, 8 Nov 2021 21:51:54 +0200 Subject: [PATCH 4/4] Release notes updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9803eda..cccf57d 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ More info about installing third party applications on the Android phones: https ### Wiki pages relevant for the "Software project" subject * [Project Vision](https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC/wiki/Project-Vision) *last updated on 10.10* -* [Release Notes](https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC/wiki/Release-notes) *last updated for iteration 2 on 10.10* +* [Release Notes](https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC/wiki/Release-notes) *last updated for iteration3 on 08.11* * [Project tasks](https://tvp-mobile-authentication.atlassian.net/jira/software/projects/MOB/boards/1/backlog) (Ask Tanel for JIRA permissions if needed). * [Project plan](https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC/wiki/Project-plan) *last updated on 10.10* * [Use Cases](https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC/wiki/Use-Cases) *last updated on 10.10*