diff --git a/app/src/main/java/org/fdroid/fdroid/IndexV1Updater.java b/app/src/main/java/org/fdroid/fdroid/IndexV1Updater.java
index 1b61d69a1..2c25c4874 100644
--- a/app/src/main/java/org/fdroid/fdroid/IndexV1Updater.java
+++ b/app/src/main/java/org/fdroid/fdroid/IndexV1Updater.java
@@ -335,8 +335,10 @@ public class IndexV1Updater extends RepoUpdater {
repoPersister.commit(contentValues, repo.getId());
profiler.log("Persited to database.");
- processRepoPushRequests(requests);
- Utils.debugLog(TAG, "Completed Repo Push Requests: " + requests);
+ if (repo.pushRequests == Repo.PUSH_REQUEST_ACCEPT_ALWAYS) {
+ processRepoPushRequests(requests);
+ Utils.debugLog(TAG, "Completed Repo Push Requests: " + requests);
+ }
}
private int getIntRepoValue(Map repoMap, String key) {
diff --git a/app/src/main/java/org/fdroid/fdroid/Preferences.java b/app/src/main/java/org/fdroid/fdroid/Preferences.java
index 3fa6dec15..aa4f1f6d6 100644
--- a/app/src/main/java/org/fdroid/fdroid/Preferences.java
+++ b/app/src/main/java/org/fdroid/fdroid/Preferences.java
@@ -108,6 +108,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
public static final String PREF_HIDE_ON_LONG_PRESS_SEARCH = "hideOnLongPressSearch";
public static final String PREF_HIDE_ALL_NOTIFICATIONS = "hideAllNotifications";
public static final String PREF_SEND_VERSION_AND_UUID_TO_SERVERS = "sendVersionAndUUIDToServers";
+ public static final String PREF_ALLOW_PUSH_REQUESTS = "allowPushRequests";
public static final int OVER_NETWORK_NEVER = 0;
public static final int OVER_NETWORK_ON_DEMAND = 1;
@@ -512,6 +513,16 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
return preferences.getBoolean(PREF_SEND_VERSION_AND_UUID_TO_SERVERS, IGNORED_B);
}
+ /**
+ * Whether push requests are globally enabled or disabled.
+ *
+ * @see org.fdroid.fdroid.data.RepoPushRequest
+ * @see RepoUpdater#processRepoPushRequests(List)
+ */
+ public boolean allowPushRequests() {
+ return preferences.getBoolean(PREF_ALLOW_PUSH_REQUESTS, IGNORED_B);
+ }
+
/**
* This is cached as it is called several times inside app list adapters.
* Providing it here means the shared preferences file only needs to be
diff --git a/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java b/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java
index 08e25cd41..566a77124 100644
--- a/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java
+++ b/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java
@@ -442,9 +442,14 @@ public class RepoUpdater {
* Server index XML can include optional {@code install} and {@code uninstall}
* requests. This processes those requests, figuring out whether the client
* should always accept, prompt the user, or ignore those requests on a
- * per repo basis.
+ * per repo basis. There is also a global preference as a failsafe.
+ *
+ * @see Preferences#allowPushRequests()
*/
void processRepoPushRequests(List requestEntries) {
+ if (!Preferences.get().allowPushRequests()) {
+ return;
+ }
for (RepoPushRequest repoPushRequest : requestEntries) {
String packageName = repoPushRequest.packageName;
PackageInfo packageInfo = Utils.getPackageInfo(context, packageName);
diff --git a/app/src/main/java/org/fdroid/fdroid/data/Repo.java b/app/src/main/java/org/fdroid/fdroid/data/Repo.java
index 348b19be6..b3b35f4b7 100644
--- a/app/src/main/java/org/fdroid/fdroid/data/Repo.java
+++ b/app/src/main/java/org/fdroid/fdroid/data/Repo.java
@@ -26,6 +26,7 @@ package org.fdroid.fdroid.data;
import android.content.ContentValues;
import android.database.Cursor;
import android.text.TextUtils;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.data.Schema.RepoTable.Cols;
@@ -61,37 +62,63 @@ public class Repo extends ValueObject {
public static final int INT_UNSET_VALUE = -1;
// these are never set by the Apk/package index metadata
+ @JsonIgnore
protected long id;
+ @JsonIgnore
+ public boolean inuse;
+ @JsonIgnore
+ public int priority;
+ @JsonIgnore
+ public Date lastUpdated;
+ @JsonIgnore
+ public boolean isSwap;
+ /**
+ * last etag we updated from, null forces update
+ */
+ @JsonIgnore
+ public String lastetag;
+ /**
+ * How to treat push requests included in this repo's index XML. This comes
+ * from {@code default_repo.xml} or perhaps user input. It should never be
+ * settable from the server-side.
+ */
+ @JsonIgnore
+ public int pushRequests = PUSH_REQUEST_IGNORE;
public String address;
public String name;
public String description;
public String icon;
- /** index version, i.e. what fdroidserver built it - 0 if not specified */
+ /**
+ * index version, i.e. what fdroidserver built it - 0 if not specified
+ */
public int version;
- public boolean inuse;
- public int priority;
- /** The signing certificate, {@code null} for a newly added repo */
+ /**
+ * The signing certificate, {@code null} for a newly added repo
+ */
public String signingCertificate;
/**
* The SHA1 fingerprint of {@link #signingCertificate}, set to {@code null} when a
* newly added repo did not include fingerprint. It should never be an
- * empty {@link String}, i.e. {@code ""} */
+ * empty {@link String}, i.e. {@code ""}
+ */
public String fingerprint;
- /** maximum age of index that will be accepted - 0 for any */
+ /**
+ * maximum age of index that will be accepted - 0 for any
+ */
public int maxage;
- /** last etag we updated from, null forces update */
- public String lastetag;
- public Date lastUpdated;
- public boolean isSwap;
public String username;
public String password;
- /** When the signed repo index was generated, used to protect against replay attacks */
+ /**
+ * When the signed repo index was generated, used to protect against replay attacks
+ */
public long timestamp;
- /** Official mirrors of this repo, considered automatically interchangeable */
+ /**
+ * Official mirrors of this repo, considered automatically interchangeable
+ */
public String[] mirrors;
/**
@@ -99,9 +126,6 @@ public class Repo extends ValueObject {
*/
public String[] userMirrors;
- /** How to treat push requests included in this repo's index XML */
- public int pushRequests = PUSH_REQUEST_IGNORE;
-
public Repo() {
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f2fa3367d..0520b5e25 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -33,6 +33,9 @@
downloading, takes affect next app restart.
Force old index format
In case there are bugs or compatibility issues, use the XML app index
+ Allow repos to install/uninstall apps
+ Repo metadata can include "push requests" to install or uninstall apps
+
Other
Automatic update interval
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 8d49dc77b..07748c8e4 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -190,6 +190,12 @@
android:summary="@string/send_version_and_uuid_summary"
android:defaultValue="false"
android:dependency="expert"/>
+
apps = AppProvider.Helper.all(context.getContentResolver());
assertEquals("63 apps present", 63, apps.size());
+ // these should never be set from the JSON, only by fdroidclient
+ assertEquals(Repo.PUSH_REQUEST_IGNORE, repo.pushRequests);
+ assertFalse(repo.isSwap);
+ assertNotEquals(99999, repo.priority);
+
String[] packages = {
"fake.app.one",
"org.adaway",
@@ -420,11 +426,18 @@ public class IndexV1UpdaterTest extends FDroidProviderTest {
assertEquals(1, apps.length);
assertEquals(1, packages.size());
- List cacerts = packages.get("info.guardianproject.cacert");
+ List cacerts = packages.get("info.guardianproject.cacert");
assertEquals(2, cacerts.size());
assertEquals(1488828510109L, repo.timestamp);
assertEquals("GPLv3", apps[0].license);
+ // these should never be set from the JSON, only by fdroidclient
+ assertEquals(Repo.PUSH_REQUEST_IGNORE, repo.pushRequests);
+ assertFalse(repo.inuse);
+ assertFalse(repo.isSwap);
+ assertNotEquals(99999, repo.priority);
+ assertNotEquals("foobar", repo.lastetag);
+
Set appFields = getFields(apps[0]);
for (String field : appFields) {
assertNotEquals("secret", field);
diff --git a/app/src/test/resources/all_fields_index-v1.json b/app/src/test/resources/all_fields_index-v1.json
index ab3b3f707..787983182 100644
--- a/app/src/test/resources/all_fields_index-v1.json
+++ b/app/src/test/resources/all_fields_index-v1.json
@@ -7,6 +7,12 @@
"address": "https://guardianproject.info/fdroid/repo",
"description": "The official app repository of The Guardian Project. Applications in this repository are official binaries build by the original application developers and signed by the same key as the APKs that are released in the Google Play store. ",
"secret": "trying to sneak something in",
+ "pushRequests": 2,
+ "inuse": true,
+ "isSwap": true,
+ "priority": 99999,
+ "id": 99999,
+ "lastetag": "foobar",
"mirrors": [
"http://bdf2wcxujkg6qqff.onion/fdroid/repo",
"https://guardianproject.info/fdroid/repo",
diff --git a/app/src/test/resources/testy.at.or.at_index-v1.jar b/app/src/test/resources/testy.at.or.at_index-v1.jar
index a2813137e..3554722f5 100644
Binary files a/app/src/test/resources/testy.at.or.at_index-v1.jar and b/app/src/test/resources/testy.at.or.at_index-v1.jar differ