1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-08 06:28:14 -05:00

updates for license validation

This commit is contained in:
Kyle Spearrin 2017-08-14 13:06:44 -04:00
parent 18cbc79dd2
commit 6b80ec6331
9 changed files with 140 additions and 25 deletions

View File

@ -42,7 +42,7 @@ namespace Bit.Api.Controllers
throw new UnauthorizedAccessException(); throw new UnauthorizedAccessException();
} }
await _userService.SaveUserAsync(model.ToUser(user)); await _userService.SaveUserAsync(model.ToUser(user), true);
var response = new DomainsResponseModel(user); var response = new DomainsResponseModel(user);
return response; return response;

View File

@ -12,9 +12,10 @@ namespace Bit.Core.Models.Business
public OrganizationLicense() public OrganizationLicense()
{ } { }
public OrganizationLicense(Organization org) public OrganizationLicense(Organization org, Guid installationId)
{ {
LicenseKey = ""; LicenseKey = "";
InstallationId = installationId;
Id = org.Id; Id = org.Id;
Name = org.Name; Name = org.Name;
Enabled = org.Enabled; Enabled = org.Enabled;
@ -29,6 +30,7 @@ namespace Bit.Core.Models.Business
} }
public string LicenseKey { get; set; } public string LicenseKey { get; set; }
public Guid InstallationId { get; set; }
public Guid Id { get; set; } public Guid Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
public bool Enabled { get; set; } public bool Enabled { get; set; }
@ -53,11 +55,12 @@ namespace Bit.Core.Models.Business
string data = null; string data = null;
if(Version == 1) if(Version == 1)
{ {
data = string.Format("organization:{0}_{1}_{2}_{3}_{4}_{5}_{6}_{7}_{8}_{9}_{10}_{11}_{12}_{13}", data = string.Format("organization:{0}_{1}_{2}_{3}_{4}_{5}_{6}_{7}_{8}_{9}_{10}_{11}_{12}_{13}_{14}",
Version, Version,
Utilities.CoreHelpers.ToEpocSeconds(Issued), Utilities.CoreHelpers.ToEpocSeconds(Issued),
Expires.HasValue ? Utilities.CoreHelpers.ToEpocSeconds(Expires.Value).ToString() : null, Expires.HasValue ? Utilities.CoreHelpers.ToEpocSeconds(Expires.Value).ToString() : null,
LicenseKey, LicenseKey,
InstallationId,
Id, Id,
Enabled, Enabled,
PlanType, PlanType,
@ -77,6 +80,28 @@ namespace Bit.Core.Models.Business
return Encoding.UTF8.GetBytes(data); return Encoding.UTF8.GetBytes(data);
} }
public bool CanUse(Guid installationId)
{
if(Issued > DateTime.UtcNow)
{
return false;
}
if(Expires < DateTime.UtcNow)
{
return false;
}
if(Version == 1)
{
return InstallationId == installationId;
}
else
{
throw new NotSupportedException($"Version {Version} is not supported.");
}
}
public bool VerifyData(Organization organization) public bool VerifyData(Organization organization)
{ {
if(Issued > DateTime.UtcNow) if(Issued > DateTime.UtcNow)

View File

@ -65,6 +65,28 @@ namespace Bit.Core.Models.Business
return Encoding.UTF8.GetBytes(data); return Encoding.UTF8.GetBytes(data);
} }
public bool CanUse(User user)
{
if(Issued > DateTime.UtcNow)
{
return false;
}
if(Expires < DateTime.UtcNow)
{
return false;
}
if(Version == 1)
{
return user.Email.Equals(Email, StringComparison.InvariantCultureIgnoreCase);
}
else
{
throw new NotSupportedException($"Version {Version} is not supported.");
}
}
public bool VerifyData(User user) public bool VerifyData(User user)
{ {
if(Issued > DateTime.UtcNow) if(Issued > DateTime.UtcNow)

View File

@ -17,7 +17,7 @@ namespace Bit.Core.Services
Task<User> GetUserByIdAsync(Guid userId); Task<User> GetUserByIdAsync(Guid userId);
Task<User> GetUserByPrincipalAsync(ClaimsPrincipal principal); Task<User> GetUserByPrincipalAsync(ClaimsPrincipal principal);
Task<DateTime> GetAccountRevisionDateByIdAsync(Guid userId); Task<DateTime> GetAccountRevisionDateByIdAsync(Guid userId);
Task SaveUserAsync(User user); Task SaveUserAsync(User user, bool push = false);
Task<IdentityResult> RegisterUserAsync(User user, string masterPassword); Task<IdentityResult> RegisterUserAsync(User user, string masterPassword);
Task SendMasterPasswordHintAsync(string email); Task SendMasterPasswordHintAsync(string email);
Task SendTwoFactorEmailAsync(User user); Task SendTwoFactorEmailAsync(User user);

View File

@ -8,6 +8,7 @@ using Newtonsoft.Json.Linq;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Net; using System.Net;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using Microsoft.Extensions.Logging;
namespace Bit.Core.Services namespace Bit.Core.Services
{ {
@ -15,10 +16,13 @@ namespace Bit.Core.Services
{ {
private dynamic _decodedToken; private dynamic _decodedToken;
private DateTime? _nextAuthAttempt = null; private DateTime? _nextAuthAttempt = null;
private readonly ILogger<BaseRelayPushNotificationService> _logger;
public BaseRelayPushNotificationService( public BaseRelayPushNotificationService(
GlobalSettings globalSettings) GlobalSettings globalSettings,
ILogger<BaseRelayPushNotificationService> logger)
{ {
_logger = logger;
GlobalSettings = globalSettings; GlobalSettings = globalSettings;
PushClient = new HttpClient PushClient = new HttpClient
@ -65,8 +69,17 @@ namespace Bit.Core.Services
}) })
}; };
var response = await IdentityClient.SendAsync(requestMessage); HttpResponseMessage response = null;
if(!response.IsSuccessStatusCode) try
{
response = await IdentityClient.SendAsync(requestMessage);
}
catch(Exception e)
{
_logger.LogError(12339, e, "Unable to auth for push.");
}
if(response == null || !response.IsSuccessStatusCode)
{ {
if(response.StatusCode == HttpStatusCode.BadRequest) if(response.StatusCode == HttpStatusCode.BadRequest)
{ {

View File

@ -6,19 +6,23 @@ using Microsoft.AspNetCore.Http;
using Bit.Core.Models; using Bit.Core.Models;
using System.Net.Http; using System.Net.Http;
using Bit.Core.Models.Api; using Bit.Core.Models.Api;
using Microsoft.Extensions.Logging;
namespace Bit.Core.Services namespace Bit.Core.Services
{ {
public class RelayPushNotificationService : BaseRelayPushNotificationService, IPushNotificationService public class RelayPushNotificationService : BaseRelayPushNotificationService, IPushNotificationService
{ {
private readonly IHttpContextAccessor _httpContextAccessor; private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ILogger<RelayPushNotificationService> _logger;
public RelayPushNotificationService( public RelayPushNotificationService(
GlobalSettings globalSettings, GlobalSettings globalSettings,
IHttpContextAccessor httpContextAccessor) IHttpContextAccessor httpContextAccessor,
: base(globalSettings) ILogger<RelayPushNotificationService> logger)
: base(globalSettings, logger)
{ {
_httpContextAccessor = httpContextAccessor; _httpContextAccessor = httpContextAccessor;
_logger = logger;
} }
public async Task PushSyncCipherCreateAsync(Cipher cipher) public async Task PushSyncCipherCreateAsync(Cipher cipher)
@ -166,8 +170,16 @@ namespace Bit.Core.Services
Method = HttpMethod.Post, Method = HttpMethod.Post,
RequestUri = new Uri(string.Concat(PushClient.BaseAddress, "/push/send")) RequestUri = new Uri(string.Concat(PushClient.BaseAddress, "/push/send"))
}; };
try
{
await PushClient.SendAsync(message); await PushClient.SendAsync(message);
} }
catch(Exception e)
{
_logger.LogError(12334, e, "Unable to send push notification.");
}
}
private void ExcludeCurrentContext(PushSendRequestModel request) private void ExcludeCurrentContext(PushSendRequestModel request)
{ {

View File

@ -5,14 +5,21 @@ using System;
using Bit.Core.Models.Api; using Bit.Core.Models.Api;
using Bit.Core.Enums; using Bit.Core.Enums;
using System.Linq; using System.Linq;
using Microsoft.Extensions.Logging;
namespace Bit.Core.Services namespace Bit.Core.Services
{ {
public class RelayPushRegistrationService : BaseRelayPushNotificationService, IPushRegistrationService public class RelayPushRegistrationService : BaseRelayPushNotificationService, IPushRegistrationService
{ {
public RelayPushRegistrationService(GlobalSettings globalSettings) private readonly ILogger<RelayPushRegistrationService> _logger;
: base(globalSettings)
{ } public RelayPushRegistrationService(
GlobalSettings globalSettings,
ILogger<RelayPushRegistrationService> logger)
: base(globalSettings, logger)
{
_logger = logger;
}
public async Task CreateOrUpdateRegistrationAsync(string pushToken, string deviceId, string userId, public async Task CreateOrUpdateRegistrationAsync(string pushToken, string deviceId, string userId,
string identifier, DeviceType type) string identifier, DeviceType type)
@ -37,8 +44,16 @@ namespace Bit.Core.Services
Method = HttpMethod.Post, Method = HttpMethod.Post,
RequestUri = new Uri(string.Concat(PushClient.BaseAddress, "/push/register")) RequestUri = new Uri(string.Concat(PushClient.BaseAddress, "/push/register"))
}; };
try
{
await PushClient.SendAsync(message); await PushClient.SendAsync(message);
} }
catch(Exception e)
{
_logger.LogError(12335, e, "Unable to create push registration.");
}
}
public async Task DeleteRegistrationAsync(string deviceId) public async Task DeleteRegistrationAsync(string deviceId)
{ {
@ -53,8 +68,16 @@ namespace Bit.Core.Services
Method = HttpMethod.Delete, Method = HttpMethod.Delete,
RequestUri = new Uri(string.Concat(PushClient.BaseAddress, "/push/", deviceId)) RequestUri = new Uri(string.Concat(PushClient.BaseAddress, "/push/", deviceId))
}; };
try
{
await PushClient.SendAsync(message); await PushClient.SendAsync(message);
} }
catch(Exception e)
{
_logger.LogError(12336, e, "Unable to delete push registration.");
}
}
public async Task AddUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId) public async Task AddUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId)
{ {
@ -75,8 +98,16 @@ namespace Bit.Core.Services
Method = HttpMethod.Put, Method = HttpMethod.Put,
RequestUri = new Uri(string.Concat(PushClient.BaseAddress, "/push/add-organization")) RequestUri = new Uri(string.Concat(PushClient.BaseAddress, "/push/add-organization"))
}; };
try
{
await PushClient.SendAsync(message); await PushClient.SendAsync(message);
} }
catch(Exception e)
{
_logger.LogError(12337, e, "Unable to add user org push registration.");
}
}
public async Task DeleteUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId) public async Task DeleteUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId)
{ {
@ -97,7 +128,15 @@ namespace Bit.Core.Services
Method = HttpMethod.Put, Method = HttpMethod.Put,
RequestUri = new Uri(string.Concat(PushClient.BaseAddress, "/push/delete-organization")) RequestUri = new Uri(string.Concat(PushClient.BaseAddress, "/push/delete-organization"))
}; };
try
{
await PushClient.SendAsync(message); await PushClient.SendAsync(message);
} }
catch(Exception e)
{
_logger.LogError(12338, e, "Unable to delete user org push registration.");
}
}
} }
} }

