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)); + } + } +}