extract linked id loading from ContentProvider
This commit is contained in:
parent
9ad29318e8
commit
377bf55b70
|
@ -0,0 +1,32 @@
|
|||
package org.sufficientlysecure.keychain.model;
|
||||
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import org.sufficientlysecure.keychain.UserPacketsModel;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
|
||||
|
||||
@AutoValue
|
||||
public abstract class UserPacket implements UserPacketsModel {
|
||||
public static final Factory<UserPacket> FACTORY = new Factory<>(AutoValue_UserPacket::new);
|
||||
public static final SelectUserIdsByMasterKeyIdMapper<UserId> USER_ID_MAPPER =
|
||||
FACTORY.selectUserIdsByMasterKeyIdMapper(AutoValue_UserPacket_UserId::new);
|
||||
public static final SelectUserAttributesByTypeAndMasterKeyIdMapper<UserAttribute> USER_ATTRIBUTE_MAPPER =
|
||||
FACTORY.selectUserAttributesByTypeAndMasterKeyIdMapper(AutoValue_UserPacket_UserAttribute::new);
|
||||
|
||||
@AutoValue
|
||||
public static abstract class UserId implements SelectUserIdsByMasterKeyIdModel {
|
||||
public boolean isVerified() {
|
||||
Integer verified = verified();
|
||||
return verified != null && verified == Certs.VERIFIED_SECRET;
|
||||
}
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
public static abstract class UserAttribute implements SelectUserAttributesByTypeAndMasterKeyIdModel {
|
||||
public boolean isVerified() {
|
||||
Integer verified = verified();
|
||||
return verified != null && verified == Certs.VERIFIED_SECRET;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -109,7 +109,6 @@ public class KeychainContract {
|
|||
|
||||
public static final String PATH_PUBLIC = "public";
|
||||
public static final String PATH_USER_IDS = "user_ids";
|
||||
public static final String PATH_LINKED_IDS = "linked_ids";
|
||||
public static final String PATH_KEYS = "keys";
|
||||
public static final String PATH_CERTS = "certs";
|
||||
|
||||
|
@ -253,15 +252,6 @@ public class KeychainContract {
|
|||
public static Uri buildUserIdsUri(Uri uri) {
|
||||
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_USER_IDS).build();
|
||||
}
|
||||
|
||||
public static Uri buildLinkedIdsUri(long masterKeyId) {
|
||||
return CONTENT_URI.buildUpon().appendPath(Long.toString(masterKeyId)).appendPath(PATH_LINKED_IDS).build();
|
||||
}
|
||||
|
||||
public static Uri buildLinkedIdsUri(Uri uri) {
|
||||
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_LINKED_IDS).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Certs implements CertsColumns, BaseColumns {
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.util.List;
|
|||
|
||||
import android.arch.persistence.db.SupportSQLiteDatabase;
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.UriMatcher;
|
||||
import android.database.Cursor;
|
||||
|
@ -39,7 +38,6 @@ import android.text.TextUtils;
|
|||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.model.AutocryptPeer;
|
||||
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
|
@ -64,7 +62,6 @@ public class KeychainProvider extends ContentProvider implements SimpleContentRe
|
|||
private static final int KEY_RING_USER_IDS = 202;
|
||||
private static final int KEY_RING_PUBLIC = 203;
|
||||
private static final int KEY_RING_CERTS = 205;
|
||||
private static final int KEY_RING_LINKED_IDS = 207;
|
||||
|
||||
private static final int KEY_RINGS_FIND_BY_EMAIL = 400;
|
||||
private static final int KEY_RINGS_FIND_BY_SUBKEY = 401;
|
||||
|
@ -140,9 +137,6 @@ public class KeychainProvider extends ContentProvider implements SimpleContentRe
|
|||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
|
||||
+ KeychainContract.PATH_USER_IDS,
|
||||
KEY_RING_USER_IDS);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
|
||||
+ KeychainContract.PATH_LINKED_IDS,
|
||||
KEY_RING_LINKED_IDS);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
|
||||
+ KeychainContract.PATH_PUBLIC,
|
||||
KEY_RING_PUBLIC);
|
||||
|
@ -473,8 +467,7 @@ public class KeychainProvider extends ContentProvider implements SimpleContentRe
|
|||
}
|
||||
|
||||
case KEY_RINGS_USER_IDS:
|
||||
case KEY_RING_USER_IDS:
|
||||
case KEY_RING_LINKED_IDS: {
|
||||
case KEY_RING_USER_IDS: {
|
||||
HashMap<String, String> projectionMap = new HashMap<>();
|
||||
projectionMap.put(UserPackets._ID, Tables.USER_PACKETS + ".oid AS _id");
|
||||
projectionMap.put(UserPackets.MASTER_KEY_ID, Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID);
|
||||
|
@ -502,15 +495,10 @@ public class KeychainProvider extends ContentProvider implements SimpleContentRe
|
|||
groupBy = Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID
|
||||
+ ", " + Tables.USER_PACKETS + "." + UserPackets.RANK;
|
||||
|
||||
if (match == KEY_RING_LINKED_IDS) {
|
||||
qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.TYPE + " = "
|
||||
+ WrappedUserAttribute.UAT_URI_ATTRIBUTE);
|
||||
} else {
|
||||
qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.TYPE + " IS NULL");
|
||||
}
|
||||
qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.TYPE + " IS NULL");
|
||||
|
||||
// If we are searching for a particular keyring's ids, add where
|
||||
if (match == KEY_RING_USER_IDS || match == KEY_RING_LINKED_IDS) {
|
||||
if (match == KEY_RING_USER_IDS) {
|
||||
qb.appendWhere(" AND ");
|
||||
qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " = ");
|
||||
qb.appendWhereEscapeString(uri.getPathSegments().get(1));
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
@ -42,6 +43,7 @@ import org.sufficientlysecure.keychain.R;
|
|||
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
|
||||
import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
|
||||
|
@ -179,7 +181,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
|
|||
private void showUserIdInfo(final int position) {
|
||||
|
||||
final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position);
|
||||
final int isVerified = mUserIdsAdapter.getIsVerified(position);
|
||||
final boolean isVerified = mUserIdsAdapter.getIsVerified(position) == Certs.VERIFIED_SECRET;
|
||||
|
||||
DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
|
||||
public void run() {
|
||||
|
|
|
@ -35,12 +35,11 @@ import android.widget.TextView;
|
|||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.linked.UriAttribute;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.IdentityAdapter.ViewHolder;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.loader.IdentityDao.AutocryptPeerInfo;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.loader.IdentityDao.IdentityInfo;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.loader.IdentityDao.LinkedIdInfo;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.loader.IdentityDao.UserIdInfo;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.loader.IdentityDao.AutocryptPeerInfo;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
|
||||
import org.sufficientlysecure.keychain.ui.util.SubtleAttentionSeeker;
|
||||
|
@ -158,7 +157,7 @@ public class IdentityAdapter extends RecyclerView.Adapter<ViewHolder> {
|
|||
public void bind(Context context, LinkedIdInfo info, boolean isSecret) {
|
||||
bindVerified(context, info, isSecret);
|
||||
|
||||
UriAttribute uriAttribute = info.getUriAttribute();
|
||||
UriAttribute uriAttribute = info.getLinkedAttribute();
|
||||
bind(context, uriAttribute);
|
||||
}
|
||||
|
||||
|
@ -178,19 +177,12 @@ public class IdentityAdapter extends RecyclerView.Adapter<ViewHolder> {
|
|||
|
||||
private void bindVerified(Context context, IdentityInfo info, boolean isSecret) {
|
||||
if (!isSecret) {
|
||||
switch (info.getVerified()) {
|
||||
case Certs.VERIFIED_SECRET:
|
||||
KeyFormattingUtils.setStatusImage(context, vVerified,
|
||||
null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
|
||||
break;
|
||||
case Certs.VERIFIED_SELF:
|
||||
KeyFormattingUtils.setStatusImage(context, vVerified,
|
||||
null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
|
||||
break;
|
||||
default:
|
||||
KeyFormattingUtils.setStatusImage(context, vVerified,
|
||||
null, State.INVALID, KeyFormattingUtils.DEFAULT_COLOR);
|
||||
break;
|
||||
if (info.isVerified()) {
|
||||
KeyFormattingUtils.setStatusImage(context, vVerified,
|
||||
null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
|
||||
} else {
|
||||
KeyFormattingUtils.setStatusImage(context, vVerified,
|
||||
null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,13 +17,11 @@
|
|||
|
||||
package org.sufficientlysecure.keychain.ui.adapter;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -33,7 +31,6 @@ import android.widget.ViewAnimator;
|
|||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
|
||||
|
@ -184,14 +181,4 @@ public class UserIdsAdapter extends UserAttributesAdapter {
|
|||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
||||
return mInflater.inflate(R.layout.view_key_adv_user_id_item, null);
|
||||
}
|
||||
|
||||
// don't show revoked user ids, irrelevant for average users
|
||||
public static final String USER_IDS_WHERE = UserPackets.IS_REVOKED + " = 0";
|
||||
|
||||
public static CursorLoader createLoader(Context context, Uri dataUri) {
|
||||
Uri baseUri = UserPackets.buildUserIdsUri(dataUri);
|
||||
return new CursorLoader(context, baseUri,
|
||||
UserIdsAdapter.USER_PACKETS_PROJECTION, USER_IDS_WHERE, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.sufficientlysecure.keychain.ui.dialog;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
|
@ -24,7 +25,6 @@ import android.os.Bundle;
|
|||
import android.support.v4.app.DialogFragment;
|
||||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
|
||||
public class UserIdInfoDialogFragment extends DialogFragment {
|
||||
private static final String ARG_IS_REVOKED = "is_revoked";
|
||||
|
@ -33,11 +33,11 @@ public class UserIdInfoDialogFragment extends DialogFragment {
|
|||
/**
|
||||
* Creates new instance of this dialog fragment
|
||||
*/
|
||||
public static UserIdInfoDialogFragment newInstance(boolean isRevoked, int isVerified) {
|
||||
public static UserIdInfoDialogFragment newInstance(boolean isRevoked, boolean isVerified) {
|
||||
UserIdInfoDialogFragment frag = new UserIdInfoDialogFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putBoolean(ARG_IS_REVOKED, isRevoked);
|
||||
args.putInt(ARG_IS_VERIFIED, isVerified);
|
||||
args.putBoolean(ARG_IS_VERIFIED, isVerified);
|
||||
|
||||
frag.setArguments(args);
|
||||
|
||||
|
@ -51,7 +51,7 @@ public class UserIdInfoDialogFragment extends DialogFragment {
|
|||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Activity activity = getActivity();
|
||||
|
||||
int isVerified = getArguments().getInt(ARG_IS_VERIFIED);
|
||||
boolean isVerified = getArguments().getBoolean(ARG_IS_VERIFIED);
|
||||
boolean isRevoked = getArguments().getBoolean(ARG_IS_REVOKED);
|
||||
|
||||
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity);
|
||||
|
@ -62,19 +62,12 @@ public class UserIdInfoDialogFragment extends DialogFragment {
|
|||
title = getString(R.string.user_id_info_revoked_title);
|
||||
message = getString(R.string.user_id_info_revoked_text);
|
||||
} else {
|
||||
switch (isVerified) {
|
||||
case KeychainContract.Certs.VERIFIED_SECRET:
|
||||
title = getString(R.string.user_id_info_certified_title);
|
||||
message = getString(R.string.user_id_info_certified_text);
|
||||
break;
|
||||
case KeychainContract.Certs.VERIFIED_SELF:
|
||||
title = getString(R.string.user_id_info_uncertified_title);
|
||||
message = getString(R.string.user_id_info_uncertified_text);
|
||||
break;
|
||||
default:
|
||||
title = getString(R.string.user_id_info_invalid_title);
|
||||
message = getString(R.string.user_id_info_invalid_text);
|
||||
break;
|
||||
if (isVerified) {
|
||||
title = getString(R.string.user_id_info_certified_title);
|
||||
message = getString(R.string.user_id_info_certified_text);
|
||||
} else {
|
||||
title = getString(R.string.user_id_info_uncertified_title);
|
||||
message = getString(R.string.user_id_info_uncertified_text);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,15 +18,12 @@
|
|||
package org.sufficientlysecure.keychain.ui.keyview;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
@ -37,10 +34,7 @@ import android.support.annotation.Nullable;
|
|||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentManager.OnBackStackChangedListener;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -62,15 +56,13 @@ import org.sufficientlysecure.keychain.operations.results.LinkedVerifyResult;
|
|||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||
import org.sufficientlysecure.keychain.provider.KeyRepository;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
|
||||
import org.sufficientlysecure.keychain.service.CertifyActionsParcel;
|
||||
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.IdentityAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.LinkedIdViewFragment.ViewHolder.VerifyState;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.loader.IdentityDao;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.loader.IdentityDao.LinkedIdInfo;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
|
@ -81,14 +73,11 @@ import org.sufficientlysecure.keychain.ui.widget.CertifyKeySpinner;
|
|||
import timber.log.Timber;
|
||||
|
||||
|
||||
public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
||||
LoaderManager.LoaderCallbacks<Cursor>, OnBackStackChangedListener {
|
||||
public class LinkedIdViewFragment extends CryptoOperationFragment implements OnBackStackChangedListener {
|
||||
|
||||
private static final String ARG_DATA_URI = "data_uri";
|
||||
private static final String ARG_LID_RANK = "rank";
|
||||
private static final String ARG_IS_SECRET = "verified";
|
||||
private static final String ARG_MASTER_KEY_ID = "master_key_id";
|
||||
private static final int LOADER_ID_LINKED_ID = 1;
|
||||
|
||||
private long masterKeyId;
|
||||
private boolean isSecret;
|
||||
|
@ -98,16 +87,14 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
|||
|
||||
private AsyncTask taskInProgress;
|
||||
|
||||
private Uri dataUri;
|
||||
private ViewHolder viewHolder;
|
||||
private int lidRank;
|
||||
private long certifyKeyId;
|
||||
|
||||
public static LinkedIdViewFragment newInstance(Uri dataUri, int rank, boolean isSecret, long masterKeyId) {
|
||||
public static LinkedIdViewFragment newInstance(long masterKeyId, int rank, boolean isSecret) {
|
||||
LinkedIdViewFragment frag = new LinkedIdViewFragment();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable(ARG_DATA_URI, dataUri);
|
||||
args.putInt(ARG_LID_RANK, rank);
|
||||
args.putBoolean(ARG_IS_SECRET, isSecret);
|
||||
args.putLong(ARG_MASTER_KEY_ID, masterKeyId);
|
||||
|
@ -127,57 +114,27 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
|||
super.onCreate(savedInstanceState);
|
||||
|
||||
Bundle args = getArguments();
|
||||
dataUri = args.getParcelable(ARG_DATA_URI);
|
||||
lidRank = args.getInt(ARG_LID_RANK);
|
||||
|
||||
isSecret = args.getBoolean(ARG_IS_SECRET);
|
||||
masterKeyId = args.getLong(ARG_MASTER_KEY_ID);
|
||||
|
||||
getLoaderManager().initLoader(LOADER_ID_LINKED_ID, null, this);
|
||||
|
||||
IdentityDao identityDao = IdentityDao.getInstance(getContext());
|
||||
GenericLiveData<LinkedIdInfo> uriAttributeLiveData =
|
||||
new GenericLiveData<>(getContext(), null, () -> identityDao.getLinkedIdInfo(masterKeyId, lidRank));
|
||||
uriAttributeLiveData.observe(this, this::onLinkedIdInfoLoaded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
switch (id) {
|
||||
case LOADER_ID_LINKED_ID:
|
||||
return new CursorLoader(getContext(), dataUri,
|
||||
UserIdsAdapter.USER_PACKETS_PROJECTION,
|
||||
Tables.USER_PACKETS + "." + UserPackets.RANK
|
||||
+ " = " + Integer.toString(lidRank), null, null);
|
||||
default:
|
||||
return null;
|
||||
private void onLinkedIdInfoLoaded(LinkedIdInfo linkedIdInfo) {
|
||||
if (linkedIdInfo == null) {
|
||||
Timber.e("error loading identity");
|
||||
Notify.create(getActivity(), "Error loading linked identity!",
|
||||
Notify.LENGTH_LONG, Style.ERROR).show();
|
||||
finishFragment();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
||||
switch (loader.getId()) {
|
||||
case LOADER_ID_LINKED_ID:
|
||||
|
||||
// Nothing to load means break if we are *expected* to load
|
||||
if (!cursor.moveToFirst()) {
|
||||
// Or just ignore, this is probably some intermediate state during certify
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
int certStatus = cursor.getInt(UserIdsAdapter.INDEX_VERIFIED);
|
||||
|
||||
byte[] data = cursor.getBlob(UserIdsAdapter.INDEX_ATTRIBUTE_DATA);
|
||||
UriAttribute linkedId = LinkedAttribute.fromAttributeData(data);
|
||||
|
||||
loadIdentity(linkedId, certStatus);
|
||||
|
||||
} catch (IOException e) {
|
||||
Timber.e(e, "error parsing identity");
|
||||
Notify.create(getActivity(), "Error parsing identity!",
|
||||
Notify.LENGTH_LONG, Style.ERROR).show();
|
||||
finishFragment();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
loadIdentity(linkedIdInfo.getLinkedAttribute(), linkedIdInfo.isVerified());
|
||||
}
|
||||
|
||||
public void finishFragment() {
|
||||
|
@ -188,28 +145,19 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
|||
});
|
||||
}
|
||||
|
||||
private void loadIdentity(UriAttribute linkedId, int certStatus) {
|
||||
private void loadIdentity(LinkedAttribute linkedId, boolean isVerified) {
|
||||
this.linkedId = linkedId;
|
||||
|
||||
if (this.linkedId instanceof LinkedAttribute) {
|
||||
LinkedResource res = ((LinkedAttribute) this.linkedId).mResource;
|
||||
linkedResource = (LinkedTokenResource) res;
|
||||
}
|
||||
LinkedResource res = ((LinkedAttribute) this.linkedId).mResource;
|
||||
linkedResource = (LinkedTokenResource) res;
|
||||
|
||||
if (!isSecret) {
|
||||
switch (certStatus) {
|
||||
case Certs.VERIFIED_SECRET:
|
||||
KeyFormattingUtils.setStatusImage(getContext(), viewHolder.mLinkedIdHolder.vVerified,
|
||||
null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
|
||||
break;
|
||||
case Certs.VERIFIED_SELF:
|
||||
KeyFormattingUtils.setStatusImage(getContext(), viewHolder.mLinkedIdHolder.vVerified,
|
||||
null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
|
||||
break;
|
||||
default:
|
||||
KeyFormattingUtils.setStatusImage(getContext(), viewHolder.mLinkedIdHolder.vVerified,
|
||||
null, State.INVALID, KeyFormattingUtils.DEFAULT_COLOR);
|
||||
break;
|
||||
if (isVerified) {
|
||||
KeyFormattingUtils.setStatusImage(getContext(), viewHolder.mLinkedIdHolder.vVerified,
|
||||
null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
|
||||
} else {
|
||||
KeyFormattingUtils.setStatusImage(getContext(), viewHolder.mLinkedIdHolder.vVerified,
|
||||
null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
|
||||
}
|
||||
} else {
|
||||
viewHolder.mLinkedIdHolder.vVerified.setImageResource(R.drawable.octo_link_24dp);
|
||||
|
@ -219,13 +167,6 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
|||
|
||||
setShowVerifying(false);
|
||||
|
||||
// no resource, nothing further we can do…
|
||||
if (linkedResource == null) {
|
||||
viewHolder.vButtonView.setVisibility(View.GONE);
|
||||
viewHolder.vButtonVerify.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (linkedResource.isViewable()) {
|
||||
viewHolder.vButtonView.setVisibility(View.VISIBLE);
|
||||
viewHolder.vButtonView.setOnClickListener(v -> {
|
||||
|
@ -241,11 +182,6 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
private final View vButtonView;
|
||||
private final ViewAnimator vVerifyingContainer;
|
||||
|
@ -395,25 +331,29 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
|||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
|
||||
View root = inflater.inflate(R.layout.linked_id_view_fragment, null);
|
||||
View root = inflater.inflate(R.layout.linked_id_view_fragment, superContainer, false);
|
||||
Context context = getContext();
|
||||
if (context == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
viewHolder = new ViewHolder(root);
|
||||
root.setTag(viewHolder);
|
||||
|
||||
((ImageView) root.findViewById(R.id.status_icon_verified))
|
||||
.setColorFilter(ContextCompat.getColor(getContext(), R.color.android_green_light),
|
||||
.setColorFilter(ContextCompat.getColor(context, R.color.android_green_light),
|
||||
PorterDuff.Mode.SRC_IN);
|
||||
((ImageView) root.findViewById(R.id.status_icon_invalid))
|
||||
.setColorFilter(ContextCompat.getColor(getContext(), R.color.android_red_light),
|
||||
.setColorFilter(ContextCompat.getColor(context, R.color.android_red_light),
|
||||
PorterDuff.Mode.SRC_IN);
|
||||
|
||||
viewHolder.vButtonVerify.setOnClickListener(v -> verifyResource());
|
||||
viewHolder.vButtonRetry.setOnClickListener(v -> verifyResource());
|
||||
viewHolder.vButtonConfirm.setOnClickListener(v -> initiateCertifying());
|
||||
|
||||
CertificationDao certificationDao = CertificationDao.getInstance(getContext());
|
||||
CertificationDao certificationDao = CertificationDao.getInstance(context);
|
||||
LiveData<CertDetails> certDetailsLiveData = new GenericLiveData<>(
|
||||
getContext(), null, () -> certificationDao.getVerifyingCertDetails(masterKeyId, lidRank));
|
||||
context, null, () -> certificationDao.getVerifyingCertDetails(masterKeyId, lidRank));
|
||||
certDetailsLiveData.observe(this, this::onLoadCertDetails);
|
||||
|
||||
return root;
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.arch.persistence.db.SupportSQLiteDatabase;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
|
@ -33,63 +33,40 @@ import android.graphics.drawable.Drawable;
|
|||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.squareup.sqldelight.SqlDelightQuery;
|
||||
import org.openintents.openpgp.util.OpenPgpApi;
|
||||
import org.sufficientlysecure.keychain.linked.LinkedAttribute;
|
||||
import org.sufficientlysecure.keychain.linked.UriAttribute;
|
||||
import org.sufficientlysecure.keychain.model.AutocryptPeer;
|
||||
import org.sufficientlysecure.keychain.model.UserPacket;
|
||||
import org.sufficientlysecure.keychain.model.UserPacket.UserAttribute;
|
||||
import org.sufficientlysecure.keychain.model.UserPacket.UserId;
|
||||
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
|
||||
import org.sufficientlysecure.keychain.provider.AutocryptPeerDao;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
|
||||
import org.sufficientlysecure.keychain.ui.util.PackageIconGetter;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
||||
public class IdentityDao {
|
||||
private static final String[] USER_PACKETS_PROJECTION = new String[]{
|
||||
UserPackets._ID,
|
||||
UserPackets.TYPE,
|
||||
UserPackets.USER_ID,
|
||||
UserPackets.ATTRIBUTE_DATA,
|
||||
UserPackets.RANK,
|
||||
UserPackets.VERIFIED,
|
||||
UserPackets.IS_PRIMARY,
|
||||
UserPackets.IS_REVOKED,
|
||||
UserPackets.NAME,
|
||||
UserPackets.EMAIL,
|
||||
UserPackets.COMMENT,
|
||||
};
|
||||
private static final int INDEX_ID = 0;
|
||||
private static final int INDEX_TYPE = 1;
|
||||
private static final int INDEX_USER_ID = 2;
|
||||
private static final int INDEX_ATTRIBUTE_DATA = 3;
|
||||
private static final int INDEX_RANK = 4;
|
||||
private static final int INDEX_VERIFIED = 5;
|
||||
private static final int INDEX_IS_PRIMARY = 6;
|
||||
private static final int INDEX_IS_REVOKED = 7;
|
||||
private static final int INDEX_NAME = 8;
|
||||
private static final int INDEX_EMAIL = 9;
|
||||
private static final int INDEX_COMMENT = 10;
|
||||
|
||||
private static final String USER_IDS_WHERE = UserPackets.IS_REVOKED + " = 0";
|
||||
|
||||
|
||||
private final ContentResolver contentResolver;
|
||||
private final SupportSQLiteDatabase db;
|
||||
private final PackageIconGetter packageIconGetter;
|
||||
private final PackageManager packageManager;
|
||||
private final AutocryptPeerDao autocryptPeerDao;
|
||||
|
||||
static IdentityDao getInstance(Context context) {
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
public static IdentityDao getInstance(Context context) {
|
||||
SupportSQLiteDatabase db = new KeychainDatabase(context).getWritableDatabase();
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
PackageIconGetter iconGetter = PackageIconGetter.getInstance(context);
|
||||
AutocryptPeerDao autocryptPeerDao = AutocryptPeerDao.getInstance(context);
|
||||
return new IdentityDao(contentResolver, packageManager, iconGetter, autocryptPeerDao);
|
||||
return new IdentityDao(db, packageManager, iconGetter, autocryptPeerDao);
|
||||
}
|
||||
|
||||
private IdentityDao(ContentResolver contentResolver, PackageManager packageManager, PackageIconGetter iconGetter,
|
||||
private IdentityDao(SupportSQLiteDatabase db,
|
||||
PackageManager packageManager, PackageIconGetter iconGetter,
|
||||
AutocryptPeerDao autocryptPeerDao) {
|
||||
this.db = db;
|
||||
this.packageManager = packageManager;
|
||||
this.contentResolver = contentResolver;
|
||||
this.packageIconGetter = iconGetter;
|
||||
this.autocryptPeerDao = autocryptPeerDao;
|
||||
}
|
||||
|
@ -156,73 +133,70 @@ public class IdentityDao {
|
|||
}
|
||||
|
||||
private void loadLinkedIds(ArrayList<IdentityInfo> identities, long masterKeyId) {
|
||||
Cursor cursor = contentResolver.query(UserPackets.buildLinkedIdsUri(masterKeyId),
|
||||
USER_PACKETS_PROJECTION, USER_IDS_WHERE, null, null);
|
||||
if (cursor == null) {
|
||||
Timber.e("Error loading key items!");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
SqlDelightQuery query = UserPacket.FACTORY.selectUserAttributesByTypeAndMasterKeyId(
|
||||
(long) WrappedUserAttribute.UAT_URI_ATTRIBUTE, masterKeyId);
|
||||
try (Cursor cursor = db.query(query)) {
|
||||
while (cursor.moveToNext()) {
|
||||
int rank = cursor.getInt(INDEX_RANK);
|
||||
int verified = cursor.getInt(INDEX_VERIFIED);
|
||||
boolean isPrimary = cursor.getInt(INDEX_IS_PRIMARY) != 0;
|
||||
UserAttribute userAttribute = UserPacket.USER_ATTRIBUTE_MAPPER.map(cursor);
|
||||
|
||||
byte[] data = cursor.getBlob(INDEX_ATTRIBUTE_DATA);
|
||||
try {
|
||||
UriAttribute uriAttribute = LinkedAttribute.fromAttributeData(data);
|
||||
if (uriAttribute instanceof LinkedAttribute) {
|
||||
LinkedIdInfo identityInfo = LinkedIdInfo.create(rank, verified, isPrimary, uriAttribute);
|
||||
identities.add(identityInfo);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Timber.e(e, "Failed parsing uri attribute");
|
||||
}
|
||||
LinkedIdInfo linkedIdInfo = parseLinkedIdInfo(userAttribute);
|
||||
identities.add(linkedIdInfo);
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadUserIds(ArrayList<IdentityInfo> identities, long masterKeyId) {
|
||||
Cursor cursor = contentResolver.query(UserPackets.buildUserIdsUri(masterKeyId),
|
||||
USER_PACKETS_PROJECTION, USER_IDS_WHERE, null, null);
|
||||
if (cursor == null) {
|
||||
Timber.e("Error loading key items!");
|
||||
return;
|
||||
public LinkedIdInfo getLinkedIdInfo(long masterKeyId, int rank) {
|
||||
SqlDelightQuery query = UserPacket.FACTORY.selectSpecificUserAttribute(
|
||||
(long) WrappedUserAttribute.UAT_URI_ATTRIBUTE, masterKeyId, rank);
|
||||
try (Cursor cursor = db.query(query)) {
|
||||
if (cursor.moveToFirst()) {
|
||||
UserAttribute userAttribute = UserPacket.USER_ATTRIBUTE_MAPPER.map(cursor);
|
||||
|
||||
return parseLinkedIdInfo(userAttribute);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private LinkedIdInfo parseLinkedIdInfo(UserAttribute userAttribute) {
|
||||
try {
|
||||
UriAttribute uriAttribute = LinkedAttribute.fromAttributeData(userAttribute.attribute_data());
|
||||
if (uriAttribute instanceof LinkedAttribute) {
|
||||
return LinkedIdInfo.create(userAttribute.rank(),
|
||||
userAttribute.isVerified(), userAttribute.is_primary(), (LinkedAttribute) uriAttribute);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Timber.e(e, "Failed parsing uri attribute");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void loadUserIds(ArrayList<IdentityInfo> identities, long masterKeyId) {
|
||||
SqlDelightQuery query = UserPacket.FACTORY.selectUserIdsByMasterKeyId(masterKeyId);
|
||||
try (Cursor cursor = db.query(query)) {
|
||||
while (cursor.moveToNext()) {
|
||||
int rank = cursor.getInt(INDEX_RANK);
|
||||
int verified = cursor.getInt(INDEX_VERIFIED);
|
||||
boolean isPrimary = cursor.getInt(INDEX_IS_PRIMARY) != 0;
|
||||
UserId userId = UserPacket.USER_ID_MAPPER.map(cursor);
|
||||
|
||||
if (!cursor.isNull(INDEX_NAME) || !cursor.isNull(INDEX_EMAIL)) {
|
||||
String name = cursor.getString(INDEX_NAME);
|
||||
String email = cursor.getString(INDEX_EMAIL);
|
||||
String comment = cursor.getString(INDEX_COMMENT);
|
||||
|
||||
IdentityInfo identityInfo = UserIdInfo.create(rank, verified, isPrimary, name, email, comment);
|
||||
if (userId.name() != null || userId.email() != null) {
|
||||
IdentityInfo identityInfo = UserIdInfo.create(
|
||||
userId.rank(), userId.isVerified(), userId.is_primary(), userId.name(), userId.email(), userId.comment());
|
||||
identities.add(identityInfo);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IdentityInfo {
|
||||
int getRank();
|
||||
int getVerified();
|
||||
boolean isVerified();
|
||||
boolean isPrimary();
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
public abstract static class UserIdInfo implements IdentityInfo {
|
||||
public abstract int getRank();
|
||||
public abstract int getVerified();
|
||||
public abstract boolean isVerified();
|
||||
public abstract boolean isPrimary();
|
||||
|
||||
@Nullable
|
||||
|
@ -232,29 +206,29 @@ public class IdentityDao {
|
|||
@Nullable
|
||||
public abstract String getComment();
|
||||
|
||||
static UserIdInfo create(int rank, int verified, boolean isPrimary, String name, String email,
|
||||
static UserIdInfo create(int rank, boolean isVerified, boolean isPrimary, String name, String email,
|
||||
String comment) {
|
||||
return new AutoValue_IdentityDao_UserIdInfo(rank, verified, isPrimary, name, email, comment);
|
||||
return new AutoValue_IdentityDao_UserIdInfo(rank, isVerified, isPrimary, name, email, comment);
|
||||
}
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
public abstract static class LinkedIdInfo implements IdentityInfo {
|
||||
public abstract int getRank();
|
||||
public abstract int getVerified();
|
||||
public abstract boolean isVerified();
|
||||
public abstract boolean isPrimary();
|
||||
|
||||
public abstract UriAttribute getUriAttribute();
|
||||
public abstract LinkedAttribute getLinkedAttribute();
|
||||
|
||||
static LinkedIdInfo create(int rank, int verified, boolean isPrimary, UriAttribute uriAttribute) {
|
||||
return new AutoValue_IdentityDao_LinkedIdInfo(rank, verified, isPrimary, uriAttribute);
|
||||
static LinkedIdInfo create(int rank, boolean isVerified, boolean isPrimary, LinkedAttribute linkedAttribute) {
|
||||
return new AutoValue_IdentityDao_LinkedIdInfo(rank, isVerified, isPrimary, linkedAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
public abstract static class AutocryptPeerInfo implements IdentityInfo {
|
||||
public abstract int getRank();
|
||||
public abstract int getVerified();
|
||||
public abstract boolean isVerified();
|
||||
public abstract boolean isPrimary();
|
||||
|
||||
public abstract String getIdentity();
|
||||
|
@ -268,13 +242,13 @@ public class IdentityDao {
|
|||
|
||||
static AutocryptPeerInfo create(UserIdInfo userIdInfo, String autocryptPeer, String packageName,
|
||||
Drawable appIcon, Intent autocryptPeerIntent) {
|
||||
return new AutoValue_IdentityDao_AutocryptPeerInfo(userIdInfo.getRank(), userIdInfo.getVerified(),
|
||||
return new AutoValue_IdentityDao_AutocryptPeerInfo(userIdInfo.getRank(), userIdInfo.isVerified(),
|
||||
userIdInfo.isPrimary(), autocryptPeer, packageName, appIcon, userIdInfo, autocryptPeerIntent);
|
||||
}
|
||||
|
||||
static AutocryptPeerInfo create(String autocryptPeer, String packageName, Drawable appIcon, Intent autocryptPeerIntent) {
|
||||
return new AutoValue_IdentityDao_AutocryptPeerInfo(
|
||||
0, Certs.VERIFIED_SELF, false, autocryptPeer, packageName, appIcon, null, autocryptPeerIntent);
|
||||
0, false, false, autocryptPeer, packageName, appIcon, null, autocryptPeerIntent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,20 +18,17 @@
|
|||
package org.sufficientlysecure.keychain.ui.keyview.presenter;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
|
||||
import org.sufficientlysecure.keychain.provider.AutocryptPeerDao;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.IdentityAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.IdentityAdapter.IdentityClickListener;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment;
|
||||
|
@ -114,17 +111,14 @@ public class IdentitiesPresenter implements Observer<List<IdentityInfo>> {
|
|||
}
|
||||
|
||||
private void showLinkedId(final LinkedIdInfo info) {
|
||||
Uri dataUri = UserPackets.buildLinkedIdsUri(KeyRings.buildGenericKeyRingUri(masterKeyId));
|
||||
LinkedIdViewFragment frag = LinkedIdViewFragment.newInstance(dataUri, info.getRank(), isSecret, masterKeyId);
|
||||
LinkedIdViewFragment frag = LinkedIdViewFragment.newInstance(masterKeyId, info.getRank(), isSecret);
|
||||
|
||||
viewKeyMvpView.switchToFragment(frag, "linked_id");
|
||||
}
|
||||
|
||||
private void showUserIdInfo(UserIdInfo info) {
|
||||
if (!isSecret) {
|
||||
final int isVerified = info.getVerified();
|
||||
|
||||
UserIdInfoDialogFragment dialogFragment = UserIdInfoDialogFragment.newInstance(false, isVerified);
|
||||
UserIdInfoDialogFragment dialogFragment = UserIdInfoDialogFragment.newInstance(false, info.isVerified());
|
||||
viewKeyMvpView.showDialogFragment(dialogFragment, "userIdInfoDialog");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -727,8 +727,6 @@
|
|||
<string name="user_id_info_certified_text">"This identity has been confirmed by you."</string>
|
||||
<string name="user_id_info_uncertified_title">"Not confirmed"</string>
|
||||
<string name="user_id_info_uncertified_text">"This identity has not been confirmed yet. You cannot be sure if the identity really corresponds to a specific person."</string>
|
||||
<string name="user_id_info_invalid_title">"Invalid"</string>
|
||||
<string name="user_id_info_invalid_text">"Something is wrong with this identity!"</string>
|
||||
|
||||
<!-- Key trust -->
|
||||
<string name="key_trust_no_cloud_evidence">"No proof from the Internet on this key’s trustworthiness."</string>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import java.lang.Integer;
|
||||
|
||||
-- TODO implement. this is only here for reference in SQLDelight
|
||||
CREATE TABLE IF NOT EXISTS certs(
|
||||
master_key_id INTEGER NOT NULL,
|
||||
rank INTEGER NOT NULL,
|
||||
key_id_certifier INTEGER NOT NULL,
|
||||
type INTEGER NOT NULL,
|
||||
verified INTEGER NOT NULL,
|
||||
verified INTEGER AS Integer NOT NULL,
|
||||
creation INTEGER NOT NULL,
|
||||
data BLOB NOT NULL,
|
||||
PRIMARY KEY(master_key_id, rank, key_id_certifier),
|
||||
|
|
|
@ -1,15 +1,35 @@
|
|||
import java.lang.Integer;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_packets(
|
||||
master_key_id INTEGER,
|
||||
master_key_id INTEGER NOT NULL,
|
||||
rank INTEGER AS Integer NOT NULL,
|
||||
type INTEGER,
|
||||
user_id TEXT,
|
||||
name TEXT,
|
||||
email TEXT,
|
||||
comment TEXT,
|
||||
attribute_data BLOB,
|
||||
is_primary INTEGER,
|
||||
is_revoked INTEGER,
|
||||
rank INTEGER,
|
||||
is_primary INTEGER AS Boolean NOT NULL,
|
||||
is_revoked INTEGER AS Boolean NOT NULL,
|
||||
PRIMARY KEY(master_key_id, rank),
|
||||
FOREIGN KEY(master_key_id) REFERENCES
|
||||
keyrings_public(master_key_id) ON DELETE CASCADE
|
||||
);
|
||||
);
|
||||
|
||||
selectUserIdsByMasterKeyId:
|
||||
SELECT user_packets.master_key_id, user_packets.rank, user_id, name, email, comment, is_primary, is_revoked, certs.verified
|
||||
FROM user_packets
|
||||
LEFT JOIN certs ON ( user_packets.master_key_id = certs.master_key_id AND user_packets.rank = certs.rank AND certs.verified > 0 )
|
||||
WHERE user_packets.type IS NULL AND user_packets.is_revoked = 0 AND user_packets.master_key_id = ?;
|
||||
|
||||
selectUserAttributesByTypeAndMasterKeyId:
|
||||
SELECT user_packets.master_key_id, user_packets.rank, attribute_data, is_primary, is_revoked, certs.verified
|
||||
FROM user_packets
|
||||
LEFT JOIN certs ON ( user_packets.master_key_id = certs.master_key_id AND user_packets.rank = certs.rank AND certs.verified > 0 )
|
||||
WHERE user_packets.type = ? AND user_packets.is_revoked = 0 AND user_packets.master_key_id = ?;
|
||||
|
||||
selectSpecificUserAttribute:
|
||||
SELECT user_packets.master_key_id, user_packets.rank, attribute_data, is_primary, is_revoked, certs.verified
|
||||
FROM user_packets
|
||||
LEFT JOIN certs ON ( user_packets.master_key_id = certs.master_key_id AND user_packets.rank = certs.rank AND certs.verified > 0 )
|
||||
WHERE user_packets.type = ? AND user_packets.master_key_id = ? AND user_packets.rank = ?;
|
||||
|
|
Loading…
Reference in a new issue