AccountAuthenticator.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /* ownCloud Android client application
  2. * Copyright (C) 2012 Bartek Przybylski
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. */
  18. package com.owncloud.android.authenticator;
  19. import com.owncloud.android.ui.activity.AuthenticatorActivity;
  20. import android.accounts.*;
  21. import android.content.Context;
  22. import android.content.Intent;
  23. import android.os.Bundle;
  24. import android.util.Log;
  25. public class AccountAuthenticator extends AbstractAccountAuthenticator {
  26. /**
  27. * Is used by android system to assign accounts to authenticators. Should be
  28. * used by application and all extensions.
  29. */
  30. public static final String ACCOUNT_TYPE = "owncloud";
  31. public static final String AUTH_TOKEN_TYPE = "org.owncloud";
  32. public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType";
  33. public static final String KEY_REQUIRED_FEATURES = "requiredFeatures";
  34. public static final String KEY_LOGIN_OPTIONS = "loginOptions";
  35. public static final String KEY_ACCOUNT = "account";
  36. /**
  37. * Value under this key should handle path to webdav php script. Will be
  38. * removed and usage should be replaced by combining
  39. * {@link eu.alefzero.owncloud.authenticator.KEY_OC_BASE_URL} and
  40. * {@link com.owncloud.android.utils.OwnCloudVersion}
  41. *
  42. * @deprecated
  43. */
  44. public static final String KEY_OC_URL = "oc_url";
  45. /**
  46. * Version should be 3 numbers separated by dot so it can be parsed by
  47. * {@link com.owncloud.android.utils.OwnCloudVersion}
  48. */
  49. public static final String KEY_OC_VERSION = "oc_version";
  50. /**
  51. * Base url should point to owncloud installation without trailing / ie:
  52. * http://server/path or https://owncloud.server
  53. */
  54. public static final String KEY_OC_BASE_URL = "oc_base_url";
  55. private static final String TAG = "AccountAuthenticator";
  56. private Context mContext;
  57. public AccountAuthenticator(Context context) {
  58. super(context);
  59. mContext = context;
  60. }
  61. /**
  62. * {@inheritDoc}
  63. */
  64. @Override
  65. public Bundle addAccount(AccountAuthenticatorResponse response,
  66. String accountType, String authTokenType,
  67. String[] requiredFeatures, Bundle options)
  68. throws NetworkErrorException {
  69. Log.i(TAG, "Adding account with type " + accountType
  70. + " and auth token " + authTokenType);
  71. try {
  72. validateAccountType(accountType);
  73. } catch (AuthenticatorException e) {
  74. Log.e(TAG, "Failed to validate account type " + accountType + ": "
  75. + e.getMessage());
  76. e.printStackTrace();
  77. return e.getFailureBundle();
  78. }
  79. final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
  80. intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
  81. response);
  82. intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
  83. intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures);
  84. intent.putExtra(KEY_LOGIN_OPTIONS, options);
  85. setIntentFlags(intent);
  86. final Bundle bundle = new Bundle();
  87. bundle.putParcelable(AccountManager.KEY_INTENT, intent);
  88. return bundle;
  89. }
  90. /**
  91. * {@inheritDoc}
  92. */
  93. @Override
  94. public Bundle confirmCredentials(AccountAuthenticatorResponse response,
  95. Account account, Bundle options) throws NetworkErrorException {
  96. try {
  97. validateAccountType(account.type);
  98. } catch (AuthenticatorException e) {
  99. Log.e(TAG, "Failed to validate account type " + account.type + ": "
  100. + e.getMessage());
  101. e.printStackTrace();
  102. return e.getFailureBundle();
  103. }
  104. Intent intent = new Intent(mContext, AuthenticatorActivity.class);
  105. intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
  106. response);
  107. intent.putExtra(KEY_ACCOUNT, account);
  108. intent.putExtra(KEY_LOGIN_OPTIONS, options);
  109. setIntentFlags(intent);
  110. Bundle resultBundle = new Bundle();
  111. resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);
  112. return resultBundle;
  113. }
  114. @Override
  115. public Bundle editProperties(AccountAuthenticatorResponse response,
  116. String accountType) {
  117. return null;
  118. }
  119. @Override
  120. public Bundle getAuthToken(AccountAuthenticatorResponse response,
  121. Account account, String authTokenType, Bundle options)
  122. throws NetworkErrorException {
  123. try {
  124. validateAccountType(account.type);
  125. validateAuthTokenType(authTokenType);
  126. } catch (AuthenticatorException e) {
  127. Log.e(TAG, "Failed to validate account type " + account.type + ": "
  128. + e.getMessage());
  129. e.printStackTrace();
  130. return e.getFailureBundle();
  131. }
  132. final AccountManager am = AccountManager.get(mContext);
  133. final String password = am.getPassword(account);
  134. if (password != null) {
  135. final Bundle result = new Bundle();
  136. result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
  137. result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
  138. result.putString(AccountManager.KEY_AUTHTOKEN, password);
  139. return result;
  140. }
  141. final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
  142. intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
  143. response);
  144. intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
  145. intent.putExtra(KEY_LOGIN_OPTIONS, options);
  146. intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
  147. final Bundle bundle = new Bundle();
  148. bundle.putParcelable(AccountManager.KEY_INTENT, intent);
  149. return bundle;
  150. }
  151. @Override
  152. public String getAuthTokenLabel(String authTokenType) {
  153. return null;
  154. }
  155. @Override
  156. public Bundle hasFeatures(AccountAuthenticatorResponse response,
  157. Account account, String[] features) throws NetworkErrorException {
  158. final Bundle result = new Bundle();
  159. result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
  160. return result;
  161. }
  162. @Override
  163. public Bundle updateCredentials(AccountAuthenticatorResponse response,
  164. Account account, String authTokenType, Bundle options)
  165. throws NetworkErrorException {
  166. final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
  167. intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
  168. response);
  169. intent.putExtra(KEY_ACCOUNT, account);
  170. intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
  171. intent.putExtra(KEY_LOGIN_OPTIONS, options);
  172. setIntentFlags(intent);
  173. final Bundle bundle = new Bundle();
  174. bundle.putParcelable(AccountManager.KEY_INTENT, intent);
  175. return bundle;
  176. }
  177. @Override
  178. public Bundle getAccountRemovalAllowed(
  179. AccountAuthenticatorResponse response, Account account)
  180. throws NetworkErrorException {
  181. return super.getAccountRemovalAllowed(response, account);
  182. }
  183. private void setIntentFlags(Intent intent) {
  184. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  185. intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
  186. intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
  187. intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
  188. intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
  189. }
  190. private void validateAccountType(String type)
  191. throws UnsupportedAccountTypeException {
  192. if (!type.equals(ACCOUNT_TYPE)) {
  193. throw new UnsupportedAccountTypeException();
  194. }
  195. }
  196. private void validateAuthTokenType(String authTokenType)
  197. throws UnsupportedAuthTokenTypeException {
  198. if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {
  199. throw new UnsupportedAuthTokenTypeException();
  200. }
  201. }
  202. public static class AuthenticatorException extends Exception {
  203. private static final long serialVersionUID = 1L;
  204. private Bundle mFailureBundle;
  205. public AuthenticatorException(int code, String errorMsg) {
  206. mFailureBundle = new Bundle();
  207. mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);
  208. mFailureBundle
  209. .putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
  210. }
  211. public Bundle getFailureBundle() {
  212. return mFailureBundle;
  213. }
  214. }
  215. public static class UnsupportedAccountTypeException extends
  216. AuthenticatorException {
  217. private static final long serialVersionUID = 1L;
  218. public UnsupportedAccountTypeException() {
  219. super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
  220. "Unsupported account type");
  221. }
  222. }
  223. public static class UnsupportedAuthTokenTypeException extends
  224. AuthenticatorException {
  225. private static final long serialVersionUID = 1L;
  226. public UnsupportedAuthTokenTypeException() {
  227. super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
  228. "Unsupported auth token type");
  229. }
  230. }
  231. public static class UnsupportedFeaturesException extends
  232. AuthenticatorException {
  233. public static final long serialVersionUID = 1L;
  234. public UnsupportedFeaturesException() {
  235. super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
  236. "Unsupported features");
  237. }
  238. }
  239. public static class AccessDeniedException extends AuthenticatorException {
  240. public AccessDeniedException(int code, String errorMsg) {
  241. super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");
  242. }
  243. private static final long serialVersionUID = 1L;
  244. }
  245. }