1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-04 01:22:50 -05:00

Create sponsorship offer (#1688)

This commit is contained in:
Matt Gibson
2021-11-04 08:25:40 -05:00
committed by Justin Baur
parent d7642d692b
commit 1b6d1b52a3
6 changed files with 351 additions and 13 deletions

View File

@ -2,27 +2,89 @@ using System;
using System.Threading.Tasks;
using Bit.Core.Models.Table;
using Bit.Core.Repositories;
using Microsoft.AspNetCore.DataProtection;
namespace Bit.Core.Services
{
public class OrganizationSponsorshipService : IOrganizationSponsorshipService
{
private readonly IOrganizationSponsorshipRepository _organizationSponsorshipRepository;
private const string FamiliesForEnterpriseTokenName = "FamiliesForEnterpriseToken";
private const string TokenClearTextPrefix = "BWOrganizationSponsorship_";
public OrganizationSponsorshipService(IOrganizationSponsorshipRepository organizationSponsorshipRepository)
private readonly IOrganizationSponsorshipRepository _organizationSponsorshipRepository;
private readonly IDataProtector _dataProtector;
public OrganizationSponsorshipService(IOrganizationSponsorshipRepository organizationSponsorshipRepository,
IDataProtector dataProtector)
{
_organizationSponsorshipRepository = organizationSponsorshipRepository;
_dataProtector = dataProtector;
}
public async Task<bool> ValidateRedemptionTokenAsync(string encryptedToken)
{
if (!encryptedToken.StartsWith(TokenClearTextPrefix))
{
return false;
}
var decryptedToken = _dataProtector.Unprotect(encryptedToken);
var dataParts = decryptedToken.Split(' ');
if (dataParts.Length != 2)
{
return false;
}
if (dataParts[0].Equals(FamiliesForEnterpriseTokenName))
{
if (!Guid.TryParse(dataParts[1], out Guid sponsorshipId))
{
return false;
}
var sponsorship = await _organizationSponsorshipRepository.GetByIdAsync(sponsorshipId);
return sponsorship != null;
}
return false;
}
private string RedemptionToken(Guid sponsorshipId) =>
string.Concat(
TokenClearTextPrefix,
_dataProtector.Protect($"{FamiliesForEnterpriseTokenName} {sponsorshipId}")
);
public async Task OfferSponsorshipAsync(Organization sponsoringOrg, OrganizationUser sponsoringOrgUser, string sponsoredEmail)
{
// TODO: send sponsorship email, update sponsorship with offered email
throw new NotImplementedException();
var sponsorship = new OrganizationSponsorship
{
SponsoringOrganizationId = sponsoringOrg.Id,
SponsoringOrganizationUserId = sponsoringOrgUser.Id,
OfferedToEmail = sponsoredEmail,
CloudSponsor = true,
};
try
{
sponsorship = await _organizationSponsorshipRepository.CreateAsync(sponsorship);
// TODO: send email to sponsoredEmail w/ redemption token link
}
catch
{
if (sponsorship.Id != default)
{
await _organizationSponsorshipRepository.DeleteAsync(sponsorship);
}
throw;
}
}
public async Task SetUpSponsorshipAsync(OrganizationSponsorship sponsorship, Organization sponsoredOrganization)
{
// TODO: set up sponsorship
// TODO: set up sponsorship, remember remove offeredToEmail from sponsorship
throw new NotImplementedException();
}