mirror of
https://codeberg.org/NextPush/nextpush-android.git
synced 2025-01-01 04:27:26 +01:00
Add (un)registration features
This commit is contained in:
parent
993ffaf8f9
commit
0ed93a9228
@ -16,6 +16,7 @@ private const val TAG = "AccountUtils"
|
||||
|
||||
const val PREF_NAME = "NextPush"
|
||||
const val PREF_DEVICE_ID = "deviceId"
|
||||
const val PREF_URL = "url"
|
||||
|
||||
lateinit var ssoAccount: SingleSignOnAccount
|
||||
|
||||
@ -59,3 +60,22 @@ fun removeDeviceId(context: Context) {
|
||||
.remove(PREF_DEVICE_ID)
|
||||
.commit()
|
||||
}
|
||||
|
||||
fun saveUrl(context: Context, url: String) {
|
||||
context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.putString(PREF_URL, url)
|
||||
.commit()
|
||||
}
|
||||
|
||||
fun getUrl(context: Context) : String? {
|
||||
return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
||||
.getString(PREF_URL,null)
|
||||
}
|
||||
|
||||
fun removeUrl(context: Context) {
|
||||
context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.remove(PREF_URL)
|
||||
.commit()
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ import org.unifiedpush.distributor.nextpush.distributor.sendUnregistered
|
||||
import org.unifiedpush.distributor.nextpush.distributor.MessagingDatabase
|
||||
import java.lang.String.format
|
||||
|
||||
const val TAG = "NextPush-MainActivity"
|
||||
private const val TAG = "NextPush-MainActivity"
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
@ -203,10 +203,15 @@ class MainActivity : AppCompatActivity() {
|
||||
alert.setTitle("Unregistering")
|
||||
alert.setMessage("Are you sure to unregister ${appList[position]} ?")
|
||||
alert.setPositiveButton("YES") { dialog, _ ->
|
||||
sendUnregistered(this, tokenList[position])
|
||||
val connectorToken = tokenList[position]
|
||||
sendUnregistered(this, connectorToken)
|
||||
val db = MessagingDatabase(this)
|
||||
db.unregisterApp(tokenList[position])
|
||||
val appToken = db.getAppToken(connectorToken)
|
||||
db.unregisterApp(connectorToken)
|
||||
db.close()
|
||||
ApiUtils().deleteApp(this, appToken) {
|
||||
Log.d(TAG,"Unregistration is finished")
|
||||
}
|
||||
tokenList.removeAt(position)
|
||||
appList.removeAt(position)
|
||||
dialog.dismiss()
|
||||
|
@ -40,7 +40,7 @@ class SettingsActivity : AppCompatActivity() {
|
||||
val tokenList = db.listTokens()
|
||||
db.close()
|
||||
tokenList.forEach {
|
||||
sendEndpoint(this, it, getEndpoint(this, it))
|
||||
sendEndpoint(this, it)
|
||||
}
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
startActivity(intent)
|
||||
|
@ -12,11 +12,9 @@ import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.sse.EventSource
|
||||
import okhttp3.sse.EventSources
|
||||
import org.unifiedpush.distributor.nextpush.account.getDeviceId
|
||||
import org.unifiedpush.distributor.nextpush.account.removeDeviceId
|
||||
import org.unifiedpush.distributor.nextpush.account.saveDeviceId
|
||||
import org.unifiedpush.distributor.nextpush.account.ssoAccount
|
||||
import org.unifiedpush.distributor.nextpush.account.*
|
||||
import org.unifiedpush.distributor.nextpush.api.ProviderApi.Companion.mApiEndpoint
|
||||
import org.unifiedpush.distributor.nextpush.distributor.MessagingDatabase
|
||||
import org.unifiedpush.distributor.nextpush.services.SSEListener
|
||||
import retrofit2.NextcloudRetrofitApiBuilder
|
||||
import java.util.concurrent.TimeUnit
|
||||
@ -83,6 +81,7 @@ class ApiUtils {
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
saveUrl(context, "${ssoAccount.url}${mApiEndpoint}")
|
||||
// Sync once it is registered
|
||||
cSync(deviceId!!)
|
||||
Log.d(TAG, "mApi register: onComplete")
|
||||
@ -131,7 +130,7 @@ class ApiUtils {
|
||||
if (response.success) {
|
||||
Log.d(TAG, "Device successfully deleted.")
|
||||
} else {
|
||||
Log.d(TAG, "An error occurred while deleting the device registration.")
|
||||
Log.d(TAG, "An error occurred while deleting the device.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,24 +139,98 @@ class ApiUtils {
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
removeUrl(context)
|
||||
}
|
||||
})
|
||||
removeDeviceId(context)
|
||||
}
|
||||
|
||||
fun createApp(context: Context) {
|
||||
cApi(context) { cCreateApp(context) }
|
||||
fun createApp(context: Context,
|
||||
appName: String,
|
||||
connectorToken: String,
|
||||
callback: ()->Unit) {
|
||||
cApi(context) {
|
||||
cCreateApp(context, appName, connectorToken) {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun cCreateApp(context: Context) {
|
||||
private fun cCreateApp(context: Context,
|
||||
appName: String,
|
||||
connectorToken: String,
|
||||
callback: ()->Unit) {
|
||||
val db = MessagingDatabase(context)
|
||||
if (db.isRegistered(appName, connectorToken)) {
|
||||
Log.i("RegisterService","$appName already registered")
|
||||
db.close()
|
||||
callback()
|
||||
return
|
||||
}
|
||||
val parameters = mutableMapOf(
|
||||
"deviceId" to getDeviceId(context)!!,
|
||||
"appName" to appName
|
||||
)
|
||||
mApi.createApp(parameters)
|
||||
?.subscribeOn(Schedulers.newThread())
|
||||
?.observeOn(Schedulers.newThread())
|
||||
?.subscribe(object : Observer<ApiResponse?> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
Log.d(TAG, "Subscribed to createApp.")
|
||||
}
|
||||
|
||||
override fun onNext(response: ApiResponse) {
|
||||
if (response.success) {
|
||||
Log.d(TAG, "App successfully created.")
|
||||
db.registerApp(appName, connectorToken, response.token)
|
||||
} else {
|
||||
Log.d(TAG, "An error occurred while creating the application.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
db.close()
|
||||
callback()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun deleteApp(context: Context) {
|
||||
cApi(context) { cDeleteApp(context) }
|
||||
fun deleteApp(context: Context, appToken: String, callback: ()->Unit) {
|
||||
cApi(context) {
|
||||
cDeleteApp(appToken) {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun cDeleteApp(context: Context) {
|
||||
private fun cDeleteApp(appToken: String, callback: ()->Unit) {
|
||||
mApi.deleteApp(appToken)
|
||||
?.subscribeOn(Schedulers.newThread())
|
||||
?.observeOn(Schedulers.newThread())
|
||||
?.subscribe(object : Observer<ApiResponse?> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
Log.d(TAG, "Subscribed to deleteApp.")
|
||||
}
|
||||
|
||||
override fun onNext(response: ApiResponse) {
|
||||
if (response.success) {
|
||||
Log.d(TAG, "App successfully deleted.")
|
||||
} else {
|
||||
Log.d(TAG, "An error occurred while deleting the application.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
callback()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -3,11 +3,14 @@ package org.unifiedpush.distributor.nextpush.distributor
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import org.unifiedpush.distributor.nextpush.account.getUrl
|
||||
|
||||
/**
|
||||
* These functions are used to send messages to other apps
|
||||
*/
|
||||
|
||||
private const val TAG = "DistributorUtils"
|
||||
|
||||
fun sendMessage(context: Context, token: String, message: String){
|
||||
val application = getApp(context, token)
|
||||
if (application.isNullOrBlank()) {
|
||||
@ -21,46 +24,46 @@ fun sendMessage(context: Context, token: String, message: String){
|
||||
context.sendBroadcast(broadcastIntent)
|
||||
}
|
||||
|
||||
fun sendEndpoint(context: Context, token: String, endpoint: String) {
|
||||
val application = getApp(context, token)
|
||||
fun sendEndpoint(context: Context, connectorToken: String) {
|
||||
val application = getApp(context, connectorToken)
|
||||
if (application.isNullOrBlank()) {
|
||||
return
|
||||
}
|
||||
val broadcastIntent = Intent()
|
||||
broadcastIntent.`package` = application
|
||||
broadcastIntent.action = ACTION_NEW_ENDPOINT
|
||||
broadcastIntent.putExtra(EXTRA_TOKEN, token)
|
||||
broadcastIntent.putExtra(EXTRA_ENDPOINT, endpoint)
|
||||
broadcastIntent.putExtra(EXTRA_TOKEN, connectorToken)
|
||||
broadcastIntent.putExtra(EXTRA_ENDPOINT, getEndpoint(context, connectorToken))
|
||||
context.sendBroadcast(broadcastIntent)
|
||||
}
|
||||
|
||||
fun sendUnregistered(context: Context, token: String) {
|
||||
val application = getApp(context, token)
|
||||
fun sendUnregistered(context: Context, connectorToken: String) {
|
||||
val application = getApp(context, connectorToken)
|
||||
if (application.isNullOrBlank()) {
|
||||
return
|
||||
}
|
||||
val broadcastIntent = Intent()
|
||||
broadcastIntent.`package` = application
|
||||
broadcastIntent.action = ACTION_UNREGISTERED
|
||||
broadcastIntent.putExtra(EXTRA_TOKEN, token)
|
||||
broadcastIntent.putExtra(EXTRA_TOKEN, connectorToken)
|
||||
context.sendBroadcast(broadcastIntent)
|
||||
}
|
||||
|
||||
fun getApp(context: Context, token: String): String?{
|
||||
fun getApp(context: Context, connectorToken: String): String?{
|
||||
val db = MessagingDatabase(context)
|
||||
val app = db.getPackageName(token)
|
||||
val app = db.getPackageName(connectorToken)
|
||||
db.close()
|
||||
return if (app.isBlank()) {
|
||||
Log.w("notifyClient", "No app found for $token")
|
||||
Log.w(TAG, "No app found for $connectorToken")
|
||||
null
|
||||
} else {
|
||||
app
|
||||
}
|
||||
}
|
||||
|
||||
fun getEndpoint(context: Context, appToken: String): String {
|
||||
val settings = context.getSharedPreferences("Config", Context.MODE_PRIVATE)
|
||||
val address = settings?.getString("address","")
|
||||
return settings?.getString("proxy","") +
|
||||
"/foo/$appToken/"
|
||||
fun getEndpoint(context: Context, connectorToken: String): String {
|
||||
val db = MessagingDatabase(context)
|
||||
val appToken = db.getAppToken(connectorToken)
|
||||
db.close()
|
||||
return "${getUrl(context)}/push/$appToken"
|
||||
}
|
@ -10,13 +10,16 @@ private const val DB_VERSION = 1
|
||||
|
||||
class MessagingDatabase(context: Context):
|
||||
SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {
|
||||
private val CREATE_TABLE_APPS = "CREATE TABLE apps (" +
|
||||
"package_name TEXT," +
|
||||
"token TEXT," +
|
||||
"PRIMARY KEY (token));"
|
||||
private val TABLE_APPS = "apps"
|
||||
private val FIELD_PACKAGE_NAME = "package_name"
|
||||
private val FIELD_TOKEN = "token"
|
||||
private val FIELD_PACKAGE_NAME = "packageName"
|
||||
private val FIELD_CONNECTOR_TOKEN = "connectorToken"
|
||||
private val FIELD_APP_TOKEN = "appToken"
|
||||
private val CREATE_TABLE_APPS = "CREATE TABLE apps (" +
|
||||
"$FIELD_PACKAGE_NAME TEXT," +
|
||||
"$FIELD_CONNECTOR_TOKEN TEXT," +
|
||||
"$FIELD_APP_TOKEN TEXT," +
|
||||
"PRIMARY KEY ($FIELD_CONNECTOR_TOKEN));"
|
||||
|
||||
|
||||
override fun onCreate(db: SQLiteDatabase) {
|
||||
db.execSQL(CREATE_TABLE_APPS)
|
||||
@ -26,26 +29,27 @@ class MessagingDatabase(context: Context):
|
||||
throw IllegalStateException("Upgrades not supported")
|
||||
}
|
||||
|
||||
fun registerApp(packageName: String, token: String) {
|
||||
fun registerApp(packageName: String, connectorToken: String, appToken: String) {
|
||||
val db = writableDatabase
|
||||
val values = ContentValues().apply {
|
||||
put(FIELD_PACKAGE_NAME, packageName)
|
||||
put(FIELD_TOKEN, token)
|
||||
put(FIELD_CONNECTOR_TOKEN, connectorToken)
|
||||
put(FIELD_APP_TOKEN, appToken)
|
||||
}
|
||||
db.insert(TABLE_APPS, null, values)
|
||||
}
|
||||
|
||||
fun unregisterApp(token: String) {
|
||||
fun unregisterApp(connectorToken: String) {
|
||||
val db = writableDatabase
|
||||
val selection = "$FIELD_TOKEN = ?"
|
||||
val selectionArgs = arrayOf(token)
|
||||
val selection = "$FIELD_CONNECTOR_TOKEN = ?"
|
||||
val selectionArgs = arrayOf(connectorToken)
|
||||
db.delete(TABLE_APPS, selection, selectionArgs)
|
||||
}
|
||||
|
||||
fun isRegistered(packageName: String, token: String): Boolean {
|
||||
fun isRegistered(packageName: String, connectorToken: String): Boolean {
|
||||
val db = readableDatabase
|
||||
val selection = "$FIELD_PACKAGE_NAME = ? AND $FIELD_TOKEN = ?"
|
||||
val selectionArgs = arrayOf(packageName, token)
|
||||
val selection = "$FIELD_PACKAGE_NAME = ? AND $FIELD_CONNECTOR_TOKEN = ?"
|
||||
val selectionArgs = arrayOf(packageName, connectorToken)
|
||||
return db.query(
|
||||
TABLE_APPS,
|
||||
null,
|
||||
@ -59,11 +63,11 @@ class MessagingDatabase(context: Context):
|
||||
}
|
||||
}
|
||||
|
||||
fun getPackageName(token: String): String {
|
||||
fun getPackageName(connectorToken: String): String {
|
||||
val db = readableDatabase
|
||||
val projection = arrayOf(FIELD_PACKAGE_NAME)
|
||||
val selection = "$FIELD_TOKEN = ?"
|
||||
val selectionArgs = arrayOf(token)
|
||||
val selection = "$FIELD_CONNECTOR_TOKEN = ?"
|
||||
val selectionArgs = arrayOf(connectorToken)
|
||||
return db.query(
|
||||
TABLE_APPS,
|
||||
projection,
|
||||
@ -78,9 +82,28 @@ class MessagingDatabase(context: Context):
|
||||
}
|
||||
}
|
||||
|
||||
fun getAppToken(connectorToken: String): String {
|
||||
val db = readableDatabase
|
||||
val projection = arrayOf(FIELD_APP_TOKEN)
|
||||
val selection = "$FIELD_CONNECTOR_TOKEN = ?"
|
||||
val selectionArgs = arrayOf(connectorToken)
|
||||
return db.query(
|
||||
TABLE_APPS,
|
||||
projection,
|
||||
selection,
|
||||
selectionArgs,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
).use { cursor ->
|
||||
val column = cursor.getColumnIndex(FIELD_APP_TOKEN)
|
||||
if (cursor.moveToFirst() && column >= 0) cursor.getString(column) else ""
|
||||
}
|
||||
}
|
||||
|
||||
fun listTokens(): List<String> {
|
||||
val db = readableDatabase
|
||||
val projection = arrayOf(FIELD_TOKEN)
|
||||
val projection = arrayOf(FIELD_CONNECTOR_TOKEN)
|
||||
return db.query(
|
||||
TABLE_APPS,
|
||||
projection,
|
||||
@ -92,7 +115,7 @@ class MessagingDatabase(context: Context):
|
||||
).use{ cursor ->
|
||||
generateSequence { if (cursor.moveToNext()) cursor else null }
|
||||
.mapNotNull{
|
||||
val column = cursor.getColumnIndex(FIELD_TOKEN)
|
||||
val column = cursor.getColumnIndex(FIELD_CONNECTOR_TOKEN)
|
||||
if (column >= 0) it.getString(column) else null }
|
||||
.toList()
|
||||
}
|
||||
|
@ -5,60 +5,45 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import org.unifiedpush.distributor.nextpush.distributor.*
|
||||
import kotlin.concurrent.thread
|
||||
import org.unifiedpush.distributor.nextpush.api.ApiUtils
|
||||
|
||||
/**
|
||||
* THIS SERVICE IS USED BY OTHER APPS TO REGISTER
|
||||
*/
|
||||
|
||||
private const val TAG = "RegisterBroadcastReceiver"
|
||||
|
||||
class RegisterBroadcastReceiver : BroadcastReceiver() {
|
||||
|
||||
private fun unregisterApp(db: MessagingDatabase, application: String, token: String) {
|
||||
Log.i("RegisterService","Unregistering $application token: $token")
|
||||
db.unregisterApp(token)
|
||||
}
|
||||
|
||||
private fun registerApp(context: Context?, db: MessagingDatabase, application: String, token: String) {
|
||||
if (application.isBlank()) {
|
||||
Log.w("RegisterService","Trying to register an app without packageName")
|
||||
return
|
||||
}
|
||||
Log.i("RegisterService","registering $application token: $token")
|
||||
// The app is registered with the same token : we re-register it
|
||||
// the client may need its endpoint again
|
||||
if (db.isRegistered(application, token)) {
|
||||
Log.i("RegisterService","$application already registered")
|
||||
return
|
||||
}
|
||||
|
||||
db.registerApp(application, token)
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
when (intent!!.action) {
|
||||
ACTION_REGISTER ->{
|
||||
Log.i("Register","REGISTER")
|
||||
val token = intent.getStringExtra(EXTRA_TOKEN)?: ""
|
||||
Log.i(TAG,"REGISTER")
|
||||
val connectorToken = intent.getStringExtra(EXTRA_TOKEN)?: ""
|
||||
val application = intent.getStringExtra(EXTRA_APPLICATION)?: ""
|
||||
thread(start = true) {
|
||||
val db = MessagingDatabase(context!!)
|
||||
registerApp(context, db, application, token)
|
||||
db.close()
|
||||
Log.i("RegisterService","Registration is finished")
|
||||
}.join()
|
||||
sendEndpoint(context!!, token, getEndpoint(context, token))
|
||||
if (application.isBlank()) {
|
||||
Log.w(TAG,"Trying to register an app without packageName")
|
||||
return
|
||||
}
|
||||
ApiUtils().createApp(context!!.applicationContext, application, connectorToken) {
|
||||
sendEndpoint(context.applicationContext, connectorToken)
|
||||
}
|
||||
}
|
||||
ACTION_UNREGISTER ->{
|
||||
Log.i("Register","UNREGISTER")
|
||||
val token = intent.getStringExtra(EXTRA_TOKEN)?: ""
|
||||
val application = intent.getStringExtra(EXTRA_APPLICATION)?: ""
|
||||
thread(start = true) {
|
||||
val db = MessagingDatabase(context!!)
|
||||
unregisterApp(db,application, token)
|
||||
db.close()
|
||||
Log.i("RegisterService","Unregistration is finished")
|
||||
Log.i(TAG,"UNREGISTER")
|
||||
val connectorToken = intent.getStringExtra(EXTRA_TOKEN)?: ""
|
||||
val application = intent.getStringExtra(EXTRA_APPLICATION)?: return
|
||||
if (application.isBlank()) {
|
||||
return
|
||||
}
|
||||
sendUnregistered(context!!.applicationContext, connectorToken)
|
||||
val db = MessagingDatabase(context.applicationContext)
|
||||
val appToken = db.getAppToken(connectorToken)
|
||||
db.unregisterApp(connectorToken)
|
||||
db.close()
|
||||
ApiUtils().deleteApp(context.applicationContext, appToken) {
|
||||
Log.d(TAG,"Unregistration is finished")
|
||||
}
|
||||
sendUnregistered(context!!, token)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user