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 
initCredential()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 
Credential()63     public Credential() {
64         mBaseUri = CONTENT_URI;
65     }
66 
Credential(long id, String providerId, String accessToken, String refreshToken, long expiration)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      */
restoreCredentialsWithId(Context context, long id)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
restore(Cursor cursor)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
describeContents()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
writeToParcel(Parcel dest, int flags)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     */
Credential(Parcel in)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
equals(Object o)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
hashCode()155    public int hashCode() {
156        return Objects.hashCode(mAccessToken, mRefreshToken, mExpiration);
157    }
158 
159    @Override
toContentValues()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 
toJson()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 
fromJson(final JSONObject json)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