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..fa5de12 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() @@ -51,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) } } @@ -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..e79c402 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,30 @@ 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 + // 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")!!) + } + } 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..0a76f1d --- /dev/null +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/model/ParametersViewModel.kt @@ -0,0 +1,27 @@ +package com.tarkvaraprojekt.mobileauthapp.model + +import androidx.lifecycle.ViewModel + +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..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 @@ -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("auth/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..4184aad 100644 --- a/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt +++ b/TestMobileApp/app/src/main/java/com/example/testmobileapp/MainActivity.kt @@ -35,17 +35,20 @@ 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("auth", true) - launchIntent.putExtra("nonce", arg) // Currently nothing + launchIntent.putExtra("action", "auth") + launchIntent.putExtra("challenge", challenge) + launchIntent.putExtra("authUrl", authUrl) + launchIntent.putExtra("mobile", true) authLauncher.launch(launchIntent) } @@ -54,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") }