Add basic REST communication. Initial minimum viable product.

This commit is contained in:
femsci 2023-03-03 23:48:17 +01:00
parent 40962c9097
commit 5f04c74daa
Signed by: femsci
GPG key ID: 08F7911F0E650C67
7 changed files with 131 additions and 27 deletions

7
.idea/vcs.xml Normal file
View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$USER_HOME$/Documents/Dev/java/automfa" vcs="Git" />
</component>
</project>

View file

@ -16,6 +16,7 @@
android:label="@string/app_name" android:label="@string/app_name"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.AutoMFA" android:theme="@style/Theme.AutoMFA"
android:usesCleartextTraffic="true"
tools:targetApi="31"> tools:targetApi="31">
<receiver android:name="net.femsci.automfa.SmsReceiver" android:exported="true" <receiver android:name="net.femsci.automfa.SmsReceiver" android:exported="true"
android:permission="android.permission.BROADCAST_SMS"> android:permission="android.permission.BROADCAST_SMS">
@ -27,7 +28,6 @@
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.AutoMFA.NoActionBar"> android:theme="@style/Theme.AutoMFA.NoActionBar">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View file

@ -1,24 +1,91 @@
package net.femsci.automfa package net.femsci.automfa
import android.util.JsonWriter
import java.io.OutputStreamWriter
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.URI
import java.net.URL import java.net.URL
import java.util.concurrent.Executors
import java.util.concurrent.FutureTask
import java.util.concurrent.TimeUnit
class AutoMFAGateway { class AutoMFAGateway {
companion object { companion object {
lateinit var url: URL lateinit var uri: URI
var connected: Boolean = false
private fun createClient(path: String, post: Boolean): HttpURLConnection {
val url = URL("${uri.scheme}://${uri.authority}$path")
val http = url.openConnection() as HttpURLConnection
if(post) {
http.requestMethod = "POST"
http.doOutput = true
} else {
http.requestMethod = "GET"
}
http.setRequestProperty("User-Agent", "AutoMFA v1.0.0E")
http.setRequestProperty("Content-Type", "application/json")
http.setRequestProperty("Accept", "application/json")
return http
}
fun connect(addr: String): Boolean fun connect(addr: String): Boolean
{ {
return try { val task = FutureTask {
url = URL(addr) try {
println("url: $url") uri = URI(addr)
val http = url.openConnection() as HttpURLConnection val http = createClient("/ping", false)
http.requestMethod = "GET"
println("r: ${http.responseCode}") println("r: ${http.responseCode}")
http.responseCode == 200 http.responseCode == 200
} catch(e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
false
}
}
val exe = Executors.newCachedThreadPool()
exe.submit(task)
return try {
val result = task.get(5, TimeUnit.SECONDS)
connected = result
result
} catch(_: Exception) {
connected = false
return false
}
}
fun publish(message: MessageModel): Boolean
{
val task = FutureTask {
try {
val http = createClient("/data/publish", true)
val out = http.outputStream
val writer = OutputStreamWriter(out, "UTF-8")
val json = JsonWriter(writer)
json.beginObject().name("MessageRaw").value(message.messageRaw).name("Timestamp").value(message.timestamp).endObject().toString()
json.flush()
println("r: ${http.responseCode}")
http.responseCode == 200
} catch (e: Exception) {
e.printStackTrace()
false
}
}
val exe = Executors.newCachedThreadPool()
exe.submit(task)
return try {
task.get(5, TimeUnit.SECONDS)
} catch(_: Exception)
{
false false
} }
} }

View file

@ -6,9 +6,9 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.addTextChangedListener
import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.AppBarConfiguration
import net.femsci.automfa.databinding.ActivityMainBinding import net.femsci.automfa.databinding.ActivityMainBinding
import java.time.Instant
class MainActivity : AppCompatActivity(), MessageListener { class MainActivity : AppCompatActivity(), MessageListener {
@ -22,14 +22,14 @@ class MainActivity : AppCompatActivity(), MessageListener {
setContentView(binding.root) setContentView(binding.root)
binding.btnServer.setOnClickListener { binding.btnServer.setOnClickListener {
val addr = binding.srvAddr.text.toString(); val addr = binding.srvAddr.text.toString()
if (AutoMFAGateway.connect(addr)) { if (AutoMFAGateway.connect(addr)) {
binding.txtStatus.setTextColor(Color.GREEN); binding.txtStatus.setTextColor(Color.GREEN)
binding.txtStatus.text = "Connection established." binding.txtStatus.text = "Connection established."
} else { } else {
binding.txtStatus.setTextColor(Color.RED); binding.txtStatus.setTextColor(Color.RED)
binding.txtStatus.text = "Connection failed..." binding.txtStatus.text = "Connection failed..."
} }
} }
@ -54,5 +54,8 @@ class MainActivity : AppCompatActivity(), MessageListener {
override fun messageReceived(msg: String) { override fun messageReceived(msg: String) {
Toast.makeText(this, "New msg: $msg", Toast.LENGTH_SHORT).show() Toast.makeText(this, "New msg: $msg", Toast.LENGTH_SHORT).show()
if (AutoMFAGateway.connected) {
AutoMFAGateway.publish(MessageModel(Instant.now().toEpochMilli(), msg))
}
} }
} }

View file

@ -0,0 +1,3 @@
package net.femsci.automfa
data class MessageModel(val timestamp: Long, val messageRaw: String)

View file

@ -12,24 +12,48 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<EditText
android:id="@+id/srvAddr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="Address" />
<TextView <TextView
android:id="@+id/txtStatus" android:id="@+id/txtStatus"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<TextView
android:id="@+id/addrLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Address:"
android:labelFor="@id/srvAddr"/>
<EditText
android:id="@+id/srvAddr"
android:layout_width="match_parent"
android:layout_height="55dp"
android:ems="10"
android:inputType="textPersonName"
android:text="http://10.0.0.40:8080" />
<Button <Button
android:id="@+id/btnServer" android:id="@+id/btnServer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Set server" /> android:text="Set server" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/listLogs"
android:layout_width="match_parent"
android:layout_height="590dp" />
</LinearLayout>
</ScrollView>
</LinearLayout> </LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -1,6 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id 'com.android.application' version '7.4.0' apply false id 'com.android.application' version '7.4.2' apply false
id 'com.android.library' version '7.4.0' apply false id 'com.android.library' version '7.4.2' apply false
id 'org.jetbrains.kotlin.android' version '1.7.21' apply false id 'org.jetbrains.kotlin.android' version '1.7.21' apply false
} }