mirror of
https://github.com/bitwarden/android.git
synced 2024-12-24 18:08:26 +03:00
user service
This commit is contained in:
parent
929727ba41
commit
13a2206735
4 changed files with 316 additions and 0 deletions
26
src/Core/Abstractions/IUserService.cs
Normal file
26
src/Core/Abstractions/IUserService.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Domain;
|
||||
|
||||
namespace Bit.Core.Abstractions
|
||||
{
|
||||
public interface IUserService
|
||||
{
|
||||
Task<bool> CanAccessPremiumAsync();
|
||||
Task ClearAsync();
|
||||
Task ClearOrganizationsAsync(string userId);
|
||||
Task<List<Organization>> GetAllOrganizationAsync();
|
||||
Task<string> GetEmailAsync();
|
||||
Task<KdfType?> GetKdfAsync();
|
||||
Task<int?> GetKdfIterationsAsync();
|
||||
Task<Organization> GetOrganizationAsync(string id);
|
||||
Task<string> GetSecurityStampAsync();
|
||||
Task<string> GetUserIdAsync();
|
||||
Task<bool> IsAuthenticatedAsync();
|
||||
Task ReplaceOrganizationsAsync(Dictionary<string, OrganizationData> organizations);
|
||||
Task SetInformationAsync(string userId, string email, KdfType kdf, int kdfIterations);
|
||||
Task SetSecurityStampAsync(string stamp);
|
||||
}
|
||||
}
|
45
src/Core/Models/Data/OrganizationData.cs
Normal file
45
src/Core/Models/Data/OrganizationData.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Response;
|
||||
|
||||
namespace Bit.Core.Models.Data
|
||||
{
|
||||
public class OrganizationData
|
||||
{
|
||||
public OrganizationData(ProfileOrganizationResponse response)
|
||||
{
|
||||
Id = response.Id;
|
||||
Name = response.Name;
|
||||
Status = response.Status;
|
||||
Type = response.Type;
|
||||
Enabled = response.Enabled;
|
||||
UseGroups = response.UseGroups;
|
||||
UseDirectory = response.UseDirectory;
|
||||
UseEvents = response.UseEvents;
|
||||
UseTotp = response.UseTotp;
|
||||
Use2fa = response.Use2fa;
|
||||
UseApi = response.UseApi;
|
||||
SelfHost = response.SelfHost;
|
||||
UsersGetPremium = response.UsersGetPremium;
|
||||
Seats = response.Seats;
|
||||
MaxCollections = response.MaxCollections;
|
||||
MaxStorageGb = response.MaxStorageGb;
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public OrganizationUserStatusType Status { get; set; }
|
||||
public OrganizationUserType Type { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool UseGroups { get; set; }
|
||||
public bool UseDirectory { get; set; }
|
||||
public bool UseEvents { get; set; }
|
||||
public bool UseTotp { get; set; }
|
||||
public bool Use2fa { get; set; }
|
||||
public bool UseApi { get; set; }
|
||||
public bool SelfHost { get; set; }
|
||||
public bool UsersGetPremium { get; set; }
|
||||
public int Seats { get; set; }
|
||||
public int MaxCollections { get; set; }
|
||||
public short? MaxStorageGb { get; set; }
|
||||
}
|
||||
}
|
78
src/Core/Models/Domain/Organization.cs
Normal file
78
src/Core/Models/Domain/Organization.cs
Normal file
|
@ -0,0 +1,78 @@
|
|||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Core.Models.Domain
|
||||
{
|
||||
public class Organization
|
||||
{
|
||||
public Organization() { }
|
||||
|
||||
public Organization(OrganizationData obj)
|
||||
{
|
||||
Id = obj.Id;
|
||||
Name = obj.Name;
|
||||
Status = obj.Status;
|
||||
Type = obj.Type;
|
||||
Enabled = obj.Enabled;
|
||||
UseGroups = obj.UseGroups;
|
||||
UseDirectory = obj.UseDirectory;
|
||||
UseEvents = obj.UseEvents;
|
||||
UseTotp = obj.UseTotp;
|
||||
Use2fa = obj.Use2fa;
|
||||
UseApi = obj.UseApi;
|
||||
SelfHost = obj.SelfHost;
|
||||
UsersGetPremium = obj.UsersGetPremium;
|
||||
Seats = obj.Seats;
|
||||
MaxCollections = obj.MaxCollections;
|
||||
MaxStorageGb = obj.MaxStorageGb;
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public OrganizationUserStatusType Status { get; set; }
|
||||
public OrganizationUserType Type { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool UseGroups { get; set; }
|
||||
public bool UseDirectory { get; set; }
|
||||
public bool UseEvents { get; set; }
|
||||
public bool UseTotp { get; set; }
|
||||
public bool Use2fa { get; set; }
|
||||
public bool UseApi { get; set; }
|
||||
public bool SelfHost { get; set; }
|
||||
public bool UsersGetPremium { get; set; }
|
||||
public int Seats { get; set; }
|
||||
public int MaxCollections { get; set; }
|
||||
public short? MaxStorageGb { get; set; }
|
||||
|
||||
public bool CanAccess
|
||||
{
|
||||
get
|
||||
{
|
||||
if(Type == OrganizationUserType.Owner)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return Enabled && Status == OrganizationUserStatusType.Confirmed;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsManager
|
||||
{
|
||||
get
|
||||
{
|
||||
switch(Type)
|
||||
{
|
||||
case OrganizationUserType.Owner:
|
||||
case OrganizationUserType.Admin:
|
||||
case OrganizationUserType.Manager:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAdmin => Type == OrganizationUserType.Owner || Type == OrganizationUserType.Admin;
|
||||
public bool IsOwner => Type == OrganizationUserType.Owner;
|
||||
}
|
||||
}
|
167
src/Core/Services/UserService.cs
Normal file
167
src/Core/Services/UserService.cs
Normal file
|
@ -0,0 +1,167 @@
|
|||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Domain;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class UserService : IUserService
|
||||
{
|
||||
private string _userId;
|
||||
private string _email;
|
||||
private string _stamp;
|
||||
private KdfType? _kdf;
|
||||
private int? _kdfIterations;
|
||||
|
||||
private const string Keys_UserId = "userId";
|
||||
private const string Keys_UserEmail = "userEmail";
|
||||
private const string Keys_Stamp = "securityStamp";
|
||||
private const string Keys_Kdf = "kdf";
|
||||
private const string Keys_KdfIterations = "kdfIterations";
|
||||
private const string Keys_OrganizationsFormat = "organizations_{0}";
|
||||
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly ITokenService _tokenService;
|
||||
|
||||
public UserService(IStorageService storageService, ITokenService tokenService)
|
||||
{
|
||||
_storageService = storageService;
|
||||
_tokenService = tokenService;
|
||||
}
|
||||
|
||||
public async Task SetInformationAsync(string userId, string email, KdfType kdf, int kdfIterations)
|
||||
{
|
||||
_email = email;
|
||||
_userId = userId;
|
||||
_kdf = kdf;
|
||||
_kdfIterations = kdfIterations;
|
||||
await Task.WhenAll(
|
||||
_storageService.SaveAsync(Keys_UserEmail, email),
|
||||
_storageService.SaveAsync(Keys_UserId, userId),
|
||||
_storageService.SaveAsync(Keys_Kdf, (int)kdf),
|
||||
_storageService.SaveAsync(Keys_KdfIterations, kdfIterations));
|
||||
}
|
||||
|
||||
public async Task SetSecurityStampAsync(string stamp)
|
||||
{
|
||||
_stamp = stamp;
|
||||
await _storageService.SaveAsync(Keys_Stamp, stamp);
|
||||
}
|
||||
|
||||
public async Task<string> GetUserIdAsync()
|
||||
{
|
||||
if(_userId == null)
|
||||
{
|
||||
_userId = await _storageService.GetAsync<string>(Keys_UserId);
|
||||
}
|
||||
return _userId;
|
||||
}
|
||||
|
||||
public async Task<string> GetEmailAsync()
|
||||
{
|
||||
if(_email == null)
|
||||
{
|
||||
_email = await _storageService.GetAsync<string>(Keys_UserEmail);
|
||||
}
|
||||
return _email;
|
||||
}
|
||||
|
||||
public async Task<string> GetSecurityStampAsync()
|
||||
{
|
||||
if(_stamp == null)
|
||||
{
|
||||
_stamp = await _storageService.GetAsync<string>(Keys_Stamp);
|
||||
}
|
||||
return _stamp;
|
||||
}
|
||||
|
||||
public async Task<KdfType?> GetKdfAsync()
|
||||
{
|
||||
if(_kdf == null)
|
||||
{
|
||||
_kdf = (KdfType?)(await _storageService.GetAsync<int?>(Keys_Kdf));
|
||||
}
|
||||
return _kdf;
|
||||
}
|
||||
|
||||
public async Task<int?> GetKdfIterationsAsync()
|
||||
{
|
||||
if(_kdfIterations == null)
|
||||
{
|
||||
_kdfIterations = await _storageService.GetAsync<int?>(Keys_KdfIterations);
|
||||
}
|
||||
return _kdfIterations;
|
||||
}
|
||||
|
||||
public async Task ClearAsync()
|
||||
{
|
||||
var userId = await GetUserIdAsync();
|
||||
await Task.WhenAll(
|
||||
_storageService.RemoveAsync(Keys_UserId),
|
||||
_storageService.RemoveAsync(Keys_UserEmail),
|
||||
_storageService.RemoveAsync(Keys_Stamp),
|
||||
_storageService.RemoveAsync(Keys_Kdf),
|
||||
_storageService.RemoveAsync(Keys_KdfIterations),
|
||||
ClearOrganizationsAsync(userId));
|
||||
_userId = _email = _stamp = null;
|
||||
_kdf = null;
|
||||
_kdfIterations = null;
|
||||
}
|
||||
|
||||
public async Task<bool> IsAuthenticatedAsync()
|
||||
{
|
||||
var token = await _tokenService.GetTokenAsync();
|
||||
if(token == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var userId = await GetUserIdAsync();
|
||||
return userId != null;
|
||||
}
|
||||
|
||||
public async Task<bool> CanAccessPremiumAsync()
|
||||
{
|
||||
var tokenPremium = _tokenService.GetPremium();
|
||||
if(tokenPremium)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var orgs = await GetAllOrganizationAsync();
|
||||
return orgs?.Any(o => o.UsersGetPremium && o.Enabled) ?? false;
|
||||
}
|
||||
|
||||
public async Task<Organization> GetOrganizationAsync(string id)
|
||||
{
|
||||
var userId = await GetUserIdAsync();
|
||||
var organizations = await _storageService.GetAsync<Dictionary<string, OrganizationData>>(
|
||||
string.Format(Keys_OrganizationsFormat, userId));
|
||||
if(organizations == null || !organizations.ContainsKey(id))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new Organization(organizations[id]);
|
||||
}
|
||||
|
||||
public async Task<List<Organization>> GetAllOrganizationAsync()
|
||||
{
|
||||
var userId = await GetUserIdAsync();
|
||||
var organizations = await _storageService.GetAsync<Dictionary<string, OrganizationData>>(
|
||||
string.Format(Keys_OrganizationsFormat, userId));
|
||||
return organizations?.Select(o => new Organization(o.Value)).ToList() ?? new List<Organization>();
|
||||
}
|
||||
|
||||
public async Task ReplaceOrganizationsAsync(Dictionary<string, OrganizationData> organizations)
|
||||
{
|
||||
var userId = await GetUserIdAsync();
|
||||
await _storageService.SaveAsync(string.Format(Keys_OrganizationsFormat, userId), organizations);
|
||||
}
|
||||
|
||||
public async Task ClearOrganizationsAsync(string userId)
|
||||
{
|
||||
await _storageService.RemoveAsync(string.Format(Keys_OrganizationsFormat, userId));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue