Update Imap.ClientSession now IMAP NO commands aren't treated as errors
Check the response code when logging in for the command, and handle as appropriate.
This commit is contained in:
parent
d6e19352f9
commit
71d8c8b1a4
2 changed files with 39 additions and 18 deletions
|
|
@ -835,6 +835,10 @@ public class Geary.Imap.ClientSession : BaseObject {
|
||||||
/**
|
/**
|
||||||
* Performs the LOGIN command using the supplied credentials.
|
* Performs the LOGIN command using the supplied credentials.
|
||||||
*
|
*
|
||||||
|
* Throws {@link ImapError.UNAUTHENTICATED} if the credentials are
|
||||||
|
* bad, unsupported, or if authentication actually failed. Returns
|
||||||
|
* the status response for the command otherwise.
|
||||||
|
*
|
||||||
* @see initiate_session_async
|
* @see initiate_session_async
|
||||||
*/
|
*/
|
||||||
public async StatusResponse login_async(Geary.Credentials credentials,
|
public async StatusResponse login_async(Geary.Credentials credentials,
|
||||||
|
|
@ -877,32 +881,40 @@ public class Geary.Imap.ClientSession : BaseObject {
|
||||||
// should always proceed; only an Error could change this
|
// should always proceed; only an Error could change this
|
||||||
assert(params.proceed);
|
assert(params.proceed);
|
||||||
|
|
||||||
GLib.Error? login_err = null;
|
StatusResponse response = yield command_transaction_async(
|
||||||
try {
|
cmd, cancellable
|
||||||
yield command_transaction_async(cmd, cancellable);
|
);
|
||||||
} catch (Error err) {
|
|
||||||
login_err = err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (login_err != null) {
|
if (response.status != Status.OK) {
|
||||||
// Throw an error indicating auth failed here, unless
|
// Throw an error indicating auth failed here, unless
|
||||||
// there is a status response and it indicates that the
|
// there is a status response and it indicates that the
|
||||||
// server is merely reporting login as being unavailable,
|
// server is merely reporting login as being unavailable,
|
||||||
// then don't since the creds might actually be fine.
|
// then don't since the creds might actually be fine.
|
||||||
ResponseCodeType? code_type = null;
|
ResponseCode? code = response.response_code;
|
||||||
if (cmd.status != null) {
|
if (code != null) {
|
||||||
ResponseCode? code = cmd.status.response_code;
|
ResponseCodeType? code_type = code.get_response_code_type();
|
||||||
if (code != null) {
|
if (code_type != null) {
|
||||||
code_type = code.get_response_code_type();
|
switch (code_type.value) {
|
||||||
|
case ResponseCodeType.UNAVAILABLE:
|
||||||
|
throw new ImapError.UNAVAILABLE(
|
||||||
|
"Login restricted: %s: ", response.to_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
case ResponseCodeType.AUTHENTICATIONFAILED:
|
||||||
|
// pass through to the error being thrown below
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ImapError.SERVER_ERROR(
|
||||||
|
"Login error: %s: ", response.to_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code_type == null ||
|
throw new ImapError.UNAUTHENTICATED(
|
||||||
code_type.value != ResponseCodeType.UNAVAILABLE) {
|
"Bad credentials: %s: ", response.to_string()
|
||||||
throw new ImapError.UNAUTHENTICATED(login_err.message);
|
);
|
||||||
} else {
|
|
||||||
throw login_err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd.status;
|
return cmd.status;
|
||||||
|
|
@ -1715,6 +1727,9 @@ public class Geary.Imap.ClientSession : BaseObject {
|
||||||
|
|
||||||
this.cx.send_command(cmd);
|
this.cx.send_command(cmd);
|
||||||
yield cmd.wait_until_complete(cancellable);
|
yield cmd.wait_until_complete(cancellable);
|
||||||
|
|
||||||
|
// This won't be null since the Command.wait_until_complete
|
||||||
|
// will throw an error if it is.
|
||||||
return cmd.status;
|
return cmd.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,12 @@ class Integration.Imap.ClientSession : TestCase {
|
||||||
assert_not_reached();
|
assert_not_reached();
|
||||||
} catch (Geary.ImapError.UNAUTHENTICATED err) {
|
} catch (Geary.ImapError.UNAUTHENTICATED err) {
|
||||||
// All good
|
// All good
|
||||||
|
} catch (Geary.ImapError.SERVER_ERROR err) {
|
||||||
|
// Some servers (Y!) return AUTHORIZATIONFAILED response
|
||||||
|
// code if the login (not password) is bad
|
||||||
|
if (!("AUTHORIZATIONFAILED" in err.message)) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue