1 package com.android.emailcommon.provider; 2 3 import android.content.ContentValues; 4 import android.content.Context; 5 import android.database.Cursor; 6 import android.net.Uri; 7 import android.os.Parcel; 8 import android.os.Parcelable; 9 import android.provider.BaseColumns; 10 import android.text.TextUtils; 11 12 import com.android.mail.utils.LogUtils; 13 import com.google.common.base.Objects; 14 15 import org.json.JSONException; 16 import org.json.JSONObject; 17 18 public class Credential extends EmailContent implements Parcelable, BaseColumns { 19 20 public static final String TABLE_NAME = "Credential"; 21 public static Uri CONTENT_URI; 22 23 public static final Credential EMPTY = new Credential(-1, "", "", "", 0); 24 25 public static void initCredential() { 26 CONTENT_URI = Uri.parse(EmailContent.CONTENT_URI + "/credential"); 27 } 28 29 // This is the Id of the oauth provider. It can be used to lookup an oauth provider 30 // from oauth.xml. 31 public String mProviderId; 32 public String mAccessToken; 33 public String mRefreshToken; 34 // This is the wall clock time, in milliseconds since Midnight, Jan 1, 1970. 35 public long mExpiration; 36 37 // Name of the authentication provider. 38 public static final String PROVIDER_COLUMN = "provider"; 39 // Access token. 40 public static final String ACCESS_TOKEN_COLUMN = "accessToken"; 41 // Refresh token. 42 public static final String REFRESH_TOKEN_COLUMN = "refreshToken"; 43 // Expiration date for these credentials. 44 public static final String EXPIRATION_COLUMN = "expiration"; 45 46 47 public interface CredentialQuery { 48 public static final int ID_COLUMN_INDEX = 0; 49 public static final int PROVIDER_COLUMN_INDEX = 1; 50 public static final int ACCESS_TOKEN_COLUMN_INDEX = 2; 51 public static final int REFRESH_TOKEN_COLUMN_INDEX = 3; 52 public static final int EXPIRATION_COLUMN_INDEX = 4; 53 54 public static final String[] PROJECTION = new String[] { 55 _ID, 56 PROVIDER_COLUMN, 57 ACCESS_TOKEN_COLUMN, 58 REFRESH_TOKEN_COLUMN, 59 EXPIRATION_COLUMN 60 }; 61 } 62 63 public Credential() { 64 mBaseUri = CONTENT_URI; 65 } 66 67 public Credential(long id, String providerId, String accessToken, String refreshToken, 68 long expiration) { 69 mBaseUri = CONTENT_URI; 70 mId = id; 71 mProviderId = providerId; 72 mAccessToken = accessToken; 73 mRefreshToken = refreshToken; 74 mExpiration = expiration; 75 } 76 77 /** 78 * Restore a Credential from the database, given its unique id 79 * @return the instantiated Credential 80 */ 81 public static Credential restoreCredentialsWithId(Context context, long id) { 82 return EmailContent.restoreContentWithId(context, Credential.class, 83 Credential.CONTENT_URI, CredentialQuery.PROJECTION, id); 84 } 85 86 @Override 87 public void restore(Cursor cursor) { 88 mBaseUri = CONTENT_URI; 89 mId = cursor.getLong(CredentialQuery.ID_COLUMN_INDEX); 90 mProviderId = cursor.getString(CredentialQuery.PROVIDER_COLUMN_INDEX); 91 mAccessToken = cursor.getString(CredentialQuery.ACCESS_TOKEN_COLUMN_INDEX); 92 mRefreshToken = cursor.getString(CredentialQuery.REFRESH_TOKEN_COLUMN_INDEX); 93 mExpiration = cursor.getInt(CredentialQuery.EXPIRATION_COLUMN_INDEX); 94 } 95 96 /** 97 * Supports Parcelable 98 */ 99 @Override 100 public int describeContents() { 101 return 0; 102 } 103 104 /** 105 * Supports Parcelable 106 */ 107 public static final Parcelable.Creator<Credential> CREATOR 108 = new Parcelable.Creator<Credential>() { 109 @Override 110 public Credential createFromParcel(Parcel in) { 111 return new Credential(in); 112 } 113 114 @Override 115 public Credential[] newArray(int size) { 116 return new Credential[size]; 117 } 118 }; 119 120 @Override 121 public void writeToParcel(Parcel dest, int flags) { 122 // mBaseUri is not parceled 123 dest.writeLong(mId); 124 dest.writeString(mProviderId); 125 dest.writeString(mAccessToken); 126 dest.writeString(mRefreshToken); 127 dest.writeLong(mExpiration); 128 } 129 130 /** 131 * Supports Parcelable 132 */ 133 public Credential(Parcel in) { 134 mBaseUri = CONTENT_URI; 135 mId = in.readLong(); 136 mProviderId = in.readString(); 137 mAccessToken = in.readString(); 138 mRefreshToken = in.readString(); 139 mExpiration = in.readLong(); 140 } 141 142 @Override 143 public boolean equals(Object o) { 144 if (!(o instanceof Credential)) { 145 return false; 146 } 147 Credential that = (Credential)o; 148 return TextUtils.equals(mProviderId, that.mProviderId) 149 && TextUtils.equals(mAccessToken, that.mAccessToken) 150 && TextUtils.equals(mRefreshToken, that.mRefreshToken) 151 && mExpiration == that.mExpiration; 152 } 153 154 @Override 155 public int hashCode() { 156 return Objects.hashCode(mAccessToken, mRefreshToken, mExpiration); 157 } 158 159 @Override 160 public ContentValues toContentValues() { 161 ContentValues values = new ContentValues(); 162 if (TextUtils.isEmpty(mProviderId)) { 163 LogUtils.wtf(LogUtils.TAG, "Credential being saved with no provider"); 164 } 165 values.put(PROVIDER_COLUMN, mProviderId); 166 values.put(ACCESS_TOKEN_COLUMN, mAccessToken); 167 values.put(REFRESH_TOKEN_COLUMN, mRefreshToken); 168 values.put(EXPIRATION_COLUMN, mExpiration); 169 return values; 170 } 171 172 protected JSONObject toJson() { 173 try { 174 final JSONObject json = new JSONObject(); 175 json.put(PROVIDER_COLUMN, mProviderId); 176 json.putOpt(ACCESS_TOKEN_COLUMN, mAccessToken); 177 json.putOpt(REFRESH_TOKEN_COLUMN, mRefreshToken); 178 json.put(EXPIRATION_COLUMN, mExpiration); 179 return json; 180 } catch (final JSONException e) { 181 LogUtils.d(LogUtils.TAG, e, "Exception while serializing Credential"); 182 } 183 return null; 184 } 185 186 protected static Credential fromJson(final JSONObject json) { 187 try { 188 final Credential c = new Credential(); 189 c.mProviderId = json.getString(PROVIDER_COLUMN); 190 c.mAccessToken = json.optString(ACCESS_TOKEN_COLUMN); 191 c.mRefreshToken = json.optString(REFRESH_TOKEN_COLUMN); 192 c.mExpiration = json.optInt(EXPIRATION_COLUMN, 0); 193 return c; 194 } catch (final JSONException e) { 195 LogUtils.d(LogUtils.TAG, e, "Exception while deserializing Credential"); 196 } 197 return null; 198 } 199 } 200