Modified:
/trunk/Snackr/src/model/feeds/readers/FeedReaderSynchronizerBase.as
/trunk/Snackr/src/model/feeds/readers/GoogleReaderSynchronizer.as
/trunk/Snackr/src/model/feeds/readers/IFeedReaderSynchronizer.as
/trunk/Snackr/src/model/feeds/readers/NullFeedReaderSynchronizer.as
/trunk/Snackr/src/model/feeds/readers/SynchronizerEvent.as
/trunk/Snackr/src/ui/popups/OptionsPopup.mxml
=======================================
--- /trunk/Snackr/src/model/feeds/readers/FeedReaderSynchronizerBase.as Mon
Jul 21 16:28:35 2008
+++ /trunk/Snackr/src/model/feeds/readers/FeedReaderSynchronizerBase.as Sun
Jun 6 22:24:01 2010
@@ -212,6 +212,10 @@
}
public function authenticate(login: String, password: String) : void {
+ authenticateCaptcha(login, password, null, null);
+ }
+
+ public function authenticateCaptcha(login: String, password: String,
captchaToken: String, captchaValue: String): void {
//implemented by subclasses
}
=======================================
--- /trunk/Snackr/src/model/feeds/readers/GoogleReaderSynchronizer.as Sat
Jun 5 23:14:47 2010
+++ /trunk/Snackr/src/model/feeds/readers/GoogleReaderSynchronizer.as Sun
Jun 6 22:24:01 2010
@@ -58,6 +58,7 @@
private static const GET_READ_ITEMS_URL:String
= "http://www.google.com/reader/atom/user/-/state/com.google/read";
private static const TAG_EDIT_URL:String
= "http://www.google.com/reader/api/0/edit-tag";
private static const GET_FEED_ITEMS_URL:String
= "http://www.google.com/reader/atom/feed/";
+ private static const CAPTCHA_AUTH_URL_PREFIX:String
= "http://www.google.com/accounts/";
private static const AUTH_BAD_CREDENTIALS_STATUS_CODE: Number = 403;
@@ -75,7 +76,7 @@
}
- override public function authenticate(login: String, password: String):
void {
+ override public function authenticateCaptcha(login: String, password:
String, captchaToken: String, captchaValue: String): void {
//TODO: Figure out if/when the cookie will expire with the server and
call authenticate()
//again automatically if that occurs
var authRequest:URLRequest = new URLRequest();
@@ -87,6 +88,10 @@
variables.accountType = "GOOGLE";
variables.Email = login;
variables.Passwd = password;
+ if(captchaToken != null)
+ variables.logintoken = captchaToken;
+ if(captchaValue != null)
+ variables.logincaptcha = captchaValue;
authRequest.data = variables;
var authConnection: URLLoader = new URLLoader();
authConnection.addEventListener(Event.COMPLETE, function
handleAuthResultEvent(event: Event): void {
@@ -107,11 +112,32 @@
Logger.instance.log("GoogleReaderSynchronizer: Authentication failed:
event:" + event, Logger.SEVERITY_NORMAL);
Logger.instance.log("GoogleReaderSynchronizer: Authentication failed:
event.target.data:" + event.target.data, Logger.SEVERITY_DEBUG);
connected = false;
- var responseVars: URLVariables = new URLVariables(event.target.data);
+ var result: String = String(event.target.data);
+ var responseVars: Object = new Object;
+ var tokens:Array = result.split(/[\n]/);
+ for(var i:int = 0; i < tokens.length; i++) {
+ var firstEqualsPosition:int = tokens[i].indexOf("=");
+ if(firstEqualsPosition != -1) {
+ if(tokens[i].slice(0,firstEqualsPosition) == "Error") {
+ responseVars.Error =
tokens[i].slice(firstEqualsPosition+1,tokens[i].length);
+ }
+ else if(tokens[i].slice(0,firstEqualsPosition) == "CaptchaToken") {
+ responseVars.CaptchaToken =
tokens[i].slice(firstEqualsPosition+1,tokens[i].length);
+ }
+ else if(tokens[i].slice(0,firstEqualsPosition) == "CaptchaUrl") {
+ responseVars.CaptchaUrl =
tokens[i].slice(firstEqualsPosition+1,tokens[i].length);
+ }
+ else if(tokens[i].slice(0,firstEqualsPosition) == "Url") {
+ responseVars.Url =
tokens[i].slice(firstEqualsPosition+1,tokens[i].length);
+ }
+ }
+
+ }
if(responseVars.Error == "CaptchaRequired") {
var syncEvent:SynchronizerEvent = new
SynchronizerEvent(SynchronizerEvent.AUTH_CAPTCHA_CHALLENGE);
syncEvent.captchaToken = responseVars.CaptchaToken;
- syncEvent.captchaURL = responseVars.CaptchaUrl;
+ syncEvent.captchaURL = CAPTCHA_AUTH_URL_PREFIX +
responseVars.CaptchaUrl;
+ syncEvent.externalCaptchaDialogURL = responseVars.Url;
dispatchEvent(syncEvent);
}
else {
=======================================
--- /trunk/Snackr/src/model/feeds/readers/IFeedReaderSynchronizer.as Mon
Jul 21 16:28:35 2008
+++ /trunk/Snackr/src/model/feeds/readers/IFeedReaderSynchronizer.as Sun
Jun 6 22:24:01 2010
@@ -47,6 +47,7 @@
* @param password The user's password
*/
function authenticate(login: String, password: String): void;
+ function authenticateCaptcha(login: String, password: String,
captchaToken: String, captchaValue: String): void;
/**
* Tells us whether the synchronizer is currently connected to its
remote reader client or not.
=======================================
--- /trunk/Snackr/src/model/feeds/readers/NullFeedReaderSynchronizer.as Mon
Jul 21 16:28:35 2008
+++ /trunk/Snackr/src/model/feeds/readers/NullFeedReaderSynchronizer.as Sun
Jun 6 22:24:01 2010
@@ -52,6 +52,10 @@
Logger.instance.log("NullFeedReaderSynchronizer: authenticate: " +
login + ", " + password, Logger.SEVERITY_DEBUG);
}
+ public function authenticateCaptcha(login: String, password: String,
captchaToken: String, captchaValue: String) : void {
+ Logger.instance.log("NullFeedReaderSynchronizer: authenticate: " +
login + ", " + password + ", " + captchaToken + ", " + captchaValue,
Logger.SEVERITY_DEBUG);
+ }
+
public function get connected() : Boolean {
Logger.instance.log("NullFeedReaderSynchronizer: connected",
Logger.SEVERITY_DEBUG);
//the null feed reader synchronizer is never connected
=======================================
--- /trunk/Snackr/src/model/feeds/readers/SynchronizerEvent.as Fri Jun 4
16:40:24 2010
+++ /trunk/Snackr/src/model/feeds/readers/SynchronizerEvent.as Sun Jun 6
22:24:01 2010
@@ -38,6 +38,7 @@
public static const AUTH_CAPTCHA_CHALLENGE: String
= "authCaptchaChallenge";
public var captchaToken: String;
public var captchaURL: String;
+ public var externalCaptchaDialogURL: String;
public function SynchronizerEvent(type:String)
{
=======================================
--- /trunk/Snackr/src/ui/popups/OptionsPopup.mxml Sat Jun 5 11:57:49 2010
+++ /trunk/Snackr/src/ui/popups/OptionsPopup.mxml Sun Jun 6 22:24:01 2010
@@ -68,6 +68,8 @@
//used to determine whether to prompt the user to authenticate with
google reader when a close event occurs
private var readerCredentialsUnchecked: Boolean = false;
+ private var captchaToken: String;
+
[Bindable]
public var popupTitle: String = "";
@@ -127,7 +129,7 @@
if(_optionsModel.getValue(OptionsModel.OPTION_READER_ENABLED) == "1"
&& ReaderSynchronizerManager.reader is NullFeedReaderSynchronizer)
badPasswordText.visible = true;
- //currentState = "CaptchaDisplayed";
+
}
@@ -286,6 +288,18 @@
authenticatingSpinner.stop();
badConnectionText.visible = false;
badPasswordText.visible = true;
+ currentState = "";
+ });
+
ReaderSynchronizerManager.reader.addEventListener(SynchronizerEvent.AUTH_CAPTCHA_CHALLENGE,
function authCaptchaChallenge(event: SynchronizerEvent) : void {
+ authenticatingLabel.visible = false;
+ authenticatingSpinner.visible = false;
+ authenticatingSpinner.stop();
+ badConnectionText.visible = false;
+ badPasswordText.visible = false;
+ currentState = "CaptchaDisplayed";
+ captchaImage.source = event.captchaURL;
+ captchaToken = event.captchaToken;
+ captchaInput.text = "";
});
ReaderSynchronizerManager.reader.addEventListener(SynchronizerEvent.AUTH_FAILURE,
function authBadConnection(event: SynchronizerEvent) : void {
if(!badPasswordText.visible) {
@@ -293,10 +307,15 @@
authenticatingSpinner.visible = false;
authenticatingSpinner.stop();
badConnectionText.visible = true;
+ currentState = "";
}
});
-
ReaderSynchronizerManager.reader.authenticate(_optionsModel.getValue(OptionsModel.OPTION_READER_USER_NAME),
- _optionsModel.getValue(OptionsModel.OPTION_READER_PASSWORD));
+ if(currentState == "CaptchaDisplayed")
+
ReaderSynchronizerManager.reader.authenticateCaptcha(_optionsModel.getValue(OptionsModel.OPTION_READER_USER_NAME),
+ _optionsModel.getValue(OptionsModel.OPTION_READER_PASSWORD),
captchaToken, captchaInput.text);
+ else
+
ReaderSynchronizerManager.reader.authenticate(_optionsModel.getValue(OptionsModel.OPTION_READER_USER_NAME),
+ _optionsModel.getValue(OptionsModel.OPTION_READER_PASSWORD));
}
else {
ReaderSynchronizerManager.initializeNullReaderSynchronizer();
@@ -309,6 +328,7 @@
authenticatingSpinner.visible = false;
authenticatingSpinner.stop();
connectedLabel.visible = true;
+ currentState = "";
var panel: MergeSetFeedsPanel = new MergeSetFeedsPanel();
panel.addEventListener(CloseEvent.CLOSE, handleMergeSetCancelClose);
PopUpManager.addPopUp(panel, this, true);
@@ -612,15 +632,17 @@
<states>
<mx:State name="CaptchaDisplayed">
<mx:AddChild relativeTo="{googleReaderTab}">
- <mx:Image left="col4:10" y="158" width="200" height="70"
id="captchaImage" />
- <mx:TextInput left="col4:10" y="228" width="170" id="captchaInput"
valueCommit="handleCaptchaInputCommit(event)" />
+ <mx:Image left="col4:11" y="158" width="200" height="70"
id="captchaImage" />
</mx:AddChild>
- <mx:SetProperty target="{connectButton}" name="y" value="262" />
- <mx:SetProperty target="{authenticatingSpinner}" name="y" value="288" />
- <mx:SetProperty target="{authenticatingLabel}" name="y" value="296" />
- <mx:SetProperty target="{connectedLabel}" name="y" value="296" />
- <mx:SetProperty target="{badPasswordText}" name="y" value="296" />
- <mx:SetProperty target="{badConnectionText}" name="y" value="296" />
+ <mx:AddChild relativeTo="{googleReaderTab}">
+ <mx:TextInput left="col4:10" y="236" width="170" id="captchaInput"
valueCommit="handleCaptchaInputCommit(event)" />
+ </mx:AddChild>
+ <mx:SetProperty target="{connectButton}" name="y" value="270" />
+ <mx:SetProperty target="{authenticatingSpinner}" name="y" value="296" />
+ <mx:SetProperty target="{authenticatingLabel}" name="y" value="304" />
+ <mx:SetProperty target="{connectedLabel}" name="y" value="304" />
+ <mx:SetProperty target="{badPasswordText}" name="y" value="304" />
+ <mx:SetProperty target="{badConnectionText}" name="y" value="304" />
</mx:State>
</states>
<popupChildren>