AccountAuthenticator.java 10 KB

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