Search code examples
c#wpfdesktop-applicationonenotelive-sdk

LiveSDK 5.6 LiveAuthClient.LoginAsync method missing


I am trying to create an integration test for retrieving a OneNote page. And when trying to use the LiveSDK 5.6 LiveAuthClient, my compiler is not even seeing any method named LiveAuthClient.LoginAsync(strin[]) which is mentioned in multiple answers (e.g. 1) on here as well as the MSDN :|

        var authClient = new LiveAuthClient(OneNoteApiConfig.ClientID);

        var result = await authClient.InitializeAsync(OneNoteApiConfig.Scopes);

        if (result.Status != LiveConnectSessionStatus.Connected)
        {
            result = await authClient.LoginAsync(Scopes); // method does not exist
        }

Any ideas?

I'm sure I am missing something obvious

There does seem to be a method called GetLoginUrl()?

Am i referencing the wrong LiveSDK?

I installed the LiveSDK 5.6 NuGet package, and the project is a .NET 4.5 Class Library project


Solution

  • I managed to get it to work, but had to use the GetLoginUrl(), than use Selenium to login to window live using a test account and approve the permission request, which then gets redirected with a code in the query string(..?code=xx.xxx) which i use to call the AuthClient.ExchangeAuthCodeAsync with, and get a Session which includes an AccessToken + RefreshToken, for all other tests I can use that refresh token :-) as it's valid for a year.

        [Test]
        public async void TryAuthoriseWithMsLiveLibrary()
        {
            var authClient = new LiveAuthClient(OneNoteApiConfig.ClientID);
    
            var result = await authClient.InitializeAsync(OneNoteApiConfig.Scopes);
    
            var getLoginUrl = authClient.GetLoginUrl(OneNoteApiConfig.Scopes);
            Console.WriteLine("\r\nGetLoginUrl = " + getLoginUrl);
    
            // New selenium Driver
            _driver = new FirefoxDriver();
    
            //Set wait to 2 seconds by defualt
            _driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(2));
    
            // Go to the url provided by auth client
            _driver.Navigate().GoToUrl(getLoginUrl);
    
            // Try find the accept button, if automatically directed to the "Grant Permission page", otherwise try find the Login/Passwd and login first
            try
            {
                _driver.FindElementById("idBtn_Accept");
            }
            catch (NoSuchElementException)
            {
                var un = _driver.FindElementByName("login"); // Login TextBox
                var pw = _driver.FindElementByName("passwd"); // Password TextBox
                var signIn = _driver.FindElementByName("SI"); // Sign-In Button
    
                un.SendKeys(OneNoteTestConfig.WindowsLiveUsername);
                pw.SendKeys(OneNoteTestConfig.WindowsLivePassword);
                signIn.Submit();
            }
            // Find a click the idBtn_Accept, if not found straight away, will implictly wait 2 seconds as set baove
            var button = _driver.FindElementById("idBtn_Accept");
            button.Click();
    
            // Try wait until the client is successfully redirected to the url with the code
            try
            {
                var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(5));
                wait.Until(d => d.Url.StartsWith("https://login.live.com/oauth20_desktop.srf"));
                //example https://login.live.com/oauth20_desktop.srf?code=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&lc=1033
            }
            catch (WebDriverTimeoutException)
            {
                Console.WriteLine(_driver.Url);
                throw;
            }
    
            Console.WriteLine("\r\nUrl = " + _driver.Url);
    
            // Retrieve code from query string (?code=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&...)
            var code = MsLiveAuthHelper.GetSessionCodeFromRedirectedUrl(_driver.Url);
    
            code.Should().NotBeNull();
            Console.WriteLine("\r\ncode = " + code);
    
            // Try get open a session using retrieved code.
            // From my uynderstanding you can only do this once with the code, as it expired after
            // and need to use the refresh token from this point, or re-request a code using above procedure
            var session = await authClient.ExchangeAuthCodeAsync(code);
    
            session.Should().NotBeNull();
            session.AccessToken.Should().NotBeNullOrWhiteSpace();
    
            Console.WriteLine("\r\nLiveConnectSession.AccessToken = " + session.AccessToken);
            Console.WriteLine("\r\nLiveConnectSession.AuthenticationToken = " + session.AuthenticationToken);
            Console.WriteLine("\r\nLiveConnectSession.Expires = " + session.Expires);
            Console.WriteLine("\r\nLiveConnectSession.RefreshToken = " + session.RefreshToken);
        }
    

    For my other tests, res.RefreshToken and have a TestRefreshTokenHandler : IRefreshTokenHandler which i save it in:

    public class TestRefreshTokenHandler : IRefreshTokenHandler
    {
        public Task SaveRefreshTokenAsync(RefreshTokenInfo tokenInfo)
        {
            return Task.Factory.StartNew(() =>
            {
                Console.WriteLine("------------------------");
    
                Console.WriteLine("\r\nUserID = " + tokenInfo.UserId);
                Console.WriteLine("\r\nRefresh Token = " + tokenInfo.RefreshToken);
    
                Console.WriteLine("\r\n------------------------");
            });
        }
    
        public Task<RefreshTokenInfo> RetrieveRefreshTokenAsync()
        {
            Console.WriteLine("RetrieveRefreshTokenAsync()");
            return Task.FromResult(new RefreshTokenInfo(OneNoteTestConfig.OneNoteRefreshToken));
        }
    }
    

    And finally in other tests:

        [Test]
        public async void GetNewTokenByRefresh()
        {
            var authClient = new LiveAuthClient(OneNoteApiConfig.ClientID, new TestRefreshTokenHandler());
            var res = (await authClient.InitializeAsync(OneNoteApiConfig.Scopes)).Session;
    
            Console.WriteLine("\r\nLiveConnectSession.AccessToken = " + res.AccessToken);
            Console.WriteLine("\r\nLiveConnectSession.AuthenticationToken = " + res.AuthenticationToken);
            Console.WriteLine("\r\nLiveConnectSession.Expires = " + res.Expires);
            Console.WriteLine("\r\nLiveConnectSession.RefreshToken = " + res.RefreshToken);
            res.AuthenticationToken.Should().NotBeNullOrWhiteSpace();
        }
    

    Hope this helps someone!