View File

@ -142,7 +142,7 @@ namespace Bit.Core.Services
return await _userRepository.GetAccountRevisionDateAsync(userId); return await _userRepository.GetAccountRevisionDateAsync(userId);
} }
public async Task SaveUserAsync(User user) public async Task SaveUserAsync(User user, bool push = false)
{ {
if(user.Id == default(Guid)) if(user.Id == default(Guid))
{ {
@ -152,9 +152,12 @@ namespace Bit.Core.Services
user.RevisionDate = user.AccountRevisionDate = DateTime.UtcNow; user.RevisionDate = user.AccountRevisionDate = DateTime.UtcNow;
await _userRepository.ReplaceAsync(user); await _userRepository.ReplaceAsync(user);
if(push)
{
// push // push
await _pushService.PushSyncSettingsAsync(user.Id); await _pushService.PushSyncSettingsAsync(user.Id);
} }
}
public override async Task<IdentityResult> DeleteAsync(User user) public override async Task<IdentityResult> DeleteAsync(User user)
{ {
@ -540,7 +543,7 @@ namespace Bit.Core.Services
IPaymentService paymentService = null; IPaymentService paymentService = null;
if(_globalSettings.SelfHosted) if(_globalSettings.SelfHosted)
{ {
if(license == null || !_licenseService.VerifyLicense(license)) if(license == null || !_licenseService.VerifyLicense(license) || !license.CanUse(user))
{ {
throw new BadRequestException("Invalid license."); throw new BadRequestException("Invalid license.");
} }
@ -605,7 +608,7 @@ namespace Bit.Core.Services
throw new InvalidOperationException("Licenses require self hosting."); throw new InvalidOperationException("Licenses require self hosting.");
} }
if(license == null || !_licenseService.VerifyLicense(license)) if(license == null || !_licenseService.VerifyLicense(license) || !license.CanUse(user))
{ {
throw new BadRequestException("Invalid license."); throw new BadRequestException("Invalid license.");
} }

View File

@ -303,7 +303,8 @@ SA_PASSWORD={dbPass}");
identityUri: ""{_url}/identity"", identityUri: ""{_url}/identity"",
stripeKey: null, stripeKey: null,
braintreeKey: null, braintreeKey: null,
whitelistDomains: [""{_domain}""] whitelistDomains: [""{_domain}""],
selfHosted: true
}};"); }};");
} }
} }