diff --git a/src/Intersvyaz.Core/Intersvyaz.Core.csproj b/src/Intersvyaz.Core/Intersvyaz.Core.csproj
index 108eaa5..1e6ba33 100644
--- a/src/Intersvyaz.Core/Intersvyaz.Core.csproj
+++ b/src/Intersvyaz.Core/Intersvyaz.Core.csproj
@@ -123,6 +123,7 @@
+
@@ -130,7 +131,12 @@
6.2.8
-
+
+
+ {d53e9b31-82ca-4b3b-a6ba-9f4b9353abb1}
+ Intersvyaz.Net
+
+
14.0
diff --git a/src/Intersvyaz.Core/Services/ISessionService.cs b/src/Intersvyaz.Core/Services/ISessionService.cs
index d0e369f..1b8e524 100644
--- a/src/Intersvyaz.Core/Services/ISessionService.cs
+++ b/src/Intersvyaz.Core/Services/ISessionService.cs
@@ -17,17 +17,20 @@ namespace Intersvyaz.Core.Services
///
/// Получить сессию пользователя.
///
+ /// Имя пользователя.
/// Данные об сессии.
- SessionData GetSession();
+ SessionData GetSession(string username);
///
/// Проверить, есть ли сессия пользователя.
///
- bool HasSession();
+ /// Имя пользователя.
+ bool HasSession(string username);
///
/// Удалить сессию пользователя.
///
- void DeleteSession();
+ /// Имя пользователя.
+ void DeleteSession(string username);
}
}
diff --git a/src/Intersvyaz.Core/Services/SessionService.cs b/src/Intersvyaz.Core/Services/SessionService.cs
new file mode 100644
index 0000000..95a3d0d
--- /dev/null
+++ b/src/Intersvyaz.Core/Services/SessionService.cs
@@ -0,0 +1,129 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Globalization;
+using Intersvyaz.Net;
+using Intersvyaz.Core.Models;
+using Windows.Security.Credentials;
+
+namespace Intersvyaz.Core.Services
+{
+ public class SessionService : ISessionService
+ {
+ ///
+ /// Имя ресурса.
+ ///
+ private const string RESOURCE_NAME = "Intersvyaz";
+
+ ///
+ /// Клиент Интерсвязи.
+ ///
+ private IntersvyazClient _intersvyazClient;
+
+ ///
+ /// Хранилище паролей.
+ ///
+ private PasswordVault _passwordVault;
+
+ public SessionService(IntersvyazClient intersvyazClient)
+ {
+ _intersvyazClient = intersvyazClient;
+ _passwordVault = new PasswordVault();
+ }
+
+ ///
+ public async Task GetSessionAsync(string username, string password)
+ {
+ try
+ {
+ return GetSession(username);
+ }
+ catch
+ {
+ return await LoginAndSaveSession(username, password);
+ }
+ }
+
+ ///
+ public SessionData GetSession(string username)
+ {
+ var passwordCredential = _passwordVault.Retrieve(RESOURCE_NAME, username);
+ return ConvertToSessionData(passwordCredential);
+ }
+
+ ///
+ public bool HasSession(string username)
+ {
+ var passwordCredentials = _passwordVault.FindAllByResource(RESOURCE_NAME);
+
+ var count = passwordCredentials
+ .Where(passwordCredential => passwordCredential.UserName == username)
+ .Count();
+ return count > 0;
+ }
+
+ ///
+ public void DeleteSession(string username)
+ {
+ var passwordCredential = _passwordVault.Retrieve(RESOURCE_NAME, username);
+ _passwordVault.Remove(passwordCredential);
+ }
+
+ ///
+ /// Войти в систему и сохранить сессию пользователя.
+ ///
+ /// Имя пользователя.
+ /// Пароль пользователя.
+ /// Данные об сессии.
+ private async Task LoginAndSaveSession(string username, string password)
+ {
+ var responseDto = await _intersvyazClient.Login(username, password);
+
+ var sessionData = new SessionData()
+ {
+ Token = responseDto.Token,
+ ExpiresAt = responseDto.AccessEnd,
+ Username = username,
+ };
+ var passwordCredential = ConvertToPasswordCredential(sessionData);
+
+ _passwordVault.Add(passwordCredential);
+ return sessionData;
+ }
+
+ ///
+ /// Сконвертировать нативную учетчую запсть в SessionData.
+ ///
+ /// Учетная запись.
+ /// Данные об сессии.
+ private SessionData ConvertToSessionData(PasswordCredential passwordCredential)
+ {
+ var entries = passwordCredential.Password.Split(
+ new string[] { ";" }, 2, StringSplitOptions.RemoveEmptyEntries);
+
+ return new SessionData()
+ {
+ Token = entries[0],
+ ExpiresAt = DateTime.Parse(entries[1], CultureInfo.InvariantCulture),
+ Username = passwordCredential.UserName,
+ };
+ }
+
+ ///
+ /// Сконвертировать SessionData в нативную учетную запись.
+ ///
+ /// Данные об сессии.
+ /// Нативная учетная запись.
+ private PasswordCredential ConvertToPasswordCredential(SessionData sessionData)
+ {
+ var entries = new string[]
+ {
+ sessionData.Token,
+ sessionData.ExpiresAt.ToString(CultureInfo.InvariantCulture),
+ };
+
+ return new PasswordCredential(
+ RESOURCE_NAME, sessionData.Username, string.Join(";", entries));
+ }
+ }
+}