7 Commits

Author SHA1 Message Date
Henrik Lepson
1e26f83db2 tweaked url 2021-12-06 23:27:43 +02:00
Henrik Lepson
74d97827f8 testing new approach 2021-12-06 22:08:04 +02:00
Henrik Lepson
60207319b7 Merge pull request #16 from TanelOrumaa/newapproach
Improved code
2021-12-06 20:27:00 +02:00
Henrik Lepson
e5300dfa5e got rid of git status syntax 2021-12-04 17:21:07 +02:00
Henrik Lepson
d4c2a11521 added more error messages 2021-12-04 17:08:58 +02:00
Henrik Lepson
09c4fa6be3 fixed small issue in testmobileapp 2021-12-04 12:46:40 +02:00
Henrik Lepson
63bc89b0e4 Merge pull request #14 from TanelOrumaa/iter4UI
UI/UX improvements for iteration 4
2021-12-03 16:24:00 +02:00
13 changed files with 191 additions and 127 deletions

View File

@@ -36,7 +36,8 @@ class AuthFragment : Fragment() {
private val paramsModel: ParametersViewModel by activityViewModels() private val paramsModel: ParametersViewModel by activityViewModels()
private var binding: FragmentAuthBinding? = null private var _binding: FragmentAuthBinding? = null
private val binding get() = _binding!!
private val args: CanFragmentArgs by navArgs() private val args: CanFragmentArgs by navArgs()
@@ -49,8 +50,8 @@ class AuthFragment : Fragment() {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
binding = FragmentAuthBinding.inflate(inflater, container, false) _binding = FragmentAuthBinding.inflate(inflater, container, false)
return binding!!.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -59,9 +60,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)
} }
} }
@@ -71,9 +72,9 @@ class AuthFragment : Fragment() {
} }
}.start() }.start()
// The button exists in code for testing reasons, but not visible to the user anymore unless visibility is changed in the code. // The button exists in code for testing reasons, but not visible to the user anymore unless visibility is changed in the code.
binding!!.nextButton.visibility = View.GONE binding.nextButton.visibility = View.GONE
binding!!.nextButton.setOnClickListener { goToNextFragment() } binding.nextButton.setOnClickListener { goToNextFragment() }
binding!!.cancelButton.setOnClickListener { cancelAuth() } binding.cancelButton.setOnClickListener { cancelAuth() }
val adapter = NfcAdapter.getDefaultAdapter(activity) val adapter = NfcAdapter.getDefaultAdapter(activity)
if (adapter != null) if (adapter != null)
getInfoFromIdCard(adapter) getInfoFromIdCard(adapter)
@@ -104,7 +105,7 @@ class AuthFragment : Fragment() {
adapter.enableReaderMode(activity, { tag -> adapter.enableReaderMode(activity, { tag ->
timer.cancel() timer.cancel()
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
binding!!.timeCounter.text = getString(R.string.card_detected) binding.timeCounter.text = getString(R.string.card_detected)
} }
val card = IsoDep.get(tag) val card = IsoDep.get(tag)
card.timeout = 32768 card.timeout = 32768
@@ -127,11 +128,11 @@ class AuthFragment : Fragment() {
when ("invalid pin") { when ("invalid pin") {
in e.message.toString().lowercase() -> requireActivity().runOnUiThread { in e.message.toString().lowercase() -> requireActivity().runOnUiThread {
val messagePieces = e.message.toString().split(" ") val messagePieces = e.message.toString().split(" ")
binding!!.timeCounter.text = getString(R.string.wrong_pin, messagePieces[messagePieces.size - 1]) binding.timeCounter.text = getString(R.string.wrong_pin, messagePieces[messagePieces.size - 1])
viewModel.deletePin(requireContext()) viewModel.deletePin(requireContext())
} }
else -> requireActivity().runOnUiThread { else -> requireActivity().runOnUiThread {
binding!!.timeCounter.text = getString(R.string.wrong_can_text) binding.timeCounter.text = getString(R.string.wrong_can_text)
viewModel.deleteCan(requireContext()) viewModel.deleteCan(requireContext())
} }
} }
@@ -149,6 +150,6 @@ class AuthFragment : Fragment() {
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
binding = null _binding = null
} }
} }

View File

@@ -29,7 +29,8 @@ class CanFragment : Fragment() {
private val viewModel: SmartCardViewModel by activityViewModels() private val viewModel: SmartCardViewModel by activityViewModels()
private var binding: FragmentCanBinding? = null private var _binding: FragmentCanBinding? = null
private val binding get() = _binding!!
// Navigation arguments: // Navigation arguments:
// saving = true means that we are navigating here from the settings menu and must return to the settings menu. // saving = true means that we are navigating here from the settings menu and must return to the settings menu.
@@ -40,17 +41,17 @@ class CanFragment : Fragment() {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
binding = FragmentCanBinding.inflate(inflater, container, false) _binding = FragmentCanBinding.inflate(inflater, container, false)
return binding!!.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
checkIfSkip() checkIfSkip()
binding!!.canTextField.editText?.addTextChangedListener { binding.canTextField.editText?.addTextChangedListener {
checkEnteredCan() checkEnteredCan()
} }
binding!!.buttonCancel.setOnClickListener { goToTheStart() } binding.buttonCancel.setOnClickListener { goToTheStart() }
} }
/** /**
@@ -112,7 +113,7 @@ class CanFragment : Fragment() {
* allowed to modify the entered can. * allowed to modify the entered can.
*/ */
private fun checkEnteredCan() { private fun checkEnteredCan() {
val enteredCan = binding!!.canTextField.editText?.text.toString() val enteredCan = binding.canTextField.editText?.text.toString()
if (enteredCan.length == 6) { if (enteredCan.length == 6) {
viewModel.setUserCan(enteredCan) viewModel.setUserCan(enteredCan)
viewModel.storeCan(requireContext()) //Maybe storeCan should always automatically call setUserCan method as well because these methods usually are used together viewModel.storeCan(requireContext()) //Maybe storeCan should always automatically call setUserCan method as well because these methods usually are used together
@@ -127,6 +128,6 @@ class CanFragment : Fragment() {
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
binding = null _binding = null
} }
} }

View File

@@ -20,11 +20,14 @@ 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.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.koushikdutta.ion.Ion
import com.tarkvaraprojekt.mobileauthapp.NFC.Comms import com.tarkvaraprojekt.mobileauthapp.NFC.Comms
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding
import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel 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 java.lang.RuntimeException
import java.net.URL
/** /**
* 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
@@ -39,7 +42,8 @@ class HomeFragment : Fragment() {
private val intentParams: ParametersViewModel by activityViewModels() private val intentParams: ParametersViewModel by activityViewModels()
private var binding: FragmentHomeBinding? = null private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
// The ID card reader mode is enabled on the home fragment when can is saved. // The ID card reader mode is enabled on the home fragment when can is saved.
private var canSaved: Boolean = false private var canSaved: Boolean = false
@@ -54,10 +58,10 @@ class HomeFragment : Fragment() {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
binding = FragmentHomeBinding.inflate(inflater, container, false) _binding = FragmentHomeBinding.inflate(inflater, container, false)
// Making settings menu active again // Making settings menu active again
(activity as MainActivity).menuAvailable = true (activity as MainActivity).menuAvailable = true
return binding!!.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -103,23 +107,64 @@ class HomeFragment : Fragment() {
intentParams.setChallenge(requireActivity().intent.getStringExtra("challenge")!!) intentParams.setChallenge(requireActivity().intent.getStringExtra("challenge")!!)
intentParams.setAuthUrl(requireActivity().intent.getStringExtra("authUrl")!!) intentParams.setAuthUrl(requireActivity().intent.getStringExtra("authUrl")!!)
intentParams.setOrigin(requireActivity().intent.getStringExtra("originUrl")!!) intentParams.setOrigin(requireActivity().intent.getStringExtra("originUrl")!!)
goToTheNextFragment(mobile)
} else { //Website } else { //Website
/*
var challenge = requireActivity().intent.data!!.getQueryParameter("challenge")!! var challenge = requireActivity().intent.data!!.getQueryParameter("challenge")!!
// TODO: Since due to encoding plus gets converted to space, temporary solution is to replace it back. // TODO: Since due to encoding plus gets converted to space, temporary solution is to replace it back.
challenge = challenge.replace(" ", "+") challenge = challenge.replace(" ", "+")
intentParams.setChallenge(challenge) intentParams.setChallenge(challenge)
intentParams.setAuthUrl(requireActivity().intent.data!!.getQueryParameter("authUrl")!!) intentParams.setAuthUrl(requireActivity().intent.data!!.getQueryParameter("authUrl")!!)
intentParams.setOrigin(requireActivity().intent.data!!.getQueryParameter("originUrl")!!) intentParams.setOrigin(requireActivity().intent.data!!.getQueryParameter("originUrl")!!)
*/
var getAuthChallengeUrl = requireActivity().intent.data!!.getQueryParameter("getAuthChallengeUrl")!!
getAuthChallengeUrl = getAuthChallengeUrl.substring(1, getAuthChallengeUrl.length - 1)
var postAuthTokenUrl = requireActivity().intent.data!!.getQueryParameter("postAuthTokenUrl")!!
postAuthTokenUrl = postAuthTokenUrl.substring(1, postAuthTokenUrl.length - 1)
val headers = requireActivity().intent.data!!.getQueryParameter("headers")!!
intentParams.setAuthUrl(postAuthTokenUrl)
val address = "https://" + URL(getAuthChallengeUrl).host
intentParams.setOrigin(address)
intentParams.setHeaders(headers)
Ion.getDefault(activity).conscryptMiddleware.enable(false)
Ion.with(activity)
.load(getAuthChallengeUrl)
.asJsonObject()
.setCallback { _, result ->
try {
// Get data from the result and call launchAuth method
val challenge = result.asJsonObject["nonce"].toString().replace("\"", "")
intentParams.setChallenge(challenge)
goToTheNextFragment(mobile)
} catch (e: Exception) {
Log.i("GETrequest", "was unsuccessful")
throw RuntimeException()
}
}
} }
} catch (e: Exception) { } catch (e: Exception) {
// There was a problem with parameters, which means that authentication is not possible. // There was a problem with parameters, which means that authentication is not possible.
// In that case we will cancel the authentication immediately as it would be waste of the user's time to carry on // In that case we will cancel the authentication immediately as it would be waste of the user's time to carry on
// before getting an inevitable error. // before getting an inevitable error.
val message = MaterialAlertDialogBuilder(requireContext())
message.setTitle(getString(R.string.problem_parameters))
if (intentParams.challenge == "") {
message.setMessage(getString(R.string.problem_challenge))
} else if (intentParams.authUrl == "") {
message.setMessage(getString(R.string.problem_authurl))
} else if (intentParams.origin == "") {
message.setMessage(getString(R.string.problem_originurl))
} else {
message.setMessage(getString(R.string.problem_other))
}
message.setPositiveButton(getString(R.string.continue_button)) {_, _ ->
val resultIntent = Intent() val resultIntent = Intent()
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent) requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
requireActivity().finish() requireActivity().finish()
} }
goToTheNextFragment(mobile) message.show()
}
} }
/** /**
@@ -127,12 +172,12 @@ class HomeFragment : Fragment() {
*/ */
private fun canState() { private fun canState() {
if (viewModel.userCan.length == 6) { if (viewModel.userCan.length == 6) {
binding!!.canStatusText.text = getString(R.string.can_status_saved) binding.canStatusText.text = getString(R.string.can_status_saved)
binding!!.canStatusLogo.setImageResource(R.drawable.ic_check_logo) binding.canStatusLogo.setImageResource(R.drawable.ic_check_logo)
canSaved = true canSaved = true
} else { } else {
binding!!.canStatusText.text = getString(R.string.can_status_negative) binding.canStatusText.text = getString(R.string.can_status_negative)
binding!!.canStatusLogo.setImageResource(R.drawable.ic_info_logo) binding.canStatusLogo.setImageResource(R.drawable.ic_info_logo)
canSaved = false canSaved = false
} }
} }
@@ -142,11 +187,11 @@ class HomeFragment : Fragment() {
*/ */
private fun pinState() { private fun pinState() {
if (viewModel.userPin.length in 4..12) { if (viewModel.userPin.length in 4..12) {
binding!!.pinStatusText.text = getString(R.string.pin_status_saved) binding.pinStatusText.text = getString(R.string.pin_status_saved)
binding!!.pinStatusLogo.setImageResource(R.drawable.ic_check_logo) binding.pinStatusLogo.setImageResource(R.drawable.ic_check_logo)
} else { } else {
binding!!.pinStatusText.text = getString(R.string.pin_status_negative) binding.pinStatusText.text = getString(R.string.pin_status_negative)
binding!!.pinStatusLogo.setImageResource(R.drawable.ic_info_logo) binding.pinStatusLogo.setImageResource(R.drawable.ic_info_logo)
} }
} }
@@ -172,10 +217,10 @@ class HomeFragment : Fragment() {
/** /**
* Displays a help message to the user explaining what the CAN is * Displays a help message to the user explaining what the CAN is
*/ */
private fun displayMessage() { private fun displayMessage(title: String, message: String) {
val dialog = MaterialAlertDialogBuilder(requireContext()) val dialog = MaterialAlertDialogBuilder(requireContext())
.setTitle(getString(R.string.can_question)) .setTitle(title)
.setMessage(getString(R.string.can_explanation)) .setMessage(message)
.setPositiveButton(R.string.return_text){_, _ -> } .setPositiveButton(R.string.return_text){_, _ -> }
.show() .show()
val title = dialog.findViewById<TextView>(R.id.alertTitle) val title = dialog.findViewById<TextView>(R.id.alertTitle)
@@ -188,22 +233,22 @@ class HomeFragment : Fragment() {
*/ */
private fun updateAction(canIsSaved: Boolean) { private fun updateAction(canIsSaved: Boolean) {
if (canIsSaved) { if (canIsSaved) {
binding!!.detectionActionText.text = getString(R.string.action_detect) binding.detectionActionText.text = getString(R.string.action_detect)
enableReaderMode() enableReaderMode()
binding!!.homeActionButton.visibility = View.GONE binding.homeActionButton.visibility = View.GONE
binding!!.homeHelpButton.visibility = View.GONE binding.homeHelpButton.visibility = View.GONE
} else { } else {
binding!!.detectionActionText.text = getString(R.string.action_detect_unavailable) binding.detectionActionText.text = getString(R.string.action_detect_unavailable)
binding!!.homeActionButton.text = getString(R.string.add_can_text) binding.homeActionButton.text = getString(R.string.add_can_text)
binding!!.homeActionButton.setOnClickListener { binding.homeActionButton.setOnClickListener {
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(saving = true, fromhome = true) val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(saving = true, fromhome = true)
findNavController().navigate(action) findNavController().navigate(action)
} }
binding!!.homeHelpButton.setOnClickListener { binding.homeHelpButton.setOnClickListener {
displayMessage() displayMessage(getString(R.string.can_question), getString(R.string.can_explanation))
} }
binding!!.homeActionButton.visibility = View.VISIBLE binding.homeActionButton.visibility = View.VISIBLE
binding!!.homeHelpButton.visibility = View.VISIBLE binding.homeHelpButton.visibility = View.VISIBLE
} }
} }
@@ -211,11 +256,11 @@ class HomeFragment : Fragment() {
* Resets the error message and allows the user to try again * Resets the error message and allows the user to try again
*/ */
private fun reset() { private fun reset() {
binding!!.homeActionButton.text = getString(R.string.try_again_text) binding.homeActionButton.text = getString(R.string.try_again_text)
binding!!.homeActionButton.setOnClickListener { binding.homeActionButton.setOnClickListener {
updateAction(canSaved) updateAction(canSaved)
} }
binding!!.homeActionButton.visibility = View.VISIBLE binding.homeActionButton.visibility = View.VISIBLE
} }
/** /**
@@ -224,11 +269,11 @@ class HomeFragment : Fragment() {
private fun enableReaderMode() { private fun enableReaderMode() {
val adapter = NfcAdapter.getDefaultAdapter(activity) val adapter = NfcAdapter.getDefaultAdapter(activity)
if (adapter == null || !adapter.isEnabled) { if (adapter == null || !adapter.isEnabled) {
binding!!.detectionActionText.text = getString(R.string.nfc_not_available) binding.detectionActionText.text = getString(R.string.nfc_not_available)
} else { } else {
adapter.enableReaderMode(activity, { tag -> adapter.enableReaderMode(activity, { tag ->
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
binding!!.detectionActionText.text = getString(R.string.card_detected) binding.detectionActionText.text = getString(R.string.card_detected)
} }
val card = IsoDep.get(tag) val card = IsoDep.get(tag)
card.timeout = 32768 card.timeout = 32768
@@ -249,11 +294,11 @@ class HomeFragment : Fragment() {
} catch (e: Exception) { } catch (e: Exception) {
when(e) { when(e) {
is TagLostException -> requireActivity().runOnUiThread { is TagLostException -> requireActivity().runOnUiThread {
binding!!.detectionActionText.text = getString(R.string.id_card_removed_early) binding.detectionActionText.text = getString(R.string.id_card_removed_early)
reset() reset()
} }
else -> requireActivity().runOnUiThread { else -> requireActivity().runOnUiThread {
binding!!.detectionActionText.text = getString(R.string.nfc_reading_error) binding.detectionActionText.text = getString(R.string.nfc_reading_error)
viewModel.deleteCan(requireContext()) viewModel.deleteCan(requireContext())
canState() canState()
reset() reset()
@@ -269,7 +314,9 @@ class HomeFragment : Fragment() {
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
if (receiver != null) {
requireActivity().unregisterReceiver(receiver) requireActivity().unregisterReceiver(receiver)
binding = null }
_binding = null
} }
} }

View File

@@ -19,23 +19,24 @@ class Pin2Fragment : Fragment() {
private val viewModel: SmartCardViewModel by activityViewModels() private val viewModel: SmartCardViewModel by activityViewModels()
private var binding: FragmentPin2Binding? = null private var _binding: FragmentPin2Binding? = null
private val binding get() = _binding!!
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
binding = FragmentPin2Binding.inflate(inflater, container, false) _binding = FragmentPin2Binding.inflate(inflater, container, false)
return binding!!.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
binding!!.nextButton.setOnClickListener { binding.nextButton.setOnClickListener {
checkPin2Length() checkPin2Length()
} }
binding!!.cancelButton.setOnClickListener { binding.cancelButton.setOnClickListener {
cancel() cancel()
} }
} }
@@ -45,7 +46,7 @@ class Pin2Fragment : Fragment() {
* then it is saved to the viewModel. * then it is saved to the viewModel.
*/ */
private fun checkPin2Length() { private fun checkPin2Length() {
val enteredPin2 = binding!!.pin2EditText.editText?.text.toString() val enteredPin2 = binding.pin2EditText.editText?.text.toString()
if (enteredPin2.length in 5..12) { if (enteredPin2.length in 5..12) {
viewModel.setUserPin2(enteredPin2) viewModel.setUserPin2(enteredPin2)
} else { } else {
@@ -66,7 +67,7 @@ class Pin2Fragment : Fragment() {
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
binding = null _binding = null
} }
} }

View File

@@ -29,7 +29,8 @@ class PinFragment : Fragment() {
private val viewModel: SmartCardViewModel by activityViewModels() private val viewModel: SmartCardViewModel by activityViewModels()
private var binding: FragmentPinBinding? = null private var _binding: FragmentPinBinding? = null
private val binding get() = _binding!!
// Navigation arguments: // Navigation arguments:
// 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
@@ -42,8 +43,8 @@ class PinFragment : Fragment() {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
binding = FragmentPinBinding.inflate(inflater, container, false) _binding = FragmentPinBinding.inflate(inflater, container, false)
return binding!!.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -51,28 +52,27 @@ class PinFragment : Fragment() {
checkIfSkip() checkIfSkip()
// Switch should be not visible when user is in savings mode // Switch should be not visible when user is in savings mode
if (args.saving) { if (args.saving) {
binding!!.savePinQuestion.visibility = View.GONE binding.savePinQuestion.visibility = View.GONE
binding!!.saveLayout.visibility = View.GONE binding.saveLayout.visibility = View.GONE
} else { } else {
saveToggle = saveToggle =
activity?.getPreferences(Context.MODE_PRIVATE)?.getBoolean("saveToggle", true) == true //Android Studio recommendation to get rid of Boolean?. activity?.getPreferences(Context.MODE_PRIVATE)?.getBoolean("saveToggle", true) == true //Android Studio recommendation to get rid of Boolean?.
Log.i("myLogging", activity?.getPreferences(Context.MODE_PRIVATE)?.getBoolean("saveToggle", true).toString())
if (!saveToggle) { if (!saveToggle) {
binding!!.saveSwitch.isChecked = false binding.saveSwitch.isChecked = false
} }
binding!!.saveSwitch.setOnCheckedChangeListener { _, isChecked -> binding.saveSwitch.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) { if (isChecked) {
binding!!.saveStatus.text = getString(R.string.pin_save_on) binding.saveStatus.text = getString(R.string.pin_save_on)
activity?.getPreferences(Context.MODE_PRIVATE)?.edit()?.putBoolean("saveToggle", true)?.apply() activity?.getPreferences(Context.MODE_PRIVATE)?.edit()?.putBoolean("saveToggle", true)?.apply()
} else { } else {
binding!!.saveStatus.text = getString(R.string.pin_save_off) binding.saveStatus.text = getString(R.string.pin_save_off)
activity?.getPreferences(Context.MODE_PRIVATE)?.edit()?.putBoolean("saveToggle", false)?.apply() activity?.getPreferences(Context.MODE_PRIVATE)?.edit()?.putBoolean("saveToggle", false)?.apply()
} }
saveToggle = !saveToggle saveToggle = !saveToggle
} }
} }
binding!!.buttonContinue.setOnClickListener { checkEnteredPin() } binding.buttonContinue.setOnClickListener { checkEnteredPin() }
binding!!.buttonCancel.setOnClickListener { goToTheStart() } binding.buttonCancel.setOnClickListener { goToTheStart() }
} }
/** /**
@@ -130,7 +130,7 @@ class PinFragment : Fragment() {
* allowed to modify the entered PIN 1. * allowed to modify the entered PIN 1.
*/ */
private fun checkEnteredPin() { private fun checkEnteredPin() {
val enteredPin = binding!!.pinTextField.editText?.text.toString() val enteredPin = binding.pinTextField.editText?.text.toString()
if (enteredPin.length in 4..12) { if (enteredPin.length in 4..12) {
viewModel.setUserPin(enteredPin) viewModel.setUserPin(enteredPin)
if (args.saving) { if (args.saving) {
@@ -152,6 +152,6 @@ class PinFragment : Fragment() {
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
binding = null _binding = null
} }
} }

View File

@@ -24,7 +24,8 @@ class ResultFragment : Fragment() {
private val paramsModel: ParametersViewModel by activityViewModels() private val paramsModel: ParametersViewModel by activityViewModels()
private var binding: FragmentResultBinding? = null private var _binding: FragmentResultBinding? = null
private val binding get() = _binding!!
private val args: ResultFragmentArgs by navArgs() private val args: ResultFragmentArgs by navArgs()
@@ -33,8 +34,8 @@ class ResultFragment : Fragment() {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
binding = FragmentResultBinding.inflate(inflater, container, false) _binding = FragmentResultBinding.inflate(inflater, container, false)
return binding!!.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -86,7 +87,7 @@ class ResultFragment : Fragment() {
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
binding = null _binding = null
} }
} }

View File

@@ -20,33 +20,34 @@ class UserFragment : Fragment() {
private val viewModel: SmartCardViewModel by activityViewModels() private val viewModel: SmartCardViewModel by activityViewModels()
private var binding: FragmentUserBinding? = null private var _binding: FragmentUserBinding? = null
private val binding get() = _binding!!
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
binding = FragmentUserBinding.inflate(inflater, container, false) _binding = FragmentUserBinding.inflate(inflater, container, false)
return binding!!.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
displayInformation() displayInformation()
binding!!.clearButton.setOnClickListener { goToTheStart() } binding.clearButton.setOnClickListener { goToTheStart() }
} }
/** /**
* Assigns text values to the fields in order to display user information. * Assigns text values to the fields in order to display user information.
*/ */
private fun displayInformation() { private fun displayInformation() {
binding!!.userName.text = binding.userName.text =
getString(R.string.user_name, viewModel.userFirstName, viewModel.userLastName) getString(R.string.user_name, viewModel.userFirstName, viewModel.userLastName)
binding!!.identificationNumber.text = viewModel.userIdentificationNumber binding.identificationNumber.text = viewModel.userIdentificationNumber
binding!!.gender.text = viewModel.gender binding.gender.text = viewModel.gender
binding!!.expiration.text = viewModel.expiration.replace(" ", "/") binding.expiration.text = viewModel.expiration.replace(" ", "/")
binding!!.citizenship.text = viewModel.citizenship binding.citizenship.text = viewModel.citizenship
} }
/** /**
@@ -59,6 +60,6 @@ class UserFragment : Fragment() {
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
binding = null _binding = null
} }
} }

View File

@@ -25,7 +25,8 @@ class SettingsFragment : Fragment() {
private val viewModel: SmartCardViewModel by activityViewModels() private val viewModel: SmartCardViewModel by activityViewModels()
private var binding: FragmentSettingsBinding? = null private var _binding: FragmentSettingsBinding? = null
private val binding get() = _binding!!
private var showPin: Boolean = false private var showPin: Boolean = false
@@ -34,8 +35,8 @@ class SettingsFragment : Fragment() {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
binding = FragmentSettingsBinding.inflate(inflater, container, false) _binding = FragmentSettingsBinding.inflate(inflater, container, false)
return binding!!.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -43,10 +44,10 @@ class SettingsFragment : Fragment() {
showCanField() showCanField()
showPinField() showPinField()
togglePinButton() togglePinButton()
binding!!.canMenuAction.setOnClickListener { canAction() } binding.canMenuAction.setOnClickListener { canAction() }
binding!!.pinMenuAction.setOnClickListener { pinAction() } binding.pinMenuAction.setOnClickListener { pinAction() }
binding!!.pinMenuShow.setOnClickListener { togglePin() } binding.pinMenuShow.setOnClickListener { togglePin() }
binding!!.returnButton.setOnClickListener { backToHome() } binding.returnButton.setOnClickListener { backToHome() }
} }
/** /**
@@ -64,11 +65,11 @@ class SettingsFragment : Fragment() {
*/ */
private fun showCanField() { private fun showCanField() {
if (viewModel.userCan.length == 6) { if (viewModel.userCan.length == 6) {
binding!!.canSaved.text = getString(R.string.saved_can, viewModel.userCan) binding.canSaved.text = getString(R.string.saved_can, viewModel.userCan)
binding!!.canMenuAction.text = getString(R.string.can_delete) binding.canMenuAction.text = getString(R.string.can_delete)
} else { } else {
binding!!.canSaved.text = getString(R.string.saved_can, getString(R.string.missing)) binding.canSaved.text = getString(R.string.saved_can, getString(R.string.missing))
binding!!.canMenuAction.text = getString(R.string.add_can_text) binding.canMenuAction.text = getString(R.string.add_can_text)
} }
} }
@@ -95,16 +96,16 @@ class SettingsFragment : Fragment() {
*/ */
private fun showPinField() { private fun showPinField() {
if (viewModel.userPin.length in 4..12) { if (viewModel.userPin.length in 4..12) {
binding!!.pinMenuShow.visibility = Button.VISIBLE binding.pinMenuShow.visibility = Button.VISIBLE
if (showPin) if (showPin)
binding!!.pinSaved.text = getString(R.string.saved_pin, viewModel.userPin) binding.pinSaved.text = getString(R.string.saved_pin, viewModel.userPin)
else else
binding!!.pinSaved.text = getString(R.string.saved_pin, getString(R.string.hidden_pin)) binding.pinSaved.text = getString(R.string.saved_pin, getString(R.string.hidden_pin))
binding!!.pinMenuAction.text = getString(R.string.pin1_delete) binding.pinMenuAction.text = getString(R.string.pin1_delete)
} else { } else {
binding!!.pinMenuShow.visibility = Button.GONE binding.pinMenuShow.visibility = Button.GONE
binding!!.pinSaved.text = getString(R.string.saved_pin, getString(R.string.missing)) binding.pinSaved.text = getString(R.string.saved_pin, getString(R.string.missing))
binding!!.pinMenuAction.text = getString(R.string.pin1_add) binding.pinMenuAction.text = getString(R.string.pin1_add)
} }
} }
@@ -138,9 +139,9 @@ class SettingsFragment : Fragment() {
*/ */
private fun togglePinButton() { private fun togglePinButton() {
if (showPin) { if (showPin) {
binding!!.pinMenuShow.text = getString(R.string.hide) binding.pinMenuShow.text = getString(R.string.hide)
} else { } else {
binding!!.pinMenuShow.text = getString(R.string.show) binding.pinMenuShow.text = getString(R.string.show)
} }
} }
@@ -154,7 +155,7 @@ class SettingsFragment : Fragment() {
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
binding = null _binding = null
} }
} }

View File

@@ -16,6 +16,9 @@ class ParametersViewModel: ViewModel() {
private var _origin: String = "" private var _origin: String = ""
val origin get() = _origin val origin get() = _origin
private var _headers: String = ""
val headers get() =_headers
fun setChallenge(newChallenge: String) { fun setChallenge(newChallenge: String) {
_challenge = newChallenge _challenge = newChallenge
} }
@@ -31,4 +34,8 @@ class ParametersViewModel: ViewModel() {
fun setOrigin(newOrigin: String) { fun setOrigin(newOrigin: String) {
_origin = newOrigin _origin = newOrigin
} }
fun setHeaders(newHeaders: String) {
_headers = newHeaders
}
} }

View File

@@ -29,7 +29,11 @@
<string name="help_text">HELP</string> <string name="help_text">HELP</string>
<string name="can_question">What is CAN?</string> <string name="can_question">What is CAN?</string>
<string name="can_explanation">CAN is a 6 digit code that is needed to communicate with an ID card. It can be found on the ID card under the card holder\'s picture with a title KASUTAJA ALLKIRI/HOLDER\'S SIGNATURE.</string> <string name="can_explanation">CAN is a 6 digit code that is needed to communicate with an ID card. It can be found on the ID card under the card holder\'s picture with a title KASUTAJA ALLKIRI/HOLDER\'S SIGNATURE.</string>
<string name="problem_parameters">Problem with parameters</string>
<string name="problem_challenge">Challenge is missing</string>
<string name="problem_authurl">AuthUrl is missing</string>
<string name="problem_originurl">OriginUrl is missing</string>
<string name="problem_other">Unspecified problem with parameters</string>
<!-- string resources for PinFragment --> <!-- string resources for PinFragment -->
<string name="pin_view">Please enter PIN 1</string> <string name="pin_view">Please enter PIN 1</string>
<string name="hint_pin">PIN 1</string> <string name="hint_pin">PIN 1</string>

View File

@@ -28,7 +28,11 @@
<string name="help_text">INFO</string> <string name="help_text">INFO</string>
<string name="can_question">Mis on CAN?</string> <string name="can_question">Mis on CAN?</string>
<string name="can_explanation">CAN on 6 kohaline numbritest koosnev kood, mida on vaja ID kaardiga suhtlemiseks. CAN-i leiab ID kaardilt omaniku pildi alt pealkirjaga KASUTAJA ALLKIRI/HOLDER\'S SIGNATURE.</string> <string name="can_explanation">CAN on 6 kohaline numbritest koosnev kood, mida on vaja ID kaardiga suhtlemiseks. CAN-i leiab ID kaardilt omaniku pildi alt pealkirjaga KASUTAJA ALLKIRI/HOLDER\'S SIGNATURE.</string>
<string name="problem_parameters">Probleem parameetritega</string>
<string name="problem_challenge">Puudub challenge parameeter</string>
<string name="problem_authurl">Puudub AuthUrl parameeter</string>
<string name="problem_originurl">Puudub OriginUrl parameeter</string>
<string name="problem_other">Täpsustamata probleem parameetritega</string>
<!-- string resources for PinFragment --> <!-- string resources for PinFragment -->
<string name="pin_view">Palun sisesta PIN 1</string> <string name="pin_view">Palun sisesta PIN 1</string>
<string name="hint_pin">PIN 1</string> <string name="hint_pin">PIN 1</string>

View File

@@ -27,7 +27,11 @@
<string name="help_text">HELP</string> <string name="help_text">HELP</string>
<string name="can_question">What is CAN?</string> <string name="can_question">What is CAN?</string>
<string name="can_explanation">CAN is a 6 digit code that is needed to communicate with an ID card. It can be found on the ID card under the card holder\'s picture with a title KASUTAJA ALLKIRI/HOLDER\'S SIGNATURE.</string> <string name="can_explanation">CAN is a 6 digit code that is needed to communicate with an ID card. It can be found on the ID card under the card holder\'s picture with a title KASUTAJA ALLKIRI/HOLDER\'S SIGNATURE.</string>
<string name="problem_parameters">Problem with parameters</string>
<string name="problem_challenge">Challenge is missing</string>
<string name="problem_authurl">AuthUrl is missing</string>
<string name="problem_originurl">OriginUrl is missing</string>
<string name="problem_other">Unspecified problem with parameters</string>
<!-- string resources for PinFragment --> <!-- string resources for PinFragment -->
<string name="pin_view">Please enter PIN 1</string> <string name="pin_view">Please enter PIN 1</string>
<string name="hint_pin">PIN 1</string> <string name="hint_pin">PIN 1</string>

View File

@@ -9,9 +9,9 @@ import android.view.View
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import com.example.testmobileapp.databinding.ActivityMainBinding import com.example.testmobileapp.databinding.ActivityMainBinding
import com.google.gson.JsonObject
import com.koushikdutta.ion.Ion import com.koushikdutta.ion.Ion
import org.json.JSONObject import org.json.JSONObject
import java.net.URL
/** /**
* Base url where the requests should be made. Add yours here. It must use https. * Base url where the requests should be made. Add yours here. It must use https.
@@ -32,12 +32,11 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
Log.i("myLoggingStuff", URL("https://www.google.ee/?hl=et").host.toString())
authLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { response -> authLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { response ->
if (response.resultCode == Activity.RESULT_OK) { if (response.resultCode == Activity.RESULT_OK) {
// Currently we are not actually checking whether we get a valid token.
// For testing purposes only, to make sure that we are able to get a response at all.
binding.loginTextView.text = getString(R.string.auth_success) binding.loginTextView.text = getString(R.string.auth_success)
// Logs are used to show what information can be retrieved from the mobileauthapp.
Log.i("getResult", response.data?.getStringExtra("token").toString()) Log.i("getResult", response.data?.getStringExtra("token").toString())
Log.i("getResult", response.data?.getStringExtra("result").toString()) Log.i("getResult", response.data?.getStringExtra("result").toString())
var user = "" var user = ""
@@ -48,14 +47,6 @@ class MainActivity : AppCompatActivity() {
Log.i("getResult", "unable to retrieve name from principal") Log.i("getResult", "unable to retrieve name from principal")
} }
showResult(user) showResult(user)
/*
binding.loginOptionNfcButton.text = "Log Out"
binding.loginOptionNfcButton.setOnClickListener {
binding.loginOptionNfcButton.text = "NFC auth"
binding.loginOptionNfcButton.setOnClickListener { getData() }
}
*/
} }
if (response.resultCode == Activity.RESULT_CANCELED) { if (response.resultCode == Activity.RESULT_CANCELED) {
binding.loginTextView.text = getString(R.string.auth_failure) binding.loginTextView.text = getString(R.string.auth_failure)
@@ -114,6 +105,7 @@ class MainActivity : AppCompatActivity() {
binding.resultLayout.visibility = View.VISIBLE binding.resultLayout.visibility = View.VISIBLE
binding.resultObject.text = getString(R.string.hello, user) binding.resultObject.text = getString(R.string.hello, user)
binding.buttonForget.setOnClickListener { binding.buttonForget.setOnClickListener {
binding.loginTextView.text = getString(R.string.login_text)
binding.resultObject.text = "" binding.resultObject.text = ""
binding.resultLayout.visibility = View.GONE binding.resultLayout.visibility = View.GONE
binding.loginOptions.visibility = View.VISIBLE binding.loginOptions.visibility = View.VISIBLE