Skip to content

Instantly share code, notes, and snippets.

@trevorprinn
Created May 4, 2016 11:26
Show Gist options
  • Save trevorprinn/f4b6b6b57ee5b23e4ba68307f513ed16 to your computer and use it in GitHub Desktop.
Save trevorprinn/f4b6b6b57ee5b23e4ba68307f513ed16 to your computer and use it in GitHub Desktop.
C#' Dropbox login class (not platform specific)
using Dropbox.Api;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Babbacombe.MobileDmx {
class DropboxManager : IDisposable {
public string AppName { get; }
public string AppKey { get; }
public string RedirectUri { get; set; } = "https://localhost/authorize";
public string AccessToken { get; private set; }
public DropboxClient Client { get; private set; }
public Func<Uri, string, Task<string>> LoginAsync { get; set; }
public Func<Uri, string, string> Login { get; set; }
public DropboxManager(string appName, string appKey, string savedAccessToken) {
AppName = appName;
AppKey = appKey;
AccessToken = savedAccessToken;
}
public async Task<bool> SetupClientAsync() {
if (Client != null) return true;
if (!await obtainAccessToken()) return false;
// Specify socket level timeout which decides maximum waiting time when on bytes are
// received by the socket.
var httpClient = new HttpClient(new WebRequestHandler { ReadWriteTimeout = 10 * 1000 }) {
// Specify request level timeout which decides maximum time that can be spent on
// download/upload files.
Timeout = TimeSpan.FromMinutes(20)
};
var config = new DropboxClientConfig(AppName) {
HttpClient = httpClient
};
Client = new DropboxClient(AccessToken, config);
return true;
}
private async Task<bool> obtainAccessToken() {
if (!string.IsNullOrWhiteSpace(AccessToken)) return true;
var oAuth2State = Guid.NewGuid().ToString("N");
var authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Token, AppKey, new Uri(RedirectUri), oAuth2State);
if (LoginAsync != null) {
AccessToken = await LoginAsync(authorizeUri, oAuth2State);
} else if (Login != null) {
AccessToken = Login(authorizeUri, oAuth2State);
}
return !string.IsNullOrWhiteSpace(AccessToken);
}
/// <summary>
/// To be called in the BrowserNavigating event of the browser.
/// </summary>
/// <param name="uri">The uri navigating to</param>
/// <param name="oAuth2State">The oAuthState passed in the event args</param>
/// <param name="accessToken">the AccessToken obtained</param>
/// <returns>True to exit the browser, False to do nothing</returns>
public virtual bool OnBrowserNavigating(Uri uri, string oAuth2State, out string accessToken) {
accessToken = null;
if (!uri.ToString().StartsWith(RedirectUri, StringComparison.OrdinalIgnoreCase)) {
// we need to ignore all navigation that isn't to the redirect uri.
return false;
}
try {
OAuth2Response result = DropboxOAuth2Helper.ParseTokenFragment(uri);
if (oAuth2State != result.State) return true;
accessToken = result.AccessToken;
} catch (ArgumentException) {
// There was an error in the URI passed to ParseTokenFragment
}
return true;
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing) {
if (!disposedValue) {
if (disposing) {
if (Client != null) {
Client.Dispose();
Client = null;
}
}
disposedValue = true;
}
}
public void Dispose() {
Dispose(true);
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment