/enough-polish-j2me/source/src/de/enough/polish/facebook/BaseFacebookAuthenticationProcess.java

https://github.com/ovidiuiliescu/j2mepolish · Java · 200 lines · 130 code · 21 blank · 49 comment · 18 complexity · b5f06fad30c3f011caa66a021f15789d MD5 · raw file

  1. package de.enough.polish.facebook;
  2. import java.util.Hashtable;
  3. import de.enough.polish.authentication.AuthenticationListener;
  4. import de.enough.polish.authentication.AuthenticationProcess;
  5. import de.enough.polish.io.CookieManager;
  6. import de.enough.polish.io.RedirectHttpConnection;
  7. import de.enough.polish.io.RmsStorage;
  8. import de.enough.polish.util.TextUtil;
  9. /**
  10. * Implements the Facebook OAuth 2.0 based authentication process.
  11. *
  12. * @author Robert Virkus, j2mepolish@enough.de
  13. * @see de.enough.polish.authentication.AuthenticationItem
  14. * @see AuthenticationProcess
  15. */
  16. public abstract class BaseFacebookAuthenticationProcess implements AuthenticationProcess {
  17. protected static final String KEY_COOKIE_MANAGER = "authcm";
  18. protected final String facebookAppId;
  19. protected final String facebookAppRedirectUrl;
  20. protected final String facebookAppPermissions;
  21. protected AuthenticationListener authenticationListener;
  22. protected CookieManager cookieManager;
  23. protected RmsStorage storage;
  24. protected boolean isRedirectEncountered;
  25. /**
  26. * Creates a new authentication process
  27. * @param facebookAppId the application ID
  28. * @param facebookAppRedirectUrl the registered redirect URL
  29. * @param listener the authentication listener
  30. */
  31. public BaseFacebookAuthenticationProcess(String facebookAppId,
  32. String facebookAppRedirectUrl,
  33. AuthenticationListener listener
  34. )
  35. {
  36. this( facebookAppId, facebookAppRedirectUrl, null, listener);
  37. }
  38. /**
  39. * Creates a new authentication process
  40. * @param facebookAppId the application ID
  41. * @param facebookAppRedirectUrl the registered redirect URL
  42. * @param optional comma separated list of Facebook permissions that should be authorized, compare http://developers.facebook.com/docs/authentication/permissions/
  43. * @param listener the authentication listener
  44. */
  45. public BaseFacebookAuthenticationProcess(String facebookAppId,
  46. String facebookAppRedirectUrl,
  47. String permissions,
  48. AuthenticationListener listener
  49. )
  50. {
  51. this.facebookAppId = facebookAppId;
  52. this.facebookAppRedirectUrl = facebookAppRedirectUrl;
  53. this.facebookAppPermissions = permissions;
  54. this.authenticationListener = listener;
  55. }
  56. /*
  57. * (non-Javadoc)
  58. * @see de.enough.polish.authentication.AuthenticationProcess#getStartUrl()
  59. */
  60. public String getStartUrl() {
  61. String url = "https://m.facebook.com/dialog/oauth?client_id=" + this.facebookAppId
  62. + "&redirect_uri=" + TextUtil.encodeUrl( this.facebookAppRedirectUrl );
  63. if (this.facebookAppPermissions != null) {
  64. url += "&scope=" + this.facebookAppPermissions;
  65. }
  66. url += "&state=" + getState();
  67. return url;
  68. }
  69. /**
  70. * Retrieves the state.
  71. * Subclasses can override this method to implement a specific state; otherwise a String representation of the current time in ms is being used.
  72. * @return a unique state for the authentication
  73. */
  74. protected String getState() {
  75. return Long.toString(System.currentTimeMillis());
  76. }
  77. /*
  78. * (non-Javadoc)
  79. * @see de.enough.polish.authentication.AuthenticationProcess#getCookieManager()
  80. */
  81. public CookieManager getCookieManager() {
  82. CookieManager manager = this.cookieManager;
  83. if (manager == null) {
  84. // try to load it from RMS:
  85. if (this.storage == null) {
  86. this.storage = new RmsStorage();
  87. }
  88. try {
  89. manager = (CookieManager) this.storage.read(KEY_COOKIE_MANAGER);
  90. } catch (Exception e) {
  91. e.printStackTrace();
  92. //#debug info
  93. System.out.println("Unable to load cookie manager" + e);
  94. }
  95. if (manager == null) {
  96. manager = new CookieManager();
  97. this.cookieManager = manager;
  98. }
  99. }
  100. return manager;
  101. }
  102. /*
  103. * (non-Javadoc)
  104. * @see de.enough.polish.io.RedirectListener#onRedirect(java.lang.String)
  105. */
  106. public String onRedirect(String url) {
  107. if (!url.startsWith(this.facebookAppRedirectUrl)) {
  108. return url;
  109. }
  110. this.isRedirectEncountered = true;
  111. Hashtable table = TextUtil.parseGetParameters(url);
  112. String accessCode = (String) table.get("code");
  113. if (accessCode == null) {
  114. this.authenticationListener.onAuthenticationFailure(AuthenticationListener.REASON_DENIED, "no access code in redirect url " + url);
  115. } else {
  116. retrieveAccessToken(accessCode);
  117. }
  118. return null;
  119. }
  120. public abstract void retrieveAccessToken(String accessCode);
  121. /**
  122. * Writes the cookie manager to the local RMS
  123. * @return true when the saving was successful
  124. */
  125. protected boolean saveCookieManager() {
  126. try {
  127. if (this.storage == null) {
  128. this.storage = new RmsStorage();
  129. }
  130. this.storage.save(this.cookieManager, KEY_COOKIE_MANAGER);
  131. return true;
  132. } catch (Exception e) {
  133. //#debug error
  134. System.out.println("Unable to persist cookie manager state" + e);
  135. return false;
  136. }
  137. }
  138. /*
  139. * (non-Javadoc)
  140. * @see de.enough.polish.authentication.AuthenticationProcess#refreshAccess(de.enough.polish.authentication.AuthenticationListener)
  141. */
  142. public void refreshAccess(AuthenticationListener listener) {
  143. this.authenticationListener = listener;
  144. RefreshThread thread = new RefreshThread();
  145. thread.start();
  146. }
  147. class RefreshThread extends Thread {
  148. public void run() {
  149. try {
  150. BaseFacebookAuthenticationProcess.this.isRedirectEncountered = false;
  151. String url = getStartUrl();
  152. RedirectHttpConnection connection = new RedirectHttpConnection(url);
  153. connection.setCookieManager( getCookieManager() );
  154. BaseFacebookAuthenticationProcess.this.cookieManager.setCookie(url, connection);
  155. connection.setRedirectListener(BaseFacebookAuthenticationProcess.this);
  156. connection.getResponseCode();
  157. if (!BaseFacebookAuthenticationProcess.this.isRedirectEncountered) {
  158. BaseFacebookAuthenticationProcess.this.authenticationListener.onAuthenticationFailure( AuthenticationListener.REASON_ABORTED, "please restart authentication process");
  159. }
  160. } catch (Exception e) {
  161. if (!BaseFacebookAuthenticationProcess.this.isRedirectEncountered) {
  162. BaseFacebookAuthenticationProcess.this.authenticationListener.onAuthenticationFailure( AuthenticationListener.REASON_NETWORK_FAILURE, e);
  163. }
  164. }
  165. }
  166. }
  167. public void clearAuthenticationData() {
  168. try {
  169. if (this.storage == null) {
  170. this.storage = new RmsStorage();
  171. }
  172. this.storage.delete(KEY_COOKIE_MANAGER);
  173. getCookieManager().clear();
  174. } catch (Exception e) {
  175. //#debug info
  176. System.out.println("Unable to delete stored cookies" + e);
  177. }
  178. }
  179. }