/// <summary>
        /// Allows the owner of this client to log in with their username and password
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="options">The options for this request</param>
        /// <returns>An awaitable task</returns>
        public async Task AuthenticateAsync(string username, string password, RequestOptions options = null)
        {
            Debug.WriteLine($"Performing client account authentication...");
            options = options ?? RequestOptions.CreateFromDefaults(ApiClient.Config);
            options.UseAccessToken = false;
            RestResponse response = await ApiClient.SendJsonAsync(
                "POST",
                "oauth/token",
                new ClientAccountAuthRequest()
            {
                ClientId     = ClientId,
                ClientSecret = ClientSecret,
                GrantType    = "password",
                Username     = username,
                Password     = password
            },
                options).ConfigureAwait(false);

            ClientAccountAuthResponse auth = await response.ReadAsJsonAsync <ClientAccountAuthResponse>(ApiClient.Config).ConfigureAwait(false);

            AccessToken            = auth.AccessToken;
            RefreshToken           = auth.RefreshToken;
            options.UseAccessToken = true;
            CurrentUser            = await GetCurrentUserAsync(options).ConfigureAwait(false);

            _clientAuth = false;
        }
        /// <summary>
        /// Allows authentication with either a facebook access token or facebook auth code
        /// </summary>
        /// <param name="type"></param>
        /// <param name="token"></param>
        /// <param name="options">The options for this request</param>
        /// <returns></returns>
        public async Task AuthenticateAsync(TokenType type, string token, RequestOptions options = null)
        {
            options = options ?? RequestOptions.CreateFromDefaults(ApiClient.Config);
            options.UseAccessToken = false;
            switch (type)
            {
            case TokenType.FacebookAccessToken:
            {
                RestResponse response = await ApiClient.SendJsonAsync(
                    "POST",
                    "oauth/token",
                    new FacebookAuthCodeRequest()
                    {
                        ClientSecret = ClientSecret,
                        ClientId     = ClientId,
                        GrantType    = "convert_code",
                        Provider     = "facebook",
                        AuthCode     = token
                    },
                    options).ConfigureAwait(false);

                ClientAccountAuthResponse auth = await response.ReadAsJsonAsync <ClientAccountAuthResponse>(ApiClient.Config).ConfigureAwait(false);

                AccessToken            = auth.AccessToken;
                RefreshToken           = auth.RefreshToken;
                options.UseAccessToken = true;
                CurrentUser            = await GetCurrentUserAsync(options).ConfigureAwait(false);
            }
            break;

            case TokenType.FacebookAuthCode:
            {
                RestResponse response = await ApiClient.SendJsonAsync(
                    "POST",
                    "oauth/token",
                    new FacebookAuthCodeRequest()
                    {
                        ClientSecret = ClientSecret,
                        ClientId     = ClientId,
                        GrantType    = "convert_token",
                        Provider     = "facebook",
                        Token        = token
                    },
                    options).ConfigureAwait(false);

                ClientAccountAuthResponse auth = await response.ReadAsJsonAsync <ClientAccountAuthResponse>(ApiClient.Config).ConfigureAwait(false);

                AccessToken            = auth.AccessToken;
                RefreshToken           = auth.RefreshToken;
                options.UseAccessToken = true;
                CurrentUser            = await GetCurrentUserAsync(options).ConfigureAwait(false);
            }
            break;

            default:
                throw new ArgumentOutOfRangeException("The provided token type does not accept one token parameter");
            }
            _clientAuth = false;
        }
        /// <summary>
        /// Retrieves a Twitter request token for the Twitter Request token auth flow
        /// </summary>
        /// <param name="options">The options for this request</param>
        /// <returns></returns>
        public async Task <string> GetTwitterRequestTokenAsync(RequestOptions options = null)
        {
            options = options ?? RequestOptions.CreateFromDefaults(ApiClient.Config);
            options.UseAccessToken = false;
            RestResponse response = await ApiClient.SendJsonAsync(
                "POST",
                "oauth/token",
                new
            {
                grant_type = "request_token",
                provider   = "twitter"
            },
                options).ConfigureAwait(false);

            TwitterRequestTokenResponse auth = await response.ReadAsJsonAsync <TwitterRequestTokenResponse>(ApiClient.Config).ConfigureAwait(false);

            return(auth.RequestToken);
        }
