using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationConnections.Interfaces; using Bit.Core.Context; using Bit.Core.Exceptions; using Bit.Core.Models.Api.OrganizationLicenses; using Bit.Core.Models.Business; using Bit.Core.OrganizationFeatures.OrganizationLicenses.Interfaces; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Bit.Api.Controllers; [Route("licenses")] [Authorize("Licensing")] [SelfHosted(NotSelfHostedOnly = true)] public class LicensesController : Controller { private readonly IUserRepository _userRepository; private readonly IUserService _userService; private readonly IOrganizationRepository _organizationRepository; private readonly ICloudGetOrganizationLicenseQuery _cloudGetOrganizationLicenseQuery; private readonly IValidateBillingSyncKeyCommand _validateBillingSyncKeyCommand; private readonly ICurrentContext _currentContext; public LicensesController( IUserRepository userRepository, IUserService userService, IOrganizationRepository organizationRepository, ICloudGetOrganizationLicenseQuery cloudGetOrganizationLicenseQuery, IValidateBillingSyncKeyCommand validateBillingSyncKeyCommand, ICurrentContext currentContext) { _userRepository = userRepository; _userService = userService; _organizationRepository = organizationRepository; _cloudGetOrganizationLicenseQuery = cloudGetOrganizationLicenseQuery; _validateBillingSyncKeyCommand = validateBillingSyncKeyCommand; _currentContext = currentContext; } [HttpGet("user/{id}")] public async Task GetUser(string id, [FromQuery] string key) { var user = await _userRepository.GetByIdAsync(new Guid(id)); if (user == null) { return null; } else if (!user.LicenseKey.Equals(key)) { await Task.Delay(2000); throw new BadRequestException("Invalid license key."); } var license = await _userService.GenerateLicenseAsync(user, null); return license; } /// /// Used by self-hosted installations to get an updated license file /// [HttpGet("organization/{id}")] public async Task OrganizationSync(string id, [FromBody] SelfHostedOrganizationLicenseRequestModel model) { var organization = await _organizationRepository.GetByIdAsync(new Guid(id)); if (organization == null) { throw new NotFoundException("Organization not found."); } if (!organization.LicenseKey.Equals(model.LicenseKey)) { await Task.Delay(2000); throw new BadRequestException("Invalid license key."); } if (!await _validateBillingSyncKeyCommand.ValidateBillingSyncKeyAsync(organization, model.BillingSyncKey)) { throw new BadRequestException("Invalid Billing Sync Key"); } var license = await _cloudGetOrganizationLicenseQuery.GetLicenseAsync(organization, _currentContext.InstallationId.Value); return license; } }