1f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki/* 2f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * Copyright (C) 2010 The Android Open Source Project 3f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * 4f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 5f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * you may not use this file except in compliance with the License. 6f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * You may obtain a copy of the License at 7f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * 8f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 9f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * 10f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * Unless required by applicable law or agreed to in writing, software 11f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 12f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * See the License for the specific language governing permissions and 14f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * limitations under the License. 15f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki */ 16f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 17c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankpackage com.android.emailcommon; 18ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler 19f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onukiimport android.content.Context; 20f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onukiimport android.content.pm.ApplicationInfo; 21f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onukiimport android.content.pm.PackageManager.NameNotFoundException; 22f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onukiimport android.os.Bundle; 23560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy 24560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedyimport com.android.mail.utils.LogUtils; 25f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 26c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankimport java.io.Serializable; 27f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onukiimport java.lang.reflect.Method; 28f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 29f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki/** 30f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * A bridge class to the email vendor policy apk. 31f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * 32f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * <p>Email vendor policy is a system apk named "com.android.email.helper". When exists, it must 33f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * contain a class called "com.android.email.policy.EmailPolicy" with a static public method 34f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * <code>Bundle getPolicy(String, Bundle)</code>, which serves vendor specific configurations. 35f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * 36f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * <p>A vendor policy apk is optional. The email application will operate properly when none is 37f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * found. 38f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki */ 39f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onukipublic class VendorPolicyLoader { 40f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki private static final String POLICY_PACKAGE = "com.android.email.policy"; 41f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki private static final String POLICY_CLASS = POLICY_PACKAGE + ".EmailPolicy"; 42f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki private static final String GET_POLICY_METHOD = "getPolicy"; 43f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki private static final Class<?>[] ARGS = new Class<?>[] {String.class, Bundle.class}; 44f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 45ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler // call keys and i/o bundle keys 46ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler // when there is only one parameter or return value, use call key 47f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki private static final String USE_ALTERNATE_EXCHANGE_STRINGS = "useAlternateExchangeStrings"; 48ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler private static final String GET_IMAP_ID = "getImapId"; 49ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler private static final String GET_IMAP_ID_USER = "getImapId.user"; 50ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler private static final String GET_IMAP_ID_HOST = "getImapId.host"; 51ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler private static final String GET_IMAP_ID_CAPA = "getImapId.capabilities"; 52ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler private static final String FIND_PROVIDER = "findProvider"; 53ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler private static final String FIND_PROVIDER_IN_URI = "findProvider.inUri"; 54ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler private static final String FIND_PROVIDER_IN_USER = "findProvider.inUser"; 55ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler private static final String FIND_PROVIDER_OUT_URI = "findProvider.outUri"; 56ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler private static final String FIND_PROVIDER_OUT_USER = "findProvider.outUser"; 57ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler private static final String FIND_PROVIDER_NOTE = "findProvider.note"; 58f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 59f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki /** Singleton instance */ 60f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki private static VendorPolicyLoader sInstance; 61f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 62f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki private final Method mPolicyMethod; 63f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 64f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki public static VendorPolicyLoader getInstance(Context context) { 65f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki if (sInstance == null) { 66f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki // It's okay to instantiate VendorPolicyLoader multiple times. No need to synchronize. 67f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki sInstance = new VendorPolicyLoader(context); 68f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 69f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki return sInstance; 70f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 71f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 7236d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki /** 7336d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki * For testing only. 7436d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki * 7536d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki * Replaces the instance with a new instance that loads a specified class. 7636d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki */ 7736d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki public static void injectPolicyForTest(Context context, String apkPackageName, Class<?> clazz) { 7836d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki String name = clazz.getName(); 79560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.d(Logging.LOG_TAG, String.format("Using policy: package=%s name=%s", 8036d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki apkPackageName, name)); 8136d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki sInstance = new VendorPolicyLoader(context, apkPackageName, name, true); 8236d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki } 8336d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki 8436d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki /** 8536d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki * For testing only. 8636d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki * 8736d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki * Clear the instance so that the next {@link #getInstance} call will return a regular, 8836d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki * non-injected instance. 8936d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki */ 9036d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki public static void clearInstanceForTest() { 9136d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki sInstance = null; 9236d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki } 9336d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki 94f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki private VendorPolicyLoader(Context context) { 95f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki this(context, POLICY_PACKAGE, POLICY_CLASS, false); 96f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 97f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 98f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki /** 99f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * Constructor for testing, where we need to use an alternate package/class name, and skip 100f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * the system apk check. 101f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki */ 10217d3a29c9d8f7a27c463239f190bdcc4e0804527Jerry Xie public VendorPolicyLoader(Context context, String apkPackageName, String className, 103f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki boolean allowNonSystemApk) { 10436d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki if (!allowNonSystemApk && !isSystemPackage(context, apkPackageName)) { 105f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki mPolicyMethod = null; 106f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki return; 107f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 108f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 109f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki Class<?> clazz = null; 110f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki Method method = null; 111f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki try { 11236d3dfaeac1a80561ef41a78ecc9bf3583d0ca7bMakoto Onuki final Context policyContext = context.createPackageContext(apkPackageName, 113f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE); 114f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki final ClassLoader classLoader = policyContext.getClassLoader(); 115f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki clazz = classLoader.loadClass(className); 116f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki method = clazz.getMethod(GET_POLICY_METHOD, ARGS); 117f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } catch (NameNotFoundException ignore) { 118a6e6dd096cf41e556ed8aa23cd18d0227e10ddd1Andrew Stadler // Package not found -- it's okay - there's no policy .apk found, which is OK 119a6e6dd096cf41e556ed8aa23cd18d0227e10ddd1Andrew Stadler } catch (ClassNotFoundException e) { 120a6e6dd096cf41e556ed8aa23cd18d0227e10ddd1Andrew Stadler // Class not found -- probably not OK, but let's not crash here 121560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "VendorPolicyLoader: " + e); 122a6e6dd096cf41e556ed8aa23cd18d0227e10ddd1Andrew Stadler } catch (NoSuchMethodException e) { 123a6e6dd096cf41e556ed8aa23cd18d0227e10ddd1Andrew Stadler // Method not found -- probably not OK, but let's not crash here 124560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "VendorPolicyLoader: " + e); 125f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 126f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki mPolicyMethod = method; 127f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 128f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 129f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki // Not private for testing 13017d3a29c9d8f7a27c463239f190bdcc4e0804527Jerry Xie public static boolean isSystemPackage(Context context, String packageName) { 131f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki try { 132f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki ApplicationInfo ai = context.getPackageManager().getApplicationInfo(packageName, 0); 133f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki return (ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 134f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } catch (NameNotFoundException e) { 135f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki return false; // Package not found. 136f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 137f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 138f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 139f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki /** 140f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * Calls the getPolicy method in the policy apk, if one exists. This method never returns null; 141f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * It returns an empty {@link Bundle} when there is no policy apk (or even if the inner 142f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * getPolicy returns null). 143f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki */ 144f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki // Not private for testing 14517d3a29c9d8f7a27c463239f190bdcc4e0804527Jerry Xie public Bundle getPolicy(String policy, Bundle args) { 146f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki Bundle ret = null; 147f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki if (mPolicyMethod != null) { 148f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki try { 149f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki ret = (Bundle) mPolicyMethod.invoke(null, policy, args); 150f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } catch (Exception e) { 151560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "VendorPolicyLoader", e); 152f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 153f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 154f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki return (ret != null) ? ret : Bundle.EMPTY; 155f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 156f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki 157f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki /** 158f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki * Returns true if alternate exchange descriptive text is required. 159ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * 160ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Vendor function: 161ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Select: USE_ALTERNATE_EXCHANGE_STRINGS 162ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Params: none 163ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Result: USE_ALTERNATE_EXCHANGE_STRINGS (boolean) 164f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki */ 165f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki public boolean useAlternateExchangeStrings() { 166f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki return getPolicy(USE_ALTERNATE_EXCHANGE_STRINGS, null) 167f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki .getBoolean(USE_ALTERNATE_EXCHANGE_STRINGS, false); 168f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki } 169ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler 170ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler /** 171ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Returns additional key/value pairs for the IMAP ID string. 172ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * 173ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Vendor function: 174ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Select: GET_IMAP_ID 175ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Params: GET_IMAP_ID_USER (String) 176ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * GET_IMAP_ID_HOST (String) 177ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * GET_IMAP_ID_CAPABILITIES (String) 178ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Result: GET_IMAP_ID (String) 179ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * 180ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * @param userName the server that is being contacted (e.g. "imap.server.com") 181ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * @param host the server that is being contacted (e.g. "imap.server.com") 182a6e6dd096cf41e556ed8aa23cd18d0227e10ddd1Andrew Stadler * @param capabilities reported capabilities, if known. null is OK 183ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * @return zero or more key/value pairs, quoted and delimited by spaces. If there is 184ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * nothing to add, return null. 185ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler */ 186ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler public String getImapIdValues(String userName, String host, String capabilities) { 187ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler Bundle params = new Bundle(); 188ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler params.putString(GET_IMAP_ID_USER, userName); 189ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler params.putString(GET_IMAP_ID_HOST, host); 190ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler params.putString(GET_IMAP_ID_CAPA, capabilities); 191ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler String result = getPolicy(GET_IMAP_ID, params).getString(GET_IMAP_ID); 192ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler return result; 193ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler } 194ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler 195e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public static class OAuthProvider implements Serializable { 196e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon private static final long serialVersionUID = 8511656164616538990L; 197e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon 198e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String id; 199e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String label; 200e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String authEndpoint; 201e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String tokenEndpoint; 202e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String refreshEndpoint; 203e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String responseType; 204e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String redirectUri; 205e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String scope; 206e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String clientId; 207e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String clientSecret; 208e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String state; 209e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon } 210e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon 211c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public static class Provider implements Serializable { 212c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank private static final long serialVersionUID = 8511656164616538989L; 213c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 214c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String id; 215c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String label; 216c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String domain; 217c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String incomingUriTemplate; 218c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String incomingUsernameTemplate; 219c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String outgoingUriTemplate; 220c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String outgoingUsernameTemplate; 221d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler public String altIncomingUriTemplate; 222d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler public String altIncomingUsernameTemplate; 223d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler public String altOutgoingUriTemplate; 224d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler public String altOutgoingUsernameTemplate; 225c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String incomingUri; 226c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String incomingUsername; 227c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String outgoingUri; 228c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String outgoingUsername; 229c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public String note; 230e62688f0d67edd7119e82a5cbfe6b8815721df2fMartin Hibdon public String oauth; 231c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 232c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank /** 233c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * Expands templates in all of the provider fields that support them. Currently, 234c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * templates are used in 4 fields -- incoming and outgoing URI and user name. 235c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * @param email user-specified data used to replace template values 236c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank */ 237c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public void expandTemplates(String email) { 238d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler final String[] emailParts = email.split("@"); 239d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler final String user = emailParts[0]; 240c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 241c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank incomingUri = expandTemplate(incomingUriTemplate, email, user); 242c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank incomingUsername = expandTemplate(incomingUsernameTemplate, email, user); 243c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank outgoingUri = expandTemplate(outgoingUriTemplate, email, user); 244c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank outgoingUsername = expandTemplate(outgoingUsernameTemplate, email, user); 245c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank } 246c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 247c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank /** 248d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler * Like the above, but expands the alternate templates instead 249d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler * @param email user-specified data used to replace template values 250d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler */ 251d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler public void expandAlternateTemplates(String email) { 252d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler final String[] emailParts = email.split("@"); 253d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler final String user = emailParts[0]; 254d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler 255d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler incomingUri = expandTemplate(altIncomingUriTemplate, email, user); 256d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler incomingUsername = expandTemplate(altIncomingUsernameTemplate, email, user); 257d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler outgoingUri = expandTemplate(altOutgoingUriTemplate, email, user); 258d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler outgoingUsername = expandTemplate(altOutgoingUsernameTemplate, email, user); 259d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler } 260d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler 261d039322f7402ef402eb66c92b899510dd6649e2dTony Mantler /** 262c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * Replaces all parameterized values in the given template. The values replaced are 263c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * $domain, $user and $email. 264c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank */ 265c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank private String expandTemplate(String template, String email, String user) { 266c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank String returnString = template; 267c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank returnString = returnString.replaceAll("\\$email", email); 268c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank returnString = returnString.replaceAll("\\$user", user); 269c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank returnString = returnString.replaceAll("\\$domain", domain); 270c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank return returnString; 271c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank } 272c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank } 273c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 274ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler /** 275ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Returns provider setup information for a given email address 276ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * 277ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Vendor function: 278ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Select: FIND_PROVIDER 279ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Param: FIND_PROVIDER (String) 280ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * Result: FIND_PROVIDER_IN_URI 281ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * FIND_PROVIDER_IN_USER 282ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * FIND_PROVIDER_OUT_URI 283ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * FIND_PROVIDER_OUT_USER 284a6e6dd096cf41e556ed8aa23cd18d0227e10ddd1Andrew Stadler * FIND_PROVIDER_NOTE (optional - null is OK) 285a6e6dd096cf41e556ed8aa23cd18d0227e10ddd1Andrew Stadler * 286a6e6dd096cf41e556ed8aa23cd18d0227e10ddd1Andrew Stadler * Note, if we get this far, we expect "correct" results from the policy method. But throwing 287a6e6dd096cf41e556ed8aa23cd18d0227e10ddd1Andrew Stadler * checked exceptions requires a bunch of upstream changes, so we're going to catch them here 288a6e6dd096cf41e556ed8aa23cd18d0227e10ddd1Andrew Stadler * and add logging. Other exceptions may escape here (such as null pointers) to fail fast. 289ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * 290ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * @param domain The domain portion of the user's email address 291ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler * @return suitable Provider definition, or null if no match found 292ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler */ 293ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler public Provider findProviderForDomain(String domain) { 294ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler Bundle params = new Bundle(); 295ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler params.putString(FIND_PROVIDER, domain); 296ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler Bundle out = getPolicy(FIND_PROVIDER, params); 2970434fef1f6706a0a6fc53b499f3e982f70d7142dAndrew Stadler if (out != null && !out.isEmpty()) { 298040ddf60cfef4aaecf4bfe1f897fce3248d777a4Todd Kennedy Provider p = new Provider(); 299040ddf60cfef4aaecf4bfe1f897fce3248d777a4Todd Kennedy p.id = null; 300040ddf60cfef4aaecf4bfe1f897fce3248d777a4Todd Kennedy p.label = null; 301040ddf60cfef4aaecf4bfe1f897fce3248d777a4Todd Kennedy p.domain = domain; 302040ddf60cfef4aaecf4bfe1f897fce3248d777a4Todd Kennedy p.incomingUriTemplate = out.getString(FIND_PROVIDER_IN_URI); 303040ddf60cfef4aaecf4bfe1f897fce3248d777a4Todd Kennedy p.incomingUsernameTemplate = out.getString(FIND_PROVIDER_IN_USER); 304040ddf60cfef4aaecf4bfe1f897fce3248d777a4Todd Kennedy p.outgoingUriTemplate = out.getString(FIND_PROVIDER_OUT_URI); 305040ddf60cfef4aaecf4bfe1f897fce3248d777a4Todd Kennedy p.outgoingUsernameTemplate = out.getString(FIND_PROVIDER_OUT_USER); 306040ddf60cfef4aaecf4bfe1f897fce3248d777a4Todd Kennedy p.note = out.getString(FIND_PROVIDER_NOTE); 307040ddf60cfef4aaecf4bfe1f897fce3248d777a4Todd Kennedy return p; 308ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler } 309ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler return null; 310ecb1af804144689d4ead96a247b565f9b4eb8160Andrew Stadler } 311f613489663cdc5df71b029dfcec5fd3c5173a549Makoto Onuki} 312