Beispiel #4
0
        /// <summary>
        /// Attempts to refresh the access token using the current refresh token or with a provided access token. If the current refresh token is null or an refresh token isn't provided, this will perform client credential authentication
        /// </summary>
        /// <returns></returns>
        public async Task <bool> RefreshTokenAsync(string providedRefreshToken = null, RequestOptions options = null)
        {
            if (!string.IsNullOrWhiteSpace(providedRefreshToken))
            {
                RefreshToken = providedRefreshToken;
            }

            options = options ?? RequestOptions.CreateFromDefaults(ApiClient.Config);
            options.UseAccessToken = false;
            if (_clientAuth)
            {
                await AuthenticateAsync(options).ConfigureAwait(false);

                return(true);
            }
            else if (RefreshToken == null)
            {
                return(false);
            }
            else
            {
                Debug.WriteLine("Refreshing token...");
                RestResponse response = await ApiClient.SendJsonAsync(
                    "POST",
                    "oauth/token",
                    new RefreshAuthRequest()
                {
                    ClientId     = ClientId,
                    ClientSecret = ClientSecret,
                    GrantType    = "refresh",
                    RefreshToken = RefreshToken
                },
                    options).ConfigureAwait(false);

                ClientAccountAuthResponse auth = await response.ReadAsJsonAsync <ClientAccountAuthResponse>(ApiClient.Config).ConfigureAwait(false);

                AccessToken            = auth.AccessToken;
                RefreshToken           = auth.RefreshToken;
                options.UseAccessToken = true;
                await CurrentUser.UpdateAsync(options).ConfigureAwait(false);

                return(true);
            }
        }
        /// <summary>
        /// Authenticates this instance using client credentials
        /// </summary>
        /// <returns>An awaitable task</returns>
        public async Task AuthenticateAsync(RequestOptions options = null)
        {
            Debug.WriteLine("Performing client credentials authentication...");
            options = options ?? RequestOptions.CreateFromDefaults(ApiClient.Config);
            options.UseAccessToken = false;
            RestResponse response = await ApiClient.SendJsonAsync(
                "POST",
                "oauth/token",
                new ClientCredentialsAuthRequest()
            {
                ClientId     = ClientId,
                ClientSecret = ClientSecret,
                GrantType    = "client_credentials"
            },
                options).ConfigureAwait(false);

            ClientCredentialsAuthResponse auth = await response.ReadAsJsonAsync <ClientCredentialsAuthResponse>(ApiClient.Config).ConfigureAwait(false);

            AccessToken = auth.AccessToken;
            CurrentUser = null;
            _clientAuth = true;
        }
        /// <summary>
        /// Attempts to move to the next item in the current page of content. If there is no content in the current page, it retrieves the next page and returns the result of that content's move next
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <bool> MoveNext(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (!_currentEnumerator.MoveNext())
            {
                if (string.IsNullOrWhiteSpace(_currentFeed.Cursor))
                {
                    return(false);
                }

                RequestOptions newOptions = _options?.Clone() ?? RequestOptions.CreateFromDefaults(_client.ApiClient.Config);
                newOptions.CancellationToken = cancellationToken;

                _currentFeed = await _currentFeed.GetNextPageAsync(RequestCount, newOptions).ConfigureAwait(false);

                _currentEnumerator?.Dispose();
                _currentEnumerator = _currentFeed.Content.GetEnumerator();
                return(_currentEnumerator.MoveNext());
            }

            return(true);
        }
        /// <summary>
        /// Attempts to refresh the access token using the current refresh token or with a provided access token. If the current refresh token is null or an refresh token isn't provided, this will perform client credential authentication
        /// </summary>
        /// <returns></returns>
        public async Task <bool> RefreshTokenAsync(string providedRefreshToken = null, RequestOptions options = null)
        {
            options = options ?? RequestOptions.CreateFromDefaults(ApiClient.Config);
            options.UseAccessToken = false;

            async Task <bool> SendRefreshRequest(string token)
            {
                Debug.WriteLine("Refreshing token...");
                try
                {
                    RestResponse response = await ApiClient.SendJsonAsync(
                        "POST",
                        "oauth/token",
                        new RefreshAuthRequest()
                    {
                        ClientId     = ClientId,
                        ClientSecret = ClientSecret,
                        GrantType    = "refresh",
                        RefreshToken = token
                    },
                        options).ConfigureAwait(false);

                    ClientAccountAuthResponse auth = await response.ReadAsJsonAsync <ClientAccountAuthResponse>(ApiClient.Config).ConfigureAwait(false);

                    AccessToken            = auth.AccessToken;
                    RefreshToken           = auth.RefreshToken;
                    options.UseAccessToken = true;
                    if (CurrentUser == null)
                    {
                        CurrentUser = await GetCurrentUserAsync(options).ConfigureAwait(false);
                    }
                    else
                    {
                        await CurrentUser.UpdateAsync(options).ConfigureAwait(false);
                    }
                }
                catch (GfycatException e) when(e.HttpCode == HttpStatusCode.Unauthorized && e.Code == "InvalidRefreshToken")
                {
                    return(false);
                }
                return(true);
            }

            if (!string.IsNullOrWhiteSpace(providedRefreshToken))
            {
                return(await SendRefreshRequest(providedRefreshToken));
            }
            else if (_clientAuth)
            {
                await AuthenticateAsync(options).ConfigureAwait(false);

                return(true);
            }
            else if (RefreshToken != null)
            {
                return(await SendRefreshRequest(RefreshToken));
            }
            else
            {
                return(false);
            }
        }
        /// <summary>
        /// Authenticates using a browser auth code and redirect uri, twitter token and secret, or twitter token and verifier
        /// </summary>
        /// <param name="type">The type of the provided tokens</param>
        /// <param name="tokenOrCode">A twitter token or browser auth code</param>
        /// <param name="verifierSecretRedirectUri">A twitter secret, verifier, or browser redirect uri</param>
        /// <param name="options">The options for this request</param>
        /// <returns></returns>
        public async Task AuthenticateAsync(TokenType type, string tokenOrCode, string verifierSecretRedirectUri, RequestOptions options = null)
        {
            options = options ?? RequestOptions.CreateFromDefaults(ApiClient.Config);
            options.UseAccessToken = false;
            switch (type)
            {
            case TokenType.AuthorizationCode:
            {
                RestResponse response = await ApiClient.SendJsonAsync(
                    "POST",
                    "oauth/token",
                    new BrowserAuthorizationCodeRequest()
                    {
                        ClientSecret = ClientSecret,
                        ClientId     = ClientId,
                        GrantType    = "authorization_code",
                        Code         = tokenOrCode,
                        RedirectUri  = verifierSecretRedirectUri
                    },
                    options).ConfigureAwait(false);

                ClientAccountAuthResponse auth = await response.ReadAsJsonAsync <ClientAccountAuthResponse>(ApiClient.Config).ConfigureAwait(false);

                AccessToken            = auth.AccessToken;
                RefreshToken           = auth.RefreshToken;
                options.UseAccessToken = true;
                CurrentUser            = await GetCurrentUserAsync(options).ConfigureAwait(false);
            }
            break;

            case TokenType.TwitterTokenSecret:
            {
                RestResponse response = await ApiClient.SendJsonAsync(
                    "POST",
                    "oauth/token",
                    new TwitterAuthCodeRequest()
                    {
                        ClientSecret = ClientSecret,
                        ClientId     = ClientId,
                        GrantType    = "convert_request_token",
                        Provider     = "twitter",
                        Token        = tokenOrCode,
                        Verifier     = verifierSecretRedirectUri
                    },
                    options).ConfigureAwait(false);

                ClientAccountAuthResponse auth = await response.ReadAsJsonAsync <ClientAccountAuthResponse>(ApiClient.Config).ConfigureAwait(false);

                AccessToken            = auth.AccessToken;
                RefreshToken           = auth.RefreshToken;
                options.UseAccessToken = true;
                CurrentUser            = await GetCurrentUserAsync(options).ConfigureAwait(false);
            }
            break;

            case TokenType.TwitterTokenVerifier:
            {
                RestResponse response = await ApiClient.SendJsonAsync(
                    "POST",
                    "oauth/token",
                    new TwitterAuthCodeRequest()
                    {
                        ClientSecret = ClientSecret,
                        ClientId     = ClientId,
                        GrantType    = "convert_token",
                        Provider     = "twitter",
                        Token        = tokenOrCode,
                        Secret       = verifierSecretRedirectUri
                    },
                    options).ConfigureAwait(false);

                ClientAccountAuthResponse auth = await response.ReadAsJsonAsync <ClientAccountAuthResponse>(ApiClient.Config).ConfigureAwait(false);

                AccessToken            = auth.AccessToken;
                RefreshToken           = auth.RefreshToken;
                options.UseAccessToken = true;
                CurrentUser            = await GetCurrentUserAsync(options).ConfigureAwait(false);
            }
            break;

            default:
                throw new ArgumentOutOfRangeException("The provided token type does not accept two token parameters");
            }
            _clientAuth = false;
        }