Esempio n. 1
0
        public async Task <bool> RefreshAccessToken(string[] scopeList = null)
        {
            if (this.options.OAuth2RefreshToken == null || this.options.AppKey == null)
            {
                // Cannot refresh token if you do not have at a minimum refresh token and app key
                return(false);
            }

            var url = "https://api.dropbox.com/oauth2/token";

            var parameters = new Dictionary <string, string>
            {
                { "refresh_token", this.options.OAuth2RefreshToken },
                { "grant_type", "refresh_token" },
                { "client_id", this.options.AppKey }
            };

            if (!string.IsNullOrEmpty(this.options.AppSecret))
            {
                parameters["client_secret"] = this.options.AppSecret;
            }

            if (scopeList != null)
            {
                parameters["scope"] = String.Join(" ", scopeList);
            }

            var bodyContent = new FormUrlEncodedContent(parameters);

            var response = await this.defaultHttpClient.PostAsync(url, bodyContent).ConfigureAwait(false);

            //if response is an invalid grant, we want to throw this exception rather than the one thrown in
            // response.EnsureSuccessStatusCode();
            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                var reason = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                if (reason == "invalid_grant")
                {
                    throw AuthException.Decode(reason, () => new AuthException(GetRequestId(response)));
                }
            }

            response.EnsureSuccessStatusCode();

            if (response.IsSuccessStatusCode)
            {
                var      json            = JObject.Parse(await response.Content.ReadAsStringAsync());
                string   accessToken     = json["access_token"].ToString();
                DateTime tokenExpiration = DateTime.Now.AddSeconds(json["expires_in"].ToObject <int>());
                this.options.OAuth2AccessToken          = accessToken;
                this.options.OAuth2AccessTokenExpiresAt = tokenExpiration;
                return(true);
            }
            return(false);
        }
Esempio n. 2
0
        /// <summary>
        /// Requests the JSON string.
        /// </summary>
        /// <param name="host">The host.</param>
        /// <param name="routeName">Name of the route.</param>
        /// <param name="auth">The auth type of the route.</param>
        /// <param name="routeStyle">The route style.</param>
        /// <param name="requestArg">The request argument.</param>
        /// <param name="body">The body to upload if <paramref name="routeStyle"/>
        /// is <see cref="RouteStyle.Upload"/>.</param>
        /// <returns>The asynchronous task with the result.</returns>
        private async Task <Result> RequestJsonString(
            string host,
            string routeName,
            string auth,
            RouteStyle routeStyle,
            string requestArg,
            Stream body = null)
        {
            var hostname = this.options.HostMap[host];
            var uri      = this.GetRouteUri(hostname, routeName);

            var request = new HttpRequestMessage(HttpMethod.Post, uri);

            if (auth == AuthType.User || auth == AuthType.Team)
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", this.options.OAuth2AccessToken);
            }
            else if (auth == AuthType.App)
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Basic", this.options.OAuth2AccessToken);
            }
            else if (auth == AuthType.NoAuth)
            {
            }
            else
            {
                throw new ArgumentException("Invalid auth type", auth);
            }

            request.Headers.TryAddWithoutValidation("User-Agent", this.options.UserAgent);

            if (this.selectUser != null)
            {
                request.Headers.TryAddWithoutValidation("Dropbox-Api-Select-User", this.selectUser);
            }

            if (this.selectAdmin != null)
            {
                request.Headers.TryAddWithoutValidation("Dropbox-Api-Select-Admin", this.selectAdmin);
            }

            var completionOption = HttpCompletionOption.ResponseContentRead;

            switch (routeStyle)
            {
            case RouteStyle.Rpc:
                request.Content = new StringContent(requestArg, Encoding.UTF8, "application/json");
                break;

            case RouteStyle.Download:
                request.Headers.Add(DropboxApiArgHeader, requestArg);

                // This is required to force libcurl remove default content type header.
                request.Content = new StringContent("");
                request.Content.Headers.ContentType = null;

                completionOption = HttpCompletionOption.ResponseHeadersRead;
                break;

            case RouteStyle.Upload:
                request.Headers.Add(DropboxApiArgHeader, requestArg);
                if (body == null)
                {
                    throw new ArgumentNullException("body");
                }

                request.Content = new CustomStreamContent(body);
                request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                break;

            default:
                throw new InvalidOperationException(string.Format(
                                                        CultureInfo.InvariantCulture,
                                                        "Unknown route style: {0}",
                                                        routeStyle));
            }

            var disposeResponse = true;
            var response        = await this.getHttpClient(host).SendAsync(request, completionOption).ConfigureAwait(false);

            var requestId = GetRequestId(response);

            try
            {
                if ((int)response.StatusCode >= 500)
                {
                    var text = await response.Content.ReadAsStringAsync();

                    text = this.CheckForError(text);
                    throw new RetryException(requestId, (int)response.StatusCode, message: text, uri: uri);
                }
                else if (response.StatusCode == HttpStatusCode.BadRequest)
                {
                    var text = await response.Content.ReadAsStringAsync();

                    text = this.CheckForError(text);
                    throw new BadInputException(requestId, text, uri);
                }
                else if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    throw AuthException.Decode(reason, () => new AuthException(GetRequestId(response)));
                }
                else if ((int)response.StatusCode == 429)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    throw RateLimitException.Decode(reason, () => new RateLimitException(GetRequestId(response)));
                }
                else if (response.StatusCode == HttpStatusCode.Forbidden)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    throw AccessException.Decode(reason, () => new AccessException(GetRequestId(response)));
                }
                else if (response.StatusCode == HttpStatusCode.Conflict ||
                         response.StatusCode == HttpStatusCode.NotFound)
                {
                    var reason = await response.Content.ReadAsStringAsync();

                    return(new Result
                    {
                        IsError = true,
                        ObjectResult = reason,
                        RequestId = GetRequestId(response)
                    });
                }
                else if ((int)response.StatusCode >= 200 && (int)response.StatusCode <= 299)
                {
                    if (routeStyle == RouteStyle.Download)
                    {
                        disposeResponse = false;
                        return(new Result
                        {
                            IsError = false,
                            ObjectResult = response.Headers.GetValues(DropboxApiResultHeader).FirstOrDefault(),
                            HttpResponse = response
                        });
                    }
                    else
                    {
                        return(new Result
                        {
                            IsError = false,
                            ObjectResult = await response.Content.ReadAsStringAsync()
                        });
                    }
                }
                else
                {
                    var text = await response.Content.ReadAsStringAsync();

                    text = this.CheckForError(text);
                    throw new HttpException(requestId, (int)response.StatusCode, text, uri);
                }
            }
            finally
            {
                if (disposeResponse)
                {
                    response.Dispose();
                }
            }
        }