From 1d8fd9c05449863ac6a151a6db87c267c4f55ac2 Mon Sep 17 00:00:00 2001 From: Martin Hibdon Date: Wed, 2 Jul 2014 13:29:58 -0700 Subject: [PATCH] Add communication class for HostAuth We want a separate class for communicating HostAuth objects to and from IEmailService. The issue is that the HostAuth object was being used for both to and from the database, and to and from IEmailService. This is dangerous because The Email app may change out of band with the Exchange app, and may need to change the format of HostAuth. This bit us before when adding OAuth. Now communication to IEmailService is done using HostAuthCompat. Change-Id: I2fb8c2bd8158f58a7bb9bc3dc83a7936948c718c --- .../service/EmailServiceProxy.java | 8 +- .../emailcommon/service/HostAuthCompat.aidl | 18 +++ .../emailcommon/service/HostAuthCompat.java | 132 ++++++++++++++++++ .../emailcommon/service/IEmailService.aidl | 8 +- .../setup/AccountCheckSettingsFragment.java | 7 +- .../email/mail/store/ServiceStore.java | 4 +- .../email/service/EmailServiceStub.java | 4 +- .../email/service/EmailServiceUtils.java | 3 +- 8 files changed, 169 insertions(+), 15 deletions(-) create mode 100644 emailcommon/src/com/android/emailcommon/service/HostAuthCompat.aidl create mode 100644 emailcommon/src/com/android/emailcommon/service/HostAuthCompat.java diff --git a/emailcommon/src/com/android/emailcommon/service/EmailServiceProxy.java b/emailcommon/src/com/android/emailcommon/service/EmailServiceProxy.java index a6ecb8192..eefa5743d 100644 --- a/emailcommon/src/com/android/emailcommon/service/EmailServiceProxy.java +++ b/emailcommon/src/com/android/emailcommon/service/EmailServiceProxy.java @@ -25,9 +25,7 @@ import android.os.RemoteException; import com.android.emailcommon.Device; import com.android.emailcommon.TempDirectory; import com.android.emailcommon.mail.MessagingException; -import com.android.emailcommon.provider.Account; import com.android.emailcommon.provider.HostAuth; -import com.android.emailcommon.provider.Mailbox; import com.android.emailcommon.provider.Policy; import com.android.mail.utils.LogUtils; @@ -145,15 +143,15 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService { * address that serves the specified protocol and credentials sufficient to be authorized * by the server to do so. * - * @param hostAuth the hostauth object to validate + * @param hostAuthCom the hostAuthCom object to validate * @return a Bundle as described above */ @Override - public Bundle validate(final HostAuth hostAuth) throws RemoteException { + public Bundle validate(final HostAuthCompat hostAuthCom) throws RemoteException { setTask(new ProxyTask() { @Override public void run() throws RemoteException{ - mReturn = mService.validate(hostAuth); + mReturn = mService.validate(hostAuthCom); } }, "validate"); waitForCompletion(); diff --git a/emailcommon/src/com/android/emailcommon/service/HostAuthCompat.aidl b/emailcommon/src/com/android/emailcommon/service/HostAuthCompat.aidl new file mode 100644 index 000000000..2e8e46e67 --- /dev/null +++ b/emailcommon/src/com/android/emailcommon/service/HostAuthCompat.aidl @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.emailcommon.service; + +parcelable HostAuthCompat; diff --git a/emailcommon/src/com/android/emailcommon/service/HostAuthCompat.java b/emailcommon/src/com/android/emailcommon/service/HostAuthCompat.java new file mode 100644 index 000000000..4c6b4daa8 --- /dev/null +++ b/emailcommon/src/com/android/emailcommon/service/HostAuthCompat.java @@ -0,0 +1,132 @@ +package com.android.emailcommon.service; + +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; + +import com.android.emailcommon.provider.Credential; +import com.android.emailcommon.provider.HostAuth; +import com.google.common.base.Objects; + +/* + * This class is explicitly for communicating HostAuth information to different implementations of + * IEmailService. We do not want to use the regular HostAuth class because it's used in many ways + * and could need to change at some point, which could break Exchange. + */ +public class HostAuthCompat implements Parcelable { + private String mProtocol; + private String mAddress; + private int mPort; + private int mFlags; + private String mLogin; + private String mPassword; + private String mDomain; + private String mClientCertAlias; + private byte[] mServerCert; + private String mProviderId; + private String mAccessToken; + private String mRefreshToken; + private long mExpiration; + + public HostAuthCompat(HostAuth hostAuth) { + mProtocol = hostAuth.mProtocol; + mAddress = hostAuth.mAddress; + mPort = hostAuth.mPort; + mFlags = hostAuth.mFlags; + mLogin = hostAuth.mLogin; + mPassword = hostAuth.mPassword; + mDomain = hostAuth.mDomain; + mClientCertAlias = hostAuth.mClientCertAlias; + mServerCert = hostAuth.mServerCert; + if (hostAuth.mCredential != null) { + mProviderId = hostAuth.mCredential.mProviderId; + mAccessToken = hostAuth.mCredential.mAccessToken; + mRefreshToken = hostAuth.mCredential.mRefreshToken; + mExpiration = hostAuth.mCredential.mExpiration; + } + } + + public HostAuth toHostAuth() { + HostAuth hostAuth = new HostAuth(); + hostAuth.mProtocol = mProtocol; + hostAuth.mAddress = mAddress; + hostAuth.mPort = mPort; + hostAuth.mFlags = mFlags; + hostAuth.mLogin = mLogin; + hostAuth.mPassword = mPassword; + hostAuth.mDomain = mDomain; + hostAuth.mClientCertAlias = mClientCertAlias; + hostAuth.mServerCert = mServerCert; + if (!TextUtils.isEmpty(mProviderId)) { + hostAuth.mCredential = new Credential(); + hostAuth.mCredential.mProviderId = mProviderId; + hostAuth.mCredential.mAccessToken = mAccessToken; + hostAuth.mCredential.mRefreshToken = mRefreshToken; + hostAuth.mCredential.mExpiration = mExpiration; + } + return hostAuth; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public String toString() { + return "[protocol " + mProtocol + "]"; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(mProtocol); + parcel.writeString(mAddress); + parcel.writeInt(mPort); + parcel.writeInt(mFlags); + parcel.writeString(mLogin); + parcel.writeString(mPassword); + parcel.writeString(mDomain); + parcel.writeString(mClientCertAlias); + parcel.writeByteArray(mServerCert); + parcel.writeString(mProviderId); + parcel.writeString(mAccessToken); + parcel.writeString(mRefreshToken); + parcel.writeLong(mExpiration); + } + + /** + * Supports Parcelable + */ + public HostAuthCompat(Parcel in) { + mProtocol = in.readString(); + mAddress = in.readString(); + mPort = in.readInt(); + mFlags = in.readInt(); + mLogin = in.readString(); + mPassword = in.readString(); + mDomain = in.readString(); + mClientCertAlias = in.readString(); + mServerCert = in.createByteArray(); + mProviderId = in.readString(); + mAccessToken = in.readString(); + mRefreshToken = in.readString(); + mExpiration = in.readLong(); + } + + /** + * Supports Parcelable + */ + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + @Override + public HostAuthCompat createFromParcel(Parcel in) { + return new HostAuthCompat(in); + } + + @Override + public HostAuthCompat[] newArray(int size) { + return new HostAuthCompat[size]; + } + }; + +} diff --git a/emailcommon/src/com/android/emailcommon/service/IEmailService.aidl b/emailcommon/src/com/android/emailcommon/service/IEmailService.aidl index 4f15a053a..f2212bbde 100644 --- a/emailcommon/src/com/android/emailcommon/service/IEmailService.aidl +++ b/emailcommon/src/com/android/emailcommon/service/IEmailService.aidl @@ -17,8 +17,7 @@ package com.android.emailcommon.service; -import com.android.emailcommon.provider.HostAuth; -import com.android.emailcommon.provider.Account; +import com.android.emailcommon.service.HostAuthCompat; import com.android.emailcommon.service.IEmailServiceCallback; import com.android.emailcommon.service.SearchParams; @@ -45,9 +44,7 @@ interface IEmailService { void pushModify(long accountId); // Other email operations. - // TODO: Decouple this call from HostAuth (i.e. use a dedicated data structure, or just pass - // the necessary strings directly). - Bundle validate(in HostAuth hostauth); + Bundle validate(in HostAuthCompat hostauth); int searchMessages(long accountId, in SearchParams params, long destMailboxId); @@ -55,6 +52,7 @@ interface IEmailService { oneway void sendMeetingResponse(long messageId, int response); // Specific to EAS protocol. + // TODO: this passes a HostAuth back in the bundle. We should be using a HostAuthCom for that. Bundle autoDiscover(String userName, String password); // Service control operations (i.e. does not generate a client-server message). diff --git a/src/com/android/email/activity/setup/AccountCheckSettingsFragment.java b/src/com/android/email/activity/setup/AccountCheckSettingsFragment.java index 9918641e2..1a5636a88 100644 --- a/src/com/android/email/activity/setup/AccountCheckSettingsFragment.java +++ b/src/com/android/email/activity/setup/AccountCheckSettingsFragment.java @@ -34,6 +34,7 @@ import com.android.emailcommon.provider.Account; import com.android.emailcommon.provider.HostAuth; import com.android.emailcommon.provider.Policy; import com.android.emailcommon.service.EmailServiceProxy; +import com.android.emailcommon.service.HostAuthCompat; import com.android.emailcommon.utility.Utility; import com.android.mail.utils.LogUtils; @@ -358,8 +359,12 @@ public class AccountCheckSettingsFragment extends Fragment { } else if (errorCode != MessagingException.NO_ERROR) { return new AutoDiscoverResults(false, null); } else { - HostAuth serverInfo = + final HostAuthCompat hostAuthCompat = result.getParcelable(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_HOST_AUTH); + HostAuth serverInfo = null; + if (hostAuthCompat != null) { + serverInfo = hostAuthCompat.toHostAuth(); + } return new AutoDiscoverResults(false, serverInfo); } } diff --git a/src/com/android/email/mail/store/ServiceStore.java b/src/com/android/email/mail/store/ServiceStore.java index ca69aeb90..ae568f516 100644 --- a/src/com/android/email/mail/store/ServiceStore.java +++ b/src/com/android/email/mail/store/ServiceStore.java @@ -26,6 +26,7 @@ import com.android.emailcommon.mail.MessagingException; import com.android.emailcommon.provider.Account; import com.android.emailcommon.provider.HostAuth; import com.android.emailcommon.service.EmailServiceProxy; +import com.android.emailcommon.service.HostAuthCompat; import com.android.emailcommon.service.IEmailService; /** @@ -66,7 +67,8 @@ public class ServiceStore extends Store { if (svc instanceof EmailServiceProxy) { ((EmailServiceProxy)svc).setTimeout(90); } - return svc.validate(mHostAuth); + HostAuthCompat hostAuthCom = new HostAuthCompat(mHostAuth); + return svc.validate(hostAuthCom); } catch (RemoteException e) { throw new MessagingException("Call to validate generated an exception", e); } diff --git a/src/com/android/email/service/EmailServiceStub.java b/src/com/android/email/service/EmailServiceStub.java index 81b4fc3c1..b64abdcd5 100644 --- a/src/com/android/email/service/EmailServiceStub.java +++ b/src/com/android/email/service/EmailServiceStub.java @@ -51,9 +51,9 @@ import com.android.emailcommon.provider.EmailContent.Body; import com.android.emailcommon.provider.EmailContent.BodyColumns; import com.android.emailcommon.provider.EmailContent.MailboxColumns; import com.android.emailcommon.provider.EmailContent.MessageColumns; -import com.android.emailcommon.provider.HostAuth; import com.android.emailcommon.provider.Mailbox; import com.android.emailcommon.service.EmailServiceStatus; +import com.android.emailcommon.service.HostAuthCompat; import com.android.emailcommon.service.IEmailService; import com.android.emailcommon.service.IEmailServiceCallback; import com.android.emailcommon.service.SearchParams; @@ -90,7 +90,7 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm } @Override - public Bundle validate(HostAuth hostauth) throws RemoteException { + public Bundle validate(HostAuthCompat hostAuthCom) throws RemoteException { // TODO Auto-generated method stub return null; } diff --git a/src/com/android/email/service/EmailServiceUtils.java b/src/com/android/email/service/EmailServiceUtils.java index 6218937bf..518c3c443 100644 --- a/src/com/android/email/service/EmailServiceUtils.java +++ b/src/com/android/email/service/EmailServiceUtils.java @@ -54,6 +54,7 @@ import com.android.emailcommon.provider.EmailContent.HostAuthColumns; import com.android.emailcommon.provider.HostAuth; import com.android.emailcommon.service.EmailServiceProxy; import com.android.emailcommon.service.EmailServiceStatus; +import com.android.emailcommon.service.HostAuthCompat; import com.android.emailcommon.service.IEmailService; import com.android.emailcommon.service.IEmailServiceCallback; import com.android.emailcommon.service.SearchParams; @@ -654,7 +655,7 @@ public class EmailServiceUtils { } @Override - public Bundle validate(HostAuth hostauth) throws RemoteException { + public Bundle validate(HostAuthCompat hostauth) throws RemoteException { return null; }