1package com.android.emailcommon.provider;
2
3import android.content.ContentValues;
4import android.content.Context;
5import android.database.Cursor;
6import android.net.Uri;
7import android.os.Parcel;
8import android.os.Parcelable;
9import android.provider.BaseColumns;
10import android.text.TextUtils;
11
12import com.android.mail.utils.LogUtils;
13import com.google.common.base.Objects;
14
15import org.json.JSONException;
16import org.json.JSONObject;
17
18public 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