532 lines
21 KiB
Kotlin
532 lines
21 KiB
Kotlin
package fr.mobdev.peertubelive.manager
|
|
|
|
import android.content.Context
|
|
import android.net.ConnectivityManager
|
|
import android.net.NetworkCapabilities
|
|
import android.os.Build
|
|
import android.os.Bundle
|
|
import fr.mobdev.peertubelive.BuildConfig
|
|
import fr.mobdev.peertubelive.R
|
|
import fr.mobdev.peertubelive.objects.OAuthData
|
|
import org.json.JSONObject
|
|
import java.io.BufferedReader
|
|
import java.io.InputStream
|
|
import java.io.InputStreamReader
|
|
import java.io.OutputStream
|
|
import java.net.HttpURLConnection
|
|
import java.net.URL
|
|
import java.net.UnknownHostException
|
|
import java.util.*
|
|
import java.util.concurrent.Semaphore
|
|
import kotlin.collections.ArrayList
|
|
|
|
class OAuthManager {
|
|
|
|
constructor() {
|
|
start()
|
|
}
|
|
|
|
fun register(context: Context, url: String, listener: InstanceManager.InstanceListener) {
|
|
val args = Bundle()
|
|
args.putString(URL, url)
|
|
|
|
val message = Message()
|
|
message.type = Message.Message_Type.REGISTER
|
|
message.context = context
|
|
message.args = args
|
|
message.listener = listener
|
|
|
|
addMessage(message)
|
|
}
|
|
|
|
fun getUserToken(context: Context, url: String, username: String, password: String, oauthData: OAuthData, listener: InstanceManager.InstanceListener) {
|
|
val args = Bundle()
|
|
args.putString(URL, url)
|
|
args.putParcelable(OAUTH_DATA, oauthData)
|
|
args.putString(USERNAME, username)
|
|
args.putString(PASSWORD, password)
|
|
|
|
val message = Message()
|
|
message.type = Message.Message_Type.GET_USER_TOKEN
|
|
message.context = context
|
|
message.args = args
|
|
message.listener = listener
|
|
|
|
addMessage(message)
|
|
}
|
|
|
|
fun refreshToken(context: Context, url: String, oauthData: OAuthData, listener: InstanceManager.InstanceListener) {
|
|
val args = Bundle()
|
|
args.putString(URL, url)
|
|
args.putParcelable(OAUTH_DATA, oauthData)
|
|
|
|
val message = Message()
|
|
message.type = Message.Message_Type.REFRESH_TOKEN
|
|
message.context = context
|
|
message.args = args
|
|
message.listener = listener
|
|
|
|
addMessage(message)
|
|
}
|
|
|
|
fun post(context: Context, url: String, oauthData: OAuthData, data: Bundle, listener: InstanceManager.InstanceListener) {
|
|
val args = Bundle()
|
|
args.putString(URL, url)
|
|
args.putParcelable(OAUTH_DATA, oauthData)
|
|
args.putBundle(DATA, data)
|
|
|
|
val message = Message()
|
|
message.type = Message.Message_Type.POST
|
|
message.context = context
|
|
message.args = args
|
|
message.listener = listener
|
|
|
|
addMessage(message)
|
|
}
|
|
|
|
fun get(context: Context, url: String, oauthData: OAuthData?, listener: InstanceManager.InstanceListener) {
|
|
val args = Bundle()
|
|
args.putString(URL, url)
|
|
args.putParcelable(OAUTH_DATA, oauthData)
|
|
|
|
val message = Message()
|
|
message.type = Message.Message_Type.GET
|
|
message.context = context
|
|
message.args = args
|
|
message.listener = listener
|
|
|
|
addMessage(message)
|
|
}
|
|
|
|
private companion object OAuthThread : Thread() {
|
|
private val messageQueue: ArrayList<Message> = ArrayList()
|
|
private val sem: Semaphore = Semaphore(0, true)
|
|
|
|
private const val URL: String = "URL"
|
|
private const val USERNAME: String = "USERNAME"
|
|
private const val PASSWORD: String = "PASSWORD"
|
|
private const val OAUTH_DATA: String = "OAUTH_DATA"
|
|
private const val DATA: String = "DATA"
|
|
private const val EXTRA_DATA: String = "EXTRA_DATA"
|
|
private const val CONTENT_TYPE: String = "CONTENT_TYPE"
|
|
private const val CONTENT_DATA: String = "CONTENT_DATA"
|
|
|
|
fun addMessage(message: Message)
|
|
{
|
|
messageQueue.add(message)
|
|
sem.release()
|
|
}
|
|
|
|
override fun run() {
|
|
var isRunning = true
|
|
while (isRunning) {
|
|
try {
|
|
sem.acquire()
|
|
val mes: Message = messageQueue.removeAt(0)
|
|
when (mes.type) {
|
|
Message.Message_Type.REGISTER -> register(mes)
|
|
Message.Message_Type.GET_USER_TOKEN -> getUserToken(mes)
|
|
Message.Message_Type.REFRESH_TOKEN -> refreshToken(mes)
|
|
Message.Message_Type.POST -> post(mes)
|
|
Message.Message_Type.GET -> get(mes)
|
|
else -> {}
|
|
}
|
|
} catch (e: InterruptedException) {
|
|
isRunning = false
|
|
}
|
|
}
|
|
}
|
|
|
|
fun register(message: Message) {
|
|
if (!isConnectedToInternet(message.context)) {
|
|
message.listener?.onError(message.context.getString(R.string.network_error))
|
|
return
|
|
}
|
|
val url: String = message.args.getString(URL,"")
|
|
val registerUrl = URL(url)
|
|
val connection: HttpURLConnection = registerUrl.openConnection() as HttpURLConnection
|
|
connection.requestMethod = "GET"
|
|
connection.setRequestProperty("User-Agent", "Peeriscope")
|
|
connection.setRequestProperty("Content-Type", "application/json")
|
|
connection.setRequestProperty("Accept", "application/json")
|
|
connection.doInput = true
|
|
|
|
var inputStream: InputStream
|
|
var inError = false
|
|
try {
|
|
inputStream = connection.inputStream
|
|
} catch (e: UnknownHostException) {
|
|
message.listener?.onError(message.context.getString(R.string.unknown_host))
|
|
return
|
|
} catch (e : Exception) {
|
|
e.printStackTrace()
|
|
inputStream = connection.errorStream
|
|
inError = true
|
|
}
|
|
|
|
val response = readInputStream(inputStream)
|
|
if(!inError) {
|
|
if(response.isNotEmpty()) {
|
|
val rootObj = JSONObject(response)
|
|
|
|
val clientId = rootObj.getString("client_id")
|
|
val clientSecret = rootObj.getString("client_secret")
|
|
|
|
val oauthData = OAuthData(null, null, clientId, clientSecret, null, null, 0, null,0)
|
|
val result = Bundle()
|
|
result.putParcelable(EXTRA_DATA, oauthData)
|
|
|
|
message.listener?.onSuccess(result)
|
|
} else {
|
|
message.listener?.onError(message.context.getString(R.string.unknwon_error))
|
|
}
|
|
} else {
|
|
if(response.isNotEmpty()) {
|
|
val rootObj = JSONObject(response)
|
|
val error = rootObj.getString("error")
|
|
message.listener?.onError(error)
|
|
} else {
|
|
message.listener?.onError(message.context.getString(R.string.unknwon_error))
|
|
}
|
|
}
|
|
}
|
|
|
|
fun getUserToken(message: Message) {
|
|
if (!isConnectedToInternet(message.context)) {
|
|
message.listener?.onError(message.context.getString(R.string.network_error))
|
|
return
|
|
}
|
|
val url: String = message.args.getString(URL, "")
|
|
val getUserTokenUrl = URL(url)
|
|
val connection: HttpURLConnection = getUserTokenUrl.openConnection() as HttpURLConnection
|
|
connection.requestMethod = "POST"
|
|
connection.setRequestProperty("User-Agent", "Peeriscope")
|
|
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
|
|
connection.setRequestProperty("Accept", "application/json")
|
|
connection.doInput = true
|
|
connection.doOutput = true
|
|
|
|
val oauth: OAuthData? = message.args.getParcelable(OAUTH_DATA)
|
|
if (BuildConfig.DEBUG && oauth == null) {
|
|
error("Missing OAUTH DATA")
|
|
}
|
|
val username: String = message.args.getString(USERNAME,"")
|
|
val password: String = message.args.getString(PASSWORD,"")
|
|
|
|
var output = ""
|
|
output += "client_id=" + (oauth?.clientId ?: "")
|
|
output += "&client_secret=" + (oauth?.clientSecret ?: "")
|
|
output += "&grant_type=password"
|
|
output += "&response_type=code"
|
|
output += "&username=$username"
|
|
output += "&password=$password"
|
|
|
|
val outputStream = connection.outputStream
|
|
outputStream.write(output.toByteArray())
|
|
|
|
var inputStream: InputStream
|
|
var inError = false
|
|
try {
|
|
inputStream = connection.inputStream
|
|
} catch (e: UnknownHostException) {
|
|
message.listener?.onError(message.context.getString(R.string.unknown_host))
|
|
return
|
|
} catch (e : Exception) {
|
|
e.printStackTrace()
|
|
inputStream = connection.errorStream
|
|
inError = true
|
|
}
|
|
|
|
val response = readInputStream(inputStream)
|
|
|
|
if(!inError) {
|
|
if(response.isNotEmpty()) {
|
|
val rootObj = JSONObject(response)
|
|
|
|
val accessToken = rootObj.getString("access_token")
|
|
val tokenType = rootObj.getString("token_type")
|
|
var expires = Calendar.getInstance().timeInMillis
|
|
expires += rootObj.getLong("expires_in")*1000
|
|
|
|
val refreshToken = rootObj.getString("refresh_token")
|
|
var refreshTokenExpires = Calendar.getInstance().timeInMillis
|
|
refreshTokenExpires += rootObj.getLong("refresh_token_expires_in")*1000
|
|
|
|
val oauthData = OAuthData(oauth?.baseUrl,username,oauth?.clientId, oauth?.clientSecret, accessToken, tokenType, expires, refreshToken, refreshTokenExpires)
|
|
val result = Bundle()
|
|
result.putParcelable(EXTRA_DATA, oauthData)
|
|
|
|
message.listener?.onSuccess(result)
|
|
} else {
|
|
message.listener?.onError(message.context.getString(R.string.unknwon_error))
|
|
}
|
|
} else {
|
|
if(response.isNotEmpty()) {
|
|
val rootObj = JSONObject(response)
|
|
val error = rootObj.getString("error")
|
|
message.listener?.onError(error)
|
|
} else {
|
|
message.listener?.onError(message.context.getString(R.string.unknwon_error))
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
fun refreshToken(message: Message) {
|
|
if (!isConnectedToInternet(message.context)) {
|
|
message.listener?.onError(message.context.getString(R.string.network_error))
|
|
return
|
|
}
|
|
val url: String = message.args.getString(URL, "")
|
|
val getUserTokenUrl = URL(url)
|
|
val connection: HttpURLConnection = getUserTokenUrl.openConnection() as HttpURLConnection
|
|
connection.requestMethod = "POST"
|
|
connection.setRequestProperty("User-Agent", "Peeriscope")
|
|
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
|
|
connection.setRequestProperty("Accept", "application/json")
|
|
connection.doInput = true
|
|
connection.doOutput = true
|
|
|
|
val oauth: OAuthData? = message.args.getParcelable(OAUTH_DATA)
|
|
if (BuildConfig.DEBUG && oauth == null) {
|
|
error("Missing OAUTH DATA")
|
|
}
|
|
|
|
var output = ""
|
|
output += "client_id=" + (oauth?.clientId ?: "")
|
|
output += "&client_secret=" + (oauth?.clientSecret ?: "")
|
|
output += "&grant_type=refresh_token"
|
|
output += "&response_type=code"
|
|
output += "&refresh_token=" +(oauth?.refreshToken?: "")
|
|
|
|
val outputStream = connection.outputStream
|
|
outputStream.write(output.toByteArray())
|
|
|
|
var inputStream: InputStream
|
|
var inError = false
|
|
try {
|
|
inputStream = connection.inputStream
|
|
} catch (e: UnknownHostException) {
|
|
message.listener?.onError(message.context.getString(R.string.unknown_host))
|
|
return
|
|
} catch (e : Exception) {
|
|
e.printStackTrace()
|
|
inputStream = connection.errorStream
|
|
inError = true
|
|
}
|
|
|
|
val response = readInputStream(inputStream)
|
|
|
|
if(!inError) {
|
|
if(response.isNotEmpty()) {
|
|
val rootObj = JSONObject(response)
|
|
|
|
val accessToken = rootObj.getString("access_token")
|
|
val tokenType = rootObj.getString("token_type")
|
|
var expires = Calendar.getInstance().timeInMillis
|
|
expires += rootObj.getLong("expires_in")*1000
|
|
val refreshToken = rootObj.getString("refresh_token")
|
|
var refreshTokenExpires = Calendar.getInstance().timeInMillis
|
|
refreshTokenExpires += rootObj.getLong("refresh_token_expires_in")*1000
|
|
|
|
val oauthData = OAuthData(oauth?.baseUrl,oauth?.username,oauth?.clientId, oauth?.clientSecret, accessToken, tokenType, expires, refreshToken, refreshTokenExpires)
|
|
val result = Bundle()
|
|
result.putParcelable(EXTRA_DATA, oauthData)
|
|
|
|
message.listener?.onSuccess(result)
|
|
} else {
|
|
message.listener?.onError(message.context.getString(R.string.unknwon_error))
|
|
}
|
|
} else {
|
|
if(response.isNotEmpty()) {
|
|
val rootObj = JSONObject(response)
|
|
val error = rootObj.getString("error")
|
|
message.listener?.onError(error)
|
|
} else {
|
|
message.listener?.onError(message.context.getString(R.string.unknwon_error))
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
fun post(message: Message) {
|
|
if (!isConnectedToInternet(message.context)) {
|
|
message.listener?.onError(message.context.getString(R.string.network_error))
|
|
return
|
|
}
|
|
val url: String = message.args.getString(URL, "")
|
|
val postUrl = URL(url)
|
|
val data = message.args.getBundle(DATA)!!
|
|
val connection: HttpURLConnection = postUrl.openConnection() as HttpURLConnection
|
|
connection.requestMethod = "POST"
|
|
connection.setRequestProperty("User-Agent", "Peeriscope")
|
|
connection.setRequestProperty("Content-Type", data.getString(CONTENT_TYPE,"application/json"))
|
|
connection.setRequestProperty("Accept", "application/json")
|
|
connection.doInput = true
|
|
connection.doOutput = true
|
|
|
|
val oauth: OAuthData? = message.args.getParcelable(OAUTH_DATA)
|
|
if (BuildConfig.DEBUG && oauth == null) {
|
|
error("Missing OAUTH DATA")
|
|
}
|
|
val extraData: String = data.getString(CONTENT_DATA,"")
|
|
connection.setRequestProperty("Authorization","Bearer ${oauth?.accessToken}")
|
|
|
|
var inputStream: InputStream? = null
|
|
val outputStream: OutputStream
|
|
var inError = false
|
|
try {
|
|
outputStream = connection.outputStream
|
|
outputStream.write(extraData.toByteArray())
|
|
outputStream.flush()
|
|
outputStream.close()
|
|
} catch (e: UnknownHostException) {
|
|
message.listener?.onError(message.context.getString(R.string.unknown_host))
|
|
return
|
|
} catch (e : Exception) {
|
|
e.printStackTrace()
|
|
inError = true
|
|
inputStream = connection.errorStream
|
|
}
|
|
|
|
|
|
if(!inError) {
|
|
try {
|
|
inputStream = connection.inputStream
|
|
} catch (e: UnknownHostException) {
|
|
message.listener?.onError(message.context.getString(R.string.unknown_host))
|
|
return
|
|
} catch (e: Exception) {
|
|
e.printStackTrace()
|
|
inputStream = connection.errorStream
|
|
inError = true
|
|
}
|
|
}
|
|
if (inputStream != null) {
|
|
val response = readInputStream(inputStream)
|
|
if (!inError) {
|
|
if (response.isNotEmpty()) {
|
|
val result = Bundle()
|
|
result.putString(EXTRA_DATA, response)
|
|
message.listener?.onSuccess(result)
|
|
} else {
|
|
message.listener?.onError(message.context.getString(R.string.unknwon_error))
|
|
}
|
|
} else {
|
|
if (response.isNotEmpty()) {
|
|
try {
|
|
val rootObj = JSONObject(response)
|
|
val error = rootObj.getString("error")
|
|
message.listener?.onError(error)
|
|
} catch (e: Exception) {
|
|
message.listener?.onError(message.context.getString(R.string.json_error))
|
|
}
|
|
} else {
|
|
message.listener?.onError(message.context.getString(R.string.unknwon_error))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun get(message: Message) {
|
|
if (!isConnectedToInternet(message.context)) {
|
|
message.listener?.onError(message.context.getString(R.string.network_error))
|
|
return
|
|
}
|
|
val url: String = message.args.getString(URL, "")
|
|
val getUserTokenUrl = URL(url)
|
|
val connection: HttpURLConnection = getUserTokenUrl.openConnection() as HttpURLConnection
|
|
connection.requestMethod = "GET"
|
|
connection.setRequestProperty("User-Agent", "Peeriscope")
|
|
connection.setRequestProperty("Content-Type", "application/json")
|
|
connection.setRequestProperty("Accept", "application/json")
|
|
|
|
connection.doInput = true
|
|
|
|
val oauth: OAuthData? = message.args.getParcelable(OAUTH_DATA)
|
|
if (oauth != null) {
|
|
connection.setRequestProperty("Authorization", "Bearer ${oauth.accessToken}")
|
|
}
|
|
|
|
var inputStream: InputStream
|
|
var inError = false
|
|
try {
|
|
inputStream = connection.inputStream
|
|
} catch (e: UnknownHostException) {
|
|
message.listener?.onError(message.context.getString(R.string.unknown_host))
|
|
return
|
|
} catch (e : Exception) {
|
|
e.printStackTrace()
|
|
inputStream = connection.errorStream
|
|
inError = true
|
|
}
|
|
|
|
val response = readInputStream(inputStream)
|
|
if(!inError) {
|
|
if(response.isNotEmpty()) {
|
|
val result = Bundle()
|
|
result.putString(EXTRA_DATA, response)
|
|
message.listener?.onSuccess(result)
|
|
} else {
|
|
message.listener?.onError(message.context.getString(R.string.unknwon_error))
|
|
}
|
|
} else {
|
|
if(response.isNotEmpty()) {
|
|
try {
|
|
val rootObj = JSONObject(response)
|
|
val error = rootObj.getString("error")
|
|
message.listener?.onError(error)
|
|
} catch (e: Exception) {
|
|
message.listener?.onError(message.context.getString(R.string.json_error))
|
|
}
|
|
} else {
|
|
message.listener?.onError(message.context.getString(R.string.unknwon_error))
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
fun readInputStream(inputStream: InputStream) : String {
|
|
val inReader = InputStreamReader(inputStream)
|
|
val bufReader = BufferedReader(inReader)
|
|
var line: String?
|
|
var response = ""
|
|
|
|
do {
|
|
line = bufReader.readLine()
|
|
if(line != null)
|
|
response += line
|
|
|
|
}while (line != null)
|
|
|
|
return response
|
|
}
|
|
|
|
private fun isConnectedToInternet(context: Context): Boolean {
|
|
//verify the connectivity
|
|
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
|
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
val network = connectivityManager.activeNetwork
|
|
val capabilities = connectivityManager.getNetworkCapabilities(network)
|
|
if(capabilities != null)
|
|
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) || capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
|
} else {
|
|
val networkInfo = connectivityManager.activeNetworkInfo
|
|
if (networkInfo != null)
|
|
return networkInfo.isConnected
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
private class Message {
|
|
var type: Message_Type = Message_Type.UNKNOWN
|
|
var args = Bundle()
|
|
var listener: InstanceManager.InstanceListener? = null
|
|
lateinit var context: Context
|
|
|
|
enum class Message_Type {
|
|
REGISTER, GET_USER_TOKEN, REFRESH_TOKEN, POST, GET, UNKNOWN
|
|
}
|
|
}
|
|
} |