1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 23:52:50 -05:00

[Provider] Setup provider (#1378)

This commit is contained in:
Oscar Hinton
2021-06-30 09:35:26 +02:00
committed by GitHub
parent 08f508f536
commit 43f7271147
85 changed files with 1810 additions and 113 deletions

View File

@ -5,47 +5,20 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.Json;
using Bit.Core.Utilities;
namespace Bit.Core.Models.Api
{
public class OrganizationUserInviteRequestModel : IValidatableObject
public class OrganizationUserInviteRequestModel
{
[Required]
[EmailAddressList]
public IEnumerable<string> Emails { get; set; }
[Required]
public Enums.OrganizationUserType? Type { get; set; }
public bool AccessAll { get; set; }
public Permissions Permissions { get; set; }
public IEnumerable<SelectionReadOnlyRequestModel> Collections { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (!Emails.Any())
{
yield return new ValidationResult("An email is required.");
}
if (Emails.Count() > 20)
{
yield return new ValidationResult("You can only invite up to 20 users at a time.");
}
var attr = new EmailAddressAttribute();
for (var i = 0; i < Emails.Count(); i++)
{
var email = Emails.ElementAt(i);
if (!attr.IsValid(email) || email.Contains(" ") || email.Contains("<"))
{
yield return new ValidationResult($"Email #{i + 1} is not valid.",
new string[] { nameof(Emails) });
}
else if (email.Length > 256)
{
yield return new ValidationResult($"Email #{i + 1} is longer than 256 characters.",
new string[] { nameof(Emails) });
}
}
}
}
public class OrganizationUserAcceptRequestModel

View File

@ -0,0 +1,14 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Models.Api
{
public class ProviderOrganizationAddRequestModel
{
[Required]
public Guid OrganizationId { get; set; }
[Required]
public string Key { get; set; }
}
}

View File

@ -0,0 +1,31 @@
using System.ComponentModel.DataAnnotations;
using Bit.Core.Models.Table.Provider;
namespace Bit.Core.Models.Api
{
public class ProviderSetupRequestModel
{
[Required]
[StringLength(50)]
public string Name { get; set; }
[StringLength(50)]
public string BusinessName { get; set; }
[Required]
[StringLength(256)]
[EmailAddress]
public string BillingEmail { get; set; }
[Required]
public string Token { get; set; }
[Required]
public string Key { get; set; }
public virtual Provider ToProvider(Provider provider)
{
provider.Name = Name;
provider.BusinessName = BusinessName;
provider.BillingEmail = BillingEmail;
return provider;
}
}
}

View File

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Bit.Core.Enums.Provider;
using Bit.Core.Models.Table.Provider;
using Bit.Core.Utilities;
namespace Bit.Core.Models.Api
{
public class ProviderUserInviteRequestModel
{
[Required]
[EmailAddressList]
public IEnumerable<string> Emails { get; set; }
[Required]
public ProviderUserType? Type { get; set; }
}
public class ProviderUserAcceptRequestModel
{
[Required]
public string Token { get; set; }
}
public class ProviderUserConfirmRequestModel
{
[Required]
public string Key { get; set; }
}
public class ProviderUserBulkConfirmRequestModelEntry
{
[Required]
public Guid Id { get; set; }
[Required]
public string Key { get; set; }
}
public class ProviderUserBulkConfirmRequestModel
{
[Required]
public IEnumerable<ProviderUserBulkConfirmRequestModelEntry> Keys { get; set; }
public Dictionary<Guid, string> ToDictionary()
{
return Keys.ToDictionary(e => e.Id, e => e.Key);
}
}
public class ProviderUserUpdateRequestModel
{
[Required]
public ProviderUserType? Type { get; set; }
public ProviderUser ToProviderUser(ProviderUser existingUser)
{
existingUser.Type = Type.Value;
return existingUser;
}
}
public class ProviderUserBulkRequestModel
{
[Required]
public IEnumerable<Guid> Ids { get; set; }
}
}

View File

@ -34,6 +34,8 @@ namespace Bit.Core.Models.Api
Permissions = CoreHelpers.LoadClassFromJsonData<Permissions>(organization.Permissions);
ResetPasswordEnrolled = organization.ResetPasswordKey != null;
UserId = organization.UserId?.ToString();
ProviderId = organization.ProviderId?.ToString();
ProviderName = organization.ProviderName;
}
public string Id { get; set; }
@ -63,5 +65,7 @@ namespace Bit.Core.Models.Api
public bool ResetPasswordEnrolled { get; set; }
public string UserId { get; set; }
public bool HasPublicAndPrivateKeys { get; set; }
public string ProviderId { get; set; }
public string ProviderName { get; set; }
}
}

