public async Task <bool> LoginAsync(string site, string username, SecureString password, bool allFilesPermitted = false) { const string xmlExceptionmessage = "The server returned an invalid response."; const string timeoutExceptionMessage = "The server did not respond."; try { Site = site; _api = new ApiUri(Site); var loginParams = new RequestParameters { { "action", "login" }, { "format", "xml" }, { "lgname", username }, }; string loginToken = await GetLoginTokenAsync().ConfigureAwait(false); bool useDeprecatedLogin = (loginToken == null); if (useDeprecatedLogin) { // use old method to fetch login token by loging in without password, required for fandom var tokenResponse = await AttemptLoginAsync(loginParams).ConfigureAwait(false); if (tokenResponse.Result != ResponseCodes.NeedToken) { return(false); } loginToken = tokenResponse.Token; } loginParams.Add("lgtoken", loginToken); // at this point we have no option other than to move password into managed memory loginParams.Add("lgpassword", password.Unsecure()); var response = await AttemptLoginAsync(loginParams).ConfigureAwait(false); if (response.Result == ResponseCodes.Aborted) { throw new LoginException("You must use a bot password (username@password)."); } if (response.Result != ResponseCodes.Success) { return(false); } Task <string> editTokenTask = useDeprecatedLogin ? GetEditTokenViaIntokenAsync() : GetEditTokenAsync(); Task <bool> userConfirmedTask = IsUserConfirmedAsync(username); Task <bool> authorizedTask = IsAuthorizedForUploadFilesAsync(username); if (allFilesPermitted) { await Task.WhenAll(userConfirmedTask, authorizedTask, editTokenTask) .ConfigureAwait(false); } else { await Task.WhenAll(userConfirmedTask, authorizedTask, GetPermittedTypes(), editTokenTask) .ConfigureAwait(false); } if (!userConfirmedTask.Result) { throw new LoginException("That account is not autoconfirmed."); } if (!authorizedTask.Result) { throw new LoginException("You are not authorized to use Wiki-Up on this wiki."); } if (string.IsNullOrEmpty(editTokenTask.Result)) { throw new LoginException("Unable to obtain edit token."); } _editToken = editTokenTask.Result; return(true); } catch (XmlException) { throw new LoginException(xmlExceptionmessage); } catch (HttpRequestException ex) { throw new LoginException(ex.Message, ex.InnerException); } catch (TaskCanceledException) { throw new LoginException(timeoutExceptionMessage); } catch (AggregateException ex) { foreach (var innerEx in ex.InnerExceptions) { if (innerEx is TaskCanceledException) { throw new LoginException(timeoutExceptionMessage); } else if (innerEx is HttpRequestException) { throw new LoginException(innerEx.Message, innerEx.InnerException); } else if (innerEx is XmlException) { throw new LoginException(xmlExceptionmessage); } } throw new LoginException("An unexpected error occured."); } }
public async Task <bool> LoginAsync(string site, string username, SecureString password, bool allFilesPermitted) { try { Site = site; _api = new ApiUri(Site); var loginParams = new RequestParameters { { "action", "login" }, { "format", "xml" }, { "lgname", username }, }; var loginToken = await GetLoginTokenAsync().ConfigureAwait(false); _useDeprecatedLogin = (loginToken == null); if (_useDeprecatedLogin) { // use old method to fetch login token by loging in without password, required for fandom var tokenResponse = await AttemptLoginAsync(loginParams).ConfigureAwait(false); if (tokenResponse.Result != ResponseCodes.NeedToken) { return(false); } loginToken = tokenResponse.Token; } loginParams.Add("lgtoken", loginToken); var response = await password.UseUnsecuredStringAsync <LoginResponse>((unsecuredPassword) => { loginParams.Add("lgpassword", unsecuredPassword); return(AttemptLoginAsync(loginParams)); }); if (response.Result == ResponseCodes.Aborted) { throw new LoginException(Resources.LoginExceptionAborted); } if (response.Result != ResponseCodes.Success) { return(false); } var editTokenTask = _useDeprecatedLogin ? GetEditTokenViaIntokenAsync() : GetEditTokenAsync(); var userConfirmedTask = IsUserConfirmedAsync(username); var authorizedTask = IsAuthorizedForUploadFilesAsync(username); var siteInfoTask = GeSiteInfoAsync(); await Task.WhenAll(userConfirmedTask, authorizedTask, editTokenTask, siteInfoTask) .ConfigureAwait(false); // From here on in if we fail the login we must also log out, as the // sucessfull login session cookies will cause any subsequent login // attempts to the same site to fail with an aborted response. if (!userConfirmedTask.Result) { LogOff(); throw new LoginException(Resources.LoginExceptionNotAutoConfirmed); } if (!authorizedTask.Result) { LogOff(); throw new LoginException(Resources.LoginExceptionNotAuthorized); } if (string.IsNullOrEmpty(editTokenTask.Result)) { LogOff(); throw new LoginException(Resources.LoginExceptionNoEditToken); } _editToken = editTokenTask.Result; var siteInfo = siteInfoTask.Result; HomePage = siteInfo.BaseUrl; ScriptPath = siteInfo.ScriptPath; if (!allFilesPermitted) { foreach (var ext in siteInfo.Extensions) { _permittedFiles.Add(ext); } } var languageCode = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; _errorLanguageCode = siteInfo.IsSupportedLanguage(languageCode) ? languageCode : "en"; var useErrorLangVersion = new Version("1.29.0.0"); _useErrorLang = siteInfo.MediaWikiVersion >= useErrorLangVersion; return(true); } catch (XmlException) { LogOffIfCookiesPresent(); throw new LoginException(Resources.LoginExceptionInvalidResponse); } catch (HttpRequestException ex) { LogOffIfCookiesPresent(); throw new LoginException(ex.Message, ex.InnerException); } catch (TaskCanceledException) { LogOffIfCookiesPresent(); throw new LoginException(Resources.LoginExceptionTimeout); } catch (AggregateException ex) { LogOffIfCookiesPresent(); foreach (var innerEx in ex.InnerExceptions) { if (innerEx is TaskCanceledException) { throw new LoginException(Resources.LoginExceptionTimeout); } else if (innerEx is HttpRequestException) { throw new LoginException(innerEx.Message, innerEx.InnerException); } else if (innerEx is XmlException) { throw new LoginException(Resources.LoginExceptionInvalidResponse); } } throw new LoginException(Resources.LoginExceptionUnexpectedError); } }