mirror of
https://github.com/bitwarden/android.git
synced 2024-12-18 23:31:52 +03:00
Added equivalent domain checks to autofill listing filter. centralized logic in login service.
This commit is contained in:
parent
2a1bd92e1a
commit
539121070a
8 changed files with 114 additions and 69 deletions
|
@ -1,11 +1,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models.Data;
|
||||
using Bit.App.Models.Data;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface ISettingsRepository : IRepository<SettingsData, string>
|
||||
{
|
||||
Task<IEnumerable<IEnumerable<string>>> GetEquivablentDomains(string userId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Bit.App.Abstractions
|
|||
Task<Login> GetByIdAsync(string id);
|
||||
Task<IEnumerable<Login>> GetAllAsync();
|
||||
Task<IEnumerable<Login>> GetAllAsync(bool favorites);
|
||||
Task<IEnumerable<Login>> GetAllAsync(string uriString);
|
||||
Task<ApiResult<LoginResponse>> SaveAsync(Login login);
|
||||
Task<ApiResult> DeleteAsync(string id);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
namespace Bit.App.Abstractions
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface ISettingsService
|
||||
{
|
||||
Task<IEnumerable<IEnumerable<string>>> GetEquivalentDomainsAsync();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,37 +26,6 @@ namespace Bit.App.Models.Page
|
|||
public string Username { get; set; }
|
||||
public Lazy<string> Password { get; set; }
|
||||
public Lazy<string> Uri { get; set; }
|
||||
|
||||
public string BaseDomain
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_baseDomain != null)
|
||||
{
|
||||
return _baseDomain;
|
||||
}
|
||||
|
||||
if(string.IsNullOrWhiteSpace(Uri.Value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Uri uri;
|
||||
if(!System.Uri.TryCreate(Uri.Value, UriKind.Absolute, out uri))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
DomainName domain;
|
||||
if(!DomainName.TryParse(uri.Host, out domain))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
_baseDomain = domain.BaseDomain;
|
||||
return _baseDomain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Folder : List<Login>
|
||||
|
|
|
@ -21,34 +21,35 @@ namespace Bit.App.Pages
|
|||
private readonly IDeviceInfoService _deviceInfoService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private CancellationTokenSource _filterResultsCancellationTokenSource;
|
||||
private readonly DomainName _domainName;
|
||||
private readonly string _name;
|
||||
private readonly bool _androidApp = false;
|
||||
|
||||
public VaultAutofillListLoginsPage(string uriString)
|
||||
: base(true)
|
||||
{
|
||||
Uri = uriString;
|
||||
|
||||
Uri uri;
|
||||
DomainName domainName;
|
||||
if(!System.Uri.TryCreate(uriString, UriKind.Absolute, out uri) ||
|
||||
!DomainName.TryParse(uri.Host, out _domainName))
|
||||
!DomainName.TryParse(uri.Host, out domainName))
|
||||
{
|
||||
if(uriString != null && uriString.StartsWith(Constants.AndroidAppProtocol))
|
||||
{
|
||||
_androidApp = true;
|
||||
_name = uriString.Substring(Constants.AndroidAppProtocol.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_name = _domainName.BaseDomain;
|
||||
_name = domainName.BaseDomain;
|
||||
}
|
||||
|
||||
_loginService = Resolver.Resolve<ILoginService>();
|
||||
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_clipboardService = Resolver.Resolve<IClipboardService>();
|
||||
_settingsService = Resolver.Resolve<ISettingsService>();
|
||||
GoogleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
||||
|
||||
Init();
|
||||
|
@ -149,17 +150,14 @@ namespace Bit.App.Pages
|
|||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var logins = await _loginService.GetAllAsync();
|
||||
var filteredLogins = logins
|
||||
.Select(s => new VaultListPageModel.Login(s))
|
||||
.Where(s => (_androidApp && _domainName == null && s.Uri.Value == Uri) ||
|
||||
(_domainName != null && s.BaseDomain != null && s.BaseDomain == _domainName.BaseDomain))
|
||||
var logins = await _loginService.GetAllAsync(Uri);
|
||||
var sortedLogins = logins.Select(l => new VaultListPageModel.Login(l))
|
||||
.OrderBy(s => s.Name)
|
||||
.ThenBy(s => s.Username);
|
||||
|
||||
Device.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
PresentationLogins.ResetWithRange(filteredLogins);
|
||||
PresentationLogins.ResetWithRange(sortedLogins);
|
||||
AdjustContent();
|
||||
});
|
||||
}, cts.Token);
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models.Data;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.App.Repositories
|
||||
{
|
||||
|
@ -12,19 +8,5 @@ namespace Bit.App.Repositories
|
|||
public SettingsRepository(ISqlService sqlService)
|
||||
: base(sqlService)
|
||||
{ }
|
||||
|
||||
public Task<IEnumerable<IEnumerable<string>>> GetEquivablentDomains(string userId)
|
||||
{
|
||||
var equivalentDomainsJson = Connection.Table<SettingsData>().Where(f => f.Id == userId)
|
||||
.Select(f => f.EquivalentDomains).FirstOrDefault();
|
||||
|
||||
if(string.IsNullOrWhiteSpace(equivalentDomainsJson))
|
||||
{
|
||||
return Task.FromResult<IEnumerable<IEnumerable<string>>>(null);
|
||||
}
|
||||
|
||||
var equivalentDomains = JsonConvert.DeserializeObject<IEnumerable<IEnumerable<string>>>(equivalentDomainsJson);
|
||||
return Task.FromResult(equivalentDomains);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,15 +15,18 @@ namespace Bit.App.Services
|
|||
private readonly ILoginRepository _loginRepository;
|
||||
private readonly IAuthService _authService;
|
||||
private readonly ILoginApiRepository _loginApiRepository;
|
||||
private readonly ISettingsService _settingsService;
|
||||
|
||||
public LoginService(
|
||||
ILoginRepository loginRepository,
|
||||
IAuthService authService,
|
||||
ILoginApiRepository loginApiRepository)
|
||||
ILoginApiRepository loginApiRepository,
|
||||
ISettingsService settingsService)
|
||||
{
|
||||
_loginRepository = loginRepository;
|
||||
_authService = authService;
|
||||
_loginApiRepository = loginApiRepository;
|
||||
_settingsService = settingsService;
|
||||
}
|
||||
|
||||
public async Task<Login> GetByIdAsync(string id)
|
||||
|
@ -52,6 +55,80 @@ namespace Bit.App.Services
|
|||
return logins;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Login>> GetAllAsync(string uriString)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(uriString))
|
||||
{
|
||||
return new List<Login>();
|
||||
}
|
||||
|
||||
Uri uri = null;
|
||||
DomainName domainName = null;
|
||||
var androidApp = false;
|
||||
|
||||
if(!Uri.TryCreate(uriString, UriKind.Absolute, out uri) || !DomainName.TryParse(uri.Host, out domainName))
|
||||
{
|
||||
if(domainName == null)
|
||||
{
|
||||
androidApp = uriString.StartsWith(Constants.AndroidAppProtocol);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!androidApp && domainName == null)
|
||||
{
|
||||
return new List<Login>();
|
||||
}
|
||||
|
||||
var eqDomains = (await _settingsService.GetEquivalentDomainsAsync()).Select(d => d.ToArray());
|
||||
var matchingDomains = eqDomains
|
||||
.Where(d => (androidApp && Array.IndexOf(d, uriString) >= 0) ||
|
||||
(!androidApp && Array.IndexOf(d, domainName.BaseDomain) >= 0))
|
||||
.SelectMany(d => d).ToList();
|
||||
if(!matchingDomains.Any())
|
||||
{
|
||||
matchingDomains.Add(androidApp ? uriString : domainName.BaseDomain);
|
||||
}
|
||||
|
||||
var matchingDomainsArray = matchingDomains.ToArray();
|
||||
var matchingLogins = new List<Login>();
|
||||
var logins = await _loginRepository.GetAllByUserIdAsync(_authService.UserId);
|
||||
foreach(var login in logins)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(login.Uri))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var loginUriString = new CipherString(login.Uri).Decrypt();
|
||||
if(string.IsNullOrWhiteSpace(loginUriString))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(androidApp && Array.IndexOf(matchingDomainsArray, loginUriString) >= 0)
|
||||
{
|
||||
matchingLogins.Add(new Login(login));
|
||||
continue;
|
||||
}
|
||||
|
||||
Uri loginUri;
|
||||
DomainName loginDomainName;
|
||||
if(!Uri.TryCreate(loginUriString, UriKind.Absolute, out loginUri)
|
||||
|| !DomainName.TryParse(loginUri.Host, out loginDomainName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(Array.IndexOf(matchingDomainsArray, loginDomainName.BaseDomain) >= 0)
|
||||
{
|
||||
matchingLogins.Add(new Login(login));
|
||||
}
|
||||
}
|
||||
|
||||
return matchingLogins;
|
||||
}
|
||||
|
||||
public async Task<ApiResult<LoginResponse>> SaveAsync(Login login)
|
||||
{
|
||||
ApiResult<LoginResponse> response = null;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
using Bit.App.Abstractions;
|
||||
using Plugin.Settings.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.App.Services
|
||||
{
|
||||
|
@ -7,13 +10,27 @@ namespace Bit.App.Services
|
|||
{
|
||||
private readonly ISettingsRepository _settingsRepository;
|
||||
private readonly ISettings _settings;
|
||||
private readonly IAuthService _authService;
|
||||
|
||||
public SettingsService(
|
||||
ISettingsRepository settingsRepository,
|
||||
ISettings settings)
|
||||
ISettings settings,
|
||||
IAuthService authService)
|
||||
{
|
||||
_settingsRepository = settingsRepository;
|
||||
_settings = settings;
|
||||
_authService = authService;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<IEnumerable<string>>> GetEquivalentDomainsAsync()
|
||||
{
|
||||
var settings = await _settingsRepository.GetByIdAsync(_authService.UserId);
|
||||
if(string.IsNullOrWhiteSpace(settings?.EquivalentDomains))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return JsonConvert.DeserializeObject<IEnumerable<IEnumerable<string>>>(settings.EquivalentDomains);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue