Merge commit 'refs/merge-requests/45' of git://gitorious.org/f-droid/fdroidclient into merge-requests/45
This commit is contained in:
commit
831a1b40fa
@ -60,10 +60,11 @@
|
||||
android:name="android.app.default_searchable"
|
||||
android:value=".SearchResults" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ManageRepo"
|
||||
android:allowTaskReparenting="true"
|
||||
android:label="@string/menu_manage"
|
||||
android:launchMode="singleTop"
|
||||
android:parentActivityName=".FDroid" >
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
@ -99,7 +100,7 @@
|
||||
<data android:pathPattern="/.*/.*/fdroid/archive/*" />
|
||||
<data android:pathPattern="/.*/.*/.*/fdroid/archive" />
|
||||
<data android:pathPattern="/.*/.*/.*/fdroid/archive/*" />
|
||||
</intent-filter>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
|
@ -4,17 +4,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/repo_alert"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableLeft="@android:drawable/ic_dialog_alert"
|
||||
android:gravity="center"
|
||||
android:text="@string/repo_exists"
|
||||
android:textAppearance="@android:style/TextAppearance.Large"
|
||||
android:textColor="@color/red"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -25,7 +14,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1"
|
||||
android:maxLines="2"
|
||||
android:text="https://" />
|
||||
|
||||
<TextView
|
||||
@ -39,15 +28,17 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:digits="0123456789ABCDEFabcedf: "
|
||||
android:inputType="textNoSuggestions"
|
||||
android:maxLines="1"
|
||||
android:maxLines="3"
|
||||
android:typeface="monospace" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/overwrite_repo"
|
||||
<TextView
|
||||
android:id="@+id/overwrite_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableLeft="@android:drawable/ic_dialog_alert"
|
||||
android:drawablePadding="20dp"
|
||||
android:padding="20dp"
|
||||
android:text="@string/repo_overwrite"
|
||||
android:text="@string/repo_delete_to_overwrite"
|
||||
android:textAppearance="@android:style/TextAppearance.Medium"
|
||||
android:visibility="gone" />
|
||||
|
||||
|
@ -56,6 +56,9 @@
|
||||
<string name="repo_add_add">Add</string>
|
||||
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="enable">Enable</string>
|
||||
<string name="add_key">Add Key</string>
|
||||
<string name="overwrite">Overwrite</string>
|
||||
<string name="repo_delete_title">Choose repository to remove</string>
|
||||
|
||||
<string name="repo_update_title">Update repositories</string>
|
||||
@ -72,7 +75,10 @@
|
||||
<string name="repo_add_url">Repository address</string>
|
||||
<string name="repo_add_fingerprint">fingerprint (optional)</string>
|
||||
<string name="repo_exists">This repo already exists!</string>
|
||||
<string name="repo_overwrite">Overwrite the existing repo?</string>
|
||||
<string name="repo_exists_add_fingerprint">This repo is already setup, this will add new key information.</string>
|
||||
<string name="repo_exists_enable">This repo is already setup, confirm that you want to re-enable it.</string>
|
||||
<string name="repo_exists_and_enabled">The incoming repo is already setup and enabled!</string>
|
||||
<string name="repo_delete_to_overwrite">You must first delete this repo before you can add one with a different key!</string>
|
||||
|
||||
<string name="repo_alrt">The list of used repositories has
|
||||
changed.\nDo you
|
||||
|
@ -11,7 +11,7 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
@ -465,6 +465,8 @@ public class DB {
|
||||
|
||||
public static String calcFingerprint(String pubkey) {
|
||||
String ret = null;
|
||||
if (pubkey == null)
|
||||
return null;
|
||||
try {
|
||||
// keytool -list -v gives you the SHA-256 fingerprint
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
@ -1410,7 +1412,7 @@ public class DB {
|
||||
String calcedFingerprint = DB.calcFingerprint(pubkey);
|
||||
if (fingerprint == null) {
|
||||
fingerprint = calcedFingerprint;
|
||||
} else {
|
||||
} else if (calcedFingerprint != null) {
|
||||
fingerprint = fingerprint.toUpperCase();
|
||||
if (!fingerprint.equals(calcedFingerprint)) {
|
||||
throw new SecurityException("Given fingerprint does not match calculated one! ("
|
||||
|
@ -11,7 +11,7 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
@ -10,7 +10,7 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
@ -11,7 +11,7 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
@ -26,6 +26,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AlertDialog.Builder;
|
||||
import android.app.ListActivity;
|
||||
@ -35,24 +36,22 @@ import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.text.format.DateFormat;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.SimpleAdapter;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.fdroid.fdroid.DB.Repo;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
|
||||
import org.fdroid.fdroid.compat.ActionBarCompat;
|
||||
|
||||
public class ManageRepo extends ListActivity {
|
||||
@ -62,6 +61,11 @@ public class ManageRepo extends ListActivity {
|
||||
|
||||
private boolean changed = false;
|
||||
|
||||
private enum PositiveAction {
|
||||
ADD_NEW, ENABLE, IGNORE
|
||||
}
|
||||
private PositiveAction positiveAction;
|
||||
|
||||
private List<DB.Repo> repos;
|
||||
|
||||
private static List<String> reposToDisable;
|
||||
@ -103,7 +107,7 @@ public class ManageRepo extends ListActivity {
|
||||
s_lastUpdateCheck = getString(R.string.never);
|
||||
} else {
|
||||
Date d = new Date(lastUpdate);
|
||||
s_lastUpdateCheck = DateFormat.getDateFormat(this).format(d) +
|
||||
s_lastUpdateCheck = DateFormat.getDateFormat(this).format(d) +
|
||||
" " + DateFormat.getTimeFormat(this).format(d);
|
||||
}
|
||||
tv_lastCheck.setText(getString(R.string.last_update_check,s_lastUpdateCheck));
|
||||
@ -116,13 +120,25 @@ public class ManageRepo extends ListActivity {
|
||||
/* an URL from a click or a QRCode scan */
|
||||
Uri uri = intent.getData();
|
||||
if (uri != null) {
|
||||
// scheme should only ever be pure ASCII:
|
||||
// scheme should only ever be pure ASCII aka Locale.ENGLISH
|
||||
String scheme = intent.getScheme().toLowerCase(Locale.ENGLISH);
|
||||
String fingerprint = uri.getUserInfo();
|
||||
String host = uri.getHost().toLowerCase(Locale.ENGLISH);
|
||||
if (scheme.equals("fdroidrepos") || scheme.equals("fdroidrepo")
|
||||
|| scheme.equals("https") || scheme.equals("http")) {
|
||||
String uriString = uri.toString().replace("fdroidrepo", "http").
|
||||
replace(fingerprint + "@", "");
|
||||
// QRCode are more efficient in all upper case, so some incoming
|
||||
// URLs might be encoded in all upper case. Therefore, we allow
|
||||
// the standard paths to be encoded all upper case, then they'll
|
||||
// be forced to lower case. The scheme and host are downcased
|
||||
// just to make them more readable in the dialog.
|
||||
String uriString = uri.toString()
|
||||
.replace(fingerprint + "@", "") // remove fingerprint
|
||||
.replaceAll("/*$", "") // remove all trailing slashes
|
||||
.replaceAll("/FDROID/REPO$", "/fdroid/repo")
|
||||
.replaceAll("/FDROID/ARCHIVE$", "/fdroid/archive")
|
||||
.replace(uri.getHost(), host) // downcase host name
|
||||
.replace(intent.getScheme(), scheme) // downcase scheme
|
||||
.replace("fdroidrepo", "http"); // make proper URL
|
||||
showAddRepo(uriString, fingerprint);
|
||||
Log.i("ManageRepo", uriString + " fingerprint: " + fingerprint);
|
||||
}
|
||||
@ -219,10 +235,10 @@ public class ManageRepo extends ListActivity {
|
||||
return repos;
|
||||
}
|
||||
|
||||
protected Repo getRepo(String repoUri, List<Repo> repos) {
|
||||
if (repoUri != null)
|
||||
protected Repo getRepoByAddress(String address, List<Repo> repos) {
|
||||
if (address != null)
|
||||
for (Repo repo : repos)
|
||||
if (repoUri.equals(repo.address))
|
||||
if (address.equals(repo.address))
|
||||
return repo;
|
||||
return null;
|
||||
}
|
||||
@ -237,7 +253,7 @@ public class ManageRepo extends ListActivity {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void showAddRepo(String uriString, String fingerprint) {
|
||||
private void showAddRepo(String newAddress, String newFingerprint) {
|
||||
LayoutInflater li = LayoutInflater.from(this);
|
||||
View view = li.inflate(R.layout.addrepo, null);
|
||||
Builder p = new AlertDialog.Builder(this).setView(view);
|
||||
@ -245,6 +261,9 @@ public class ManageRepo extends ListActivity {
|
||||
final EditText uriEditText = (EditText) view.findViewById(R.id.edit_uri);
|
||||
final EditText fingerprintEditText = (EditText) view.findViewById(R.id.edit_fingerprint);
|
||||
|
||||
List<Repo> repos = getRepos();
|
||||
final Repo repo = getRepoByAddress(newAddress, repos);
|
||||
|
||||
alrt.setIcon(android.R.drawable.ic_menu_add);
|
||||
alrt.setTitle(getString(R.string.repo_add_title));
|
||||
alrt.setButton(DialogInterface.BUTTON_POSITIVE,
|
||||
@ -252,10 +271,15 @@ public class ManageRepo extends ListActivity {
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
addRepo(uriEditText.getText().toString(),
|
||||
fingerprintEditText.getText().toString());
|
||||
changed = true;
|
||||
redraw();
|
||||
String fp = fingerprintEditText.getText().toString();
|
||||
// the DB uses null for no fingerprint but the above
|
||||
// code returns "" rather than null if its blank
|
||||
if (fp.equals(""))
|
||||
fp = null;
|
||||
if (positiveAction == PositiveAction.ADD_NEW)
|
||||
addRepoPositiveAction(uriEditText.getText().toString(), fp, null);
|
||||
else if (positiveAction == PositiveAction.ENABLE)
|
||||
addRepoPositiveAction(null, null, repo);
|
||||
}
|
||||
});
|
||||
|
||||
@ -264,35 +288,74 @@ public class ManageRepo extends ListActivity {
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
setResult(Activity.RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
});
|
||||
alrt.show();
|
||||
|
||||
List<Repo> repos = getRepos();
|
||||
Repo repo = getRepo(uriString, repos);
|
||||
if (repo != null) {
|
||||
TextView tv = (TextView) view.findViewById(R.id.repo_alert);
|
||||
tv.setVisibility(0);
|
||||
tv.setText(R.string.repo_exists);
|
||||
final TextView overwriteMessage = (TextView) view.findViewById(R.id.overwrite_message);
|
||||
overwriteMessage.setVisibility(View.GONE);
|
||||
if (repo == null) {
|
||||
// no existing repo, add based on what we have
|
||||
positiveAction = PositiveAction.ADD_NEW;
|
||||
} else {
|
||||
// found the address in the DB of existing repos
|
||||
final Button addButton = alrt.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
addButton.setEnabled(false);
|
||||
final CheckBox overwriteCheckBox = (CheckBox) view.findViewById(R.id.overwrite_repo);
|
||||
overwriteCheckBox.setVisibility(0);
|
||||
overwriteCheckBox.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
addButton.setEnabled(overwriteCheckBox.isChecked());
|
||||
alrt.setTitle(R.string.repo_exists);
|
||||
overwriteMessage.setVisibility(View.VISIBLE);
|
||||
if (repo.fingerprint == null && newFingerprint != null) {
|
||||
// we're upgrading from unsigned to signed repo
|
||||
overwriteMessage.setText(R.string.repo_exists_add_fingerprint);
|
||||
addButton.setText(R.string.add_key);
|
||||
positiveAction = PositiveAction.ADD_NEW;
|
||||
} else if (newFingerprint == null || newFingerprint.equals(repo.fingerprint)) {
|
||||
// this entry already exists and is not enabled, offer to enable it
|
||||
if (repo.inuse) {
|
||||
alrt.dismiss();
|
||||
Toast.makeText(this, R.string.repo_exists_and_enabled, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
} else {
|
||||
overwriteMessage.setText(R.string.repo_exists_enable);
|
||||
addButton.setText(R.string.enable);
|
||||
positiveAction = PositiveAction.ENABLE;
|
||||
}
|
||||
});
|
||||
// TODO if address and fingerprint match, then enable existing repo
|
||||
// TODO if address matches but fingerprint doesn't, handle this with extra widgets
|
||||
} else {
|
||||
// same address with different fingerprint, this could be
|
||||
// malicious, so force the user to manually delete the repo
|
||||
// before adding this one
|
||||
overwriteMessage.setTextColor(getResources().getColor(R.color.red));
|
||||
overwriteMessage.setText(R.string.repo_delete_to_overwrite);
|
||||
addButton.setText(R.string.overwrite);
|
||||
addButton.setEnabled(false);
|
||||
positiveAction = PositiveAction.IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
if (uriString != null)
|
||||
uriEditText.setText(uriString);
|
||||
if (fingerprint != null)
|
||||
fingerprintEditText.setText(fingerprint);
|
||||
if (newAddress != null)
|
||||
uriEditText.setText(newAddress);
|
||||
if (newFingerprint != null)
|
||||
fingerprintEditText.setText(newFingerprint);
|
||||
}
|
||||
|
||||
private void addRepoPositiveAction(String address, String fingerprint, Repo repo) {
|
||||
if (address != null) {
|
||||
addRepo(address, fingerprint);
|
||||
} else if (repo != null) {
|
||||
// force-enable an existing repo
|
||||
repo.inuse = true;
|
||||
try {
|
||||
DB db = DB.getDB();
|
||||
db.updateRepoByAddress(repo);
|
||||
} finally {
|
||||
DB.releaseDB();
|
||||
}
|
||||
}
|
||||
changed = true;
|
||||
redraw();
|
||||
setResult(Activity.RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -10,7 +10,7 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
@ -10,7 +10,7 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
@ -11,7 +11,7 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
@ -359,7 +359,7 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
|
||||
// This is a signed repo - we download the jar file,
|
||||
// check the signature, and extract the index...
|
||||
Log.d("FDroid", "Getting signed index from " + repo.address + " at " +
|
||||
Log.d("FDroid", "Getting signed index from " + repo.address + " at " +
|
||||
logDateFormat.format(new Date(System.currentTimeMillis())));
|
||||
String address = repo.address + "/index.jar?"
|
||||
+ ctx.getString(R.string.version_name);
|
||||
|
@ -10,7 +10,7 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
@ -10,7 +10,7 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
@ -10,7 +10,7 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
Loading…
x
Reference in New Issue
Block a user