View File

@ -10,8 +10,8 @@ namespace Bit.Core.Models.Api
public class ProfileResponseModel : ResponseModel
{
public ProfileResponseModel(User user,
IEnumerable<OrganizationUserOrganizationDetails> organizationsUserDetails, bool twoFactorEnabled)
: base("profile")
IEnumerable<OrganizationUserOrganizationDetails> organizationsUserDetails,
IEnumerable<ProviderUserProviderDetails> providerUserDetails, bool twoFactorEnabled) : base("profile")
{
if (user == null)
{
@ -30,6 +30,7 @@ namespace Bit.Core.Models.Api
PrivateKey = user.PrivateKey;
SecurityStamp = user.SecurityStamp;
Organizations = organizationsUserDetails?.Select(o => new ProfileOrganizationResponseModel(o));
Providers = providerUserDetails?.Select(p => new ProfileProviderResponseModel(p));
}
public string Id { get; set; }
@ -44,5 +45,6 @@ namespace Bit.Core.Models.Api
public string PrivateKey { get; set; }
public string SecurityStamp { get; set; }
public IEnumerable<ProfileOrganizationResponseModel> Organizations { get; set; }
public IEnumerable<ProfileProviderResponseModel> Providers { get; set; }
}
}

View File

@ -0,0 +1,31 @@
using Bit.Core.Enums.Provider;
using Bit.Core.Models.Data;
using Bit.Core.Utilities;
namespace Bit.Core.Models.Api
{
public class ProfileProviderResponseModel : ResponseModel
{
public ProfileProviderResponseModel(ProviderUserProviderDetails provider)
: base("profileProvider")
{
Id = provider.ProviderId.ToString();
Name = provider.Name;
Key = provider.Key;
Status = provider.Status;
Type = provider.Type;
Enabled = provider.Enabled;
Permissions = CoreHelpers.LoadClassFromJsonData<Permissions>(provider.Permissions);
UserId = provider.UserId?.ToString();
}
public string Id { get; set; }
public string Name { get; set; }
public string Key { get; set; }
public ProviderUserStatusType Status { get; set; }
public ProviderUserType Type { get; set; }
public bool Enabled { get; set; }
public Permissions Permissions { get; set; }
public string UserId { get; set; }
}
}

View File

@ -0,0 +1,35 @@
using System;
using Bit.Core.Models.Data;
namespace Bit.Core.Models.Api
{
public class ProviderOrganizationOrganizationDetailsResponseModel : ResponseModel
{
public ProviderOrganizationOrganizationDetailsResponseModel(ProviderOrganizationOrganizationDetails providerOrganization,
string obj = "providerOrganization") : base(obj)
{
if (providerOrganization == null)
{
throw new ArgumentNullException(nameof(providerOrganization));
}
Id = providerOrganization.Id;
ProviderId = providerOrganization.ProviderId;
OrganizationId = providerOrganization.OrganizationId;
OrganizationName = providerOrganization.OrganizationName;
Key = providerOrganization.Key;
Settings = providerOrganization.Settings;
CreationDate = providerOrganization.CreationDate;
RevisionDate = providerOrganization.RevisionDate;
}
public Guid Id { get; set; }
public Guid ProviderId { get; set; }
public Guid OrganizationId { get; set; }
public string OrganizationName { get; set; }
public string Key { get; set; }
public string Settings { get; set; }
public DateTime CreationDate { get; set; }
public DateTime RevisionDate { get; set; }
}
}

View File

@ -0,0 +1,36 @@
using System;
using Bit.Core.Models.Table.Provider;
namespace Bit.Core.Models.Api
{
public class ProviderResponseModel : ResponseModel
{
public ProviderResponseModel(Provider provider, string obj = "provider") : base(obj)
{
if (provider == null)
{
throw new ArgumentNullException(nameof(provider));
}
Id = provider.Id;
Name = provider.Name;
BusinessName = provider.BusinessName;
BusinessAddress1 = provider.BusinessAddress1;
BusinessAddress2 = provider.BusinessAddress2;
BusinessAddress3 = provider.BusinessAddress3;
BusinessCountry = provider.BusinessCountry;
BusinessTaxNumber = provider.BusinessTaxNumber;
BillingEmail = provider.BillingEmail;
}
public Guid Id { get; set; }
public string Name { get; set; }
public string BusinessName { get; set; }
public string BusinessAddress1 { get; set; }
public string BusinessAddress2 { get; set; }
public string BusinessAddress3 { get; set; }
public string BusinessCountry { get; set; }
public string BusinessTaxNumber { get; set; }
public string BillingEmail { get; set; }
}
}

