Merge pull request #12 from TanelOrumaa/fixesIter3

Iter3 related fixes
This commit is contained in:
Henrik Lepson 2021-11-08 20:36:12 +02:00 committed by GitHub
commit aaa8d8f13c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 133 additions and 34 deletions

View File

@ -16,8 +16,10 @@ import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import com.tarkvaraprojekt.mobileauthapp.NFC.Comms import com.tarkvaraprojekt.mobileauthapp.NFC.Comms
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentAuthBinding import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentAuthBinding
import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
import java.lang.Exception import java.lang.Exception
import kotlin.system.exitProcess
/** /**
* Fragment that asks the user to detect the ID card with mobile NFC chip. * 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 viewModel: SmartCardViewModel by activityViewModels()
private val intentParameters: ParametersViewModel by activityViewModels()
private var binding: FragmentAuthBinding? = null private var binding: FragmentAuthBinding? = null
private val args: CanFragmentArgs by navArgs() private val args: CanFragmentArgs by navArgs()
@ -51,9 +55,9 @@ class AuthFragment : Fragment() {
override fun onTick(p0: Long) { override fun onTick(p0: Long) {
timeRemaining-- timeRemaining--
if (timeRemaining == 0) { if (timeRemaining == 0) {
binding!!.timeCounter.text = getString(R.string.no_time) binding?.timeCounter?.text = getString(R.string.no_time)
} else { } else {
binding!!.timeCounter.text = getString(R.string.time_left, timeRemaining) binding?.timeCounter?.text = getString(R.string.time_left, timeRemaining)
} }
} }
@ -125,12 +129,18 @@ class AuthFragment : Fragment() {
timer.cancel() timer.cancel()
if (args.reading) { if (args.reading) {
findNavController().navigate(R.id.action_authFragment_to_homeFragment) findNavController().navigate(R.id.action_authFragment_to_homeFragment)
} else {
if (!args.mobile) {
//Currently for some reason the activity is not killed entirely. Must be looked into further.
requireActivity().finish()
exitProcess(0)
} else { } else {
val resultIntent = Intent() val resultIntent = Intent()
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent) requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
requireActivity().finish() requireActivity().finish()
} }
} }
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()

View File

@ -6,11 +6,14 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding
import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel 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 * 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 viewModel: SmartCardViewModel by activityViewModels()
private val intentParams: ParametersViewModel by activityViewModels()
private var binding: FragmentHomeBinding? = null private var binding: FragmentHomeBinding? = null
override fun onCreateView( override fun onCreateView(
@ -39,12 +44,30 @@ class HomeFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
initialChecks() initialChecks()
var mobile = false var auth = false
if (requireActivity().intent.data?.getQueryParameter("arg1") != null) { if (requireActivity().intent.data?.getQueryParameter("action") != null) {
mobile = true // 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){ 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) goToTheNextFragment(true, mobile)
} }
binding!!.beginButton.setOnClickListener { goToTheNextFragment() } binding!!.beginButton.setOnClickListener { goToTheNextFragment() }

View File

@ -30,7 +30,7 @@ class PinFragment : Fragment() {
// saving = true means that the user must be returned to the settings menu // 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 // 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. // 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( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,

View File

@ -11,7 +11,14 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentResultBinding import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentResultBinding
import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel 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 * 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() { class ResultFragment : Fragment() {
private val viewModel: SmartCardViewModel by activityViewModels() private val paramsModel: ParametersViewModel by activityViewModels()
private var binding: FragmentResultBinding? = null private var binding: FragmentResultBinding? = null
private val args: CanFragmentArgs by navArgs() private val args: ResultFragmentArgs by navArgs()
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -38,15 +45,44 @@ class ResultFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
binding!!.resultBackButton.setOnClickListener { binding!!.resultBackButton.setOnClickListener {
if (!args.mobile) { if (args.mobile) {
createResponse() 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() val resultIntent = Intent()
requireActivity().setResult(AppCompatActivity.RESULT_OK, resultIntent) requireActivity().setResult(responseCode, resultIntent)
requireActivity().finish() requireActivity().finish()
} }

View File

@ -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
}
}

View File

@ -1,9 +0,0 @@
package com.tarkvaraprojekt.mobileauthapp.network
/**
* Placeholder ResponseItem.
*/
data class ResponseItem (
val data1: Int,
val data2: Int,
)

View File

@ -22,12 +22,9 @@ private val retrofit = Retrofit.Builder().addConverterFactory(MoshiConverterFact
.baseUrl(BASE_URL).build() .baseUrl(BASE_URL).build()
interface TokenApiService { interface TokenApiService {
@GET("something")
suspend fun getData(): ResponseItem
@Headers("Content-Type: application/json") @Headers("Content-Type: application/json")
@POST("posts") @POST("auth/authentication")
suspend fun addData(@Body data: ResponseItem): Response<ResponseItem> suspend fun postToken(@Body data: TokenItem): Response<TokenItem>
} }
object TokenApi { object TokenApi {

View File

@ -0,0 +1,9 @@
package com.tarkvaraprojekt.mobileauthapp.network
/**
* TokenItem for making POST request.
*/
data class TokenItem (
val token: String,
val challenge: String,
)

View File

@ -35,17 +35,20 @@ class MainActivity : AppCompatActivity() {
} }
binding.loginOptionNfcButton.setOnClickListener { launchAuth() } binding.loginOptionNfcButton.setOnClickListener { launchAuth() }
//binding.loginOptionNfcButton.setOnClickListener { getData() }
} }
/** /**
* Method that creates an intent to launch the MobileAuthApp * 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() val launchIntent = Intent()
launchIntent.setClassName("com.tarkvaraprojekt.mobileauthapp", "com.tarkvaraprojekt.mobileauthapp.MainActivity") launchIntent.setClassName("com.tarkvaraprojekt.mobileauthapp", "com.tarkvaraprojekt.mobileauthapp.MainActivity")
launchIntent.putExtra("auth", true) launchIntent.putExtra("action", "auth")
launchIntent.putExtra("nonce", arg) // Currently nothing launchIntent.putExtra("challenge", challenge)
launchIntent.putExtra("authUrl", authUrl)
launchIntent.putExtra("mobile", true)
authLauncher.launch(launchIntent) authLauncher.launch(launchIntent)
} }
@ -54,14 +57,17 @@ class MainActivity : AppCompatActivity() {
* Ion library is used as it is very convenient for making simple GET requests. * Ion library is used as it is very convenient for making simple GET requests.
*/ */
private fun getData() { 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) Ion.with(applicationContext)
.load(url) .load(url)
.asJsonObject() .asJsonObject()
.setCallback { _, result -> .setCallback { _, result ->
try { try {
// Get data from the result and call launchAuth method // Get data from the result and call launchAuth method
launchAuth() val challenge = result.asJsonObject["nonce"].toString()
launchAuth(challenge, baseUrl)
} catch (e: Exception) { } catch (e: Exception) {
Log.i("GETrequest", "was unsuccessful") Log.i("GETrequest", "was unsuccessful")
} }