Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
DropboxCoreService: Now loading/saving authentication token in a file.
  • Loading branch information
ycastonguay committed Oct 26, 2013
1 parent b6f7270 commit affbcc4
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 51 deletions.
Expand Up @@ -17,27 +17,25 @@

using System;
using System.IO;
using System.Xml.Serialization;
using MPfm.MVP.Config;

#if WINDOWSSTORE
using Windows.Storage;
#endif

namespace MPfm.MVP.Helpers
namespace MPfm.Core.Helpers
{
/// <summary>
/// Helper static class for configuration paths.
/// </summary>
public static class ConfigurationHelper
public static class PathHelper
{
public static string HomeDirectory;
public static string PeakFileDirectory;
public static string ConfigurationFilePath;
public static string DatabaseFilePath;
public static string LogFilePath;
public static string HomeDirectory { get; set; }
public static string PeakFileDirectory { get; set; }
public static string ConfigurationFilePath { get; set; }
public static string DatabaseFilePath { get; set; }
public static string LogFilePath { get; set; }

static ConfigurationHelper()
static PathHelper()
{
// Get assembly directory
//string assemblyDirectory = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
Expand Down
5 changes: 4 additions & 1 deletion MPfm/MPfm.Core/MPfm.Core.csproj
Expand Up @@ -96,6 +96,7 @@
<Compile Include="Attributes\DatabaseFieldAttribute.cs" />
<Compile Include="DatabaseFieldMap.cs" />
<Compile Include="Extensions\DictionaryExtension.cs" />
<Compile Include="Helpers\PathHelper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tracing.cs" />
<Compile Include="OS.cs" />
Expand All @@ -104,7 +105,9 @@
<Compile Include="Normalizer.cs" />
<Compile Include="Helpers\XMLHelper.cs" />
<Compile Include="Network\IPAddressRangeFinder.cs" />
<Compile Include="Network\WebClientTimeout.cs" />
<Compile Include="Network\WebClientTimeout.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="XmlSerialization.cs" />
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions MPfm/MPfm.Library/MPfm.Library.csproj
Expand Up @@ -171,6 +171,7 @@
<Compile Include="Database\Interfaces\IDatabaseFacade.cs" />
<Compile Include="Database\Interfaces\ISQLiteGateway.cs" />
<Compile Include="Database\DatabaseFacade.cs" />
<Compile Include="Objects\AuthenticationToken.cs" />
<Compile Include="Objects\CloudDeviceInfo.cs" />
<Compile Include="Objects\CloudPlaylist.cs" />
<Compile Include="Objects\PlaylistAudioFile.cs" />
Expand Down
31 changes: 31 additions & 0 deletions MPfm/MPfm.Library/Objects/AuthenticationToken.cs
@@ -0,0 +1,31 @@
// Copyright © 2011-2013 Yanick Castonguay
//
// This file is part of MPfm.
//
// MPfm is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// MPfm is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with MPfm. If not, see <http://www.gnu.org/licenses/>.

using System;

namespace MPfm.Library.Objects
{
/// <summary>
/// Object representing a authentication token (value + secret) and user name.
/// </summary>
public class AuthenticationToken
{
public string Value { get; set; }
public string Secret { get; set; }
public string UserName { get; set; }
}
}
114 changes: 98 additions & 16 deletions MPfm/MPfm.Library/Services/DropboxCoreService.cs
Expand Up @@ -17,6 +17,7 @@

using System.Text;
using MPfm.Core;
using MPfm.Core.Helpers;
using MPfm.Library.Objects;
using MPfm.Sound.Playlists;
using Newtonsoft.Json;
Expand Down Expand Up @@ -80,20 +81,26 @@ public void LinkApp(object view)
OnCloudAuthenticationStatusChanged(CloudAuthenticationStatusType.GetRequestToken);

// Authorization without callback url
//Console.Write("Getting request token...");
_oauthToken = _dropboxServiceProvider.OAuthOperations.FetchRequestTokenAsync(null, null).Result;
//Console.WriteLine("Done - FetchRequestToken - secret: {0} value: {1}", _oauthToken.Secret, _oauthToken.Value);
OAuth1Parameters parameters = new OAuth1Parameters();
//parameters.Add("locale", CultureInfo.CurrentUICulture.IetfLanguageTag); // for a localized version of the authorization website
string authenticateUrl = _dropboxServiceProvider.OAuthOperations.BuildAuthorizeUrl(_oauthToken.Value, parameters);
//Console.WriteLine("Redirect user for authorization");

// Update status
if (OnCloudAuthenticationStatusChanged != null)
OnCloudAuthenticationStatusChanged(CloudAuthenticationStatusType.OpenWebBrowser);

// Open web browser for authentication
Process.Start(authenticateUrl);
// Try to get a previously saved token
var token = LoadToken();
if (token == null)
{
// Open web browser for authentication
OAuth1Parameters parameters = new OAuth1Parameters();
//parameters.Add("locale", CultureInfo.CurrentUICulture.IetfLanguageTag); // for a localized version of the authorization website
string authenticateUrl = _dropboxServiceProvider.OAuthOperations.BuildAuthorizeUrl(_oauthToken.Value, parameters);
Process.Start(authenticateUrl);
}
else
{
ContinueLinkApp(token);
}
}
catch (AggregateException ae)
{
Expand All @@ -110,28 +117,45 @@ public void LinkApp(object view)
}

public void ContinueLinkApp()
{
}

private void ContinueLinkApp(AuthenticationToken token)
{
try
{
Console.Write("Getting access token...");
AuthorizedRequestToken requestToken = new AuthorizedRequestToken(_oauthToken, null);
OAuthToken oauthAccessToken = _dropboxServiceProvider.OAuthOperations.ExchangeForAccessTokenAsync(requestToken, null).Result;
Console.WriteLine("Done - FetchAccessToken - secret: {0} value: {1}", oauthAccessToken.Secret, oauthAccessToken.Value);
OAuthToken oauthAccessToken = null;
if (token == null)
{
Console.Write("Getting access token...");
AuthorizedRequestToken requestToken = new AuthorizedRequestToken(_oauthToken, null);
oauthAccessToken = _dropboxServiceProvider.OAuthOperations.ExchangeForAccessTokenAsync(requestToken, null).Result;
Console.WriteLine("Done - FetchAccessToken - secret: {0} value: {1}", oauthAccessToken.Secret, oauthAccessToken.Value);
}
else
{
oauthAccessToken = new OAuthToken(token.Value, token.Secret);
}

// Update status
if (OnCloudAuthenticationStatusChanged != null)
OnCloudAuthenticationStatusChanged(CloudAuthenticationStatusType.RequestAccessToken);

// TODO: Take token from storage
//OAuthToken oauthAccessToken2 = new OAuthToken("z20l3g6vs5bbvqcr", "b8eiq09w1gxsyad");

// Connect to Dropbox API
_dropbox = _dropboxServiceProvider.GetApi(oauthAccessToken.Value, oauthAccessToken.Secret);
//IDropbox dropbox = dropboxServiceProvider.GetApi(oauthAccessToken2.Value, oauthAccessToken2.Secret);
//dropbox.Locale = CultureInfo.CurrentUICulture.IetfLanguageTag;

// Get user name from profile
DropboxProfile profile = _dropbox.GetUserProfileAsync().Result;
Console.WriteLine("Hi " + profile.DisplayName + "!");

// Save token to hard disk
SaveToken(new AuthenticationToken() {
Value = oauthAccessToken.Value,
Secret = oauthAccessToken.Secret,
UserName = profile.DisplayName
});

// Update status
if (OnCloudAuthenticationStatusChanged != null)
OnCloudAuthenticationStatusChanged(CloudAuthenticationStatusType.ConnectedToDropbox);
Expand All @@ -150,6 +174,64 @@ public void ContinueLinkApp()
}
}

private AuthenticationToken LoadToken()
{
FileStream fileStream = null;
try
{
byte[] bytes = new byte[4096]; // 4k is way enough to store the token
string filePath = Path.Combine(PathHelper.HomeDirectory, "dropbox.json");
fileStream = File.OpenRead(filePath);
fileStream.Read(bytes, 0, (int) fileStream.Length);
string json = Encoding.UTF8.GetString(bytes);
var token = JsonConvert.DeserializeObject<AuthenticationToken>(json);

return token;
}
catch (Exception ex)
{
Tracing.Log("DropboxCoreService - LoadToken - Failed to load token: {0}", ex);
}
finally
{
if (fileStream != null)
fileStream.Close();
}

return null;
}

private void SaveToken(AuthenticationToken token)
{
FileStream fileStream = null;
try
{
// If the file exists, decrypt it before changing its contents
string filePath = Path.Combine(PathHelper.HomeDirectory, "dropbox.json");
if (File.Exists(filePath))
File.Decrypt(filePath);

// Write file to disk
string json = JsonConvert.SerializeObject(token);
byte[] bytes = Encoding.UTF8.GetBytes(json);
fileStream = File.OpenWrite(filePath);
fileStream.Write(bytes, 0, bytes.Length);
fileStream.Close();

// Encrypt file
File.Encrypt(filePath);
}
catch (Exception ex)
{
Tracing.Log("DropboxCoreService - SaveToken - Failed to save token: {0}", ex);
}
finally
{
if (fileStream != null)
fileStream.Close();
}
}

public void UnlinkApp()
{
//_dropbox.
Expand Down
3 changes: 2 additions & 1 deletion MPfm/MPfm.MVP/Bootstrap/Bootstrapper.cs
Expand Up @@ -15,6 +15,7 @@
// You should have received a copy of the GNU General Public License
// along with MPfm. If not, see <http://www.gnu.org/licenses/>.

using MPfm.Core.Helpers;
using MPfm.Library.Database;
using MPfm.Library.Database.Interfaces;
using MPfm.Library.Services;
Expand Down Expand Up @@ -44,7 +45,7 @@ static Bootstrapper()
var container = TinyIoC.TinyIoCContainer.Current;

// Register services
container.Register<IDatabaseFacade>(new DatabaseFacade(ConfigurationHelper.DatabaseFilePath));
container.Register<IDatabaseFacade>(new DatabaseFacade(PathHelper.DatabaseFilePath));
container.Register<ITinyMessengerHub, TinyMessengerHub>().AsSingleton();
container.Register<IInitializationService, InitializationService>().AsSingleton();
container.Register<IPlayerService, PlayerService>().AsSingleton();
Expand Down
7 changes: 4 additions & 3 deletions MPfm/MPfm.MVP/Config/AppConfigManager.cs
@@ -1,4 +1,4 @@
// Copyright © 2011-2013 Yanick Castonguay
// Copyright © 2011-2013 Yanick Castonguay
//
// This file is part of MPfm.
//
Expand All @@ -15,6 +15,7 @@
// You should have received a copy of the GNU General Public License
// along with MPfm. If not, see <http://www.gnu.org/licenses/>.

using MPfm.Core.Helpers;
using MPfm.MVP.Bootstrap;
using MPfm.MVP.Config.Providers;
using MPfm.MVP.Helpers;
Expand Down Expand Up @@ -56,12 +57,12 @@ public AppConfigManager()

public void Load()
{
Root = _provider.Load(ConfigurationHelper.ConfigurationFilePath);
Root = _provider.Load(PathHelper.ConfigurationFilePath);
}

public void Save()
{
_provider.Save(ConfigurationHelper.ConfigurationFilePath, Root);
_provider.Save(PathHelper.ConfigurationFilePath, Root);
}
}
}
1 change: 0 additions & 1 deletion MPfm/MPfm.MVP/MPfm.MVP.csproj
Expand Up @@ -201,7 +201,6 @@
<Compile Include="Models\LibraryBrowserEntity.cs" />
<Compile Include="Views\ILibraryBrowserView.cs" />
<Compile Include="Presenters\LibraryBrowserPresenter.cs" />
<Compile Include="Helpers\ConfigurationHelper.cs" />
<Compile Include="Presenters\SongBrowserPresenter.cs" />
<Compile Include="Views\ISongBrowserView.cs" />
<Compile Include="Presenters\Interfaces\ILibraryBrowserPresenter.cs" />
Expand Down

0 comments on commit affbcc4

Please sign in to comment.