user service

This commit is contained in:
Kyle Spearrin 2019-04-09 16:13:32 -04:00
parent 929727ba41
commit 13a2206735
4 changed files with 316 additions and 0 deletions

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

View 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; }
}
}

View 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;
}
}

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