Skip to content

Commit

Permalink
Do not store password, just the session
Browse files Browse the repository at this point in the history
Encrypted session data stored in binary format
  • Loading branch information
geloczi committed Dec 1, 2021
1 parent 7c6ccb4 commit 7940dc9
Show file tree
Hide file tree
Showing 20 changed files with 317 additions and 309 deletions.
23 changes: 14 additions & 9 deletions SynAudio/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public partial class App : Application
internal static readonly string UserDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), nameof(SynAudio));
#endif

internal static readonly Encryption.Encrypter Encrypter = new Encryption.Encrypter("2BE93913-B573-4DE5-8CCA-9BC14FA41201", Encoding.UTF8.GetBytes("35FE3A9B-227A-4184-8426-3765669C12F8"));
internal static readonly Encryption.Encrypter Encrypter = new Encryption.Encrypter("833236b9e38f36c240fba48a48d2a160185671cc08a9d4fef75cc8b33e4166cd", Encoding.UTF8.GetBytes($"{UserDataFolder}-{Environment.UserDomainName}-{Environment.UserName}"));

internal static readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings()
{
Expand Down Expand Up @@ -76,21 +76,27 @@ internal static void RefreshCommands()
Current.Dispatcher.BeginInvoke(new Action(() => System.Windows.Input.CommandManager.InvalidateRequerySuggested()));
}

internal static string GetNasFileFullUncPath(string internalPath) => NetworkHelper.GetUncPath(Settings.Connection.MusicFolderPath, internalPath);
//internal static string GetNasFileFullUncPath(string internalPath) => NetworkHelper.GetUncPath(MusicFolderPath, internalPath);

internal static bool ExistsOnHost(string path, out string uncPath)
{
uncPath = null;
if (MusicFolderAvailableOnLan)
{
uncPath = GetNasFileFullUncPath(path);
return File.Exists(uncPath);
}
// Todo
//if (MusicFolderAvailableOnLan)
//{
// uncPath = GetNasFileFullUncPath(path);
// return File.Exists(uncPath);
//}
return false;
}

internal static SqlCeLibrary.SqlCe GetSql() => new SqlCeLibrary.SqlCe(LibraryDatabaseFile, false);

internal static void SaveSettings()
{
Storage.Save(nameof(Settings), Settings);
}

protected override void OnStartup(StartupEventArgs e)
{
_mutex = new Mutex(true, MutexName, out var createdNewMutex);
Expand Down Expand Up @@ -165,7 +171,6 @@ protected override void OnStartup(StartupEventArgs e)
if (!Storage.TryLoad<SettingsModel>(nameof(Settings), out var settings))
settings = new SettingsModel();
Settings = settings;
MusicFolderAvailableOnLan = !string.IsNullOrWhiteSpace(Settings.Connection.MusicFolderPath) && Directory.Exists(Settings.Connection.MusicFolderPath);

// Catch binding errors
PresentationTraceSources.Refresh();
Expand Down Expand Up @@ -196,7 +201,7 @@ private void App_DispatcherUnhandledException(object sender, System.Windows.Thre
protected override void OnExit(ExitEventArgs e)
{
_log.Info(nameof(OnExit));
Storage.Save(nameof(Settings), Settings);
SaveSettings();
NLog.LogManager.Shutdown();
if (_mutex != null)
_mutex.ReleaseMutex();
Expand Down
27 changes: 27 additions & 0 deletions SynAudio/DAL/ByteArrayValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using SqlCeLibrary;

namespace SynAudio.DAL
{
[Table("ByteArray")]
public class ByteArrayValue
{
[Column, PrimaryKey]
public string Key { get; set; }
[Column]
public byte[] Value { get; set; }

public static byte[] Read(SqlCe sql, string key) => sql.SelectFirstByPrimaryKeys<ByteArrayValue>(key)?.Value;
public static bool TryRead(SqlCe sql, string key, out byte[] value)
{
var v = sql.SelectFirstByPrimaryKeys<ByteArrayValue>(key);
value = v?.Value;
return !(value is null);
}
public static void Write(SqlCe sql, string key, byte[] value)
{
sql.DeleteSingleByPrimaryKey<ByteArrayValue>(key);
if (value?.Length > 0 == true)
sql.Insert(new ByteArrayValue() { Key = key, Value = value });
}
}
}
7 changes: 7 additions & 0 deletions SynAudio/DAL/ByteArrayValues.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace SynAudio.DAL
{
public enum ByteArrayValues
{
AudioStationConnectorSession
}
}
1 change: 1 addition & 0 deletions SynAudio/DAL/StringValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class StringValue
{
[Column, PrimaryKey]
public string Key { get; set; }

[Column(Size = "1000"), NotNull]
public string Value { get; set; }

Expand Down
1 change: 0 additions & 1 deletion SynAudio/DAL/StringValues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
{
public enum StringValues
{
AudioStationConnectorSession,
NowPlaying_CurrentSongId
}
}
6 changes: 6 additions & 0 deletions SynAudio/Extensions/SqlCeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,11 @@ static class SqlCeExtensions
public static bool TryReadString(this SqlCe sql, StringValues key, out string value) => StringValue.TryRead(sql, key.ToString(), out value);
public static void WriteString(this SqlCe sql, StringValues key, string value) => StringValue.Write(sql, key.ToString(), value);
#endregion

#region BlobValue
public static byte[] ReadBlob(this SqlCe sql, ByteArrayValues key) => ByteArrayValue.Read(sql, key.ToString());
public static bool TryReadBlob(this SqlCe sql, ByteArrayValues key, out byte[] value) => ByteArrayValue.TryRead(sql, key.ToString(), out value);
public static void WriteBlob(this SqlCe sql, ByteArrayValues key, byte[] value) => ByteArrayValue.Write(sql, key.ToString(), value);
#endregion
}
}
75 changes: 38 additions & 37 deletions SynAudio/Library/AudioLibrary.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using SqlCeLibrary;
using SynAudio.DAL;
using SynAudio.Library.Exceptions;
using SynAudio.Models;
using SynAudio.Models.Config;
using SynAudio.Utils;
using SynCommon.Serialization;
using SynologyDotNet;
using SynologyDotNet.AudioStation;
using SynologyDotNet.Core.Model;
Expand Down Expand Up @@ -79,49 +82,47 @@ public AudioLibrary(SettingsModel settings, ViewModels.StatusViewModel status)
}
}

public async Task<bool> ConnectAsync()
public async Task<bool> ConnectAsync(string password = null)
{
_log.Debug(nameof(ConnectAsync));
try
if (!(_audioStation is null))
{
if (!(_audioStation is null))
{
_audioStation.Dispose();
_audioStation = null;
}
_audioStation.Dispose();
_audioStation = null;
}

if (string.IsNullOrWhiteSpace(Settings.Connection.Url))
throw new NullReferenceException("API url is null");
if (string.IsNullOrWhiteSpace(Settings.Url))
throw new NullReferenceException("API url is null");

_audioStation = new AudioStationClient();
_synoClient = new SynoClient(new Uri(Settings.Connection.Url), true, _audioStation);
_audioStation = new AudioStationClient();
_synoClient = new SynoClient(new Uri(Settings.Url), true, _audioStation);

using (var sql = Sql())
using (var sql = Sql())
{
// Login
SynoSession session = null;
if (password is null && sql.TryReadBlob(ByteArrayValues.AudioStationConnectorSession, out var encryptedSession))
{
// Login
SynoSession session;
if (sql.TryReadString(StringValues.AudioStationConnectorSession, out var json))
{
session = JsonConvert.DeserializeObject<SynoSession>(json);
await _synoClient.LoginWithPreviousSessionAsync(session, false);
}
else
{
session = await _synoClient.LoginAsync(Settings.Connection.Username, App.Encrypter.Decrypt(Settings.Connection.Password)).ConfigureAwait(false);
}

// Test connection
var response = await _audioStation.ListSongsAsync(1, 0, SynologyDotNet.AudioStation.Model.SongQueryAdditional.None).ConfigureAwait(false);
if (!response.Success)
session = null;
sql.WriteString(StringValues.AudioStationConnectorSession, !(session is null) ? JsonConvert.SerializeObject(session) : null);
Connected = response.Success;
// Re-use session
session = JsonSerialization.DeserializeFromBytes<SynoSession>(App.Encrypter.Decrypt(encryptedSession));
await _synoClient.LoginWithPreviousSessionAsync(session, false);
}
}
catch (Exception ex)
{
Connected = false;
_log.Error(ex);
else if (!(password is null))
{
// Login with credentials
session = await _synoClient.LoginAsync(Settings.Username, password).ConfigureAwait(false);
}
else
{
// Must enter credentials
throw new System.Security.Authentication.AuthenticationException("Must enter crdentials.");
}

// Test connection
var response = await _audioStation.ListSongsAsync(1, 0, SynologyDotNet.AudioStation.Model.SongQueryAdditional.None).ConfigureAwait(false);
if (!response.Success)
session = null;
sql.WriteBlob(ByteArrayValues.AudioStationConnectorSession, !(session is null) ? App.Encrypter.Encrypt(JsonSerialization.SerializeToBytes(session)) : null);
Connected = response.Success;
}
return Connected;
}
Expand All @@ -131,7 +132,7 @@ public void Logout()
_log.Debug(nameof(Logout));
Connected = false;
using (var sql = Sql())
sql.WriteString(StringValues.AudioStationConnectorSession, null);
sql.WriteBlob(ByteArrayValues.AudioStationConnectorSession, null);
}

public void Dispose()
Expand Down
32 changes: 0 additions & 32 deletions SynAudio/Models/Config/ConnectionSettingsModel.cs

This file was deleted.

12 changes: 11 additions & 1 deletion SynAudio/Models/Config/SettingsModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@ namespace SynAudio.Models.Config
[Serializable]
public class SettingsModel
{
public ConnectionSettingsModel Connection { get; set; } = new ConnectionSettingsModel();
/// <summary>
/// Url to the NAS, like "https://yourserver.example.com:5001"
/// Both HTTP and HTTPS endpoints are supported.
/// </summary>
public string Url { get; set; }

/// <summary>
/// NAS user account name
/// </summary>
public string Username { get; set; }

public TranscodeMode Transcoding { get; set; } = TranscodeMode.WAV;
public int Volume { get; set; } = 100;
public System.Windows.WindowState WindowState { get; set; } = System.Windows.WindowState.Maximized;
Expand Down
9 changes: 9 additions & 0 deletions SynAudio/Models/Credentials.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace SynAudio.Models
{
public class Credentials
{
public string Url { get; set; } = string.Empty;
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
}
4 changes: 2 additions & 2 deletions SynAudio/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.3.0.0")]
[assembly: AssemblyFileVersion("0.3.0.0")]
[assembly: AssemblyVersion("0.3.1.0")]
[assembly: AssemblyFileVersion("0.3.1.0")]
[assembly: Guid("127198AC-AB11-4077-B64A-B1618E5B231F")]
5 changes: 3 additions & 2 deletions SynAudio/SynAudio.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Behaviors\TabContent.cs" />
<Compile Include="DAL\ByteArrayValue.cs" />
<Compile Include="DAL\ByteArrayValues.cs" />
<Compile Include="MediaPlayer\PlaybackStateType.cs" />
<Compile Include="Utils\BindingErrorTraceListener.cs" />
<Compile Include="Utils\RangeObservableCollection.cs" />
Expand Down Expand Up @@ -133,12 +135,12 @@
<Compile Include="Library\AudioLibrary.synchronization.cs" />
<Compile Include="Library\Cache.cs" />
<Compile Include="Library\Exceptions\LibraryResponseException.cs" />
<Compile Include="Models\Config\ConnectionSettingsModel.cs" />
<Compile Include="Models\Config\RectangleD.cs" />
<Compile Include="Models\Config\SettingsModel.cs" />
<Compile Include="DAL\SongBackup.cs" />
<Compile Include="Models\FolderContentsModel.cs" />
<Compile Include="ViewModels\FolderViewModel.cs" />
<Compile Include="Models\Credentials.cs" />
<Compile Include="ViewModels\ViewModelBase.cs" />
<Compile Include="DAL\AlbumModel.cs" />
<Compile Include="DAL\ArtistModel.cs" />
Expand All @@ -149,7 +151,6 @@
<Compile Include="ViewModels\NowPlayingViewModel.cs" />
<Compile Include="ViewModels\SongViewModel.cs" />
<Compile Include="StaticCommands.cs" />
<Compile Include="ViewModels\LoginDialogViewModel.cs" />
<Compile Include="ViewModels\TabContentViewModel.cs" />
<Compile Include="ViewModels\TabViewModel.cs" />
<Compile Include="ViewModels\NavigationItem.cs" />
Expand Down
12 changes: 0 additions & 12 deletions SynAudio/ViewModels/LoginDialogViewModel.cs

This file was deleted.

Loading

0 comments on commit 7940dc9

Please sign in to comment.