mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-04-20 03:24:50 +00:00
Properly check for different author and show it as a warning when the author has changed. Properly show signature warnings when installing a script.
This commit is contained in:
parent
f19b7fa584
commit
1531a558a5
5 changed files with 80 additions and 34 deletions
|
@ -42,7 +42,8 @@ class AddSourceActivity : AppCompatActivity() {
|
|||
|
||||
private val _client = ManagedHttpClient();
|
||||
|
||||
private var _config : SourcePluginConfig? = null;
|
||||
private var _config: SourcePluginConfig? = null;
|
||||
private var _script: String? = null;
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -81,7 +82,7 @@ class AddSourceActivity : AppCompatActivity() {
|
|||
}
|
||||
_buttonInstall.setOnClickListener {
|
||||
_config?.let {
|
||||
install(_config!!);
|
||||
install(_config!!, _script!!);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -114,6 +115,7 @@ class AddSourceActivity : AppCompatActivity() {
|
|||
setLoading(true);
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val config: SourcePluginConfig;
|
||||
try {
|
||||
val configResp = _client.get(url);
|
||||
if(!configResp.isOk)
|
||||
|
@ -121,33 +123,51 @@ class AddSourceActivity : AppCompatActivity() {
|
|||
val configJson = configResp.body?.string();
|
||||
if(configJson.isNullOrEmpty())
|
||||
throw IllegalStateException("No response");
|
||||
val config = SourcePluginConfig.fromJson(configJson, url);
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
loadConfig(config);
|
||||
}
|
||||
}
|
||||
catch(ex: SerializationException) {
|
||||
config = SourcePluginConfig.fromJson(configJson, url);
|
||||
} catch(ex: SerializationException) {
|
||||
Logger.e(TAG, "Failed decode config", ex);
|
||||
withContext(Dispatchers.Main) {
|
||||
UIDialogs.showDialog(this@AddSourceActivity, R.drawable.ic_error,
|
||||
"Invalid Config Format", null, null,
|
||||
0, UIDialogs.Action("Ok", { finish() }, UIDialogs.ActionStyle.PRIMARY));
|
||||
};
|
||||
}
|
||||
catch(ex: Exception) {
|
||||
return@launch;
|
||||
} catch(ex: Exception) {
|
||||
Logger.e(TAG, "Failed fetch config", ex);
|
||||
withContext(Dispatchers.Main) {
|
||||
UIDialogs.showGeneralErrorDialog(this@AddSourceActivity, "Failed to fetch configuration", ex);
|
||||
};
|
||||
return@launch;
|
||||
}
|
||||
|
||||
val script: String?
|
||||
try {
|
||||
val scriptResp = _client.get(config.absoluteScriptUrl);
|
||||
if (!scriptResp.isOk)
|
||||
throw IllegalStateException("script not available [${scriptResp.code}]");
|
||||
script = scriptResp.body?.string();
|
||||
if (script.isNullOrEmpty())
|
||||
throw IllegalStateException("script empty");
|
||||
} catch (ex: Exception) {
|
||||
Logger.e(TAG, "Failed fetch script", ex);
|
||||
withContext(Dispatchers.Main) {
|
||||
UIDialogs.showGeneralErrorDialog(this@AddSourceActivity, "Failed to fetch script", ex);
|
||||
};
|
||||
return@launch;
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
loadConfig(config, script);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fun loadConfig(config: SourcePluginConfig) {
|
||||
private fun loadConfig(config: SourcePluginConfig, script: String) {
|
||||
_config = config;
|
||||
_script = script;
|
||||
|
||||
_sourceHeader.loadConfig(config);
|
||||
_sourceHeader.loadConfig(config, script);
|
||||
_sourcePermissions.removeAllViews();
|
||||
_sourceWarnings.removeAllViews();
|
||||
|
||||
|
@ -171,7 +191,7 @@ class AddSourceActivity : AppCompatActivity() {
|
|||
|
||||
val pastelRed = resources.getColor(R.color.pastel_red);
|
||||
|
||||
for(warning in config.getWarnings())
|
||||
for(warning in config.getWarnings(script))
|
||||
_sourceWarnings.addView(
|
||||
SourceInfoView(this,
|
||||
R.drawable.ic_security_pred,
|
||||
|
@ -182,8 +202,8 @@ class AddSourceActivity : AppCompatActivity() {
|
|||
setLoading(false);
|
||||
}
|
||||
|
||||
fun install(config: SourcePluginConfig) {
|
||||
StatePlugins.instance.installPlugin(this, lifecycleScope, config) {
|
||||
fun install(config: SourcePluginConfig, script: String) {
|
||||
StatePlugins.instance.installPlugin(this, lifecycleScope, config, script) {
|
||||
if(it)
|
||||
backToSources();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.net.Uri
|
|||
import com.futo.platformplayer.SignatureProvider
|
||||
import com.futo.platformplayer.api.media.Serializer
|
||||
import com.futo.platformplayer.engine.IV8PluginConfig
|
||||
import com.futo.platformplayer.states.StatePlugins
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import java.net.URL
|
||||
import java.util.*
|
||||
|
@ -78,6 +79,15 @@ class SourcePluginConfig(
|
|||
fun getWarnings(scriptToCheck: String? = null) : List<Pair<String,String>> {
|
||||
val list = mutableListOf<Pair<String,String>>();
|
||||
|
||||
val currentlyInstalledPlugin = StatePlugins.instance.getPlugin(id);
|
||||
if (currentlyInstalledPlugin != null) {
|
||||
if (currentlyInstalledPlugin.config.scriptPublicKey != scriptPublicKey) {
|
||||
list.add(Pair(
|
||||
"Different Author",
|
||||
"This plugin was signed by a different author. Please ensure that this is correct and that the plugin was not provided by a malicious actor."));
|
||||
}
|
||||
}
|
||||
|
||||
if(scriptPublicKey.isNullOrEmpty() || scriptSignature.isNullOrEmpty())
|
||||
list.add(Pair(
|
||||
"Missing Signature",
|
||||
|
|
|
@ -185,7 +185,7 @@ class SourceDetailFragment : MainFragment() {
|
|||
val config = _config;
|
||||
|
||||
if (config != null) {
|
||||
_sourceHeader.loadConfig(config);
|
||||
_sourceHeader.loadConfig(config, StatePlugins.instance.getScript(config.id));
|
||||
} else {
|
||||
_sourceHeader.clear();
|
||||
}
|
||||
|
|
|
@ -177,18 +177,16 @@ class StatePlugins {
|
|||
}
|
||||
fun installPlugin(context: Context, scope: CoroutineScope, sourceUrl: String, handler: ((Boolean) -> Unit)? = null) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val client = ManagedHttpClient();
|
||||
val config: SourcePluginConfig;
|
||||
try {
|
||||
val configResp = ManagedHttpClient().get(sourceUrl);
|
||||
val configResp = client.get(sourceUrl);
|
||||
if(!configResp.isOk)
|
||||
throw IllegalStateException("Failed request with ${configResp.code}");
|
||||
val configJson = configResp.body?.string();
|
||||
if(configJson.isNullOrEmpty())
|
||||
throw IllegalStateException("No response");
|
||||
val config = SourcePluginConfig.fromJson(configJson, sourceUrl);
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
installPlugin(context, scope, config, handler);
|
||||
}
|
||||
config = SourcePluginConfig.fromJson(configJson, sourceUrl);
|
||||
}
|
||||
catch(ex: SerializationException) {
|
||||
Logger.e(TAG, "Failed decode config", ex);
|
||||
|
@ -199,8 +197,8 @@ class StatePlugins {
|
|||
finish();
|
||||
handler?.invoke(false);
|
||||
}, UIDialogs.ActionStyle.PRIMARY));
|
||||
|
||||
};
|
||||
return@launch;
|
||||
}
|
||||
catch(ex: Exception) {
|
||||
Logger.e(TAG, "Failed fetch config", ex);
|
||||
|
@ -209,13 +207,36 @@ class StatePlugins {
|
|||
handler?.invoke(false);
|
||||
});
|
||||
};
|
||||
return@launch;
|
||||
}
|
||||
|
||||
val script: String?
|
||||
try {
|
||||
val scriptResp = client.get(config.absoluteScriptUrl);
|
||||
if (!scriptResp.isOk)
|
||||
throw IllegalStateException("script not available [${scriptResp.code}]");
|
||||
script = scriptResp.body?.string();
|
||||
if (script.isNullOrEmpty())
|
||||
throw IllegalStateException("script empty");
|
||||
} catch (ex: Exception) {
|
||||
Logger.e(TAG, "Failed fetch script", ex);
|
||||
withContext(Dispatchers.Main) {
|
||||
UIDialogs.showGeneralErrorDialog(context, "Failed to fetch script", ex);
|
||||
};
|
||||
return@launch;
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
installPlugin(context, scope, config, script, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
fun installPlugin(context: Context, scope: CoroutineScope, config: SourcePluginConfig, handler: ((Boolean)->Unit)? = null) {
|
||||
fun installPlugin(context: Context, scope: CoroutineScope, config: SourcePluginConfig, script: String, handler: ((Boolean)->Unit)? = null) {
|
||||
val client = ManagedHttpClient();
|
||||
val warnings = config.getWarnings();
|
||||
|
||||
if (script.isEmpty())
|
||||
throw IllegalStateException("script empty");
|
||||
|
||||
fun doInstall(reinstall: Boolean) {
|
||||
UIDialogs.showDialogProgress(context) {
|
||||
|
@ -224,13 +245,6 @@ class StatePlugins {
|
|||
|
||||
scope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val scriptResp = client.get(config.absoluteScriptUrl);
|
||||
if (!scriptResp.isOk)
|
||||
throw IllegalStateException("script not available [${scriptResp.code}]");
|
||||
val script = scriptResp.body?.string();
|
||||
if (script.isNullOrEmpty())
|
||||
throw IllegalStateException("script empty");
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
it.setText("Validating script...");
|
||||
it.setProgress(0.25);
|
||||
|
|
|
@ -55,7 +55,7 @@ class SourceHeaderView : LinearLayout {
|
|||
};
|
||||
}
|
||||
|
||||
fun loadConfig(config: SourcePluginConfig) {
|
||||
fun loadConfig(config: SourcePluginConfig, script: String?) {
|
||||
_config = config;
|
||||
|
||||
val loadedIcon = StatePlugins.instance.getPluginIconOrNull(config.id);
|
||||
|
@ -80,8 +80,10 @@ class SourceHeaderView : LinearLayout {
|
|||
_sourceBy.setTextColor(Color.WHITE);
|
||||
|
||||
if (!config.scriptPublicKey.isNullOrEmpty() && !config.scriptSignature.isNullOrEmpty()) {
|
||||
val script = StatePlugins.instance.getScript(config.id);
|
||||
if (script != null && config.validate(script)) {
|
||||
if (script == null) {
|
||||
_sourceSignature.setTextColor(Color.rgb(0xAC, 0xAC, 0xAC));
|
||||
_sourceSignature.text = "Script is not available";
|
||||
} else if (config.validate(script)) {
|
||||
_sourceSignature.setTextColor(Color.rgb(0, 255, 0));
|
||||
_sourceSignature.text = "Signature is valid";
|
||||
} else {
|
||||
|
|
Loading…
Add table
Reference in a new issue