View File

@ -0,0 +1,90 @@
using System;
using Bit.Core.Models.Data;
using Bit.Core.Enums.Provider;
using Bit.Core.Models.Table.Provider;
using Bit.Core.Utilities;
namespace Bit.Core.Models.Api
{
public class ProviderUserResponseModel : ResponseModel
{
public ProviderUserResponseModel(ProviderUser providerUser, string obj = "providerUser")
: base(obj)
{
if (providerUser == null)
{
throw new ArgumentNullException(nameof(providerUser));
}
Id = providerUser.Id.ToString();
UserId = providerUser.UserId?.ToString();
Type = providerUser.Type;
Status = providerUser.Status;
Permissions = CoreHelpers.LoadClassFromJsonData<Permissions>(providerUser.Permissions);
}
public ProviderUserResponseModel(ProviderUserUserDetails providerUser, string obj = "providerUser")
: base(obj)
{
if (providerUser == null)
{
throw new ArgumentNullException(nameof(providerUser));
}
Id = providerUser.Id.ToString();
UserId = providerUser.UserId?.ToString();
Type = providerUser.Type;
Status = providerUser.Status;
Permissions = CoreHelpers.LoadClassFromJsonData<Permissions>(providerUser.Permissions);
}
public string Id { get; set; }
public string UserId { get; set; }
public ProviderUserType Type { get; set; }
public ProviderUserStatusType Status { get; set; }
public Permissions Permissions { get; set; }
}
public class ProviderUserUserDetailsResponseModel : ProviderUserResponseModel
{
public ProviderUserUserDetailsResponseModel(ProviderUserUserDetails providerUser,
string obj = "providerUserUserDetails") : base(providerUser, obj)
{
if (providerUser == null)
{
throw new ArgumentNullException(nameof(providerUser));
}
Name = providerUser.Name;
Email = providerUser.Email;
}
public string Name { get; set; }
public string Email { get; set; }
}
public class ProviderUserPublicKeyResponseModel : ResponseModel
{
public ProviderUserPublicKeyResponseModel(Guid id, string key,
string obj = "providerUserPublicKeyResponseModel") : base(obj)
{
Id = id;
Key = key;
}
public Guid Id { get; set; }
public string Key { get; set; }
}
public class ProviderUserBulkResponseModel : ResponseModel
{
public ProviderUserBulkResponseModel(Guid id, string error,
string obj = "providerBulkConfirmResponseModel") : base(obj)
{
Id = id;
Error = error;
}
public Guid Id { get; set; }
public string Error { get; set; }
}
}

View File

@ -15,6 +15,7 @@ namespace Bit.Core.Models.Api
User user,
bool userTwoFactorEnabled,
IEnumerable<OrganizationUserOrganizationDetails> organizationUserDetails,
IEnumerable<ProviderUserProviderDetails> providerUserDetails,
IEnumerable<Folder> folders,
IEnumerable<CollectionDetails> collections,
IEnumerable<CipherDetails> ciphers,
@ -24,7 +25,7 @@ namespace Bit.Core.Models.Api
IEnumerable<Send> sends)
: base("sync")
{
Profile = new ProfileResponseModel(user, organizationUserDetails, userTwoFactorEnabled);
Profile = new ProfileResponseModel(user, organizationUserDetails, providerUserDetails, userTwoFactorEnabled);
Folders = folders.Select(f => new FolderResponseModel(f));
Ciphers = ciphers.Select(c => new CipherDetailsResponseModel(c, globalSettings, collectionCiphersDict));
Collections = collections?.Select(

View File

@ -1,5 +1,6 @@
using System.Collections.Generic;
using Bit.Core.Enums.Provider;
using Bit.Core.Models.Api;
using Bit.Core.Models.Data;
namespace Bit.Core.Models.Business.Provider
@ -8,8 +9,11 @@ namespace Bit.Core.Models.Business.Provider
{
public IEnumerable<string> Emails { get; set; }
public ProviderUserType Type { get; set; }
public Permissions Permissions { get; set; }
public ProviderUserInvite() {}
public ProviderUserInvite(ProviderUserInviteRequestModel requestModel)
{
Emails = requestModel.Emails;
Type = requestModel.Type.Value;
}
}
}

View File

@ -20,11 +20,13 @@ namespace Bit.Core.Models.Data
public EventType Type { get; set; }
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public Guid? ProviderId { get; set; }
public Guid? CipherId { get; set; }
public Guid? CollectionId { get; set; }
public Guid? GroupId { get; set; }
public Guid? PolicyId { get; set; }
public Guid? OrganizationUserId { get; set; }
public Guid? ProviderUserId { get; set; }
public Guid? ActingUserId { get; set; }
public DeviceType? DeviceType { get; set; }
public string IpAddress { get; set; }

View File

@ -32,5 +32,7 @@ namespace Bit.Core.Models.Data
public string ResetPasswordKey { get; set; }
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
public Guid? ProviderId { get; set; }
public string ProviderName { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using System;
using Bit.Core.Models.Table;
using Bit.Core.Models.Table.Provider;
namespace Bit.Core.Models.Data
{
public class ProviderAbility
{
public ProviderAbility() { }
public ProviderAbility(Provider provider)
{
Id = provider.Id;
UseEvents = provider.UseEvents;
Enabled = provider.Enabled;
}
public Guid Id { get; set; }
public bool UseEvents { get; set; }
public bool Enabled { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using System;
using Bit.Core.Enums.Provider;
namespace Bit.Core.Models.Data
{
public class ProviderOrganizationOrganizationDetails
{
public Guid Id { get; set; }
public Guid ProviderId { get; set; }
public Guid OrganizationId { get; set; }
public string OrganizationName { get; set; }
public string Key { get; set; }
public string Settings { get; set; }
public DateTime CreationDate { get; set; }
public DateTime RevisionDate { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using System;
using Bit.Core.Enums.Provider;
namespace Bit.Core.Models.Data
{
public class ProviderUserProviderDetails
{
public Guid ProviderId { get; set; }
public Guid? UserId { get; set; }
public string Name { get; set; }
public string Key { get; set; }
public ProviderUserStatusType Status { get; set; }
public ProviderUserType Type { get; set; }
public bool Enabled { get; set; }
public string Permissions { get; set; }
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace Bit.Core.Models.Data
{
public class ProviderUserPublicKey
{
public Guid Id { get; set; }
public string PublicKey { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using System;
using Bit.Core.Enums.Provider;
namespace Bit.Core.Models.Data
{
public class ProviderUserUserDetails
{
public Guid Id { get; set; }
public Guid ProviderId { get; set; }
public Guid? UserId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public ProviderUserStatusType Status { get; set; }
public ProviderUserType Type { get; set; }
public string Permissions { get; set; }
}
}

View File

@ -5,7 +5,7 @@
public string ProviderId { get; set; }
public string Email { get; set; }
public string Token { get; set; }
public string Url => string.Format("{0}/setup-provider?providerId={1}&email={2}&token={3}",
public string Url => string.Format("{0}/providers/setup-provider?providerId={1}&email={2}&token={3}",
WebVaultUrl,
ProviderId,
Email,

View File

@ -8,7 +8,7 @@
public string Email { get; set; }
public string ProviderNameUrlEncoded { get; set; }
public string Token { get; set; }
public string Url => string.Format("{0}/accept-provider?providerId={1}&" +
public string Url => string.Format("{0}/providers/accept-provider?providerId={1}&" +
"providerUserId={2}&email={3}&providerName={4}&token={5}",
WebVaultUrl,
ProviderId,

View File

@ -16,6 +16,7 @@ namespace Bit.Core.Models.Table.Provider
public string BusinessTaxNumber { get; set; }
public string BillingEmail { get; set; }
public ProviderStatusType Status { get; set; }
public bool UseEvents { get; set; }
public bool Enabled { get; set; } = true;
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;

View File

@ -14,8 +14,8 @@ namespace Bit.Core.Models.Table.Provider
public ProviderUserStatusType Status { get; set; }
public ProviderUserType Type { get; set; }
public string Permissions { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public void SetNewId()
{