mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 23:52:50 -05:00
Run formatting (#2230)
This commit is contained in:
@ -1,21 +1,20 @@
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models
|
||||
namespace Bit.Api.Models;
|
||||
|
||||
public class CipherAttachmentModel
|
||||
{
|
||||
public class CipherAttachmentModel
|
||||
public CipherAttachmentModel() { }
|
||||
|
||||
public CipherAttachmentModel(CipherAttachment.MetaData data)
|
||||
{
|
||||
public CipherAttachmentModel() { }
|
||||
|
||||
public CipherAttachmentModel(CipherAttachment.MetaData data)
|
||||
{
|
||||
FileName = data.FileName;
|
||||
Key = data.Key;
|
||||
}
|
||||
|
||||
[EncryptedStringLength(1000)]
|
||||
public string FileName { get; set; }
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Key { get; set; }
|
||||
FileName = data.FileName;
|
||||
Key = data.Key;
|
||||
}
|
||||
|
||||
[EncryptedStringLength(1000)]
|
||||
public string FileName { get; set; }
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
@ -2,39 +2,38 @@
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models
|
||||
namespace Bit.Api.Models;
|
||||
|
||||
public class CipherCardModel
|
||||
{
|
||||
public class CipherCardModel
|
||||
public CipherCardModel() { }
|
||||
|
||||
public CipherCardModel(CipherCardData data)
|
||||
{
|
||||
public CipherCardModel() { }
|
||||
|
||||
public CipherCardModel(CipherCardData data)
|
||||
{
|
||||
CardholderName = data.CardholderName;
|
||||
Brand = data.Brand;
|
||||
Number = data.Number;
|
||||
ExpMonth = data.ExpMonth;
|
||||
ExpYear = data.ExpYear;
|
||||
Code = data.Code;
|
||||
}
|
||||
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string CardholderName { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Brand { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Number { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string ExpMonth { get; set; }
|
||||
[EncryptedString]
|
||||
[StringLength(1000)]
|
||||
public string ExpYear { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Code { get; set; }
|
||||
CardholderName = data.CardholderName;
|
||||
Brand = data.Brand;
|
||||
Number = data.Number;
|
||||
ExpMonth = data.ExpMonth;
|
||||
ExpYear = data.ExpYear;
|
||||
Code = data.Code;
|
||||
}
|
||||
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string CardholderName { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Brand { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Number { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string ExpMonth { get; set; }
|
||||
[EncryptedString]
|
||||
[StringLength(1000)]
|
||||
public string ExpYear { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Code { get; set; }
|
||||
}
|
||||
|
@ -2,36 +2,35 @@
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models
|
||||
namespace Bit.Api.Models;
|
||||
|
||||
public class CipherFieldModel
|
||||
{
|
||||
public class CipherFieldModel
|
||||
public CipherFieldModel() { }
|
||||
|
||||
public CipherFieldModel(CipherFieldData data)
|
||||
{
|
||||
public CipherFieldModel() { }
|
||||
Type = data.Type;
|
||||
Name = data.Name;
|
||||
Value = data.Value;
|
||||
LinkedId = data.LinkedId ?? null;
|
||||
}
|
||||
|
||||
public CipherFieldModel(CipherFieldData data)
|
||||
public FieldType Type { get; set; }
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Name { get; set; }
|
||||
[EncryptedStringLength(5000)]
|
||||
public string Value { get; set; }
|
||||
public int? LinkedId { get; set; }
|
||||
|
||||
public CipherFieldData ToCipherFieldData()
|
||||
{
|
||||
return new CipherFieldData
|
||||
{
|
||||
Type = data.Type;
|
||||
Name = data.Name;
|
||||
Value = data.Value;
|
||||
LinkedId = data.LinkedId ?? null;
|
||||
}
|
||||
|
||||
public FieldType Type { get; set; }
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Name { get; set; }
|
||||
[EncryptedStringLength(5000)]
|
||||
public string Value { get; set; }
|
||||
public int? LinkedId { get; set; }
|
||||
|
||||
public CipherFieldData ToCipherFieldData()
|
||||
{
|
||||
return new CipherFieldData
|
||||
{
|
||||
Type = Type,
|
||||
Name = Name,
|
||||
Value = Value,
|
||||
LinkedId = LinkedId ?? null,
|
||||
};
|
||||
}
|
||||
Type = Type,
|
||||
Name = Name,
|
||||
Value = Value,
|
||||
LinkedId = LinkedId ?? null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2,87 +2,86 @@
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models
|
||||
namespace Bit.Api.Models;
|
||||
|
||||
public class CipherIdentityModel
|
||||
{
|
||||
public class CipherIdentityModel
|
||||
public CipherIdentityModel() { }
|
||||
|
||||
public CipherIdentityModel(CipherIdentityData data)
|
||||
{
|
||||
public CipherIdentityModel() { }
|
||||
|
||||
public CipherIdentityModel(CipherIdentityData data)
|
||||
{
|
||||
Title = data.Title;
|
||||
FirstName = data.FirstName;
|
||||
MiddleName = data.MiddleName;
|
||||
LastName = data.LastName;
|
||||
Address1 = data.Address1;
|
||||
Address2 = data.Address2;
|
||||
Address3 = data.Address3;
|
||||
City = data.City;
|
||||
State = data.State;
|
||||
PostalCode = data.PostalCode;
|
||||
Country = data.Country;
|
||||
Company = data.Company;
|
||||
Email = data.Email;
|
||||
Phone = data.Phone;
|
||||
SSN = data.SSN;
|
||||
Username = data.Username;
|
||||
PassportNumber = data.PassportNumber;
|
||||
LicenseNumber = data.LicenseNumber;
|
||||
}
|
||||
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Title { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string FirstName { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string MiddleName { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string LastName { get; set; }
|
||||
[EncryptedString]
|
||||
[StringLength(1000)]
|
||||
public string Address1 { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Address2 { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Address3 { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string City { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string State { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string PostalCode { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Country { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Company { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Email { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Phone { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string SSN { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Username { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string PassportNumber { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string LicenseNumber { get; set; }
|
||||
Title = data.Title;
|
||||
FirstName = data.FirstName;
|
||||
MiddleName = data.MiddleName;
|
||||
LastName = data.LastName;
|
||||
Address1 = data.Address1;
|
||||
Address2 = data.Address2;
|
||||
Address3 = data.Address3;
|
||||
City = data.City;
|
||||
State = data.State;
|
||||
PostalCode = data.PostalCode;
|
||||
Country = data.Country;
|
||||
Company = data.Company;
|
||||
Email = data.Email;
|
||||
Phone = data.Phone;
|
||||
SSN = data.SSN;
|
||||
Username = data.Username;
|
||||
PassportNumber = data.PassportNumber;
|
||||
LicenseNumber = data.LicenseNumber;
|
||||
}
|
||||
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Title { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string FirstName { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string MiddleName { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string LastName { get; set; }
|
||||
[EncryptedString]
|
||||
[StringLength(1000)]
|
||||
public string Address1 { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Address2 { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Address3 { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string City { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string State { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string PostalCode { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Country { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Company { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Email { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Phone { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string SSN { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Username { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string PassportNumber { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string LicenseNumber { get; set; }
|
||||
}
|
||||
|
@ -2,84 +2,83 @@
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models
|
||||
{
|
||||
public class CipherLoginModel
|
||||
{
|
||||
public CipherLoginModel() { }
|
||||
namespace Bit.Api.Models;
|
||||
|
||||
public CipherLoginModel(CipherLoginData data)
|
||||
public class CipherLoginModel
|
||||
{
|
||||
public CipherLoginModel() { }
|
||||
|
||||
public CipherLoginModel(CipherLoginData data)
|
||||
{
|
||||
Uris = data.Uris?.Select(u => new CipherLoginUriModel(u))?.ToList();
|
||||
if (!Uris?.Any() ?? true)
|
||||
{
|
||||
Uris = data.Uris?.Select(u => new CipherLoginUriModel(u))?.ToList();
|
||||
if (!Uris?.Any() ?? true)
|
||||
Uri = data.Uri;
|
||||
}
|
||||
|
||||
Username = data.Username;
|
||||
Password = data.Password;
|
||||
PasswordRevisionDate = data.PasswordRevisionDate;
|
||||
Totp = data.Totp;
|
||||
AutofillOnPageLoad = data.AutofillOnPageLoad;
|
||||
}
|
||||
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(10000)]
|
||||
public string Uri
|
||||
{
|
||||
get => Uris?.FirstOrDefault()?.Uri;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
Uri = data.Uri;
|
||||
return;
|
||||
}
|
||||
|
||||
Username = data.Username;
|
||||
Password = data.Password;
|
||||
PasswordRevisionDate = data.PasswordRevisionDate;
|
||||
Totp = data.Totp;
|
||||
AutofillOnPageLoad = data.AutofillOnPageLoad;
|
||||
if (Uris == null)
|
||||
{
|
||||
Uris = new List<CipherLoginUriModel>();
|
||||
}
|
||||
|
||||
Uris.Add(new CipherLoginUriModel(value));
|
||||
}
|
||||
}
|
||||
public List<CipherLoginUriModel> Uris { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Username { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(5000)]
|
||||
public string Password { get; set; }
|
||||
public DateTime? PasswordRevisionDate { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Totp { get; set; }
|
||||
public bool? AutofillOnPageLoad { get; set; }
|
||||
|
||||
public class CipherLoginUriModel
|
||||
{
|
||||
public CipherLoginUriModel() { }
|
||||
|
||||
public CipherLoginUriModel(string uri)
|
||||
{
|
||||
Uri = uri;
|
||||
}
|
||||
|
||||
public CipherLoginUriModel(CipherLoginData.CipherLoginUriData uri)
|
||||
{
|
||||
Uri = uri.Uri;
|
||||
Match = uri.Match;
|
||||
}
|
||||
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(10000)]
|
||||
public string Uri
|
||||
public string Uri { get; set; }
|
||||
public UriMatchType? Match { get; set; } = null;
|
||||
|
||||
public CipherLoginData.CipherLoginUriData ToCipherLoginUriData()
|
||||
{
|
||||
get => Uris?.FirstOrDefault()?.Uri;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Uris == null)
|
||||
{
|
||||
Uris = new List<CipherLoginUriModel>();
|
||||
}
|
||||
|
||||
Uris.Add(new CipherLoginUriModel(value));
|
||||
}
|
||||
}
|
||||
public List<CipherLoginUriModel> Uris { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Username { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(5000)]
|
||||
public string Password { get; set; }
|
||||
public DateTime? PasswordRevisionDate { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Totp { get; set; }
|
||||
public bool? AutofillOnPageLoad { get; set; }
|
||||
|
||||
public class CipherLoginUriModel
|
||||
{
|
||||
public CipherLoginUriModel() { }
|
||||
|
||||
public CipherLoginUriModel(string uri)
|
||||
{
|
||||
Uri = uri;
|
||||
}
|
||||
|
||||
public CipherLoginUriModel(CipherLoginData.CipherLoginUriData uri)
|
||||
{
|
||||
Uri = uri.Uri;
|
||||
Match = uri.Match;
|
||||
}
|
||||
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(10000)]
|
||||
public string Uri { get; set; }
|
||||
public UriMatchType? Match { get; set; } = null;
|
||||
|
||||
public CipherLoginData.CipherLoginUriData ToCipherLoginUriData()
|
||||
{
|
||||
return new CipherLoginData.CipherLoginUriData { Uri = Uri, Match = Match, };
|
||||
}
|
||||
return new CipherLoginData.CipherLoginUriData { Uri = Uri, Match = Match, };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,28 +2,27 @@
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models
|
||||
namespace Bit.Api.Models;
|
||||
|
||||
public class CipherPasswordHistoryModel
|
||||
{
|
||||
public class CipherPasswordHistoryModel
|
||||
public CipherPasswordHistoryModel() { }
|
||||
|
||||
public CipherPasswordHistoryModel(CipherPasswordHistoryData data)
|
||||
{
|
||||
public CipherPasswordHistoryModel() { }
|
||||
Password = data.Password;
|
||||
LastUsedDate = data.LastUsedDate;
|
||||
}
|
||||
|
||||
public CipherPasswordHistoryModel(CipherPasswordHistoryData data)
|
||||
{
|
||||
Password = data.Password;
|
||||
LastUsedDate = data.LastUsedDate;
|
||||
}
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(5000)]
|
||||
[Required]
|
||||
public string Password { get; set; }
|
||||
[Required]
|
||||
public DateTime? LastUsedDate { get; set; }
|
||||
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(5000)]
|
||||
[Required]
|
||||
public string Password { get; set; }
|
||||
[Required]
|
||||
public DateTime? LastUsedDate { get; set; }
|
||||
|
||||
public CipherPasswordHistoryData ToCipherPasswordHistoryData()
|
||||
{
|
||||
return new CipherPasswordHistoryData { Password = Password, LastUsedDate = LastUsedDate.Value, };
|
||||
}
|
||||
public CipherPasswordHistoryData ToCipherPasswordHistoryData()
|
||||
{
|
||||
return new CipherPasswordHistoryData { Password = Password, LastUsedDate = LastUsedDate.Value, };
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Api.Models
|
||||
namespace Bit.Api.Models;
|
||||
|
||||
public class CipherSecureNoteModel
|
||||
{
|
||||
public class CipherSecureNoteModel
|
||||
public CipherSecureNoteModel() { }
|
||||
|
||||
public CipherSecureNoteModel(CipherSecureNoteData data)
|
||||
{
|
||||
public CipherSecureNoteModel() { }
|
||||
|
||||
public CipherSecureNoteModel(CipherSecureNoteData data)
|
||||
{
|
||||
Type = data.Type;
|
||||
}
|
||||
|
||||
public SecureNoteType Type { get; set; }
|
||||
Type = data.Type;
|
||||
}
|
||||
|
||||
public SecureNoteType Type { get; set; }
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Public
|
||||
namespace Bit.Api.Models.Public;
|
||||
|
||||
public abstract class AssociationWithPermissionsBaseModel
|
||||
{
|
||||
public abstract class AssociationWithPermissionsBaseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The associated object's unique identifier.
|
||||
/// </summary>
|
||||
/// <example>bfbc8338-e329-4dc0-b0c9-317c2ebf1a09</example>
|
||||
[Required]
|
||||
public Guid? Id { get; set; }
|
||||
/// <summary>
|
||||
/// When true, the read only permission will not allow the user or group to make changes to items.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool? ReadOnly { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The associated object's unique identifier.
|
||||
/// </summary>
|
||||
/// <example>bfbc8338-e329-4dc0-b0c9-317c2ebf1a09</example>
|
||||
[Required]
|
||||
public Guid? Id { get; set; }
|
||||
/// <summary>
|
||||
/// When true, the read only permission will not allow the user or group to make changes to items.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool? ReadOnly { get; set; }
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Public
|
||||
namespace Bit.Api.Models.Public;
|
||||
|
||||
public abstract class CollectionBaseModel
|
||||
{
|
||||
public abstract class CollectionBaseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// External identifier for reference or linking this collection to another system.
|
||||
/// </summary>
|
||||
/// <example>external_id_123456</example>
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// External identifier for reference or linking this collection to another system.
|
||||
/// </summary>
|
||||
/// <example>external_id_123456</example>
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
}
|
||||
|
@ -1,27 +1,26 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Public
|
||||
namespace Bit.Api.Models.Public;
|
||||
|
||||
public abstract class GroupBaseModel
|
||||
{
|
||||
public abstract class GroupBaseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the group.
|
||||
/// </summary>
|
||||
/// <example>Development Team</example>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Determines if this group can access all collections within the organization, or only the associated
|
||||
/// collections. If set to <c>true</c>, this option overrides any collection assignments.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool? AccessAll { get; set; }
|
||||
/// <summary>
|
||||
/// External identifier for reference or linking this group to another system, such as a user directory.
|
||||
/// </summary>
|
||||
/// <example>external_id_123456</example>
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The name of the group.
|
||||
/// </summary>
|
||||
/// <example>Development Team</example>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Determines if this group can access all collections within the organization, or only the associated
|
||||
/// collections. If set to <c>true</c>, this option overrides any collection assignments.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool? AccessAll { get; set; }
|
||||
/// <summary>
|
||||
/// External identifier for reference or linking this group to another system, such as a user directory.
|
||||
/// </summary>
|
||||
/// <example>external_id_123456</example>
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
}
|
||||
|
@ -3,59 +3,58 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
|
||||
namespace Bit.Api.Models.Public
|
||||
namespace Bit.Api.Models.Public;
|
||||
|
||||
public abstract class MemberBaseModel
|
||||
{
|
||||
public abstract class MemberBaseModel
|
||||
public MemberBaseModel() { }
|
||||
|
||||
public MemberBaseModel(OrganizationUser user)
|
||||
{
|
||||
public MemberBaseModel() { }
|
||||
|
||||
public MemberBaseModel(OrganizationUser user)
|
||||
if (user == null)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
Type = user.Type;
|
||||
AccessAll = user.AccessAll;
|
||||
ExternalId = user.ExternalId;
|
||||
ResetPasswordEnrolled = user.ResetPasswordKey != null;
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
public MemberBaseModel(OrganizationUserUserDetails user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
Type = user.Type;
|
||||
AccessAll = user.AccessAll;
|
||||
ExternalId = user.ExternalId;
|
||||
ResetPasswordEnrolled = user.ResetPasswordKey != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The member's type (or role) within the organization.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public OrganizationUserType? Type { get; set; }
|
||||
/// <summary>
|
||||
/// Determines if this member can access all collections within the organization, or only the associated
|
||||
/// collections. If set to <c>true</c>, this option overrides any collection assignments.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool? AccessAll { get; set; }
|
||||
/// <summary>
|
||||
/// External identifier for reference or linking this member to another system, such as a user directory.
|
||||
/// </summary>
|
||||
/// <example>external_id_123456</example>
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if the member has enrolled in Password Reset assistance within the organization
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool ResetPasswordEnrolled { get; set; }
|
||||
Type = user.Type;
|
||||
AccessAll = user.AccessAll;
|
||||
ExternalId = user.ExternalId;
|
||||
ResetPasswordEnrolled = user.ResetPasswordKey != null;
|
||||
}
|
||||
|
||||
public MemberBaseModel(OrganizationUserUserDetails user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
Type = user.Type;
|
||||
AccessAll = user.AccessAll;
|
||||
ExternalId = user.ExternalId;
|
||||
ResetPasswordEnrolled = user.ResetPasswordKey != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The member's type (or role) within the organization.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public OrganizationUserType? Type { get; set; }
|
||||
/// <summary>
|
||||
/// Determines if this member can access all collections within the organization, or only the associated
|
||||
/// collections. If set to <c>true</c>, this option overrides any collection assignments.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool? AccessAll { get; set; }
|
||||
/// <summary>
|
||||
/// External identifier for reference or linking this member to another system, such as a user directory.
|
||||
/// </summary>
|
||||
/// <example>external_id_123456</example>
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if the member has enrolled in Password Reset assistance within the organization
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool ResetPasswordEnrolled { get; set; }
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Public
|
||||
namespace Bit.Api.Models.Public;
|
||||
|
||||
public abstract class PolicyBaseModel
|
||||
{
|
||||
public abstract class PolicyBaseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines if this policy is enabled and enforced.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool? Enabled { get; set; }
|
||||
/// <summary>
|
||||
/// Data for the policy.
|
||||
/// </summary>
|
||||
public Dictionary<string, object> Data { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Determines if this policy is enabled and enforced.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool? Enabled { get; set; }
|
||||
/// <summary>
|
||||
/// Data for the policy.
|
||||
/// </summary>
|
||||
public Dictionary<string, object> Data { get; set; }
|
||||
}
|
||||
|
@ -1,16 +1,15 @@
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Api.Models.Public.Request
|
||||
namespace Bit.Api.Models.Public.Request;
|
||||
|
||||
public class AssociationWithPermissionsRequestModel : AssociationWithPermissionsBaseModel
|
||||
{
|
||||
public class AssociationWithPermissionsRequestModel : AssociationWithPermissionsBaseModel
|
||||
public SelectionReadOnly ToSelectionReadOnly()
|
||||
{
|
||||
public SelectionReadOnly ToSelectionReadOnly()
|
||||
return new SelectionReadOnly
|
||||
{
|
||||
return new SelectionReadOnly
|
||||
{
|
||||
Id = Id.Value,
|
||||
ReadOnly = ReadOnly.Value
|
||||
};
|
||||
}
|
||||
Id = Id.Value,
|
||||
ReadOnly = ReadOnly.Value
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
using Bit.Core.Entities;
|
||||
|
||||
namespace Bit.Api.Models.Public.Request
|
||||
{
|
||||
public class CollectionUpdateRequestModel : CollectionBaseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The associated groups that this collection is assigned to.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsRequestModel> Groups { get; set; }
|
||||
namespace Bit.Api.Models.Public.Request;
|
||||
|
||||
public Collection ToCollection(Collection existingCollection)
|
||||
{
|
||||
existingCollection.ExternalId = ExternalId;
|
||||
return existingCollection;
|
||||
}
|
||||
public class CollectionUpdateRequestModel : CollectionBaseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The associated groups that this collection is assigned to.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsRequestModel> Groups { get; set; }
|
||||
|
||||
public Collection ToCollection(Collection existingCollection)
|
||||
{
|
||||
existingCollection.ExternalId = ExternalId;
|
||||
return existingCollection;
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +1,49 @@
|
||||
using Bit.Core.Exceptions;
|
||||
|
||||
namespace Bit.Api.Models.Public.Request
|
||||
namespace Bit.Api.Models.Public.Request;
|
||||
|
||||
public class EventFilterRequestModel
|
||||
{
|
||||
public class EventFilterRequestModel
|
||||
/// <summary>
|
||||
/// The start date. Must be less than the end date.
|
||||
/// </summary>
|
||||
public DateTime? Start { get; set; }
|
||||
/// <summary>
|
||||
/// The end date. Must be greater than the start date.
|
||||
/// </summary>
|
||||
public DateTime? End { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the user that performed the event.
|
||||
/// </summary>
|
||||
public Guid? ActingUserId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related item that the event describes.
|
||||
/// </summary>
|
||||
public Guid? ItemId { get; set; }
|
||||
/// <summary>
|
||||
/// A cursor for use in pagination.
|
||||
/// </summary>
|
||||
public string ContinuationToken { get; set; }
|
||||
|
||||
public Tuple<DateTime, DateTime> ToDateRange()
|
||||
{
|
||||
/// <summary>
|
||||
/// The start date. Must be less than the end date.
|
||||
/// </summary>
|
||||
public DateTime? Start { get; set; }
|
||||
/// <summary>
|
||||
/// The end date. Must be greater than the start date.
|
||||
/// </summary>
|
||||
public DateTime? End { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the user that performed the event.
|
||||
/// </summary>
|
||||
public Guid? ActingUserId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related item that the event describes.
|
||||
/// </summary>
|
||||
public Guid? ItemId { get; set; }
|
||||
/// <summary>
|
||||
/// A cursor for use in pagination.
|
||||
/// </summary>
|
||||
public string ContinuationToken { get; set; }
|
||||
|
||||
public Tuple<DateTime, DateTime> ToDateRange()
|
||||
if (!End.HasValue || !Start.HasValue)
|
||||
{
|
||||
if (!End.HasValue || !Start.HasValue)
|
||||
{
|
||||
End = DateTime.UtcNow.Date.AddDays(1).AddMilliseconds(-1);
|
||||
Start = DateTime.UtcNow.Date.AddDays(-30);
|
||||
}
|
||||
else if (Start.Value > End.Value)
|
||||
{
|
||||
var newEnd = Start;
|
||||
Start = End;
|
||||
End = newEnd;
|
||||
}
|
||||
|
||||
if ((End.Value - Start.Value) > TimeSpan.FromDays(367))
|
||||
{
|
||||
throw new BadRequestException("Date range must be < 367 days.");
|
||||
}
|
||||
|
||||
return new Tuple<DateTime, DateTime>(Start.Value, End.Value);
|
||||
End = DateTime.UtcNow.Date.AddDays(1).AddMilliseconds(-1);
|
||||
Start = DateTime.UtcNow.Date.AddDays(-30);
|
||||
}
|
||||
else if (Start.Value > End.Value)
|
||||
{
|
||||
var newEnd = Start;
|
||||
Start = End;
|
||||
End = newEnd;
|
||||
}
|
||||
|
||||
if ((End.Value - Start.Value) > TimeSpan.FromDays(367))
|
||||
{
|
||||
throw new BadRequestException("Date range must be < 367 days.");
|
||||
}
|
||||
|
||||
return new Tuple<DateTime, DateTime>(Start.Value, End.Value);
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,27 @@
|
||||
using Bit.Core.Entities;
|
||||
|
||||
namespace Bit.Api.Models.Public.Request
|
||||
namespace Bit.Api.Models.Public.Request;
|
||||
|
||||
public class GroupCreateUpdateRequestModel : GroupBaseModel
|
||||
{
|
||||
public class GroupCreateUpdateRequestModel : GroupBaseModel
|
||||
/// <summary>
|
||||
/// The associated collections that this group can access.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsRequestModel> Collections { get; set; }
|
||||
|
||||
public Group ToGroup(Guid orgId)
|
||||
{
|
||||
/// <summary>
|
||||
/// The associated collections that this group can access.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsRequestModel> Collections { get; set; }
|
||||
|
||||
public Group ToGroup(Guid orgId)
|
||||
return ToGroup(new Group
|
||||
{
|
||||
return ToGroup(new Group
|
||||
{
|
||||
OrganizationId = orgId
|
||||
});
|
||||
}
|
||||
OrganizationId = orgId
|
||||
});
|
||||
}
|
||||
|
||||
public Group ToGroup(Group existingGroup)
|
||||
{
|
||||
existingGroup.Name = Name;
|
||||
existingGroup.AccessAll = AccessAll.Value;
|
||||
existingGroup.ExternalId = ExternalId;
|
||||
return existingGroup;
|
||||
}
|
||||
public Group ToGroup(Group existingGroup)
|
||||
{
|
||||
existingGroup.Name = Name;
|
||||
existingGroup.AccessAll = AccessAll.Value;
|
||||
existingGroup.ExternalId = ExternalId;
|
||||
return existingGroup;
|
||||
}
|
||||
}
|
||||
|
@ -2,22 +2,21 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Public.Request
|
||||
{
|
||||
public class MemberCreateRequestModel : MemberUpdateRequestModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The member's email address.
|
||||
/// </summary>
|
||||
/// <example>jsmith@example.com</example>
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
[StrictEmailAddress]
|
||||
public string Email { get; set; }
|
||||
namespace Bit.Api.Models.Public.Request;
|
||||
|
||||
public override OrganizationUser ToOrganizationUser(OrganizationUser existingUser)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public class MemberCreateRequestModel : MemberUpdateRequestModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The member's email address.
|
||||
/// </summary>
|
||||
/// <example>jsmith@example.com</example>
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
[StrictEmailAddress]
|
||||
public string Email { get; set; }
|
||||
|
||||
public override OrganizationUser ToOrganizationUser(OrganizationUser existingUser)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
using Bit.Core.Entities;
|
||||
|
||||
namespace Bit.Api.Models.Public.Request
|
||||
{
|
||||
public class MemberUpdateRequestModel : MemberBaseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The associated collections that this member can access.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsRequestModel> Collections { get; set; }
|
||||
namespace Bit.Api.Models.Public.Request;
|
||||
|
||||
public virtual OrganizationUser ToOrganizationUser(OrganizationUser existingUser)
|
||||
{
|
||||
existingUser.Type = Type.Value;
|
||||
existingUser.AccessAll = AccessAll.Value;
|
||||
existingUser.ExternalId = ExternalId;
|
||||
return existingUser;
|
||||
}
|
||||
public class MemberUpdateRequestModel : MemberBaseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The associated collections that this member can access.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsRequestModel> Collections { get; set; }
|
||||
|
||||
public virtual OrganizationUser ToOrganizationUser(OrganizationUser existingUser)
|
||||
{
|
||||
existingUser.Type = Type.Value;
|
||||
existingUser.AccessAll = AccessAll.Value;
|
||||
existingUser.ExternalId = ExternalId;
|
||||
return existingUser;
|
||||
}
|
||||
}
|
||||
|
@ -4,108 +4,107 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Public.Request
|
||||
namespace Bit.Api.Models.Public.Request;
|
||||
|
||||
public class OrganizationImportRequestModel
|
||||
{
|
||||
public class OrganizationImportRequestModel
|
||||
/// <summary>
|
||||
/// Groups to import.
|
||||
/// </summary>
|
||||
public OrganizationImportGroupRequestModel[] Groups { get; set; }
|
||||
/// <summary>
|
||||
/// Members to import.
|
||||
/// </summary>
|
||||
public OrganizationImportMemberRequestModel[] Members { get; set; }
|
||||
/// <summary>
|
||||
/// Determines if the data in this request should overwrite or append to the existing organization data.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool? OverwriteExisting { get; set; }
|
||||
/// <summary>
|
||||
/// Indicates an import of over 2000 users and/or groups is expected
|
||||
/// </summary>
|
||||
public bool LargeImport { get; set; } = false;
|
||||
|
||||
public class OrganizationImportGroupRequestModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Groups to import.
|
||||
/// </summary>
|
||||
public OrganizationImportGroupRequestModel[] Groups { get; set; }
|
||||
/// <summary>
|
||||
/// Members to import.
|
||||
/// </summary>
|
||||
public OrganizationImportMemberRequestModel[] Members { get; set; }
|
||||
/// <summary>
|
||||
/// Determines if the data in this request should overwrite or append to the existing organization data.
|
||||
/// The name of the group.
|
||||
/// </summary>
|
||||
/// <example>Development Team</example>
|
||||
[Required]
|
||||
public bool? OverwriteExisting { get; set; }
|
||||
[StringLength(100)]
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Indicates an import of over 2000 users and/or groups is expected
|
||||
/// External identifier for reference or linking this group to another system, such as a user directory.
|
||||
/// </summary>
|
||||
public bool LargeImport { get; set; } = false;
|
||||
/// <example>external_id_123456</example>
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
[JsonConverter(typeof(PermissiveStringConverter))]
|
||||
public string ExternalId { get; set; }
|
||||
/// <summary>
|
||||
/// The associated external ids for members in this group.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(PermissiveStringEnumerableConverter))]
|
||||
public IEnumerable<string> MemberExternalIds { get; set; }
|
||||
|
||||
public class OrganizationImportGroupRequestModel
|
||||
public ImportedGroup ToImportedGroup(Guid organizationId)
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the group.
|
||||
/// </summary>
|
||||
/// <example>Development Team</example>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// External identifier for reference or linking this group to another system, such as a user directory.
|
||||
/// </summary>
|
||||
/// <example>external_id_123456</example>
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
[JsonConverter(typeof(PermissiveStringConverter))]
|
||||
public string ExternalId { get; set; }
|
||||
/// <summary>
|
||||
/// The associated external ids for members in this group.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(PermissiveStringEnumerableConverter))]
|
||||
public IEnumerable<string> MemberExternalIds { get; set; }
|
||||
|
||||
public ImportedGroup ToImportedGroup(Guid organizationId)
|
||||
var importedGroup = new ImportedGroup
|
||||
{
|
||||
var importedGroup = new ImportedGroup
|
||||
Group = new Group
|
||||
{
|
||||
Group = new Group
|
||||
{
|
||||
OrganizationId = organizationId,
|
||||
Name = Name,
|
||||
ExternalId = ExternalId
|
||||
},
|
||||
ExternalUserIds = new HashSet<string>(MemberExternalIds)
|
||||
};
|
||||
OrganizationId = organizationId,
|
||||
Name = Name,
|
||||
ExternalId = ExternalId
|
||||
},
|
||||
ExternalUserIds = new HashSet<string>(MemberExternalIds)
|
||||
};
|
||||
|
||||
return importedGroup;
|
||||
}
|
||||
return importedGroup;
|
||||
}
|
||||
}
|
||||
|
||||
public class OrganizationImportMemberRequestModel : IValidatableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// The member's email address. Required for non-deleted users.
|
||||
/// </summary>
|
||||
/// <example>jsmith@example.com</example>
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
/// <summary>
|
||||
/// External identifier for reference or linking this member to another system, such as a user directory.
|
||||
/// </summary>
|
||||
/// <example>external_id_123456</example>
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
[JsonConverter(typeof(PermissiveStringConverter))]
|
||||
public string ExternalId { get; set; }
|
||||
/// <summary>
|
||||
/// Determines if this member should be removed from the organization during import.
|
||||
/// </summary>
|
||||
public bool Deleted { get; set; }
|
||||
|
||||
public ImportedOrganizationUser ToImportedOrganizationUser()
|
||||
{
|
||||
var importedUser = new ImportedOrganizationUser
|
||||
{
|
||||
Email = Email.ToLowerInvariant(),
|
||||
ExternalId = ExternalId
|
||||
};
|
||||
|
||||
return importedUser;
|
||||
}
|
||||
|
||||
public class OrganizationImportMemberRequestModel : IValidatableObject
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
/// <summary>
|
||||
/// The member's email address. Required for non-deleted users.
|
||||
/// </summary>
|
||||
/// <example>jsmith@example.com</example>
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
/// <summary>
|
||||
/// External identifier for reference or linking this member to another system, such as a user directory.
|
||||
/// </summary>
|
||||
/// <example>external_id_123456</example>
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
[JsonConverter(typeof(PermissiveStringConverter))]
|
||||
public string ExternalId { get; set; }
|
||||
/// <summary>
|
||||
/// Determines if this member should be removed from the organization during import.
|
||||
/// </summary>
|
||||
public bool Deleted { get; set; }
|
||||
|
||||
public ImportedOrganizationUser ToImportedOrganizationUser()
|
||||
if (string.IsNullOrWhiteSpace(Email) && !Deleted)
|
||||
{
|
||||
var importedUser = new ImportedOrganizationUser
|
||||
{
|
||||
Email = Email.ToLowerInvariant(),
|
||||
ExternalId = ExternalId
|
||||
};
|
||||
|
||||
return importedUser;
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Email) && !Deleted)
|
||||
{
|
||||
yield return new ValidationResult("Email is required for enabled members.",
|
||||
new string[] { nameof(Email) });
|
||||
}
|
||||
yield return new ValidationResult("Email is required for enabled members.",
|
||||
new string[] { nameof(Email) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,22 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
|
||||
namespace Bit.Api.Models.Public.Request
|
||||
{
|
||||
public class PolicyUpdateRequestModel : PolicyBaseModel
|
||||
{
|
||||
public Policy ToPolicy(Guid orgId)
|
||||
{
|
||||
return ToPolicy(new Policy
|
||||
{
|
||||
OrganizationId = orgId
|
||||
});
|
||||
}
|
||||
namespace Bit.Api.Models.Public.Request;
|
||||
|
||||
public virtual Policy ToPolicy(Policy existingPolicy)
|
||||
public class PolicyUpdateRequestModel : PolicyBaseModel
|
||||
{
|
||||
public Policy ToPolicy(Guid orgId)
|
||||
{
|
||||
return ToPolicy(new Policy
|
||||
{
|
||||
existingPolicy.Enabled = Enabled.GetValueOrDefault();
|
||||
existingPolicy.Data = Data != null ? JsonSerializer.Serialize(Data) : null;
|
||||
return existingPolicy;
|
||||
}
|
||||
OrganizationId = orgId
|
||||
});
|
||||
}
|
||||
|
||||
public virtual Policy ToPolicy(Policy existingPolicy)
|
||||
{
|
||||
existingPolicy.Enabled = Enabled.GetValueOrDefault();
|
||||
existingPolicy.Data = Data != null ? JsonSerializer.Serialize(Data) : null;
|
||||
return existingPolicy;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
namespace Bit.Api.Models.Public.Request
|
||||
namespace Bit.Api.Models.Public.Request;
|
||||
|
||||
public class UpdateGroupIdsRequestModel
|
||||
{
|
||||
public class UpdateGroupIdsRequestModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The associated group ids that this object can access.
|
||||
/// </summary>
|
||||
public IEnumerable<Guid> GroupIds { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The associated group ids that this object can access.
|
||||
/// </summary>
|
||||
public IEnumerable<Guid> GroupIds { get; set; }
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
namespace Bit.Api.Models.Public.Request
|
||||
namespace Bit.Api.Models.Public.Request;
|
||||
|
||||
public class UpdateMemberIdsRequestModel
|
||||
{
|
||||
public class UpdateMemberIdsRequestModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The associated member ids that have access to this object.
|
||||
/// </summary>
|
||||
public IEnumerable<Guid> MemberIds { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The associated member ids that have access to this object.
|
||||
/// </summary>
|
||||
public IEnumerable<Guid> MemberIds { get; set; }
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Api.Models.Public.Response
|
||||
namespace Bit.Api.Models.Public.Response;
|
||||
|
||||
public class AssociationWithPermissionsResponseModel : AssociationWithPermissionsBaseModel
|
||||
{
|
||||
public class AssociationWithPermissionsResponseModel : AssociationWithPermissionsBaseModel
|
||||
public AssociationWithPermissionsResponseModel(SelectionReadOnly selection)
|
||||
{
|
||||
public AssociationWithPermissionsResponseModel(SelectionReadOnly selection)
|
||||
if (selection == null)
|
||||
{
|
||||
if (selection == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(selection));
|
||||
}
|
||||
Id = selection.Id;
|
||||
ReadOnly = selection.ReadOnly;
|
||||
throw new ArgumentNullException(nameof(selection));
|
||||
}
|
||||
Id = selection.Id;
|
||||
ReadOnly = selection.ReadOnly;
|
||||
}
|
||||
}
|
||||
|
@ -2,40 +2,39 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Api.Models.Public.Response
|
||||
{
|
||||
/// <summary>
|
||||
/// A collection.
|
||||
/// </summary>
|
||||
public class CollectionResponseModel : CollectionBaseModel, IResponseModel
|
||||
{
|
||||
public CollectionResponseModel(Collection collection, IEnumerable<SelectionReadOnly> groups)
|
||||
{
|
||||
if (collection == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
}
|
||||
namespace Bit.Api.Models.Public.Response;
|
||||
|
||||
Id = collection.Id;
|
||||
ExternalId = collection.ExternalId;
|
||||
Groups = groups?.Select(c => new AssociationWithPermissionsResponseModel(c));
|
||||
/// <summary>
|
||||
/// A collection.
|
||||
/// </summary>
|
||||
public class CollectionResponseModel : CollectionBaseModel, IResponseModel
|
||||
{
|
||||
public CollectionResponseModel(Collection collection, IEnumerable<SelectionReadOnly> groups)
|
||||
{
|
||||
if (collection == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>collection</example>
|
||||
[Required]
|
||||
public string Object => "collection";
|
||||
/// <summary>
|
||||
/// The collection's unique identifier.
|
||||
/// </summary>
|
||||
/// <example>539a36c5-e0d2-4cf9-979e-51ecf5cf6593</example>
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// The associated groups that this collection is assigned to.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsResponseModel> Groups { get; set; }
|
||||
Id = collection.Id;
|
||||
ExternalId = collection.ExternalId;
|
||||
Groups = groups?.Select(c => new AssociationWithPermissionsResponseModel(c));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>collection</example>
|
||||
[Required]
|
||||
public string Object => "collection";
|
||||
/// <summary>
|
||||
/// The collection's unique identifier.
|
||||
/// </summary>
|
||||
/// <example>539a36c5-e0d2-4cf9-979e-51ecf5cf6593</example>
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// The associated groups that this collection is assigned to.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsResponseModel> Groups { get; set; }
|
||||
}
|
||||
|
@ -1,77 +1,76 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
|
||||
namespace Bit.Api.Models.Public.Response
|
||||
namespace Bit.Api.Models.Public.Response;
|
||||
|
||||
public class ErrorResponseModel : IResponseModel
|
||||
{
|
||||
public class ErrorResponseModel : IResponseModel
|
||||
public ErrorResponseModel(string message)
|
||||
{
|
||||
public ErrorResponseModel(string message)
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
|
||||
public ErrorResponseModel(ModelStateDictionary modelState)
|
||||
{
|
||||
Message = "The request's model state is invalid.";
|
||||
Errors = new Dictionary<string, IEnumerable<string>>();
|
||||
|
||||
var keys = modelState.Keys.ToList();
|
||||
var values = modelState.Values.ToList();
|
||||
|
||||
for (var i = 0; i < values.Count; i++)
|
||||
{
|
||||
var value = values[i];
|
||||
if (keys.Count <= i)
|
||||
{
|
||||
// Keys not available for some reason.
|
||||
break;
|
||||
}
|
||||
|
||||
var key = keys[i];
|
||||
if (value.ValidationState != ModelValidationState.Invalid || value.Errors.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var errors = value.Errors.Select(e => e.ErrorMessage);
|
||||
Errors.Add(key, errors);
|
||||
}
|
||||
}
|
||||
|
||||
public ErrorResponseModel(Dictionary<string, IEnumerable<string>> errors)
|
||||
: this("Errors have occurred.", errors)
|
||||
{ }
|
||||
|
||||
public ErrorResponseModel(string errorKey, string errorValue)
|
||||
: this(errorKey, new string[] { errorValue })
|
||||
{ }
|
||||
|
||||
public ErrorResponseModel(string errorKey, IEnumerable<string> errorValues)
|
||||
: this(new Dictionary<string, IEnumerable<string>> { { errorKey, errorValues } })
|
||||
{ }
|
||||
|
||||
public ErrorResponseModel(string message, Dictionary<string, IEnumerable<string>> errors)
|
||||
{
|
||||
Message = message;
|
||||
Errors = errors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>error</example>
|
||||
[Required]
|
||||
public string Object => "error";
|
||||
/// <summary>
|
||||
/// A human-readable message providing details about the error.
|
||||
/// </summary>
|
||||
/// <example>The request model is invalid.</example>
|
||||
[Required]
|
||||
public string Message { get; set; }
|
||||
/// <summary>
|
||||
/// If multiple errors occurred, they are listed in dictionary. Errors related to a specific
|
||||
/// request parameter will include a dictionary key describing that parameter.
|
||||
/// </summary>
|
||||
public Dictionary<string, IEnumerable<string>> Errors { get; set; }
|
||||
Message = message;
|
||||
}
|
||||
|
||||
public ErrorResponseModel(ModelStateDictionary modelState)
|
||||
{
|
||||
Message = "The request's model state is invalid.";
|
||||
Errors = new Dictionary<string, IEnumerable<string>>();
|
||||
|
||||
var keys = modelState.Keys.ToList();
|
||||
var values = modelState.Values.ToList();
|
||||
|
||||
for (var i = 0; i < values.Count; i++)
|
||||
{
|
||||
var value = values[i];
|
||||
if (keys.Count <= i)
|
||||
{
|
||||
// Keys not available for some reason.
|
||||
break;
|
||||
}
|
||||
|
||||
var key = keys[i];
|
||||
if (value.ValidationState != ModelValidationState.Invalid || value.Errors.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var errors = value.Errors.Select(e => e.ErrorMessage);
|
||||
Errors.Add(key, errors);
|
||||
}
|
||||
}
|
||||
|
||||
public ErrorResponseModel(Dictionary<string, IEnumerable<string>> errors)
|
||||
: this("Errors have occurred.", errors)
|
||||
{ }
|
||||
|
||||
public ErrorResponseModel(string errorKey, string errorValue)
|
||||
: this(errorKey, new string[] { errorValue })
|
||||
{ }
|
||||
|
||||
public ErrorResponseModel(string errorKey, IEnumerable<string> errorValues)
|
||||
: this(new Dictionary<string, IEnumerable<string>> { { errorKey, errorValues } })
|
||||
{ }
|
||||
|
||||
public ErrorResponseModel(string message, Dictionary<string, IEnumerable<string>> errors)
|
||||
{
|
||||
Message = message;
|
||||
Errors = errors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>error</example>
|
||||
[Required]
|
||||
public string Object => "error";
|
||||
/// <summary>
|
||||
/// A human-readable message providing details about the error.
|
||||
/// </summary>
|
||||
/// <example>The request model is invalid.</example>
|
||||
[Required]
|
||||
public string Message { get; set; }
|
||||
/// <summary>
|
||||
/// If multiple errors occurred, they are listed in dictionary. Errors related to a specific
|
||||
/// request parameter will include a dictionary key describing that parameter.
|
||||
/// </summary>
|
||||
public Dictionary<string, IEnumerable<string>> Errors { get; set; }
|
||||
}
|
||||
|
@ -2,92 +2,91 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Api.Models.Public.Response
|
||||
{
|
||||
/// <summary>
|
||||
/// An event log.
|
||||
/// </summary>
|
||||
public class EventResponseModel : IResponseModel
|
||||
{
|
||||
public EventResponseModel(IEvent ev)
|
||||
{
|
||||
if (ev == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(ev));
|
||||
}
|
||||
namespace Bit.Api.Models.Public.Response;
|
||||
|
||||
Type = ev.Type;
|
||||
ItemId = ev.CipherId;
|
||||
CollectionId = ev.CollectionId;
|
||||
GroupId = ev.GroupId;
|
||||
PolicyId = ev.PolicyId;
|
||||
MemberId = ev.OrganizationUserId;
|
||||
ActingUserId = ev.ActingUserId;
|
||||
Date = ev.Date;
|
||||
Device = ev.DeviceType;
|
||||
IpAddress = ev.IpAddress;
|
||||
InstallationId = ev.InstallationId;
|
||||
/// <summary>
|
||||
/// An event log.
|
||||
/// </summary>
|
||||
public class EventResponseModel : IResponseModel
|
||||
{
|
||||
public EventResponseModel(IEvent ev)
|
||||
{
|
||||
if (ev == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(ev));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>event</example>
|
||||
[Required]
|
||||
public string Object => "event";
|
||||
/// <summary>
|
||||
/// The type of event.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public EventType Type { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related item that the event describes.
|
||||
/// </summary>
|
||||
/// <example>3767a302-8208-4dc6-b842-030428a1cfad</example>
|
||||
public Guid? ItemId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related collection that the event describes.
|
||||
/// </summary>
|
||||
/// <example>bce212a4-25f3-4888-8a0a-4c5736d851e0</example>
|
||||
public Guid? CollectionId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related group that the event describes.
|
||||
/// </summary>
|
||||
/// <example>f29a2515-91d2-4452-b49b-5e8040e6b0f4</example>
|
||||
public Guid? GroupId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related policy that the event describes.
|
||||
/// </summary>
|
||||
/// <example>f29a2515-91d2-4452-b49b-5e8040e6b0f4</example>
|
||||
public Guid? PolicyId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related member that the event describes.
|
||||
/// </summary>
|
||||
/// <example>e68b8629-85eb-4929-92c0-b84464976ba4</example>
|
||||
public Guid? MemberId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the user that performed the event.
|
||||
/// </summary>
|
||||
/// <example>a2549f79-a71f-4eb9-9234-eb7247333f94</example>
|
||||
public Guid? ActingUserId { get; set; }
|
||||
/// <summary>
|
||||
/// The Unique identifier of the Installation that performed the event.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public Guid? InstallationId { get; set; }
|
||||
/// <summary>
|
||||
/// The date/timestamp when the event occurred.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DateTime Date { get; set; }
|
||||
/// <summary>
|
||||
/// The type of device used by the acting user when the event occurred.
|
||||
/// </summary>
|
||||
public DeviceType? Device { get; set; }
|
||||
/// <summary>
|
||||
/// The IP address of the acting user.
|
||||
/// </summary>
|
||||
/// <example>172.16.254.1</example>
|
||||
public string IpAddress { get; set; }
|
||||
Type = ev.Type;
|
||||
ItemId = ev.CipherId;
|
||||
CollectionId = ev.CollectionId;
|
||||
GroupId = ev.GroupId;
|
||||
PolicyId = ev.PolicyId;
|
||||
MemberId = ev.OrganizationUserId;
|
||||
ActingUserId = ev.ActingUserId;
|
||||
Date = ev.Date;
|
||||
Device = ev.DeviceType;
|
||||
IpAddress = ev.IpAddress;
|
||||
InstallationId = ev.InstallationId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>event</example>
|
||||
[Required]
|
||||
public string Object => "event";
|
||||
/// <summary>
|
||||
/// The type of event.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public EventType Type { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related item that the event describes.
|
||||
/// </summary>
|
||||
/// <example>3767a302-8208-4dc6-b842-030428a1cfad</example>
|
||||
public Guid? ItemId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related collection that the event describes.
|
||||
/// </summary>
|
||||
/// <example>bce212a4-25f3-4888-8a0a-4c5736d851e0</example>
|
||||
public Guid? CollectionId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related group that the event describes.
|
||||
/// </summary>
|
||||
/// <example>f29a2515-91d2-4452-b49b-5e8040e6b0f4</example>
|
||||
public Guid? GroupId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related policy that the event describes.
|
||||
/// </summary>
|
||||
/// <example>f29a2515-91d2-4452-b49b-5e8040e6b0f4</example>
|
||||
public Guid? PolicyId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the related member that the event describes.
|
||||
/// </summary>
|
||||
/// <example>e68b8629-85eb-4929-92c0-b84464976ba4</example>
|
||||
public Guid? MemberId { get; set; }
|
||||
/// <summary>
|
||||
/// The unique identifier of the user that performed the event.
|
||||
/// </summary>
|
||||
/// <example>a2549f79-a71f-4eb9-9234-eb7247333f94</example>
|
||||
public Guid? ActingUserId { get; set; }
|
||||
/// <summary>
|
||||
/// The Unique identifier of the Installation that performed the event.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public Guid? InstallationId { get; set; }
|
||||
/// <summary>
|
||||
/// The date/timestamp when the event occurred.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DateTime Date { get; set; }
|
||||
/// <summary>
|
||||
/// The type of device used by the acting user when the event occurred.
|
||||
/// </summary>
|
||||
public DeviceType? Device { get; set; }
|
||||
/// <summary>
|
||||
/// The IP address of the acting user.
|
||||
/// </summary>
|
||||
/// <example>172.16.254.1</example>
|
||||
public string IpAddress { get; set; }
|
||||
}
|
||||
|
@ -2,42 +2,41 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Api.Models.Public.Response
|
||||
{
|
||||
/// <summary>
|
||||
/// A user group.
|
||||
/// </summary>
|
||||
public class GroupResponseModel : GroupBaseModel, IResponseModel
|
||||
{
|
||||
public GroupResponseModel(Group group, IEnumerable<SelectionReadOnly> collections)
|
||||
{
|
||||
if (group == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(group));
|
||||
}
|
||||
namespace Bit.Api.Models.Public.Response;
|
||||
|
||||
Id = group.Id;
|
||||
Name = group.Name;
|
||||
AccessAll = group.AccessAll;
|
||||
ExternalId = group.ExternalId;
|
||||
Collections = collections?.Select(c => new AssociationWithPermissionsResponseModel(c));
|
||||
/// <summary>
|
||||
/// A user group.
|
||||
/// </summary>
|
||||
public class GroupResponseModel : GroupBaseModel, IResponseModel
|
||||
{
|
||||
public GroupResponseModel(Group group, IEnumerable<SelectionReadOnly> collections)
|
||||
{
|
||||
if (group == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(group));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>group</example>
|
||||
[Required]
|
||||
public string Object => "group";
|
||||
/// <summary>
|
||||
/// The group's unique identifier.
|
||||
/// </summary>
|
||||
/// <example>539a36c5-e0d2-4cf9-979e-51ecf5cf6593</example>
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// The associated collections that this group can access.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsResponseModel> Collections { get; set; }
|
||||
Id = group.Id;
|
||||
Name = group.Name;
|
||||
AccessAll = group.AccessAll;
|
||||
ExternalId = group.ExternalId;
|
||||
Collections = collections?.Select(c => new AssociationWithPermissionsResponseModel(c));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>group</example>
|
||||
[Required]
|
||||
public string Object => "group";
|
||||
/// <summary>
|
||||
/// The group's unique identifier.
|
||||
/// </summary>
|
||||
/// <example>539a36c5-e0d2-4cf9-979e-51ecf5cf6593</example>
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// The associated collections that this group can access.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsResponseModel> Collections { get; set; }
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
namespace Bit.Api.Models.Public.Response
|
||||
namespace Bit.Api.Models.Public.Response;
|
||||
|
||||
public interface IResponseModel
|
||||
{
|
||||
public interface IResponseModel
|
||||
{
|
||||
string Object { get; }
|
||||
}
|
||||
string Object { get; }
|
||||
}
|
||||
|
@ -1,29 +1,28 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Public.Response
|
||||
{
|
||||
public class ListResponseModel<T> : IResponseModel where T : IResponseModel
|
||||
{
|
||||
public ListResponseModel(IEnumerable<T> data, string continuationToken = null)
|
||||
{
|
||||
Data = data;
|
||||
ContinuationToken = continuationToken;
|
||||
}
|
||||
namespace Bit.Api.Models.Public.Response;
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>list</example>
|
||||
[Required]
|
||||
public string Object => "list";
|
||||
/// <summary>
|
||||
/// An array containing the actual response elements, paginated by any request parameters.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public IEnumerable<T> Data { get; set; }
|
||||
/// <summary>
|
||||
/// A cursor for use in pagination.
|
||||
/// </summary>
|
||||
public string ContinuationToken { get; set; }
|
||||
public class ListResponseModel<T> : IResponseModel where T : IResponseModel
|
||||
{
|
||||
public ListResponseModel(IEnumerable<T> data, string continuationToken = null)
|
||||
{
|
||||
Data = data;
|
||||
ContinuationToken = continuationToken;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>list</example>
|
||||
[Required]
|
||||
public string Object => "list";
|
||||
/// <summary>
|
||||
/// An array containing the actual response elements, paginated by any request parameters.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public IEnumerable<T> Data { get; set; }
|
||||
/// <summary>
|
||||
/// A cursor for use in pagination.
|
||||
/// </summary>
|
||||
public string ContinuationToken { get; set; }
|
||||
}
|
||||
|
@ -4,91 +4,90 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
|
||||
namespace Bit.Api.Models.Public.Response
|
||||
namespace Bit.Api.Models.Public.Response;
|
||||
|
||||
/// <summary>
|
||||
/// An organization member.
|
||||
/// </summary>
|
||||
public class MemberResponseModel : MemberBaseModel, IResponseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// An organization member.
|
||||
/// </summary>
|
||||
public class MemberResponseModel : MemberBaseModel, IResponseModel
|
||||
public MemberResponseModel(OrganizationUser user, IEnumerable<SelectionReadOnly> collections)
|
||||
: base(user)
|
||||
{
|
||||
public MemberResponseModel(OrganizationUser user, IEnumerable<SelectionReadOnly> collections)
|
||||
: base(user)
|
||||
if (user == null)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
Id = user.Id;
|
||||
UserId = user.UserId;
|
||||
Email = user.Email;
|
||||
Status = user.Status;
|
||||
Collections = collections?.Select(c => new AssociationWithPermissionsResponseModel(c));
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
public MemberResponseModel(OrganizationUserUserDetails user, bool twoFactorEnabled,
|
||||
IEnumerable<SelectionReadOnly> collections)
|
||||
: base(user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
Id = user.Id;
|
||||
UserId = user.UserId;
|
||||
Name = user.Name;
|
||||
Email = user.Email;
|
||||
TwoFactorEnabled = twoFactorEnabled;
|
||||
Status = user.Status;
|
||||
Collections = collections?.Select(c => new AssociationWithPermissionsResponseModel(c));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>member</example>
|
||||
[Required]
|
||||
public string Object => "member";
|
||||
/// <summary>
|
||||
/// The member's unique identifier within the organization.
|
||||
/// </summary>
|
||||
/// <example>539a36c5-e0d2-4cf9-979e-51ecf5cf6593</example>
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// The member's unique identifier across Bitwarden.
|
||||
/// </summary>
|
||||
/// <example>48b47ee1-493e-4c67-aef7-014996c40eca</example>
|
||||
[Required]
|
||||
public Guid? UserId { get; set; }
|
||||
/// <summary>
|
||||
/// The member's name, set from their user account profile.
|
||||
/// </summary>
|
||||
/// <example>John Smith</example>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// The member's email address.
|
||||
/// </summary>
|
||||
/// <example>jsmith@example.com</example>
|
||||
[Required]
|
||||
public string Email { get; set; }
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if the member has a two-step login method enabled on their user account.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool TwoFactorEnabled { get; set; }
|
||||
/// <summary>
|
||||
/// The member's status within the organization. All created members start with a status of "Invited".
|
||||
/// Once a member accept's their invitation to join the organization, their status changes to "Accepted".
|
||||
/// Accepted members are then "Confirmed" by an organization administrator. Once a member is "Confirmed",
|
||||
/// their status can no longer change.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public OrganizationUserStatusType Status { get; set; }
|
||||
/// <summary>
|
||||
/// The associated collections that this member can access.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsResponseModel> Collections { get; set; }
|
||||
Id = user.Id;
|
||||
UserId = user.UserId;
|
||||
Email = user.Email;
|
||||
Status = user.Status;
|
||||
Collections = collections?.Select(c => new AssociationWithPermissionsResponseModel(c));
|
||||
}
|
||||
|
||||
public MemberResponseModel(OrganizationUserUserDetails user, bool twoFactorEnabled,
|
||||
IEnumerable<SelectionReadOnly> collections)
|
||||
: base(user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
Id = user.Id;
|
||||
UserId = user.UserId;
|
||||
Name = user.Name;
|
||||
Email = user.Email;
|
||||
TwoFactorEnabled = twoFactorEnabled;
|
||||
Status = user.Status;
|
||||
Collections = collections?.Select(c => new AssociationWithPermissionsResponseModel(c));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>member</example>
|
||||
[Required]
|
||||
public string Object => "member";
|
||||
/// <summary>
|
||||
/// The member's unique identifier within the organization.
|
||||
/// </summary>
|
||||
/// <example>539a36c5-e0d2-4cf9-979e-51ecf5cf6593</example>
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// The member's unique identifier across Bitwarden.
|
||||
/// </summary>
|
||||
/// <example>48b47ee1-493e-4c67-aef7-014996c40eca</example>
|
||||
[Required]
|
||||
public Guid? UserId { get; set; }
|
||||
/// <summary>
|
||||
/// The member's name, set from their user account profile.
|
||||
/// </summary>
|
||||
/// <example>John Smith</example>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// The member's email address.
|
||||
/// </summary>
|
||||
/// <example>jsmith@example.com</example>
|
||||
[Required]
|
||||
public string Email { get; set; }
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if the member has a two-step login method enabled on their user account.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool TwoFactorEnabled { get; set; }
|
||||
/// <summary>
|
||||
/// The member's status within the organization. All created members start with a status of "Invited".
|
||||
/// Once a member accept's their invitation to join the organization, their status changes to "Accepted".
|
||||
/// Accepted members are then "Confirmed" by an organization administrator. Once a member is "Confirmed",
|
||||
/// their status can no longer change.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public OrganizationUserStatusType Status { get; set; }
|
||||
/// <summary>
|
||||
/// The associated collections that this member can access.
|
||||
/// </summary>
|
||||
public IEnumerable<AssociationWithPermissionsResponseModel> Collections { get; set; }
|
||||
}
|
||||
|
@ -3,45 +3,44 @@ using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Api.Models.Public.Response
|
||||
{
|
||||
/// <summary>
|
||||
/// A policy.
|
||||
/// </summary>
|
||||
public class PolicyResponseModel : PolicyBaseModel, IResponseModel
|
||||
{
|
||||
public PolicyResponseModel(Policy policy)
|
||||
{
|
||||
if (policy == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(policy));
|
||||
}
|
||||
namespace Bit.Api.Models.Public.Response;
|
||||
|
||||
Id = policy.Id;
|
||||
Type = policy.Type;
|
||||
Enabled = policy.Enabled;
|
||||
if (!string.IsNullOrWhiteSpace(policy.Data))
|
||||
{
|
||||
Data = JsonSerializer.Deserialize<Dictionary<string, object>>(policy.Data);
|
||||
}
|
||||
/// <summary>
|
||||
/// A policy.
|
||||
/// </summary>
|
||||
public class PolicyResponseModel : PolicyBaseModel, IResponseModel
|
||||
{
|
||||
public PolicyResponseModel(Policy policy)
|
||||
{
|
||||
if (policy == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(policy));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>policy</example>
|
||||
[Required]
|
||||
public string Object => "policy";
|
||||
/// <summary>
|
||||
/// The policy's unique identifier.
|
||||
/// </summary>
|
||||
/// <example>539a36c5-e0d2-4cf9-979e-51ecf5cf6593</example>
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// The type of policy.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public PolicyType? Type { get; set; }
|
||||
Id = policy.Id;
|
||||
Type = policy.Type;
|
||||
Enabled = policy.Enabled;
|
||||
if (!string.IsNullOrWhiteSpace(policy.Data))
|
||||
{
|
||||
Data = JsonSerializer.Deserialize<Dictionary<string, object>>(policy.Data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representing the object's type. Objects of the same type share the same properties.
|
||||
/// </summary>
|
||||
/// <example>policy</example>
|
||||
[Required]
|
||||
public string Object => "policy";
|
||||
/// <summary>
|
||||
/// The policy's unique identifier.
|
||||
/// </summary>
|
||||
/// <example>539a36c5-e0d2-4cf9-979e-51ecf5cf6593</example>
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// The type of policy.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public PolicyType? Type { get; set; }
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class DeleteRecoverRequestModel
|
||||
{
|
||||
public class DeleteRecoverRequestModel
|
||||
{
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
}
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class EmailRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
public class EmailRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StrictEmailAddress]
|
||||
[StringLength(256)]
|
||||
public string NewEmail { get; set; }
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string NewMasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
public string Token { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
[Required]
|
||||
[StrictEmailAddress]
|
||||
[StringLength(256)]
|
||||
public string NewEmail { get; set; }
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string NewMasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
public string Token { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class EmailTokenRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
public class EmailTokenRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StrictEmailAddress]
|
||||
[StringLength(256)]
|
||||
public string NewEmail { get; set; }
|
||||
}
|
||||
[Required]
|
||||
[StrictEmailAddress]
|
||||
[StringLength(256)]
|
||||
public string NewEmail { get; set; }
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class ImportCiphersRequestModel
|
||||
{
|
||||
public class ImportCiphersRequestModel
|
||||
{
|
||||
public FolderRequestModel[] Folders { get; set; }
|
||||
public CipherRequestModel[] Ciphers { get; set; }
|
||||
public KeyValuePair<int, int>[] FolderRelationships { get; set; }
|
||||
}
|
||||
public FolderRequestModel[] Folders { get; set; }
|
||||
public CipherRequestModel[] Ciphers { get; set; }
|
||||
public KeyValuePair<int, int>[] FolderRelationships { get; set; }
|
||||
}
|
||||
|
@ -1,30 +1,29 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
{
|
||||
public class KdfRequestModel : PasswordRequestModel, IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public KdfType? Kdf { get; set; }
|
||||
[Required]
|
||||
public int? KdfIterations { get; set; }
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
public class KdfRequestModel : PasswordRequestModel, IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public KdfType? Kdf { get; set; }
|
||||
[Required]
|
||||
public int? KdfIterations { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (Kdf.HasValue && KdfIterations.HasValue)
|
||||
{
|
||||
if (Kdf.HasValue && KdfIterations.HasValue)
|
||||
switch (Kdf.Value)
|
||||
{
|
||||
switch (Kdf.Value)
|
||||
{
|
||||
case KdfType.PBKDF2_SHA256:
|
||||
if (KdfIterations.Value < 5000 || KdfIterations.Value > 2_000_000)
|
||||
{
|
||||
yield return new ValidationResult("KDF iterations must be between 5000 and 2000000.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case KdfType.PBKDF2_SHA256:
|
||||
if (KdfIterations.Value < 5000 || KdfIterations.Value > 2_000_000)
|
||||
{
|
||||
yield return new ValidationResult("KDF iterations must be between 5000 and 2000000.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class OrganizationApiKeyRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
public class OrganizationApiKeyRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
public OrganizationApiKeyType Type { get; set; }
|
||||
}
|
||||
public OrganizationApiKeyType Type { get; set; }
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class PasswordHintRequestModel
|
||||
{
|
||||
public class PasswordHintRequestModel
|
||||
{
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
}
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class PasswordRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
public class PasswordRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string NewMasterPasswordHash { get; set; }
|
||||
[StringLength(50)]
|
||||
public string MasterPasswordHint { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string NewMasterPasswordHash { get; set; }
|
||||
[StringLength(50)]
|
||||
public string MasterPasswordHint { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
@ -2,41 +2,40 @@
|
||||
using Bit.Core.Settings;
|
||||
using Enums = Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class PremiumRequestModel : IValidatableObject
|
||||
{
|
||||
public class PremiumRequestModel : IValidatableObject
|
||||
[Required]
|
||||
public Enums.PaymentMethodType? PaymentMethodType { get; set; }
|
||||
public string PaymentToken { get; set; }
|
||||
[Range(0, 99)]
|
||||
public short? AdditionalStorageGb { get; set; }
|
||||
public IFormFile License { get; set; }
|
||||
public string Country { get; set; }
|
||||
public string PostalCode { get; set; }
|
||||
|
||||
public bool Validate(GlobalSettings globalSettings)
|
||||
{
|
||||
[Required]
|
||||
public Enums.PaymentMethodType? PaymentMethodType { get; set; }
|
||||
public string PaymentToken { get; set; }
|
||||
[Range(0, 99)]
|
||||
public short? AdditionalStorageGb { get; set; }
|
||||
public IFormFile License { get; set; }
|
||||
public string Country { get; set; }
|
||||
public string PostalCode { get; set; }
|
||||
|
||||
public bool Validate(GlobalSettings globalSettings)
|
||||
if (!(License == null && !globalSettings.SelfHosted) ||
|
||||
(License != null && globalSettings.SelfHosted))
|
||||
{
|
||||
if (!(License == null && !globalSettings.SelfHosted) ||
|
||||
(License != null && globalSettings.SelfHosted))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return globalSettings.SelfHosted || !string.IsNullOrWhiteSpace(Country);
|
||||
return false;
|
||||
}
|
||||
return globalSettings.SelfHosted || !string.IsNullOrWhiteSpace(Country);
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
var creditType = PaymentMethodType.HasValue && PaymentMethodType.Value == Enums.PaymentMethodType.Credit;
|
||||
if (string.IsNullOrWhiteSpace(PaymentToken) && !creditType && License == null)
|
||||
{
|
||||
var creditType = PaymentMethodType.HasValue && PaymentMethodType.Value == Enums.PaymentMethodType.Credit;
|
||||
if (string.IsNullOrWhiteSpace(PaymentToken) && !creditType && License == null)
|
||||
{
|
||||
yield return new ValidationResult("Payment token or license is required.");
|
||||
}
|
||||
if (Country == "US" && string.IsNullOrWhiteSpace(PostalCode))
|
||||
{
|
||||
yield return new ValidationResult("Zip / postal code is required.",
|
||||
new string[] { nameof(PostalCode) });
|
||||
}
|
||||
yield return new ValidationResult("Payment token or license is required.");
|
||||
}
|
||||
if (Country == "US" && string.IsNullOrWhiteSpace(PostalCode))
|
||||
{
|
||||
yield return new ValidationResult("Zip / postal code is required.",
|
||||
new string[] { nameof(PostalCode) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class RegenerateTwoFactorRequestModel
|
||||
{
|
||||
public class RegenerateTwoFactorRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string MasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
[Required]
|
||||
public string MasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
{
|
||||
public class SecretVerificationRequestModel : IValidatableObject
|
||||
{
|
||||
[StringLength(300)]
|
||||
public string MasterPasswordHash { get; set; }
|
||||
public string OTP { get; set; }
|
||||
public string Secret => !string.IsNullOrEmpty(MasterPasswordHash) ? MasterPasswordHash : OTP;
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
public class SecretVerificationRequestModel : IValidatableObject
|
||||
{
|
||||
[StringLength(300)]
|
||||
public string MasterPasswordHash { get; set; }
|
||||
public string OTP { get; set; }
|
||||
public string Secret => !string.IsNullOrEmpty(MasterPasswordHash) ? MasterPasswordHash : OTP;
|
||||
|
||||
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Secret))
|
||||
{
|
||||
if (string.IsNullOrEmpty(Secret))
|
||||
{
|
||||
yield return new ValidationResult("MasterPasswordHash or OTP must be supplied.");
|
||||
}
|
||||
yield return new ValidationResult("MasterPasswordHash or OTP must be supplied.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,28 +3,27 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api.Request.Accounts;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
{
|
||||
public class SetKeyConnectorKeyRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
[Required]
|
||||
public KeysRequestModel Keys { get; set; }
|
||||
[Required]
|
||||
public KdfType Kdf { get; set; }
|
||||
[Required]
|
||||
public int KdfIterations { get; set; }
|
||||
[Required]
|
||||
public string OrgIdentifier { get; set; }
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public User ToUser(User existingUser)
|
||||
{
|
||||
existingUser.Kdf = Kdf;
|
||||
existingUser.KdfIterations = KdfIterations;
|
||||
existingUser.Key = Key;
|
||||
Keys.ToUser(existingUser);
|
||||
return existingUser;
|
||||
}
|
||||
public class SetKeyConnectorKeyRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
[Required]
|
||||
public KeysRequestModel Keys { get; set; }
|
||||
[Required]
|
||||
public KdfType Kdf { get; set; }
|
||||
[Required]
|
||||
public int KdfIterations { get; set; }
|
||||
[Required]
|
||||
public string OrgIdentifier { get; set; }
|
||||
|
||||
public User ToUser(User existingUser)
|
||||
{
|
||||
existingUser.Kdf = Kdf;
|
||||
existingUser.KdfIterations = KdfIterations;
|
||||
existingUser.Key = Key;
|
||||
Keys.ToUser(existingUser);
|
||||
return existingUser;
|
||||
}
|
||||
}
|
||||
|
@ -3,33 +3,32 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api.Request.Accounts;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
{
|
||||
public class SetPasswordRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string MasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
[StringLength(50)]
|
||||
public string MasterPasswordHint { get; set; }
|
||||
[Required]
|
||||
public KeysRequestModel Keys { get; set; }
|
||||
[Required]
|
||||
public KdfType Kdf { get; set; }
|
||||
[Required]
|
||||
public int KdfIterations { get; set; }
|
||||
public string OrgIdentifier { get; set; }
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public User ToUser(User existingUser)
|
||||
{
|
||||
existingUser.MasterPasswordHint = MasterPasswordHint;
|
||||
existingUser.Kdf = Kdf;
|
||||
existingUser.KdfIterations = KdfIterations;
|
||||
existingUser.Key = Key;
|
||||
Keys.ToUser(existingUser);
|
||||
return existingUser;
|
||||
}
|
||||
public class SetPasswordRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string MasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
[StringLength(50)]
|
||||
public string MasterPasswordHint { get; set; }
|
||||
[Required]
|
||||
public KeysRequestModel Keys { get; set; }
|
||||
[Required]
|
||||
public KdfType Kdf { get; set; }
|
||||
[Required]
|
||||
public int KdfIterations { get; set; }
|
||||
public string OrgIdentifier { get; set; }
|
||||
|
||||
public User ToUser(User existingUser)
|
||||
{
|
||||
existingUser.MasterPasswordHint = MasterPasswordHint;
|
||||
existingUser.Kdf = Kdf;
|
||||
existingUser.KdfIterations = KdfIterations;
|
||||
existingUser.Key = Key;
|
||||
Keys.ToUser(existingUser);
|
||||
return existingUser;
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
{
|
||||
public class StorageRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public short? StorageGbAdjustment { get; set; }
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
public class StorageRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public short? StorageGbAdjustment { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (StorageGbAdjustment == 0)
|
||||
{
|
||||
if (StorageGbAdjustment == 0)
|
||||
{
|
||||
yield return new ValidationResult("Storage adjustment cannot be 0.",
|
||||
new string[] { nameof(StorageGbAdjustment) });
|
||||
}
|
||||
yield return new ValidationResult("Storage adjustment cannot be 0.",
|
||||
new string[] { nameof(StorageGbAdjustment) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
{
|
||||
public class TaxInfoUpdateRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public string Country { get; set; }
|
||||
public string PostalCode { get; set; }
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
public class TaxInfoUpdateRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public string Country { get; set; }
|
||||
public string PostalCode { get; set; }
|
||||
|
||||
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (Country == "US" && string.IsNullOrWhiteSpace(PostalCode))
|
||||
{
|
||||
if (Country == "US" && string.IsNullOrWhiteSpace(PostalCode))
|
||||
{
|
||||
yield return new ValidationResult("Zip / postal code is required.",
|
||||
new string[] { nameof(PostalCode) });
|
||||
}
|
||||
yield return new ValidationResult("Zip / postal code is required.",
|
||||
new string[] { nameof(PostalCode) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class UpdateKeyRequestModel
|
||||
{
|
||||
public class UpdateKeyRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string MasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
public IEnumerable<CipherWithIdRequestModel> Ciphers { get; set; }
|
||||
[Required]
|
||||
public IEnumerable<FolderWithIdRequestModel> Folders { get; set; }
|
||||
public IEnumerable<SendWithIdRequestModel> Sends { get; set; }
|
||||
[Required]
|
||||
public string PrivateKey { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string MasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
public IEnumerable<CipherWithIdRequestModel> Ciphers { get; set; }
|
||||
[Required]
|
||||
public IEnumerable<FolderWithIdRequestModel> Folders { get; set; }
|
||||
public IEnumerable<SendWithIdRequestModel> Sends { get; set; }
|
||||
[Required]
|
||||
public string PrivateKey { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
@ -1,21 +1,20 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Entities;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
{
|
||||
public class UpdateProfileRequestModel
|
||||
{
|
||||
[StringLength(50)]
|
||||
public string Name { get; set; }
|
||||
[StringLength(50)]
|
||||
[Obsolete("Changes will be made via the 'password' endpoint going forward.")]
|
||||
public string MasterPasswordHint { get; set; }
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public User ToUser(User existingUser)
|
||||
{
|
||||
existingUser.Name = Name;
|
||||
existingUser.MasterPasswordHint = string.IsNullOrWhiteSpace(MasterPasswordHint) ? null : MasterPasswordHint;
|
||||
return existingUser;
|
||||
}
|
||||
public class UpdateProfileRequestModel
|
||||
{
|
||||
[StringLength(50)]
|
||||
public string Name { get; set; }
|
||||
[StringLength(50)]
|
||||
[Obsolete("Changes will be made via the 'password' endpoint going forward.")]
|
||||
public string MasterPasswordHint { get; set; }
|
||||
|
||||
public User ToUser(User existingUser)
|
||||
{
|
||||
existingUser.Name = Name;
|
||||
existingUser.MasterPasswordHint = string.IsNullOrWhiteSpace(MasterPasswordHint) ? null : MasterPasswordHint;
|
||||
return existingUser;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Api.Models.Request.Organizations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class UpdateTempPasswordRequestModel : OrganizationUserResetPasswordRequestModel
|
||||
{
|
||||
public class UpdateTempPasswordRequestModel : OrganizationUserResetPasswordRequestModel
|
||||
{
|
||||
[StringLength(50)]
|
||||
public string MasterPasswordHint { get; set; }
|
||||
}
|
||||
[StringLength(50)]
|
||||
public string MasterPasswordHint { get; set; }
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class VerifyDeleteRecoverRequestModel
|
||||
{
|
||||
public class VerifyDeleteRecoverRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string UserId { get; set; }
|
||||
[Required]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
[Required]
|
||||
public string UserId { get; set; }
|
||||
[Required]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class VerifyEmailRequestModel
|
||||
{
|
||||
public class VerifyEmailRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string UserId { get; set; }
|
||||
[Required]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
[Required]
|
||||
public string UserId { get; set; }
|
||||
[Required]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Accounts
|
||||
namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class VerifyOTPRequestModel
|
||||
{
|
||||
public class VerifyOTPRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string OTP { get; set; }
|
||||
}
|
||||
[Required]
|
||||
public string OTP { get; set; }
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class AttachmentRequestModel
|
||||
{
|
||||
public class AttachmentRequestModel
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public long FileSize { get; set; }
|
||||
public bool AdminRequest { get; set; } = false;
|
||||
}
|
||||
public string Key { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public long FileSize { get; set; }
|
||||
public bool AdminRequest { get; set; } = false;
|
||||
}
|
||||
|
@ -1,66 +1,65 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Settings;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class BitPayInvoiceRequestModel : IValidatableObject
|
||||
{
|
||||
public class BitPayInvoiceRequestModel : IValidatableObject
|
||||
public Guid? UserId { get; set; }
|
||||
public Guid? OrganizationId { get; set; }
|
||||
public bool Credit { get; set; }
|
||||
[Required]
|
||||
public decimal? Amount { get; set; }
|
||||
public string ReturnUrl { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
|
||||
public BitPayLight.Models.Invoice.Invoice ToBitpayInvoice(GlobalSettings globalSettings)
|
||||
{
|
||||
public Guid? UserId { get; set; }
|
||||
public Guid? OrganizationId { get; set; }
|
||||
public bool Credit { get; set; }
|
||||
[Required]
|
||||
public decimal? Amount { get; set; }
|
||||
public string ReturnUrl { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
|
||||
public BitPayLight.Models.Invoice.Invoice ToBitpayInvoice(GlobalSettings globalSettings)
|
||||
var inv = new BitPayLight.Models.Invoice.Invoice
|
||||
{
|
||||
var inv = new BitPayLight.Models.Invoice.Invoice
|
||||
Price = Convert.ToDouble(Amount.Value),
|
||||
Currency = "USD",
|
||||
RedirectUrl = ReturnUrl,
|
||||
Buyer = new BitPayLight.Models.Invoice.Buyer
|
||||
{
|
||||
Price = Convert.ToDouble(Amount.Value),
|
||||
Currency = "USD",
|
||||
RedirectUrl = ReturnUrl,
|
||||
Buyer = new BitPayLight.Models.Invoice.Buyer
|
||||
{
|
||||
Email = Email,
|
||||
Name = Name
|
||||
},
|
||||
NotificationUrl = globalSettings.BitPay.NotificationUrl,
|
||||
FullNotifications = true,
|
||||
ExtendedNotifications = true
|
||||
};
|
||||
Email = Email,
|
||||
Name = Name
|
||||
},
|
||||
NotificationUrl = globalSettings.BitPay.NotificationUrl,
|
||||
FullNotifications = true,
|
||||
ExtendedNotifications = true
|
||||
};
|
||||
|
||||
var posData = string.Empty;
|
||||
if (UserId.HasValue)
|
||||
{
|
||||
posData = "userId:" + UserId.Value;
|
||||
}
|
||||
else if (OrganizationId.HasValue)
|
||||
{
|
||||
posData = "organizationId:" + OrganizationId.Value;
|
||||
}
|
||||
|
||||
if (Credit)
|
||||
{
|
||||
posData += ",accountCredit:1";
|
||||
inv.ItemDesc = "Bitwarden Account Credit";
|
||||
}
|
||||
else
|
||||
{
|
||||
inv.ItemDesc = "Bitwarden";
|
||||
}
|
||||
|
||||
inv.PosData = posData;
|
||||
return inv;
|
||||
var posData = string.Empty;
|
||||
if (UserId.HasValue)
|
||||
{
|
||||
posData = "userId:" + UserId.Value;
|
||||
}
|
||||
else if (OrganizationId.HasValue)
|
||||
{
|
||||
posData = "organizationId:" + OrganizationId.Value;
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
if (Credit)
|
||||
{
|
||||
if (!UserId.HasValue && !OrganizationId.HasValue)
|
||||
{
|
||||
yield return new ValidationResult("User or Ooganization is required.");
|
||||
}
|
||||
posData += ",accountCredit:1";
|
||||
inv.ItemDesc = "Bitwarden Account Credit";
|
||||
}
|
||||
else
|
||||
{
|
||||
inv.ItemDesc = "Bitwarden";
|
||||
}
|
||||
|
||||
inv.PosData = posData;
|
||||
return inv;
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (!UserId.HasValue && !OrganizationId.HasValue)
|
||||
{
|
||||
yield return new ValidationResult("User or Ooganization is required.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class CipherPartialRequestModel
|
||||
{
|
||||
public class CipherPartialRequestModel
|
||||
{
|
||||
[StringLength(36)]
|
||||
public string FolderId { get; set; }
|
||||
public bool Favorite { get; set; }
|
||||
}
|
||||
[StringLength(36)]
|
||||
public string FolderId { get; set; }
|
||||
public bool Favorite { get; set; }
|
||||
}
|
||||
|
@ -8,342 +8,341 @@ using Core.Models.Data;
|
||||
using NS = Newtonsoft.Json;
|
||||
using NSL = Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class CipherRequestModel
|
||||
{
|
||||
public class CipherRequestModel
|
||||
public CipherType Type { get; set; }
|
||||
|
||||
[StringLength(36)]
|
||||
public string OrganizationId { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public bool Favorite { get; set; }
|
||||
public CipherRepromptType Reprompt { get; set; }
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Name { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(10000)]
|
||||
public string Notes { get; set; }
|
||||
public IEnumerable<CipherFieldModel> Fields { get; set; }
|
||||
public IEnumerable<CipherPasswordHistoryModel> PasswordHistory { get; set; }
|
||||
[Obsolete]
|
||||
public Dictionary<string, string> Attachments { get; set; }
|
||||
// TODO: Rename to Attachments whenever the above is finally removed.
|
||||
public Dictionary<string, CipherAttachmentModel> Attachments2 { get; set; }
|
||||
|
||||
public CipherLoginModel Login { get; set; }
|
||||
public CipherCardModel Card { get; set; }
|
||||
public CipherIdentityModel Identity { get; set; }
|
||||
public CipherSecureNoteModel SecureNote { get; set; }
|
||||
public DateTime? LastKnownRevisionDate { get; set; } = null;
|
||||
|
||||
public CipherDetails ToCipherDetails(Guid userId, bool allowOrgIdSet = true)
|
||||
{
|
||||
public CipherType Type { get; set; }
|
||||
|
||||
[StringLength(36)]
|
||||
public string OrganizationId { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public bool Favorite { get; set; }
|
||||
public CipherRepromptType Reprompt { get; set; }
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Name { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(10000)]
|
||||
public string Notes { get; set; }
|
||||
public IEnumerable<CipherFieldModel> Fields { get; set; }
|
||||
public IEnumerable<CipherPasswordHistoryModel> PasswordHistory { get; set; }
|
||||
[Obsolete]
|
||||
public Dictionary<string, string> Attachments { get; set; }
|
||||
// TODO: Rename to Attachments whenever the above is finally removed.
|
||||
public Dictionary<string, CipherAttachmentModel> Attachments2 { get; set; }
|
||||
|
||||
public CipherLoginModel Login { get; set; }
|
||||
public CipherCardModel Card { get; set; }
|
||||
public CipherIdentityModel Identity { get; set; }
|
||||
public CipherSecureNoteModel SecureNote { get; set; }
|
||||
public DateTime? LastKnownRevisionDate { get; set; } = null;
|
||||
|
||||
public CipherDetails ToCipherDetails(Guid userId, bool allowOrgIdSet = true)
|
||||
var hasOrgId = !string.IsNullOrWhiteSpace(OrganizationId);
|
||||
var cipher = new CipherDetails
|
||||
{
|
||||
var hasOrgId = !string.IsNullOrWhiteSpace(OrganizationId);
|
||||
var cipher = new CipherDetails
|
||||
{
|
||||
Type = Type,
|
||||
UserId = !hasOrgId ? (Guid?)userId : null,
|
||||
OrganizationId = allowOrgIdSet && hasOrgId ? new Guid(OrganizationId) : (Guid?)null,
|
||||
Edit = true,
|
||||
ViewPassword = true,
|
||||
};
|
||||
ToCipherDetails(cipher);
|
||||
return cipher;
|
||||
Type = Type,
|
||||
UserId = !hasOrgId ? (Guid?)userId : null,
|
||||
OrganizationId = allowOrgIdSet && hasOrgId ? new Guid(OrganizationId) : (Guid?)null,
|
||||
Edit = true,
|
||||
ViewPassword = true,
|
||||
};
|
||||
ToCipherDetails(cipher);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
public CipherDetails ToCipherDetails(CipherDetails existingCipher)
|
||||
{
|
||||
existingCipher.FolderId = string.IsNullOrWhiteSpace(FolderId) ? null : (Guid?)new Guid(FolderId);
|
||||
existingCipher.Favorite = Favorite;
|
||||
ToCipher(existingCipher);
|
||||
return existingCipher;
|
||||
}
|
||||
|
||||
public Cipher ToCipher(Cipher existingCipher)
|
||||
{
|
||||
switch (existingCipher.Type)
|
||||
{
|
||||
case CipherType.Login:
|
||||
var loginObj = NSL.JObject.FromObject(ToCipherLoginData(),
|
||||
new NS.JsonSerializer { NullValueHandling = NS.NullValueHandling.Ignore });
|
||||
// TODO: Switch to JsonNode in .NET 6 https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-use-dom-utf8jsonreader-utf8jsonwriter?pivots=dotnet-6-0
|
||||
loginObj[nameof(CipherLoginData.Uri)]?.Parent?.Remove();
|
||||
existingCipher.Data = loginObj.ToString(NS.Formatting.None);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherCardData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherIdentityData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherSecureNoteData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
||||
}
|
||||
|
||||
public CipherDetails ToCipherDetails(CipherDetails existingCipher)
|
||||
existingCipher.Reprompt = Reprompt;
|
||||
|
||||
var hasAttachments2 = (Attachments2?.Count ?? 0) > 0;
|
||||
var hasAttachments = (Attachments?.Count ?? 0) > 0;
|
||||
|
||||
if (!hasAttachments2 && !hasAttachments)
|
||||
{
|
||||
existingCipher.FolderId = string.IsNullOrWhiteSpace(FolderId) ? null : (Guid?)new Guid(FolderId);
|
||||
existingCipher.Favorite = Favorite;
|
||||
ToCipher(existingCipher);
|
||||
return existingCipher;
|
||||
}
|
||||
|
||||
public Cipher ToCipher(Cipher existingCipher)
|
||||
var attachments = existingCipher.GetAttachments();
|
||||
if ((attachments?.Count ?? 0) == 0)
|
||||
{
|
||||
switch (existingCipher.Type)
|
||||
{
|
||||
case CipherType.Login:
|
||||
var loginObj = NSL.JObject.FromObject(ToCipherLoginData(),
|
||||
new NS.JsonSerializer { NullValueHandling = NS.NullValueHandling.Ignore });
|
||||
// TODO: Switch to JsonNode in .NET 6 https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-use-dom-utf8jsonreader-utf8jsonwriter?pivots=dotnet-6-0
|
||||
loginObj[nameof(CipherLoginData.Uri)]?.Parent?.Remove();
|
||||
existingCipher.Data = loginObj.ToString(NS.Formatting.None);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherCardData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherIdentityData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherSecureNoteData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
||||
}
|
||||
|
||||
existingCipher.Reprompt = Reprompt;
|
||||
|
||||
var hasAttachments2 = (Attachments2?.Count ?? 0) > 0;
|
||||
var hasAttachments = (Attachments?.Count ?? 0) > 0;
|
||||
|
||||
if (!hasAttachments2 && !hasAttachments)
|
||||
{
|
||||
return existingCipher;
|
||||
}
|
||||
|
||||
var attachments = existingCipher.GetAttachments();
|
||||
if ((attachments?.Count ?? 0) == 0)
|
||||
{
|
||||
return existingCipher;
|
||||
}
|
||||
|
||||
if (hasAttachments2)
|
||||
{
|
||||
foreach (var attachment in attachments.Where(a => Attachments2.ContainsKey(a.Key)))
|
||||
{
|
||||
var attachment2 = Attachments2[attachment.Key];
|
||||
attachment.Value.FileName = attachment2.FileName;
|
||||
attachment.Value.Key = attachment2.Key;
|
||||
}
|
||||
}
|
||||
else if (hasAttachments)
|
||||
{
|
||||
foreach (var attachment in attachments.Where(a => Attachments.ContainsKey(a.Key)))
|
||||
{
|
||||
attachment.Value.FileName = Attachments[attachment.Key];
|
||||
attachment.Value.Key = null;
|
||||
}
|
||||
}
|
||||
|
||||
existingCipher.SetAttachments(attachments);
|
||||
return existingCipher;
|
||||
}
|
||||
|
||||
public Cipher ToOrganizationCipher()
|
||||
if (hasAttachments2)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(OrganizationId))
|
||||
foreach (var attachment in attachments.Where(a => Attachments2.ContainsKey(a.Key)))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(OrganizationId));
|
||||
}
|
||||
|
||||
return ToCipher(new Cipher
|
||||
{
|
||||
Type = Type,
|
||||
OrganizationId = new Guid(OrganizationId)
|
||||
});
|
||||
}
|
||||
|
||||
public CipherDetails ToOrganizationCipherDetails(Guid orgId)
|
||||
{
|
||||
return ToCipherDetails(new CipherDetails
|
||||
{
|
||||
Type = Type,
|
||||
OrganizationId = orgId,
|
||||
Edit = true
|
||||
});
|
||||
}
|
||||
|
||||
private CipherLoginData ToCipherLoginData()
|
||||
{
|
||||
return new CipherLoginData
|
||||
{
|
||||
Name = Name,
|
||||
Notes = Notes,
|
||||
Fields = Fields?.Select(f => f.ToCipherFieldData()),
|
||||
PasswordHistory = PasswordHistory?.Select(ph => ph.ToCipherPasswordHistoryData()),
|
||||
|
||||
Uris =
|
||||
Login.Uris?.Where(u => u != null)
|
||||
.Select(u => u.ToCipherLoginUriData()),
|
||||
Username = Login.Username,
|
||||
Password = Login.Password,
|
||||
PasswordRevisionDate = Login.PasswordRevisionDate,
|
||||
Totp = Login.Totp,
|
||||
AutofillOnPageLoad = Login.AutofillOnPageLoad,
|
||||
};
|
||||
}
|
||||
|
||||
private CipherIdentityData ToCipherIdentityData()
|
||||
{
|
||||
return new CipherIdentityData
|
||||
{
|
||||
Name = Name,
|
||||
Notes = Notes,
|
||||
Fields = Fields?.Select(f => f.ToCipherFieldData()),
|
||||
PasswordHistory = PasswordHistory?.Select(ph => ph.ToCipherPasswordHistoryData()),
|
||||
|
||||
Title = Identity.Title,
|
||||
FirstName = Identity.FirstName,
|
||||
MiddleName = Identity.MiddleName,
|
||||
LastName = Identity.LastName,
|
||||
Address1 = Identity.Address1,
|
||||
Address2 = Identity.Address2,
|
||||
Address3 = Identity.Address3,
|
||||
City = Identity.City,
|
||||
State = Identity.State,
|
||||
PostalCode = Identity.PostalCode,
|
||||
Country = Identity.Country,
|
||||
Company = Identity.Company,
|
||||
Email = Identity.Email,
|
||||
Phone = Identity.Phone,
|
||||
SSN = Identity.SSN,
|
||||
Username = Identity.Username,
|
||||
PassportNumber = Identity.PassportNumber,
|
||||
LicenseNumber = Identity.LicenseNumber,
|
||||
};
|
||||
}
|
||||
|
||||
private CipherCardData ToCipherCardData()
|
||||
{
|
||||
return new CipherCardData
|
||||
{
|
||||
Name = Name,
|
||||
Notes = Notes,
|
||||
Fields = Fields?.Select(f => f.ToCipherFieldData()),
|
||||
PasswordHistory = PasswordHistory?.Select(ph => ph.ToCipherPasswordHistoryData()),
|
||||
|
||||
CardholderName = Card.CardholderName,
|
||||
Brand = Card.Brand,
|
||||
Number = Card.Number,
|
||||
ExpMonth = Card.ExpMonth,
|
||||
ExpYear = Card.ExpYear,
|
||||
Code = Card.Code,
|
||||
};
|
||||
}
|
||||
|
||||
private CipherSecureNoteData ToCipherSecureNoteData()
|
||||
{
|
||||
return new CipherSecureNoteData
|
||||
{
|
||||
Name = Name,
|
||||
Notes = Notes,
|
||||
Fields = Fields?.Select(f => f.ToCipherFieldData()),
|
||||
PasswordHistory = PasswordHistory?.Select(ph => ph.ToCipherPasswordHistoryData()),
|
||||
|
||||
Type = SecureNote.Type,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class CipherWithIdRequestModel : CipherRequestModel
|
||||
{
|
||||
[Required]
|
||||
public Guid? Id { get; set; }
|
||||
}
|
||||
|
||||
public class CipherCreateRequestModel : IValidatableObject
|
||||
{
|
||||
public IEnumerable<Guid> CollectionIds { get; set; }
|
||||
[Required]
|
||||
public CipherRequestModel Cipher { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(Cipher.OrganizationId) && (!CollectionIds?.Any() ?? true))
|
||||
{
|
||||
yield return new ValidationResult("You must select at least one collection.",
|
||||
new string[] { nameof(CollectionIds) });
|
||||
var attachment2 = Attachments2[attachment.Key];
|
||||
attachment.Value.FileName = attachment2.FileName;
|
||||
attachment.Value.Key = attachment2.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CipherShareRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> CollectionIds { get; set; }
|
||||
[Required]
|
||||
public CipherRequestModel Cipher { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
else if (hasAttachments)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Cipher.OrganizationId))
|
||||
foreach (var attachment in attachments.Where(a => Attachments.ContainsKey(a.Key)))
|
||||
{
|
||||
yield return new ValidationResult("Cipher OrganizationId is required.",
|
||||
new string[] { nameof(Cipher.OrganizationId) });
|
||||
}
|
||||
|
||||
if (!CollectionIds?.Any() ?? true)
|
||||
{
|
||||
yield return new ValidationResult("You must select at least one collection.",
|
||||
new string[] { nameof(CollectionIds) });
|
||||
attachment.Value.FileName = Attachments[attachment.Key];
|
||||
attachment.Value.Key = null;
|
||||
}
|
||||
}
|
||||
|
||||
existingCipher.SetAttachments(attachments);
|
||||
return existingCipher;
|
||||
}
|
||||
|
||||
public class CipherCollectionsRequestModel
|
||||
public Cipher ToOrganizationCipher()
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> CollectionIds { get; set; }
|
||||
}
|
||||
|
||||
public class CipherBulkDeleteRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> Ids { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
}
|
||||
|
||||
public class CipherBulkRestoreRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> Ids { get; set; }
|
||||
}
|
||||
|
||||
public class CipherBulkMoveRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> Ids { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
}
|
||||
|
||||
public class CipherBulkShareRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> CollectionIds { get; set; }
|
||||
[Required]
|
||||
public IEnumerable<CipherWithIdRequestModel> Ciphers { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
if (string.IsNullOrWhiteSpace(OrganizationId))
|
||||
{
|
||||
if (!Ciphers?.Any() ?? true)
|
||||
{
|
||||
yield return new ValidationResult("You must select at least one cipher.",
|
||||
new string[] { nameof(Ciphers) });
|
||||
}
|
||||
else
|
||||
{
|
||||
var allHaveIds = true;
|
||||
var organizationIds = new HashSet<string>();
|
||||
foreach (var c in Ciphers)
|
||||
{
|
||||
organizationIds.Add(c.OrganizationId);
|
||||
if (allHaveIds)
|
||||
{
|
||||
allHaveIds = !(!c.Id.HasValue || string.IsNullOrWhiteSpace(c.OrganizationId));
|
||||
}
|
||||
}
|
||||
throw new ArgumentNullException(nameof(OrganizationId));
|
||||
}
|
||||
|
||||
if (!allHaveIds)
|
||||
{
|
||||
yield return new ValidationResult("All Ciphers must have an Id and OrganizationId.",
|
||||
new string[] { nameof(Ciphers) });
|
||||
}
|
||||
else if (organizationIds.Count != 1)
|
||||
{
|
||||
yield return new ValidationResult("All ciphers must be for the same organization.");
|
||||
}
|
||||
}
|
||||
return ToCipher(new Cipher
|
||||
{
|
||||
Type = Type,
|
||||
OrganizationId = new Guid(OrganizationId)
|
||||
});
|
||||
}
|
||||
|
||||
if (!CollectionIds?.Any() ?? true)
|
||||
{
|
||||
yield return new ValidationResult("You must select at least one collection.",
|
||||
new string[] { nameof(CollectionIds) });
|
||||
}
|
||||
public CipherDetails ToOrganizationCipherDetails(Guid orgId)
|
||||
{
|
||||
return ToCipherDetails(new CipherDetails
|
||||
{
|
||||
Type = Type,
|
||||
OrganizationId = orgId,
|
||||
Edit = true
|
||||
});
|
||||
}
|
||||
|
||||
private CipherLoginData ToCipherLoginData()
|
||||
{
|
||||
return new CipherLoginData
|
||||
{
|
||||
Name = Name,
|
||||
Notes = Notes,
|
||||
Fields = Fields?.Select(f => f.ToCipherFieldData()),
|
||||
PasswordHistory = PasswordHistory?.Select(ph => ph.ToCipherPasswordHistoryData()),
|
||||
|
||||
Uris =
|
||||
Login.Uris?.Where(u => u != null)
|
||||
.Select(u => u.ToCipherLoginUriData()),
|
||||
Username = Login.Username,
|
||||
Password = Login.Password,
|
||||
PasswordRevisionDate = Login.PasswordRevisionDate,
|
||||
Totp = Login.Totp,
|
||||
AutofillOnPageLoad = Login.AutofillOnPageLoad,
|
||||
};
|
||||
}
|
||||
|
||||
private CipherIdentityData ToCipherIdentityData()
|
||||
{
|
||||
return new CipherIdentityData
|
||||
{
|
||||
Name = Name,
|
||||
Notes = Notes,
|
||||
Fields = Fields?.Select(f => f.ToCipherFieldData()),
|
||||
PasswordHistory = PasswordHistory?.Select(ph => ph.ToCipherPasswordHistoryData()),
|
||||
|
||||
Title = Identity.Title,
|
||||
FirstName = Identity.FirstName,
|
||||
MiddleName = Identity.MiddleName,
|
||||
LastName = Identity.LastName,
|
||||
Address1 = Identity.Address1,
|
||||
Address2 = Identity.Address2,
|
||||
Address3 = Identity.Address3,
|
||||
City = Identity.City,
|
||||
State = Identity.State,
|
||||
PostalCode = Identity.PostalCode,
|
||||
Country = Identity.Country,
|
||||
Company = Identity.Company,
|
||||
Email = Identity.Email,
|
||||
Phone = Identity.Phone,
|
||||
SSN = Identity.SSN,
|
||||
Username = Identity.Username,
|
||||
PassportNumber = Identity.PassportNumber,
|
||||
LicenseNumber = Identity.LicenseNumber,
|
||||
};
|
||||
}
|
||||
|
||||
private CipherCardData ToCipherCardData()
|
||||
{
|
||||
return new CipherCardData
|
||||
{
|
||||
Name = Name,
|
||||
Notes = Notes,
|
||||
Fields = Fields?.Select(f => f.ToCipherFieldData()),
|
||||
PasswordHistory = PasswordHistory?.Select(ph => ph.ToCipherPasswordHistoryData()),
|
||||
|
||||
CardholderName = Card.CardholderName,
|
||||
Brand = Card.Brand,
|
||||
Number = Card.Number,
|
||||
ExpMonth = Card.ExpMonth,
|
||||
ExpYear = Card.ExpYear,
|
||||
Code = Card.Code,
|
||||
};
|
||||
}
|
||||
|
||||
private CipherSecureNoteData ToCipherSecureNoteData()
|
||||
{
|
||||
return new CipherSecureNoteData
|
||||
{
|
||||
Name = Name,
|
||||
Notes = Notes,
|
||||
Fields = Fields?.Select(f => f.ToCipherFieldData()),
|
||||
PasswordHistory = PasswordHistory?.Select(ph => ph.ToCipherPasswordHistoryData()),
|
||||
|
||||
Type = SecureNote.Type,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class CipherWithIdRequestModel : CipherRequestModel
|
||||
{
|
||||
[Required]
|
||||
public Guid? Id { get; set; }
|
||||
}
|
||||
|
||||
public class CipherCreateRequestModel : IValidatableObject
|
||||
{
|
||||
public IEnumerable<Guid> CollectionIds { get; set; }
|
||||
[Required]
|
||||
public CipherRequestModel Cipher { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(Cipher.OrganizationId) && (!CollectionIds?.Any() ?? true))
|
||||
{
|
||||
yield return new ValidationResult("You must select at least one collection.",
|
||||
new string[] { nameof(CollectionIds) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CipherShareRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> CollectionIds { get; set; }
|
||||
[Required]
|
||||
public CipherRequestModel Cipher { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Cipher.OrganizationId))
|
||||
{
|
||||
yield return new ValidationResult("Cipher OrganizationId is required.",
|
||||
new string[] { nameof(Cipher.OrganizationId) });
|
||||
}
|
||||
|
||||
if (!CollectionIds?.Any() ?? true)
|
||||
{
|
||||
yield return new ValidationResult("You must select at least one collection.",
|
||||
new string[] { nameof(CollectionIds) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CipherCollectionsRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> CollectionIds { get; set; }
|
||||
}
|
||||
|
||||
public class CipherBulkDeleteRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> Ids { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
}
|
||||
|
||||
public class CipherBulkRestoreRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> Ids { get; set; }
|
||||
}
|
||||
|
||||
public class CipherBulkMoveRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> Ids { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
}
|
||||
|
||||
public class CipherBulkShareRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> CollectionIds { get; set; }
|
||||
[Required]
|
||||
public IEnumerable<CipherWithIdRequestModel> Ciphers { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (!Ciphers?.Any() ?? true)
|
||||
{
|
||||
yield return new ValidationResult("You must select at least one cipher.",
|
||||
new string[] { nameof(Ciphers) });
|
||||
}
|
||||
else
|
||||
{
|
||||
var allHaveIds = true;
|
||||
var organizationIds = new HashSet<string>();
|
||||
foreach (var c in Ciphers)
|
||||
{
|
||||
organizationIds.Add(c.OrganizationId);
|
||||
if (allHaveIds)
|
||||
{
|
||||
allHaveIds = !(!c.Id.HasValue || string.IsNullOrWhiteSpace(c.OrganizationId));
|
||||
}
|
||||
}
|
||||
|
||||
if (!allHaveIds)
|
||||
{
|
||||
yield return new ValidationResult("All Ciphers must have an Id and OrganizationId.",
|
||||
new string[] { nameof(Ciphers) });
|
||||
}
|
||||
else if (organizationIds.Count != 1)
|
||||
{
|
||||
yield return new ValidationResult("All ciphers must be for the same organization.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!CollectionIds?.Any() ?? true)
|
||||
{
|
||||
yield return new ValidationResult("You must select at least one collection.",
|
||||
new string[] { nameof(CollectionIds) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,31 +2,30 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class CollectionRequestModel
|
||||
{
|
||||
public class CollectionRequestModel
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Name { get; set; }
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
public IEnumerable<SelectionReadOnlyRequestModel> Groups { get; set; }
|
||||
|
||||
public Collection ToCollection(Guid orgId)
|
||||
{
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Name { get; set; }
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
public IEnumerable<SelectionReadOnlyRequestModel> Groups { get; set; }
|
||||
|
||||
public Collection ToCollection(Guid orgId)
|
||||
return ToCollection(new Collection
|
||||
{
|
||||
return ToCollection(new Collection
|
||||
{
|
||||
OrganizationId = orgId
|
||||
});
|
||||
}
|
||||
OrganizationId = orgId
|
||||
});
|
||||
}
|
||||
|
||||
public Collection ToCollection(Collection existingCollection)
|
||||
{
|
||||
existingCollection.Name = Name;
|
||||
existingCollection.ExternalId = ExternalId;
|
||||
return existingCollection;
|
||||
}
|
||||
public Collection ToCollection(Collection existingCollection)
|
||||
{
|
||||
existingCollection.Name = Name;
|
||||
existingCollection.ExternalId = ExternalId;
|
||||
return existingCollection;
|
||||
}
|
||||
}
|
||||
|
@ -2,49 +2,48 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class DeviceRequestModel
|
||||
{
|
||||
public class DeviceRequestModel
|
||||
[Required]
|
||||
public DeviceType? Type { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Identifier { get; set; }
|
||||
[StringLength(255)]
|
||||
public string PushToken { get; set; }
|
||||
|
||||
public Device ToDevice(Guid? userId = null)
|
||||
{
|
||||
[Required]
|
||||
public DeviceType? Type { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Identifier { get; set; }
|
||||
[StringLength(255)]
|
||||
public string PushToken { get; set; }
|
||||
|
||||
public Device ToDevice(Guid? userId = null)
|
||||
return ToDevice(new Device
|
||||
{
|
||||
return ToDevice(new Device
|
||||
{
|
||||
UserId = userId == null ? default(Guid) : userId.Value
|
||||
});
|
||||
}
|
||||
|
||||
public Device ToDevice(Device existingDevice)
|
||||
{
|
||||
existingDevice.Name = Name;
|
||||
existingDevice.Identifier = Identifier;
|
||||
existingDevice.PushToken = PushToken;
|
||||
existingDevice.Type = Type.Value;
|
||||
|
||||
return existingDevice;
|
||||
}
|
||||
UserId = userId == null ? default(Guid) : userId.Value
|
||||
});
|
||||
}
|
||||
|
||||
public class DeviceTokenRequestModel
|
||||
public Device ToDevice(Device existingDevice)
|
||||
{
|
||||
[StringLength(255)]
|
||||
public string PushToken { get; set; }
|
||||
existingDevice.Name = Name;
|
||||
existingDevice.Identifier = Identifier;
|
||||
existingDevice.PushToken = PushToken;
|
||||
existingDevice.Type = Type.Value;
|
||||
|
||||
public Device ToDevice(Device existingDevice)
|
||||
{
|
||||
existingDevice.PushToken = PushToken;
|
||||
return existingDevice;
|
||||
}
|
||||
return existingDevice;
|
||||
}
|
||||
}
|
||||
|
||||
public class DeviceTokenRequestModel
|
||||
{
|
||||
[StringLength(255)]
|
||||
public string PushToken { get; set; }
|
||||
|
||||
public Device ToDevice(Device existingDevice)
|
||||
{
|
||||
existingDevice.PushToken = PushToken;
|
||||
return existingDevice;
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Entities;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
{
|
||||
public class DeviceVerificationRequestModel
|
||||
{
|
||||
[Required]
|
||||
public bool UnknownDeviceVerificationEnabled { get; set; }
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public User ToUser(User user)
|
||||
{
|
||||
user.UnknownDeviceVerificationEnabled = UnknownDeviceVerificationEnabled;
|
||||
return user;
|
||||
}
|
||||
public class DeviceVerificationRequestModel
|
||||
{
|
||||
[Required]
|
||||
public bool UnknownDeviceVerificationEnabled { get; set; }
|
||||
|
||||
public User ToUser(User user)
|
||||
{
|
||||
user.UnknownDeviceVerificationEnabled = UnknownDeviceVerificationEnabled;
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
@ -3,47 +3,46 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class EmergencyAccessInviteRequestModel
|
||||
{
|
||||
public class EmergencyAccessInviteRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StrictEmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
[Required]
|
||||
public EmergencyAccessType? Type { get; set; }
|
||||
[Required]
|
||||
public int WaitTimeDays { get; set; }
|
||||
}
|
||||
[Required]
|
||||
[StrictEmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
[Required]
|
||||
public EmergencyAccessType? Type { get; set; }
|
||||
[Required]
|
||||
public int WaitTimeDays { get; set; }
|
||||
}
|
||||
|
||||
public class EmergencyAccessUpdateRequestModel
|
||||
{
|
||||
[Required]
|
||||
public EmergencyAccessType Type { get; set; }
|
||||
[Required]
|
||||
public int WaitTimeDays { get; set; }
|
||||
public string KeyEncrypted { get; set; }
|
||||
public class EmergencyAccessUpdateRequestModel
|
||||
{
|
||||
[Required]
|
||||
public EmergencyAccessType Type { get; set; }
|
||||
[Required]
|
||||
public int WaitTimeDays { get; set; }
|
||||
public string KeyEncrypted { get; set; }
|
||||
|
||||
public EmergencyAccess ToEmergencyAccess(EmergencyAccess existingEmergencyAccess)
|
||||
public EmergencyAccess ToEmergencyAccess(EmergencyAccess existingEmergencyAccess)
|
||||
{
|
||||
// Ensure we only set keys for a confirmed emergency access.
|
||||
if (!string.IsNullOrWhiteSpace(existingEmergencyAccess.KeyEncrypted) && !string.IsNullOrWhiteSpace(KeyEncrypted))
|
||||
{
|
||||
// Ensure we only set keys for a confirmed emergency access.
|
||||
if (!string.IsNullOrWhiteSpace(existingEmergencyAccess.KeyEncrypted) && !string.IsNullOrWhiteSpace(KeyEncrypted))
|
||||
{
|
||||
existingEmergencyAccess.KeyEncrypted = KeyEncrypted;
|
||||
}
|
||||
existingEmergencyAccess.Type = Type;
|
||||
existingEmergencyAccess.WaitTimeDays = WaitTimeDays;
|
||||
return existingEmergencyAccess;
|
||||
existingEmergencyAccess.KeyEncrypted = KeyEncrypted;
|
||||
}
|
||||
}
|
||||
|
||||
public class EmergencyAccessPasswordRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string NewMasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
existingEmergencyAccess.Type = Type;
|
||||
existingEmergencyAccess.WaitTimeDays = WaitTimeDays;
|
||||
return existingEmergencyAccess;
|
||||
}
|
||||
}
|
||||
|
||||
public class EmergencyAccessPasswordRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string NewMasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
@ -2,32 +2,31 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class FolderRequestModel
|
||||
{
|
||||
public class FolderRequestModel
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Name { get; set; }
|
||||
|
||||
public Folder ToFolder(Guid userId)
|
||||
{
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Name { get; set; }
|
||||
|
||||
public Folder ToFolder(Guid userId)
|
||||
return ToFolder(new Folder
|
||||
{
|
||||
return ToFolder(new Folder
|
||||
{
|
||||
UserId = userId
|
||||
});
|
||||
}
|
||||
|
||||
public Folder ToFolder(Folder existingFolder)
|
||||
{
|
||||
existingFolder.Name = Name;
|
||||
return existingFolder;
|
||||
}
|
||||
UserId = userId
|
||||
});
|
||||
}
|
||||
|
||||
public class FolderWithIdRequestModel : FolderRequestModel
|
||||
public Folder ToFolder(Folder existingFolder)
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
existingFolder.Name = Name;
|
||||
return existingFolder;
|
||||
}
|
||||
}
|
||||
|
||||
public class FolderWithIdRequestModel : FolderRequestModel
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
}
|
||||
|
@ -1,33 +1,32 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Entities;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class GroupRequestModel
|
||||
{
|
||||
public class GroupRequestModel
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
public bool? AccessAll { get; set; }
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
public IEnumerable<SelectionReadOnlyRequestModel> Collections { get; set; }
|
||||
|
||||
public Group ToGroup(Guid orgId)
|
||||
{
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
public bool? AccessAll { get; set; }
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
public IEnumerable<SelectionReadOnlyRequestModel> Collections { get; set; }
|
||||
|
||||
public Group ToGroup(Guid orgId)
|
||||
return ToGroup(new Group
|
||||
{
|
||||
return ToGroup(new Group
|
||||
{
|
||||
OrganizationId = orgId
|
||||
});
|
||||
}
|
||||
OrganizationId = orgId
|
||||
});
|
||||
}
|
||||
|
||||
public Group ToGroup(Group existingGroup)
|
||||
{
|
||||
existingGroup.Name = Name;
|
||||
existingGroup.AccessAll = AccessAll.Value;
|
||||
existingGroup.ExternalId = ExternalId;
|
||||
return existingGroup;
|
||||
}
|
||||
public Group ToGroup(Group existingGroup)
|
||||
{
|
||||
existingGroup.Name = Name;
|
||||
existingGroup.AccessAll = AccessAll.Value;
|
||||
existingGroup.ExternalId = ExternalId;
|
||||
return existingGroup;
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Enums = Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
{
|
||||
public class IapCheckRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public Enums.PaymentMethodType? PaymentMethodType { get; set; }
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
public class IapCheckRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public Enums.PaymentMethodType? PaymentMethodType { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (PaymentMethodType != Enums.PaymentMethodType.AppleInApp)
|
||||
{
|
||||
if (PaymentMethodType != Enums.PaymentMethodType.AppleInApp)
|
||||
{
|
||||
yield return new ValidationResult("Not a supported in-app purchase payment method.",
|
||||
new string[] { nameof(PaymentMethodType) });
|
||||
}
|
||||
yield return new ValidationResult("Not a supported in-app purchase payment method.",
|
||||
new string[] { nameof(PaymentMethodType) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,23 +2,22 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
{
|
||||
public class InstallationRequestModel
|
||||
{
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public Installation ToInstallation()
|
||||
public class InstallationRequestModel
|
||||
{
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
|
||||
public Installation ToInstallation()
|
||||
{
|
||||
return new Installation
|
||||
{
|
||||
return new Installation
|
||||
{
|
||||
Key = CoreHelpers.SecureRandomString(20),
|
||||
Email = Email,
|
||||
Enabled = true
|
||||
};
|
||||
}
|
||||
Key = CoreHelpers.SecureRandomString(20),
|
||||
Email = Email,
|
||||
Enabled = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class LicenseRequestModel
|
||||
{
|
||||
public class LicenseRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IFormFile License { get; set; }
|
||||
}
|
||||
[Required]
|
||||
public IFormFile License { get; set; }
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class ImportOrganizationCiphersRequestModel
|
||||
{
|
||||
public class ImportOrganizationCiphersRequestModel
|
||||
{
|
||||
public CollectionRequestModel[] Collections { get; set; }
|
||||
public CipherRequestModel[] Ciphers { get; set; }
|
||||
public KeyValuePair<int, int>[] CollectionRelationships { get; set; }
|
||||
}
|
||||
public CollectionRequestModel[] Collections { get; set; }
|
||||
public CipherRequestModel[] Ciphers { get; set; }
|
||||
public KeyValuePair<int, int>[] CollectionRelationships { get; set; }
|
||||
}
|
||||
|
@ -1,69 +1,68 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Models.Business;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class ImportOrganizationUsersRequestModel
|
||||
{
|
||||
public class ImportOrganizationUsersRequestModel
|
||||
public Group[] Groups { get; set; }
|
||||
public User[] Users { get; set; }
|
||||
public bool OverwriteExisting { get; set; }
|
||||
public bool LargeImport { get; set; }
|
||||
|
||||
public class Group
|
||||
{
|
||||
public Group[] Groups { get; set; }
|
||||
public User[] Users { get; set; }
|
||||
public bool OverwriteExisting { get; set; }
|
||||
public bool LargeImport { get; set; }
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
public IEnumerable<string> Users { get; set; }
|
||||
|
||||
public class Group
|
||||
public ImportedGroup ToImportedGroup(Guid organizationId)
|
||||
{
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
public IEnumerable<string> Users { get; set; }
|
||||
|
||||
public ImportedGroup ToImportedGroup(Guid organizationId)
|
||||
var importedGroup = new ImportedGroup
|
||||
{
|
||||
var importedGroup = new ImportedGroup
|
||||
Group = new Core.Entities.Group
|
||||
{
|
||||
Group = new Core.Entities.Group
|
||||
{
|
||||
OrganizationId = organizationId,
|
||||
Name = Name,
|
||||
ExternalId = ExternalId
|
||||
},
|
||||
ExternalUserIds = new HashSet<string>(Users)
|
||||
};
|
||||
OrganizationId = organizationId,
|
||||
Name = Name,
|
||||
ExternalId = ExternalId
|
||||
},
|
||||
ExternalUserIds = new HashSet<string>(Users)
|
||||
};
|
||||
|
||||
return importedGroup;
|
||||
}
|
||||
return importedGroup;
|
||||
}
|
||||
}
|
||||
|
||||
public class User : IValidatableObject
|
||||
{
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
public bool Deleted { get; set; }
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
|
||||
public ImportedOrganizationUser ToImportedOrganizationUser()
|
||||
{
|
||||
var importedUser = new ImportedOrganizationUser
|
||||
{
|
||||
Email = Email.ToLowerInvariant(),
|
||||
ExternalId = ExternalId
|
||||
};
|
||||
|
||||
return importedUser;
|
||||
}
|
||||
|
||||
public class User : IValidatableObject
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
public bool Deleted { get; set; }
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
|
||||
public ImportedOrganizationUser ToImportedOrganizationUser()
|
||||
if (string.IsNullOrWhiteSpace(Email) && !Deleted)
|
||||
{
|
||||
var importedUser = new ImportedOrganizationUser
|
||||
{
|
||||
Email = Email.ToLowerInvariant(),
|
||||
ExternalId = ExternalId
|
||||
};
|
||||
|
||||
return importedUser;
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Email) && !Deleted)
|
||||
{
|
||||
yield return new ValidationResult("Email is required for enabled users.", new string[] { nameof(Email) });
|
||||
}
|
||||
yield return new ValidationResult("Email is required for enabled users.", new string[] { nameof(Email) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,48 +4,47 @@ using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationConnections;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationConnectionRequestModel
|
||||
{
|
||||
public class OrganizationConnectionRequestModel
|
||||
{
|
||||
public OrganizationConnectionType Type { get; set; }
|
||||
public Guid OrganizationId { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public JsonDocument Config { get; set; }
|
||||
public OrganizationConnectionType Type { get; set; }
|
||||
public Guid OrganizationId { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public JsonDocument Config { get; set; }
|
||||
|
||||
public OrganizationConnectionRequestModel() { }
|
||||
}
|
||||
|
||||
|
||||
public class OrganizationConnectionRequestModel<T> : OrganizationConnectionRequestModel where T : new()
|
||||
{
|
||||
public T ParsedConfig { get; private set; }
|
||||
|
||||
public OrganizationConnectionRequestModel(OrganizationConnectionRequestModel model)
|
||||
{
|
||||
Type = model.Type;
|
||||
OrganizationId = model.OrganizationId;
|
||||
Enabled = model.Enabled;
|
||||
Config = model.Config;
|
||||
|
||||
try
|
||||
{
|
||||
ParsedConfig = model.Config.ToObject<T>(JsonHelpers.IgnoreCase);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
throw new BadRequestException("Organization Connection configuration malformed");
|
||||
}
|
||||
}
|
||||
|
||||
public OrganizationConnectionData<T> ToData(Guid? id = null) =>
|
||||
new()
|
||||
{
|
||||
Id = id,
|
||||
Type = Type,
|
||||
OrganizationId = OrganizationId,
|
||||
Enabled = Enabled,
|
||||
Config = ParsedConfig,
|
||||
};
|
||||
}
|
||||
public OrganizationConnectionRequestModel() { }
|
||||
}
|
||||
|
||||
|
||||
public class OrganizationConnectionRequestModel<T> : OrganizationConnectionRequestModel where T : new()
|
||||
{
|
||||
public T ParsedConfig { get; private set; }
|
||||
|
||||
public OrganizationConnectionRequestModel(OrganizationConnectionRequestModel model)
|
||||
{
|
||||
Type = model.Type;
|
||||
OrganizationId = model.OrganizationId;
|
||||
Enabled = model.Enabled;
|
||||
Config = model.Config;
|
||||
|
||||
try
|
||||
{
|
||||
ParsedConfig = model.Config.ToObject<T>(JsonHelpers.IgnoreCase);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
throw new BadRequestException("Organization Connection configuration malformed");
|
||||
}
|
||||
}
|
||||
|
||||
public OrganizationConnectionData<T> ToData(Guid? id = null) =>
|
||||
new()
|
||||
{
|
||||
Id = id,
|
||||
Type = Type,
|
||||
OrganizationId = OrganizationId,
|
||||
Enabled = Enabled,
|
||||
Config = ParsedConfig,
|
||||
};
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationCreateLicenseRequestModel : LicenseRequestModel
|
||||
{
|
||||
public class OrganizationCreateLicenseRequestModel : LicenseRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string CollectionName { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
}
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string CollectionName { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
}
|
||||
|
@ -4,99 +4,98 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationCreateRequestModel : IValidatableObject
|
||||
{
|
||||
public class OrganizationCreateRequestModel : IValidatableObject
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Name { get; set; }
|
||||
[StringLength(50)]
|
||||
public string BusinessName { get; set; }
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
[EmailAddress]
|
||||
public string BillingEmail { get; set; }
|
||||
public PlanType PlanType { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
public PaymentMethodType? PaymentMethodType { get; set; }
|
||||
public string PaymentToken { get; set; }
|
||||
[Range(0, int.MaxValue)]
|
||||
public int AdditionalSeats { get; set; }
|
||||
[Range(0, 99)]
|
||||
public short? AdditionalStorageGb { get; set; }
|
||||
public bool PremiumAccessAddon { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string CollectionName { get; set; }
|
||||
public string TaxIdNumber { get; set; }
|
||||
public string BillingAddressLine1 { get; set; }
|
||||
public string BillingAddressLine2 { get; set; }
|
||||
public string BillingAddressCity { get; set; }
|
||||
public string BillingAddressState { get; set; }
|
||||
public string BillingAddressPostalCode { get; set; }
|
||||
[StringLength(2)]
|
||||
public string BillingAddressCountry { get; set; }
|
||||
public int? MaxAutoscaleSeats { get; set; }
|
||||
|
||||
public virtual OrganizationSignup ToOrganizationSignup(User user)
|
||||
{
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Name { get; set; }
|
||||
[StringLength(50)]
|
||||
public string BusinessName { get; set; }
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
[EmailAddress]
|
||||
public string BillingEmail { get; set; }
|
||||
public PlanType PlanType { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
public PaymentMethodType? PaymentMethodType { get; set; }
|
||||
public string PaymentToken { get; set; }
|
||||
[Range(0, int.MaxValue)]
|
||||
public int AdditionalSeats { get; set; }
|
||||
[Range(0, 99)]
|
||||
public short? AdditionalStorageGb { get; set; }
|
||||
public bool PremiumAccessAddon { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string CollectionName { get; set; }
|
||||
public string TaxIdNumber { get; set; }
|
||||
public string BillingAddressLine1 { get; set; }
|
||||
public string BillingAddressLine2 { get; set; }
|
||||
public string BillingAddressCity { get; set; }
|
||||
public string BillingAddressState { get; set; }
|
||||
public string BillingAddressPostalCode { get; set; }
|
||||
[StringLength(2)]
|
||||
public string BillingAddressCountry { get; set; }
|
||||
public int? MaxAutoscaleSeats { get; set; }
|
||||
|
||||
public virtual OrganizationSignup ToOrganizationSignup(User user)
|
||||
var orgSignup = new OrganizationSignup
|
||||
{
|
||||
var orgSignup = new OrganizationSignup
|
||||
Owner = user,
|
||||
OwnerKey = Key,
|
||||
Name = Name,
|
||||
Plan = PlanType,
|
||||
PaymentMethodType = PaymentMethodType,
|
||||
PaymentToken = PaymentToken,
|
||||
AdditionalSeats = AdditionalSeats,
|
||||
MaxAutoscaleSeats = MaxAutoscaleSeats,
|
||||
AdditionalStorageGb = AdditionalStorageGb.GetValueOrDefault(0),
|
||||
PremiumAccessAddon = PremiumAccessAddon,
|
||||
BillingEmail = BillingEmail,
|
||||
BusinessName = BusinessName,
|
||||
CollectionName = CollectionName,
|
||||
TaxInfo = new TaxInfo
|
||||
{
|
||||
Owner = user,
|
||||
OwnerKey = Key,
|
||||
Name = Name,
|
||||
Plan = PlanType,
|
||||
PaymentMethodType = PaymentMethodType,
|
||||
PaymentToken = PaymentToken,
|
||||
AdditionalSeats = AdditionalSeats,
|
||||
MaxAutoscaleSeats = MaxAutoscaleSeats,
|
||||
AdditionalStorageGb = AdditionalStorageGb.GetValueOrDefault(0),
|
||||
PremiumAccessAddon = PremiumAccessAddon,
|
||||
BillingEmail = BillingEmail,
|
||||
BusinessName = BusinessName,
|
||||
CollectionName = CollectionName,
|
||||
TaxInfo = new TaxInfo
|
||||
{
|
||||
TaxIdNumber = TaxIdNumber,
|
||||
BillingAddressLine1 = BillingAddressLine1,
|
||||
BillingAddressLine2 = BillingAddressLine2,
|
||||
BillingAddressCity = BillingAddressCity,
|
||||
BillingAddressState = BillingAddressState,
|
||||
BillingAddressPostalCode = BillingAddressPostalCode,
|
||||
BillingAddressCountry = BillingAddressCountry,
|
||||
},
|
||||
};
|
||||
TaxIdNumber = TaxIdNumber,
|
||||
BillingAddressLine1 = BillingAddressLine1,
|
||||
BillingAddressLine2 = BillingAddressLine2,
|
||||
BillingAddressCity = BillingAddressCity,
|
||||
BillingAddressState = BillingAddressState,
|
||||
BillingAddressPostalCode = BillingAddressPostalCode,
|
||||
BillingAddressCountry = BillingAddressCountry,
|
||||
},
|
||||
};
|
||||
|
||||
Keys?.ToOrganizationSignup(orgSignup);
|
||||
Keys?.ToOrganizationSignup(orgSignup);
|
||||
|
||||
return orgSignup;
|
||||
return orgSignup;
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (PlanType != PlanType.Free && string.IsNullOrWhiteSpace(PaymentToken))
|
||||
{
|
||||
yield return new ValidationResult("Payment required.", new string[] { nameof(PaymentToken) });
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
if (PlanType != PlanType.Free && !PaymentMethodType.HasValue)
|
||||
{
|
||||
if (PlanType != PlanType.Free && string.IsNullOrWhiteSpace(PaymentToken))
|
||||
{
|
||||
yield return new ValidationResult("Payment required.", new string[] { nameof(PaymentToken) });
|
||||
}
|
||||
if (PlanType != PlanType.Free && !PaymentMethodType.HasValue)
|
||||
{
|
||||
yield return new ValidationResult("Payment method type required.",
|
||||
new string[] { nameof(PaymentMethodType) });
|
||||
}
|
||||
if (PlanType != PlanType.Free && string.IsNullOrWhiteSpace(BillingAddressCountry))
|
||||
{
|
||||
yield return new ValidationResult("Country required.",
|
||||
new string[] { nameof(BillingAddressCountry) });
|
||||
}
|
||||
if (PlanType != PlanType.Free && BillingAddressCountry == "US" &&
|
||||
string.IsNullOrWhiteSpace(BillingAddressPostalCode))
|
||||
{
|
||||
yield return new ValidationResult("Zip / postal code is required.",
|
||||
new string[] { nameof(BillingAddressPostalCode) });
|
||||
}
|
||||
yield return new ValidationResult("Payment method type required.",
|
||||
new string[] { nameof(PaymentMethodType) });
|
||||
}
|
||||
if (PlanType != PlanType.Free && string.IsNullOrWhiteSpace(BillingAddressCountry))
|
||||
{
|
||||
yield return new ValidationResult("Country required.",
|
||||
new string[] { nameof(BillingAddressCountry) });
|
||||
}
|
||||
if (PlanType != PlanType.Free && BillingAddressCountry == "US" &&
|
||||
string.IsNullOrWhiteSpace(BillingAddressPostalCode))
|
||||
{
|
||||
yield return new ValidationResult("Zip / postal code is required.",
|
||||
new string[] { nameof(BillingAddressPostalCode) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,58 +2,57 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Business;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationKeysRequestModel
|
||||
{
|
||||
public class OrganizationKeysRequestModel
|
||||
[Required]
|
||||
public string PublicKey { get; set; }
|
||||
[Required]
|
||||
public string EncryptedPrivateKey { get; set; }
|
||||
|
||||
public OrganizationSignup ToOrganizationSignup(OrganizationSignup existingSignup)
|
||||
{
|
||||
[Required]
|
||||
public string PublicKey { get; set; }
|
||||
[Required]
|
||||
public string EncryptedPrivateKey { get; set; }
|
||||
|
||||
public OrganizationSignup ToOrganizationSignup(OrganizationSignup existingSignup)
|
||||
if (string.IsNullOrWhiteSpace(existingSignup.PublicKey))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingSignup.PublicKey))
|
||||
{
|
||||
existingSignup.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingSignup.PrivateKey))
|
||||
{
|
||||
existingSignup.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
return existingSignup;
|
||||
existingSignup.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
public OrganizationUpgrade ToOrganizationUpgrade(OrganizationUpgrade existingUpgrade)
|
||||
if (string.IsNullOrWhiteSpace(existingSignup.PrivateKey))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingUpgrade.PublicKey))
|
||||
{
|
||||
existingUpgrade.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingUpgrade.PrivateKey))
|
||||
{
|
||||
existingUpgrade.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
return existingUpgrade;
|
||||
existingSignup.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
public Organization ToOrganization(Organization existingOrg)
|
||||
return existingSignup;
|
||||
}
|
||||
|
||||
public OrganizationUpgrade ToOrganizationUpgrade(OrganizationUpgrade existingUpgrade)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingUpgrade.PublicKey))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingOrg.PublicKey))
|
||||
{
|
||||
existingOrg.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingOrg.PrivateKey))
|
||||
{
|
||||
existingOrg.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
return existingOrg;
|
||||
existingUpgrade.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingUpgrade.PrivateKey))
|
||||
{
|
||||
existingUpgrade.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
return existingUpgrade;
|
||||
}
|
||||
|
||||
public Organization ToOrganization(Organization existingOrg)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingOrg.PublicKey))
|
||||
{
|
||||
existingOrg.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingOrg.PrivateKey))
|
||||
{
|
||||
existingOrg.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
return existingOrg;
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
{
|
||||
public class OrganizationSeatRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public int? SeatAdjustment { get; set; }
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
public class OrganizationSeatRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public int? SeatAdjustment { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (SeatAdjustment == 0)
|
||||
{
|
||||
if (SeatAdjustment == 0)
|
||||
{
|
||||
yield return new ValidationResult("Seat adjustment cannot be 0.", new string[] { nameof(SeatAdjustment) });
|
||||
}
|
||||
yield return new ValidationResult("Seat adjustment cannot be 0.", new string[] { nameof(SeatAdjustment) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,19 +2,18 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationSponsorshipCreateRequestModel
|
||||
{
|
||||
public class OrganizationSponsorshipCreateRequestModel
|
||||
{
|
||||
[Required]
|
||||
public PlanSponsorshipType PlanSponsorshipType { get; set; }
|
||||
[Required]
|
||||
public PlanSponsorshipType PlanSponsorshipType { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
[StrictEmailAddress]
|
||||
public string SponsoredEmail { get; set; }
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
[StrictEmailAddress]
|
||||
public string SponsoredEmail { get; set; }
|
||||
|
||||
[StringLength(256)]
|
||||
public string FriendlyName { get; set; }
|
||||
}
|
||||
[StringLength(256)]
|
||||
public string FriendlyName { get; set; }
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationSponsorshipRedeemRequestModel
|
||||
{
|
||||
public class OrganizationSponsorshipRedeemRequestModel
|
||||
{
|
||||
[Required]
|
||||
public PlanSponsorshipType PlanSponsorshipType { get; set; }
|
||||
[Required]
|
||||
public Guid SponsoredOrganizationId { get; set; }
|
||||
}
|
||||
[Required]
|
||||
public PlanSponsorshipType PlanSponsorshipType { get; set; }
|
||||
[Required]
|
||||
public Guid SponsoredOrganizationId { get; set; }
|
||||
}
|
||||
|
@ -10,216 +10,215 @@ using Bit.Core.Sso;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationSsoRequestModel
|
||||
{
|
||||
public class OrganizationSsoRequestModel
|
||||
[Required]
|
||||
public bool Enabled { get; set; }
|
||||
[Required]
|
||||
public SsoConfigurationDataRequest Data { get; set; }
|
||||
|
||||
public SsoConfig ToSsoConfig(Guid organizationId)
|
||||
{
|
||||
[Required]
|
||||
public bool Enabled { get; set; }
|
||||
[Required]
|
||||
public SsoConfigurationDataRequest Data { get; set; }
|
||||
|
||||
public SsoConfig ToSsoConfig(Guid organizationId)
|
||||
{
|
||||
return ToSsoConfig(new SsoConfig { OrganizationId = organizationId });
|
||||
}
|
||||
|
||||
public SsoConfig ToSsoConfig(SsoConfig existingConfig)
|
||||
{
|
||||
existingConfig.Enabled = Enabled;
|
||||
var configurationData = Data.ToConfigurationData();
|
||||
existingConfig.SetData(configurationData);
|
||||
return existingConfig;
|
||||
}
|
||||
return ToSsoConfig(new SsoConfig { OrganizationId = organizationId });
|
||||
}
|
||||
|
||||
public class SsoConfigurationDataRequest : IValidatableObject
|
||||
public SsoConfig ToSsoConfig(SsoConfig existingConfig)
|
||||
{
|
||||
public SsoConfigurationDataRequest() { }
|
||||
|
||||
[Required]
|
||||
public SsoType ConfigType { get; set; }
|
||||
|
||||
public bool KeyConnectorEnabled { get; set; }
|
||||
public string KeyConnectorUrl { get; set; }
|
||||
|
||||
// OIDC
|
||||
public string Authority { get; set; }
|
||||
public string ClientId { get; set; }
|
||||
public string ClientSecret { get; set; }
|
||||
public string MetadataAddress { get; set; }
|
||||
public OpenIdConnectRedirectBehavior RedirectBehavior { get; set; }
|
||||
public bool? GetClaimsFromUserInfoEndpoint { get; set; }
|
||||
public string AdditionalScopes { get; set; }
|
||||
public string AdditionalUserIdClaimTypes { get; set; }
|
||||
public string AdditionalEmailClaimTypes { get; set; }
|
||||
public string AdditionalNameClaimTypes { get; set; }
|
||||
public string AcrValues { get; set; }
|
||||
public string ExpectedReturnAcrValue { get; set; }
|
||||
|
||||
// SAML2 SP
|
||||
public Saml2NameIdFormat SpNameIdFormat { get; set; }
|
||||
public string SpOutboundSigningAlgorithm { get; set; }
|
||||
public Saml2SigningBehavior SpSigningBehavior { get; set; }
|
||||
public bool? SpWantAssertionsSigned { get; set; }
|
||||
public bool? SpValidateCertificates { get; set; }
|
||||
public string SpMinIncomingSigningAlgorithm { get; set; }
|
||||
|
||||
// SAML2 IDP
|
||||
public string IdpEntityId { get; set; }
|
||||
public Saml2BindingType IdpBindingType { get; set; }
|
||||
public string IdpSingleSignOnServiceUrl { get; set; }
|
||||
public string IdpSingleLogoutServiceUrl { get; set; }
|
||||
public string IdpArtifactResolutionServiceUrl { get => null; set { /*IGNORE*/ } }
|
||||
public string IdpX509PublicCert { get; set; }
|
||||
public string IdpOutboundSigningAlgorithm { get; set; }
|
||||
public bool? IdpAllowUnsolicitedAuthnResponse { get; set; }
|
||||
public bool? IdpDisableOutboundLogoutRequests { get; set; }
|
||||
public bool? IdpWantAuthnRequestsSigned { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext context)
|
||||
{
|
||||
var i18nService = context.GetService(typeof(II18nService)) as I18nService;
|
||||
|
||||
if (ConfigType == SsoType.OpenIdConnect)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Authority))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("AuthorityValidationError"),
|
||||
new[] { nameof(Authority) });
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ClientId))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("ClientIdValidationError"),
|
||||
new[] { nameof(ClientId) });
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ClientSecret))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("ClientSecretValidationError"),
|
||||
new[] { nameof(ClientSecret) });
|
||||
}
|
||||
}
|
||||
else if (ConfigType == SsoType.Saml2)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(IdpEntityId))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpEntityIdValidationError"),
|
||||
new[] { nameof(IdpEntityId) });
|
||||
}
|
||||
|
||||
if (!Uri.IsWellFormedUriString(IdpEntityId, UriKind.Absolute) && string.IsNullOrWhiteSpace(IdpSingleSignOnServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleSignOnServiceUrlValidationError"),
|
||||
new[] { nameof(IdpSingleSignOnServiceUrl) });
|
||||
}
|
||||
|
||||
if (InvalidServiceUrl(IdpSingleSignOnServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleSignOnServiceUrlInvalid"),
|
||||
new[] { nameof(IdpSingleSignOnServiceUrl) });
|
||||
}
|
||||
|
||||
if (InvalidServiceUrl(IdpSingleLogoutServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleLogoutServiceUrlInvalid"),
|
||||
new[] { nameof(IdpSingleLogoutServiceUrl) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(IdpX509PublicCert))
|
||||
{
|
||||
// Validate the certificate is in a valid format
|
||||
ValidationResult failedResult = null;
|
||||
try
|
||||
{
|
||||
var certData = CoreHelpers.Base64UrlDecode(StripPemCertificateElements(IdpX509PublicCert));
|
||||
new X509Certificate2(certData);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertInvalidFormatValidationError"),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
catch (CryptographicException cryptoEx)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertCryptographicExceptionValidationError", cryptoEx.Message),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertValidationError", ex.Message),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
if (failedResult != null)
|
||||
{
|
||||
yield return failedResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SsoConfigurationData ToConfigurationData()
|
||||
{
|
||||
return new SsoConfigurationData
|
||||
{
|
||||
ConfigType = ConfigType,
|
||||
KeyConnectorEnabled = KeyConnectorEnabled,
|
||||
KeyConnectorUrl = KeyConnectorUrl,
|
||||
Authority = Authority,
|
||||
ClientId = ClientId,
|
||||
ClientSecret = ClientSecret,
|
||||
MetadataAddress = MetadataAddress,
|
||||
GetClaimsFromUserInfoEndpoint = GetClaimsFromUserInfoEndpoint.GetValueOrDefault(),
|
||||
RedirectBehavior = RedirectBehavior,
|
||||
IdpEntityId = IdpEntityId,
|
||||
IdpBindingType = IdpBindingType,
|
||||
IdpSingleSignOnServiceUrl = IdpSingleSignOnServiceUrl,
|
||||
IdpSingleLogoutServiceUrl = IdpSingleLogoutServiceUrl,
|
||||
IdpArtifactResolutionServiceUrl = null,
|
||||
IdpX509PublicCert = StripPemCertificateElements(IdpX509PublicCert),
|
||||
IdpOutboundSigningAlgorithm = IdpOutboundSigningAlgorithm,
|
||||
IdpAllowUnsolicitedAuthnResponse = IdpAllowUnsolicitedAuthnResponse.GetValueOrDefault(),
|
||||
IdpDisableOutboundLogoutRequests = IdpDisableOutboundLogoutRequests.GetValueOrDefault(),
|
||||
IdpWantAuthnRequestsSigned = IdpWantAuthnRequestsSigned.GetValueOrDefault(),
|
||||
SpNameIdFormat = SpNameIdFormat,
|
||||
SpOutboundSigningAlgorithm = SpOutboundSigningAlgorithm ?? SamlSigningAlgorithms.Sha256,
|
||||
SpSigningBehavior = SpSigningBehavior,
|
||||
SpWantAssertionsSigned = SpWantAssertionsSigned.GetValueOrDefault(),
|
||||
SpValidateCertificates = SpValidateCertificates.GetValueOrDefault(),
|
||||
SpMinIncomingSigningAlgorithm = SpMinIncomingSigningAlgorithm,
|
||||
AdditionalScopes = AdditionalScopes,
|
||||
AdditionalUserIdClaimTypes = AdditionalUserIdClaimTypes,
|
||||
AdditionalEmailClaimTypes = AdditionalEmailClaimTypes,
|
||||
AdditionalNameClaimTypes = AdditionalNameClaimTypes,
|
||||
AcrValues = AcrValues,
|
||||
ExpectedReturnAcrValue = ExpectedReturnAcrValue,
|
||||
};
|
||||
}
|
||||
|
||||
private string StripPemCertificateElements(string certificateText)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(certificateText))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return Regex.Replace(certificateText,
|
||||
@"(((BEGIN|END) CERTIFICATE)|([\-\n\r\t\s\f]))",
|
||||
string.Empty,
|
||||
RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
||||
}
|
||||
|
||||
private bool InvalidServiceUrl(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!url.StartsWith("http://") && !url.StartsWith("https://"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return Regex.IsMatch(url, "[<>\"]");
|
||||
}
|
||||
existingConfig.Enabled = Enabled;
|
||||
var configurationData = Data.ToConfigurationData();
|
||||
existingConfig.SetData(configurationData);
|
||||
return existingConfig;
|
||||
}
|
||||
}
|
||||
|
||||
public class SsoConfigurationDataRequest : IValidatableObject
|
||||
{
|
||||
public SsoConfigurationDataRequest() { }
|
||||
|
||||
[Required]
|
||||
public SsoType ConfigType { get; set; }
|
||||
|
||||
public bool KeyConnectorEnabled { get; set; }
|
||||
public string KeyConnectorUrl { get; set; }
|
||||
|
||||
// OIDC
|
||||
public string Authority { get; set; }
|
||||
public string ClientId { get; set; }
|
||||
public string ClientSecret { get; set; }
|
||||
public string MetadataAddress { get; set; }
|
||||
public OpenIdConnectRedirectBehavior RedirectBehavior { get; set; }
|
||||
public bool? GetClaimsFromUserInfoEndpoint { get; set; }
|
||||
public string AdditionalScopes { get; set; }
|
||||
public string AdditionalUserIdClaimTypes { get; set; }
|
||||
public string AdditionalEmailClaimTypes { get; set; }
|
||||
public string AdditionalNameClaimTypes { get; set; }
|
||||
public string AcrValues { get; set; }
|
||||
public string ExpectedReturnAcrValue { get; set; }
|
||||
|
||||
// SAML2 SP
|
||||
public Saml2NameIdFormat SpNameIdFormat { get; set; }
|
||||
public string SpOutboundSigningAlgorithm { get; set; }
|
||||
public Saml2SigningBehavior SpSigningBehavior { get; set; }
|
||||
public bool? SpWantAssertionsSigned { get; set; }
|
||||
public bool? SpValidateCertificates { get; set; }
|
||||
public string SpMinIncomingSigningAlgorithm { get; set; }
|
||||
|
||||
// SAML2 IDP
|
||||
public string IdpEntityId { get; set; }
|
||||
public Saml2BindingType IdpBindingType { get; set; }
|
||||
public string IdpSingleSignOnServiceUrl { get; set; }
|
||||
public string IdpSingleLogoutServiceUrl { get; set; }
|
||||
public string IdpArtifactResolutionServiceUrl { get => null; set { /*IGNORE*/ } }
|
||||
public string IdpX509PublicCert { get; set; }
|
||||
public string IdpOutboundSigningAlgorithm { get; set; }
|
||||
public bool? IdpAllowUnsolicitedAuthnResponse { get; set; }
|
||||
public bool? IdpDisableOutboundLogoutRequests { get; set; }
|
||||
public bool? IdpWantAuthnRequestsSigned { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext context)
|
||||
{
|
||||
var i18nService = context.GetService(typeof(II18nService)) as I18nService;
|
||||
|
||||
if (ConfigType == SsoType.OpenIdConnect)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Authority))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("AuthorityValidationError"),
|
||||
new[] { nameof(Authority) });
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ClientId))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("ClientIdValidationError"),
|
||||
new[] { nameof(ClientId) });
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ClientSecret))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("ClientSecretValidationError"),
|
||||
new[] { nameof(ClientSecret) });
|
||||
}
|
||||
}
|
||||
else if (ConfigType == SsoType.Saml2)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(IdpEntityId))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpEntityIdValidationError"),
|
||||
new[] { nameof(IdpEntityId) });
|
||||
}
|
||||
|
||||
if (!Uri.IsWellFormedUriString(IdpEntityId, UriKind.Absolute) && string.IsNullOrWhiteSpace(IdpSingleSignOnServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleSignOnServiceUrlValidationError"),
|
||||
new[] { nameof(IdpSingleSignOnServiceUrl) });
|
||||
}
|
||||
|
||||
if (InvalidServiceUrl(IdpSingleSignOnServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleSignOnServiceUrlInvalid"),
|
||||
new[] { nameof(IdpSingleSignOnServiceUrl) });
|
||||
}
|
||||
|
||||
if (InvalidServiceUrl(IdpSingleLogoutServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleLogoutServiceUrlInvalid"),
|
||||
new[] { nameof(IdpSingleLogoutServiceUrl) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(IdpX509PublicCert))
|
||||
{
|
||||
// Validate the certificate is in a valid format
|
||||
ValidationResult failedResult = null;
|
||||
try
|
||||
{
|
||||
var certData = CoreHelpers.Base64UrlDecode(StripPemCertificateElements(IdpX509PublicCert));
|
||||
new X509Certificate2(certData);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertInvalidFormatValidationError"),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
catch (CryptographicException cryptoEx)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertCryptographicExceptionValidationError", cryptoEx.Message),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertValidationError", ex.Message),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
if (failedResult != null)
|
||||
{
|
||||
yield return failedResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SsoConfigurationData ToConfigurationData()
|
||||
{
|
||||
return new SsoConfigurationData
|
||||
{
|
||||
ConfigType = ConfigType,
|
||||
KeyConnectorEnabled = KeyConnectorEnabled,
|
||||
KeyConnectorUrl = KeyConnectorUrl,
|
||||
Authority = Authority,
|
||||
ClientId = ClientId,
|
||||
ClientSecret = ClientSecret,
|
||||
MetadataAddress = MetadataAddress,
|
||||
GetClaimsFromUserInfoEndpoint = GetClaimsFromUserInfoEndpoint.GetValueOrDefault(),
|
||||
RedirectBehavior = RedirectBehavior,
|
||||
IdpEntityId = IdpEntityId,
|
||||
IdpBindingType = IdpBindingType,
|
||||
IdpSingleSignOnServiceUrl = IdpSingleSignOnServiceUrl,
|
||||
IdpSingleLogoutServiceUrl = IdpSingleLogoutServiceUrl,
|
||||
IdpArtifactResolutionServiceUrl = null,
|
||||
IdpX509PublicCert = StripPemCertificateElements(IdpX509PublicCert),
|
||||
IdpOutboundSigningAlgorithm = IdpOutboundSigningAlgorithm,
|
||||
IdpAllowUnsolicitedAuthnResponse = IdpAllowUnsolicitedAuthnResponse.GetValueOrDefault(),
|
||||
IdpDisableOutboundLogoutRequests = IdpDisableOutboundLogoutRequests.GetValueOrDefault(),
|
||||
IdpWantAuthnRequestsSigned = IdpWantAuthnRequestsSigned.GetValueOrDefault(),
|
||||
SpNameIdFormat = SpNameIdFormat,
|
||||
SpOutboundSigningAlgorithm = SpOutboundSigningAlgorithm ?? SamlSigningAlgorithms.Sha256,
|
||||
SpSigningBehavior = SpSigningBehavior,
|
||||
SpWantAssertionsSigned = SpWantAssertionsSigned.GetValueOrDefault(),
|
||||
SpValidateCertificates = SpValidateCertificates.GetValueOrDefault(),
|
||||
SpMinIncomingSigningAlgorithm = SpMinIncomingSigningAlgorithm,
|
||||
AdditionalScopes = AdditionalScopes,
|
||||
AdditionalUserIdClaimTypes = AdditionalUserIdClaimTypes,
|
||||
AdditionalEmailClaimTypes = AdditionalEmailClaimTypes,
|
||||
AdditionalNameClaimTypes = AdditionalNameClaimTypes,
|
||||
AcrValues = AcrValues,
|
||||
ExpectedReturnAcrValue = ExpectedReturnAcrValue,
|
||||
};
|
||||
}
|
||||
|
||||
private string StripPemCertificateElements(string certificateText)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(certificateText))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return Regex.Replace(certificateText,
|
||||
@"(((BEGIN|END) CERTIFICATE)|([\-\n\r\t\s\f]))",
|
||||
string.Empty,
|
||||
RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
||||
}
|
||||
|
||||
private bool InvalidServiceUrl(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!url.StartsWith("http://") && !url.StartsWith("https://"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return Regex.IsMatch(url, "[<>\"]");
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationSubscriptionUpdateRequestModel
|
||||
{
|
||||
public class OrganizationSubscriptionUpdateRequestModel
|
||||
{
|
||||
[Required]
|
||||
public int SeatAdjustment { get; set; }
|
||||
public int? MaxAutoscaleSeats { get; set; }
|
||||
}
|
||||
[Required]
|
||||
public int SeatAdjustment { get; set; }
|
||||
public int? MaxAutoscaleSeats { get; set; }
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
using Bit.Api.Models.Request.Accounts;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationTaxInfoUpdateRequestModel : TaxInfoUpdateRequestModel
|
||||
{
|
||||
public class OrganizationTaxInfoUpdateRequestModel : TaxInfoUpdateRequestModel
|
||||
{
|
||||
public string TaxId { get; set; }
|
||||
public string Line1 { get; set; }
|
||||
public string Line2 { get; set; }
|
||||
public string City { get; set; }
|
||||
public string State { get; set; }
|
||||
}
|
||||
public string TaxId { get; set; }
|
||||
public string Line1 { get; set; }
|
||||
public string Line2 { get; set; }
|
||||
public string City { get; set; }
|
||||
public string State { get; set; }
|
||||
}
|
||||
|
@ -3,36 +3,35 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Settings;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
{
|
||||
public class OrganizationUpdateRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Name { get; set; }
|
||||
[StringLength(50)]
|
||||
public string BusinessName { get; set; }
|
||||
[StringLength(50)]
|
||||
public string Identifier { get; set; }
|
||||
[EmailAddress]
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
public string BillingEmail { get; set; }
|
||||
public Permissions Permissions { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public virtual Organization ToOrganization(Organization existingOrganization, GlobalSettings globalSettings)
|
||||
public class OrganizationUpdateRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Name { get; set; }
|
||||
[StringLength(50)]
|
||||
public string BusinessName { get; set; }
|
||||
[StringLength(50)]
|
||||
public string Identifier { get; set; }
|
||||
[EmailAddress]
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
public string BillingEmail { get; set; }
|
||||
public Permissions Permissions { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
|
||||
public virtual Organization ToOrganization(Organization existingOrganization, GlobalSettings globalSettings)
|
||||
{
|
||||
if (!globalSettings.SelfHosted)
|
||||
{
|
||||
if (!globalSettings.SelfHosted)
|
||||
{
|
||||
// These items come from the license file
|
||||
existingOrganization.Name = Name;
|
||||
existingOrganization.BusinessName = BusinessName;
|
||||
existingOrganization.BillingEmail = BillingEmail?.ToLowerInvariant()?.Trim();
|
||||
}
|
||||
existingOrganization.Identifier = Identifier;
|
||||
Keys?.ToOrganization(existingOrganization);
|
||||
return existingOrganization;
|
||||
// These items come from the license file
|
||||
existingOrganization.Name = Name;
|
||||
existingOrganization.BusinessName = BusinessName;
|
||||
existingOrganization.BillingEmail = BillingEmail?.ToLowerInvariant()?.Trim();
|
||||
}
|
||||
existingOrganization.Identifier = Identifier;
|
||||
Keys?.ToOrganization(existingOrganization);
|
||||
return existingOrganization;
|
||||
}
|
||||
}
|
||||
|
@ -2,41 +2,40 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Business;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationUpgradeRequestModel
|
||||
{
|
||||
public class OrganizationUpgradeRequestModel
|
||||
[StringLength(50)]
|
||||
public string BusinessName { get; set; }
|
||||
public PlanType PlanType { get; set; }
|
||||
[Range(0, int.MaxValue)]
|
||||
public int AdditionalSeats { get; set; }
|
||||
[Range(0, 99)]
|
||||
public short? AdditionalStorageGb { get; set; }
|
||||
public bool PremiumAccessAddon { get; set; }
|
||||
public string BillingAddressCountry { get; set; }
|
||||
public string BillingAddressPostalCode { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
|
||||
public OrganizationUpgrade ToOrganizationUpgrade()
|
||||
{
|
||||
[StringLength(50)]
|
||||
public string BusinessName { get; set; }
|
||||
public PlanType PlanType { get; set; }
|
||||
[Range(0, int.MaxValue)]
|
||||
public int AdditionalSeats { get; set; }
|
||||
[Range(0, 99)]
|
||||
public short? AdditionalStorageGb { get; set; }
|
||||
public bool PremiumAccessAddon { get; set; }
|
||||
public string BillingAddressCountry { get; set; }
|
||||
public string BillingAddressPostalCode { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
|
||||
public OrganizationUpgrade ToOrganizationUpgrade()
|
||||
var orgUpgrade = new OrganizationUpgrade
|
||||
{
|
||||
var orgUpgrade = new OrganizationUpgrade
|
||||
AdditionalSeats = AdditionalSeats,
|
||||
AdditionalStorageGb = AdditionalStorageGb.GetValueOrDefault(),
|
||||
BusinessName = BusinessName,
|
||||
Plan = PlanType,
|
||||
PremiumAccessAddon = PremiumAccessAddon,
|
||||
TaxInfo = new TaxInfo()
|
||||
{
|
||||
AdditionalSeats = AdditionalSeats,
|
||||
AdditionalStorageGb = AdditionalStorageGb.GetValueOrDefault(),
|
||||
BusinessName = BusinessName,
|
||||
Plan = PlanType,
|
||||
PremiumAccessAddon = PremiumAccessAddon,
|
||||
TaxInfo = new TaxInfo()
|
||||
{
|
||||
BillingAddressCountry = BillingAddressCountry,
|
||||
BillingAddressPostalCode = BillingAddressPostalCode
|
||||
}
|
||||
};
|
||||
BillingAddressCountry = BillingAddressCountry,
|
||||
BillingAddressPostalCode = BillingAddressPostalCode
|
||||
}
|
||||
};
|
||||
|
||||
Keys?.ToOrganizationUpgrade(orgUpgrade);
|
||||
Keys?.ToOrganizationUpgrade(orgUpgrade);
|
||||
|
||||
return orgUpgrade;
|
||||
}
|
||||
return orgUpgrade;
|
||||
}
|
||||
}
|
||||
|
@ -7,99 +7,98 @@ using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationUserInviteRequestModel
|
||||
{
|
||||
public class OrganizationUserInviteRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StrictEmailAddressList]
|
||||
public IEnumerable<string> Emails { get; set; }
|
||||
[Required]
|
||||
public OrganizationUserType? Type { get; set; }
|
||||
public bool AccessAll { get; set; }
|
||||
public Permissions Permissions { get; set; }
|
||||
public IEnumerable<SelectionReadOnlyRequestModel> Collections { get; set; }
|
||||
[Required]
|
||||
[StrictEmailAddressList]
|
||||
public IEnumerable<string> Emails { get; set; }
|
||||
[Required]
|
||||
public OrganizationUserType? Type { get; set; }
|
||||
public bool AccessAll { get; set; }
|
||||
public Permissions Permissions { get; set; }
|
||||
public IEnumerable<SelectionReadOnlyRequestModel> Collections { get; set; }
|
||||
|
||||
public OrganizationUserInviteData ToData()
|
||||
public OrganizationUserInviteData ToData()
|
||||
{
|
||||
return new OrganizationUserInviteData
|
||||
{
|
||||
return new OrganizationUserInviteData
|
||||
{
|
||||
Emails = Emails,
|
||||
Type = Type,
|
||||
AccessAll = AccessAll,
|
||||
Collections = Collections?.Select(c => c.ToSelectionReadOnly()),
|
||||
Permissions = Permissions,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class OrganizationUserAcceptRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string Token { get; set; }
|
||||
// Used to auto-enroll in master password reset
|
||||
public string ResetPasswordKey { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserConfirmRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserBulkConfirmRequestModelEntry
|
||||
{
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserBulkConfirmRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<OrganizationUserBulkConfirmRequestModelEntry> Keys { get; set; }
|
||||
|
||||
public Dictionary<Guid, string> ToDictionary()
|
||||
{
|
||||
return Keys.ToDictionary(e => e.Id, e => e.Key);
|
||||
}
|
||||
}
|
||||
|
||||
public class OrganizationUserUpdateRequestModel
|
||||
{
|
||||
[Required]
|
||||
public OrganizationUserType? Type { get; set; }
|
||||
public bool AccessAll { get; set; }
|
||||
public Permissions Permissions { get; set; }
|
||||
public IEnumerable<SelectionReadOnlyRequestModel> Collections { get; set; }
|
||||
|
||||
public OrganizationUser ToOrganizationUser(OrganizationUser existingUser)
|
||||
{
|
||||
existingUser.Type = Type.Value;
|
||||
existingUser.Permissions = JsonSerializer.Serialize(Permissions, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
});
|
||||
existingUser.AccessAll = AccessAll;
|
||||
return existingUser;
|
||||
}
|
||||
}
|
||||
|
||||
public class OrganizationUserUpdateGroupsRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> GroupIds { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserResetPasswordEnrollmentRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
public string ResetPasswordKey { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserBulkRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<Guid> Ids { get; set; }
|
||||
Emails = Emails,
|
||||
Type = Type,
|
||||
AccessAll = AccessAll,
|
||||
Collections = Collections?.Select(c => c.ToSelectionReadOnly()),
|
||||
Permissions = Permissions,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class OrganizationUserAcceptRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string Token { get; set; }
|
||||
// Used to auto-enroll in master password reset
|
||||
public string ResetPasswordKey { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserConfirmRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserBulkConfirmRequestModelEntry
|
||||
{
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserBulkConfirmRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<OrganizationUserBulkConfirmRequestModelEntry> Keys { get; set; }
|
||||
|
||||
public Dictionary<Guid, string> ToDictionary()
|
||||
{
|
||||
return Keys.ToDictionary(e => e.Id, e => e.Key);
|
||||
}
|
||||
}
|
||||
|
||||
public class OrganizationUserUpdateRequestModel
|
||||
{
|
||||
[Required]
|
||||
public OrganizationUserType? Type { get; set; }
|
||||
public bool AccessAll { get; set; }
|
||||
public Permissions Permissions { get; set; }
|
||||
public IEnumerable<SelectionReadOnlyRequestModel> Collections { get; set; }
|
||||
|
||||
public OrganizationUser ToOrganizationUser(OrganizationUser existingUser)
|
||||
{
|
||||
existingUser.Type = Type.Value;
|
||||
existingUser.Permissions = JsonSerializer.Serialize(Permissions, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
});
|
||||
existingUser.AccessAll = AccessAll;
|
||||
return existingUser;
|
||||
}
|
||||
}
|
||||
|
||||
public class OrganizationUserUpdateGroupsRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<string> GroupIds { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserResetPasswordEnrollmentRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
public string ResetPasswordKey { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserBulkRequestModel
|
||||
{
|
||||
[Required]
|
||||
public IEnumerable<Guid> Ids { get; set; }
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationUserResetPasswordRequestModel
|
||||
{
|
||||
public class OrganizationUserResetPasswordRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string NewMasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string NewMasterPasswordHash { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationVerifyBankRequestModel
|
||||
{
|
||||
public class OrganizationVerifyBankRequestModel
|
||||
{
|
||||
[Required]
|
||||
[Range(1, 99)]
|
||||
public int? Amount1 { get; set; }
|
||||
[Required]
|
||||
[Range(1, 99)]
|
||||
public int? Amount2 { get; set; }
|
||||
}
|
||||
[Required]
|
||||
[Range(1, 99)]
|
||||
public int? Amount1 { get; set; }
|
||||
[Required]
|
||||
[Range(1, 99)]
|
||||
public int? Amount2 { get; set; }
|
||||
}
|
||||
|
@ -2,13 +2,12 @@
|
||||
using Bit.Api.Models.Request.Organizations;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class PaymentRequestModel : OrganizationTaxInfoUpdateRequestModel
|
||||
{
|
||||
public class PaymentRequestModel : OrganizationTaxInfoUpdateRequestModel
|
||||
{
|
||||
[Required]
|
||||
public PaymentMethodType? PaymentMethodType { get; set; }
|
||||
[Required]
|
||||
public string PaymentToken { get; set; }
|
||||
}
|
||||
[Required]
|
||||
public PaymentMethodType? PaymentMethodType { get; set; }
|
||||
[Required]
|
||||
public string PaymentToken { get; set; }
|
||||
}
|
||||
|
@ -3,30 +3,29 @@ using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class PolicyRequestModel
|
||||
{
|
||||
public class PolicyRequestModel
|
||||
[Required]
|
||||
public PolicyType? Type { get; set; }
|
||||
[Required]
|
||||
public bool? Enabled { get; set; }
|
||||
public Dictionary<string, object> Data { get; set; }
|
||||
|
||||
public Policy ToPolicy(Guid orgId)
|
||||
{
|
||||
[Required]
|
||||
public PolicyType? Type { get; set; }
|
||||
[Required]
|
||||
public bool? Enabled { get; set; }
|
||||
public Dictionary<string, object> Data { get; set; }
|
||||
|
||||
public Policy ToPolicy(Guid orgId)
|
||||
return ToPolicy(new Policy
|
||||
{
|
||||
return ToPolicy(new Policy
|
||||
{
|
||||
Type = Type.Value,
|
||||
OrganizationId = orgId
|
||||
});
|
||||
}
|
||||
Type = Type.Value,
|
||||
OrganizationId = orgId
|
||||
});
|
||||
}
|
||||
|
||||
public Policy ToPolicy(Policy existingPolicy)
|
||||
{
|
||||
existingPolicy.Enabled = Enabled.GetValueOrDefault();
|
||||
existingPolicy.Data = Data != null ? JsonSerializer.Serialize(Data) : null;
|
||||
return existingPolicy;
|
||||
}
|
||||
public Policy ToPolicy(Policy existingPolicy)
|
||||
{
|
||||
existingPolicy.Enabled = Enabled.GetValueOrDefault();
|
||||
existingPolicy.Data = Data != null ? JsonSerializer.Serialize(Data) : null;
|
||||
return existingPolicy;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request.Providers
|
||||
{
|
||||
public class ProviderOrganizationAddRequestModel
|
||||
{
|
||||
[Required]
|
||||
public Guid OrganizationId { get; set; }
|
||||
namespace Bit.Api.Models.Request.Providers;
|
||||
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
public class ProviderOrganizationAddRequestModel
|
||||
{
|
||||
[Required]
|
||||
public Guid OrganizationId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
@ -2,15 +2,14 @@
|
||||
using Bit.Api.Models.Request.Organizations;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request.Providers
|
||||
namespace Bit.Api.Models.Request.Providers;
|
||||
|
||||
public class ProviderOrganizationCreateRequestModel
|
||||
{
|
||||
public class ProviderOrganizationCreateRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
[StrictEmailAddress]
|
||||
public string ClientOwnerEmail { get; set; }
|
||||
[Required]
|
||||
public OrganizationCreateRequestModel OrganizationCreateRequest { get; set; }
|
||||
}
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
[StrictEmailAddress]
|
||||
public string ClientOwnerEmail { get; set; }
|
||||
[Required]
|
||||
public OrganizationCreateRequestModel OrganizationCreateRequest { get; set; }
|
||||
}
|
||||
|
@ -1,31 +1,30 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Entities.Provider;
|
||||
|
||||
namespace Bit.Api.Models.Request.Providers
|
||||
namespace Bit.Api.Models.Request.Providers;
|
||||
|
||||
public class ProviderSetupRequestModel
|
||||
{
|
||||
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)
|
||||
{
|
||||
[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; }
|
||||
provider.Name = Name;
|
||||
provider.BusinessName = BusinessName;
|
||||
provider.BillingEmail = BillingEmail;
|
||||
|
||||
public virtual Provider ToProvider(Provider provider)
|
||||
{
|
||||
provider.Name = Name;
|
||||
provider.BusinessName = BusinessName;
|
||||
provider.BillingEmail = BillingEmail;
|
||||
|
||||
return provider;
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
|
@ -2,30 +2,29 @@
|
||||
using Bit.Core.Entities.Provider;
|
||||
using Bit.Core.Settings;
|
||||
|
||||
namespace Bit.Api.Models.Request.Providers
|
||||
{
|
||||
public class ProviderUpdateRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Name { get; set; }
|
||||
[StringLength(50)]
|
||||
public string BusinessName { get; set; }
|
||||
[EmailAddress]
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
public string BillingEmail { get; set; }
|
||||
namespace Bit.Api.Models.Request.Providers;
|
||||
|
||||
public virtual Provider ToProvider(Provider existingProvider, GlobalSettings globalSettings)
|
||||
public class ProviderUpdateRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Name { get; set; }
|
||||
[StringLength(50)]
|
||||
public string BusinessName { get; set; }
|
||||
[EmailAddress]
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
public string BillingEmail { get; set; }
|
||||
|
||||
public virtual Provider ToProvider(Provider existingProvider, GlobalSettings globalSettings)
|
||||
{
|
||||
if (!globalSettings.SelfHosted)
|
||||
{
|
||||
if (!globalSettings.SelfHosted)
|
||||
{
|
||||
// These items come from the license file
|
||||
existingProvider.Name = Name;
|
||||
existingProvider.BusinessName = BusinessName;
|
||||
existingProvider.BillingEmail = BillingEmail?.ToLowerInvariant()?.Trim();
|
||||
}
|
||||
return existingProvider;
|
||||
// These items come from the license file
|
||||
existingProvider.Name = Name;
|
||||
existingProvider.BusinessName = BusinessName;
|
||||
existingProvider.BillingEmail = BillingEmail?.ToLowerInvariant()?.Trim();
|
||||
}
|
||||
return existingProvider;
|
||||
}
|
||||
}
|
||||
|
@ -3,63 +3,62 @@ using Bit.Core.Entities.Provider;
|
||||
using Bit.Core.Enums.Provider;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request.Providers
|
||||
namespace Bit.Api.Models.Request.Providers;
|
||||
|
||||
public class ProviderUserInviteRequestModel
|
||||
{
|
||||
public class ProviderUserInviteRequestModel
|
||||
[Required]
|
||||
[StrictEmailAddressList]
|
||||
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()
|
||||
{
|
||||
[Required]
|
||||
[StrictEmailAddressList]
|
||||
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; }
|
||||
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; }
|
||||
}
|
||||
|
@ -1,23 +1,22 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
{
|
||||
public class SelectionReadOnlyRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string Id { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
public bool HidePasswords { get; set; }
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public SelectionReadOnly ToSelectionReadOnly()
|
||||
public class SelectionReadOnlyRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string Id { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
public bool HidePasswords { get; set; }
|
||||
|
||||
public SelectionReadOnly ToSelectionReadOnly()
|
||||
{
|
||||
return new SelectionReadOnly
|
||||
{
|
||||
return new SelectionReadOnly
|
||||
{
|
||||
Id = new Guid(Id),
|
||||
ReadOnly = ReadOnly,
|
||||
HidePasswords = HidePasswords,
|
||||
};
|
||||
}
|
||||
Id = new Guid(Id),
|
||||
ReadOnly = ReadOnly,
|
||||
HidePasswords = HidePasswords,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class SendAccessRequestModel
|
||||
{
|
||||
public class SendAccessRequestModel
|
||||
{
|
||||
[StringLength(300)]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
[StringLength(300)]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
|
@ -7,135 +7,134 @@ using Bit.Core.Models.Data;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class SendRequestModel
|
||||
{
|
||||
public class SendRequestModel
|
||||
public SendType Type { get; set; }
|
||||
public long? FileLength { get; set; } = null;
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Name { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Notes { get; set; }
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Key { get; set; }
|
||||
[Range(1, int.MaxValue)]
|
||||
public int? MaxAccessCount { get; set; }
|
||||
public DateTime? ExpirationDate { get; set; }
|
||||
[Required]
|
||||
public DateTime? DeletionDate { get; set; }
|
||||
public SendFileModel File { get; set; }
|
||||
public SendTextModel Text { get; set; }
|
||||
[StringLength(1000)]
|
||||
public string Password { get; set; }
|
||||
[Required]
|
||||
public bool? Disabled { get; set; }
|
||||
public bool? HideEmail { get; set; }
|
||||
|
||||
public Send ToSend(Guid userId, ISendService sendService)
|
||||
{
|
||||
public SendType Type { get; set; }
|
||||
public long? FileLength { get; set; } = null;
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Name { get; set; }
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Notes { get; set; }
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string Key { get; set; }
|
||||
[Range(1, int.MaxValue)]
|
||||
public int? MaxAccessCount { get; set; }
|
||||
public DateTime? ExpirationDate { get; set; }
|
||||
[Required]
|
||||
public DateTime? DeletionDate { get; set; }
|
||||
public SendFileModel File { get; set; }
|
||||
public SendTextModel Text { get; set; }
|
||||
[StringLength(1000)]
|
||||
public string Password { get; set; }
|
||||
[Required]
|
||||
public bool? Disabled { get; set; }
|
||||
public bool? HideEmail { get; set; }
|
||||
|
||||
public Send ToSend(Guid userId, ISendService sendService)
|
||||
var send = new Send
|
||||
{
|
||||
var send = new Send
|
||||
{
|
||||
Type = Type,
|
||||
UserId = (Guid?)userId
|
||||
};
|
||||
ToSend(send, sendService);
|
||||
return send;
|
||||
Type = Type,
|
||||
UserId = (Guid?)userId
|
||||
};
|
||||
ToSend(send, sendService);
|
||||
return send;
|
||||
}
|
||||
|
||||
public (Send, SendFileData) ToSend(Guid userId, string fileName, ISendService sendService)
|
||||
{
|
||||
var send = ToSendBase(new Send
|
||||
{
|
||||
Type = Type,
|
||||
UserId = (Guid?)userId
|
||||
}, sendService);
|
||||
var data = new SendFileData(Name, Notes, fileName);
|
||||
return (send, data);
|
||||
}
|
||||
|
||||
public Send ToSend(Send existingSend, ISendService sendService)
|
||||
{
|
||||
existingSend = ToSendBase(existingSend, sendService);
|
||||
switch (existingSend.Type)
|
||||
{
|
||||
case SendType.File:
|
||||
var fileData = JsonSerializer.Deserialize<SendFileData>(existingSend.Data);
|
||||
fileData.Name = Name;
|
||||
fileData.Notes = Notes;
|
||||
existingSend.Data = JsonSerializer.Serialize(fileData, JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
case SendType.Text:
|
||||
existingSend.Data = JsonSerializer.Serialize(ToSendTextData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
||||
}
|
||||
return existingSend;
|
||||
}
|
||||
|
||||
public (Send, SendFileData) ToSend(Guid userId, string fileName, ISendService sendService)
|
||||
public void ValidateCreation()
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
// Add 1 minute for a sane buffer and client clock float
|
||||
var nowPlus1Minute = now.AddMinutes(1);
|
||||
if (ExpirationDate.HasValue && ExpirationDate.Value <= nowPlus1Minute)
|
||||
{
|
||||
var send = ToSendBase(new Send
|
||||
{
|
||||
Type = Type,
|
||||
UserId = (Guid?)userId
|
||||
}, sendService);
|
||||
var data = new SendFileData(Name, Notes, fileName);
|
||||
return (send, data);
|
||||
throw new BadRequestException("You cannot create a Send that is already expired. " +
|
||||
"Adjust the expiration date and try again.");
|
||||
}
|
||||
ValidateEdit();
|
||||
}
|
||||
|
||||
public Send ToSend(Send existingSend, ISendService sendService)
|
||||
public void ValidateEdit()
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
// Add 1 minute for a sane buffer and client clock float
|
||||
var nowPlus1Minute = now.AddMinutes(1);
|
||||
if (DeletionDate.HasValue)
|
||||
{
|
||||
existingSend = ToSendBase(existingSend, sendService);
|
||||
switch (existingSend.Type)
|
||||
if (DeletionDate.Value <= nowPlus1Minute)
|
||||
{
|
||||
case SendType.File:
|
||||
var fileData = JsonSerializer.Deserialize<SendFileData>(existingSend.Data);
|
||||
fileData.Name = Name;
|
||||
fileData.Notes = Notes;
|
||||
existingSend.Data = JsonSerializer.Serialize(fileData, JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
case SendType.Text:
|
||||
existingSend.Data = JsonSerializer.Serialize(ToSendTextData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
||||
throw new BadRequestException("You cannot have a Send with a deletion date in the past. " +
|
||||
"Adjust the deletion date and try again.");
|
||||
}
|
||||
return existingSend;
|
||||
}
|
||||
|
||||
public void ValidateCreation()
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
// Add 1 minute for a sane buffer and client clock float
|
||||
var nowPlus1Minute = now.AddMinutes(1);
|
||||
if (ExpirationDate.HasValue && ExpirationDate.Value <= nowPlus1Minute)
|
||||
if (DeletionDate.Value > now.AddDays(31))
|
||||
{
|
||||
throw new BadRequestException("You cannot create a Send that is already expired. " +
|
||||
"Adjust the expiration date and try again.");
|
||||
throw new BadRequestException("You cannot have a Send with a deletion date that far " +
|
||||
"into the future. Adjust the Deletion Date to a value less than 31 days from now " +
|
||||
"and try again.");
|
||||
}
|
||||
ValidateEdit();
|
||||
}
|
||||
|
||||
public void ValidateEdit()
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
// Add 1 minute for a sane buffer and client clock float
|
||||
var nowPlus1Minute = now.AddMinutes(1);
|
||||
if (DeletionDate.HasValue)
|
||||
{
|
||||
if (DeletionDate.Value <= nowPlus1Minute)
|
||||
{
|
||||
throw new BadRequestException("You cannot have a Send with a deletion date in the past. " +
|
||||
"Adjust the deletion date and try again.");
|
||||
}
|
||||
if (DeletionDate.Value > now.AddDays(31))
|
||||
{
|
||||
throw new BadRequestException("You cannot have a Send with a deletion date that far " +
|
||||
"into the future. Adjust the Deletion Date to a value less than 31 days from now " +
|
||||
"and try again.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Send ToSendBase(Send existingSend, ISendService sendService)
|
||||
{
|
||||
existingSend.Key = Key;
|
||||
existingSend.ExpirationDate = ExpirationDate;
|
||||
existingSend.DeletionDate = DeletionDate.Value;
|
||||
existingSend.MaxAccessCount = MaxAccessCount;
|
||||
if (!string.IsNullOrWhiteSpace(Password))
|
||||
{
|
||||
existingSend.Password = sendService.HashPassword(Password);
|
||||
}
|
||||
existingSend.Disabled = Disabled.GetValueOrDefault();
|
||||
existingSend.HideEmail = HideEmail.GetValueOrDefault();
|
||||
return existingSend;
|
||||
}
|
||||
|
||||
private SendTextData ToSendTextData()
|
||||
{
|
||||
return new SendTextData(Name, Notes, Text.Text, Text.Hidden);
|
||||
}
|
||||
}
|
||||
|
||||
public class SendWithIdRequestModel : SendRequestModel
|
||||
private Send ToSendBase(Send existingSend, ISendService sendService)
|
||||
{
|
||||
[Required]
|
||||
public Guid? Id { get; set; }
|
||||
existingSend.Key = Key;
|
||||
existingSend.ExpirationDate = ExpirationDate;
|
||||
existingSend.DeletionDate = DeletionDate.Value;
|
||||
existingSend.MaxAccessCount = MaxAccessCount;
|
||||
if (!string.IsNullOrWhiteSpace(Password))
|
||||
{
|
||||
existingSend.Password = sendService.HashPassword(Password);
|
||||
}
|
||||
existingSend.Disabled = Disabled.GetValueOrDefault();
|
||||
existingSend.HideEmail = HideEmail.GetValueOrDefault();
|
||||
return existingSend;
|
||||
}
|
||||
|
||||
private SendTextData ToSendTextData()
|
||||
{
|
||||
return new SendTextData(Name, Notes, Text.Text, Text.Hidden);
|
||||
}
|
||||
}
|
||||
|
||||
public class SendWithIdRequestModel : SendRequestModel
|
||||
{
|
||||
[Required]
|
||||
public Guid? Id { get; set; }
|
||||
}
|
||||
|
@ -5,270 +5,269 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Fido2NetLib;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public class UpdateTwoFactorAuthenticatorRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
public class UpdateTwoFactorAuthenticatorRequestModel : SecretVerificationRequestModel
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Token { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Key { get; set; }
|
||||
|
||||
public User ToUser(User extistingUser)
|
||||
{
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Token { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Key { get; set; }
|
||||
|
||||
public User ToUser(User extistingUser)
|
||||
var providers = extistingUser.GetTwoFactorProviders();
|
||||
if (providers == null)
|
||||
{
|
||||
var providers = extistingUser.GetTwoFactorProviders();
|
||||
if (providers == null)
|
||||
{
|
||||
providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>();
|
||||
}
|
||||
else if (providers.ContainsKey(TwoFactorProviderType.Authenticator))
|
||||
{
|
||||
providers.Remove(TwoFactorProviderType.Authenticator);
|
||||
}
|
||||
|
||||
providers.Add(TwoFactorProviderType.Authenticator, new TwoFactorProvider
|
||||
{
|
||||
MetaData = new Dictionary<string, object> { ["Key"] = Key },
|
||||
Enabled = true
|
||||
});
|
||||
extistingUser.SetTwoFactorProviders(providers);
|
||||
return extistingUser;
|
||||
providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>();
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateTwoFactorDuoRequestModel : SecretVerificationRequestModel, IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string IntegrationKey { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string SecretKey { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Host { get; set; }
|
||||
|
||||
public User ToUser(User extistingUser)
|
||||
else if (providers.ContainsKey(TwoFactorProviderType.Authenticator))
|
||||
{
|
||||
var providers = extistingUser.GetTwoFactorProviders();
|
||||
if (providers == null)
|
||||
{
|
||||
providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>();
|
||||
}
|
||||
else if (providers.ContainsKey(TwoFactorProviderType.Duo))
|
||||
{
|
||||
providers.Remove(TwoFactorProviderType.Duo);
|
||||
}
|
||||
|
||||
providers.Add(TwoFactorProviderType.Duo, new TwoFactorProvider
|
||||
{
|
||||
MetaData = new Dictionary<string, object>
|
||||
{
|
||||
["SKey"] = SecretKey,
|
||||
["IKey"] = IntegrationKey,
|
||||
["Host"] = Host
|
||||
},
|
||||
Enabled = true
|
||||
});
|
||||
extistingUser.SetTwoFactorProviders(providers);
|
||||
return extistingUser;
|
||||
providers.Remove(TwoFactorProviderType.Authenticator);
|
||||
}
|
||||
|
||||
public Organization ToOrganization(Organization extistingOrg)
|
||||
providers.Add(TwoFactorProviderType.Authenticator, new TwoFactorProvider
|
||||
{
|
||||
var providers = extistingOrg.GetTwoFactorProviders();
|
||||
if (providers == null)
|
||||
{
|
||||
providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>();
|
||||
}
|
||||
else if (providers.ContainsKey(TwoFactorProviderType.OrganizationDuo))
|
||||
{
|
||||
providers.Remove(TwoFactorProviderType.OrganizationDuo);
|
||||
}
|
||||
|
||||
providers.Add(TwoFactorProviderType.OrganizationDuo, new TwoFactorProvider
|
||||
{
|
||||
MetaData = new Dictionary<string, object>
|
||||
{
|
||||
["SKey"] = SecretKey,
|
||||
["IKey"] = IntegrationKey,
|
||||
["Host"] = Host
|
||||
},
|
||||
Enabled = true
|
||||
});
|
||||
extistingOrg.SetTwoFactorProviders(providers);
|
||||
return extistingOrg;
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (!Core.Utilities.Duo.DuoApi.ValidHost(Host))
|
||||
{
|
||||
yield return new ValidationResult("Host is invalid.", new string[] { nameof(Host) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateTwoFactorYubicoOtpRequestModel : SecretVerificationRequestModel, IValidatableObject
|
||||
{
|
||||
public string Key1 { get; set; }
|
||||
public string Key2 { get; set; }
|
||||
public string Key3 { get; set; }
|
||||
public string Key4 { get; set; }
|
||||
public string Key5 { get; set; }
|
||||
[Required]
|
||||
public bool? Nfc { get; set; }
|
||||
|
||||
public User ToUser(User extistingUser)
|
||||
{
|
||||
var providers = extistingUser.GetTwoFactorProviders();
|
||||
if (providers == null)
|
||||
{
|
||||
providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>();
|
||||
}
|
||||
else if (providers.ContainsKey(TwoFactorProviderType.YubiKey))
|
||||
{
|
||||
providers.Remove(TwoFactorProviderType.YubiKey);
|
||||
}
|
||||
|
||||
providers.Add(TwoFactorProviderType.YubiKey, new TwoFactorProvider
|
||||
{
|
||||
MetaData = new Dictionary<string, object>
|
||||
{
|
||||
["Key1"] = FormatKey(Key1),
|
||||
["Key2"] = FormatKey(Key2),
|
||||
["Key3"] = FormatKey(Key3),
|
||||
["Key4"] = FormatKey(Key4),
|
||||
["Key5"] = FormatKey(Key5),
|
||||
["Nfc"] = Nfc.Value
|
||||
},
|
||||
Enabled = true
|
||||
});
|
||||
extistingUser.SetTwoFactorProviders(providers);
|
||||
return extistingUser;
|
||||
}
|
||||
|
||||
private string FormatKey(string keyValue)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(keyValue))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return keyValue.Substring(0, 12);
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Key1) && string.IsNullOrWhiteSpace(Key2) && string.IsNullOrWhiteSpace(Key3) &&
|
||||
string.IsNullOrWhiteSpace(Key4) && string.IsNullOrWhiteSpace(Key5))
|
||||
{
|
||||
yield return new ValidationResult("A key is required.", new string[] { nameof(Key1) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Key1) && Key1.Length < 12)
|
||||
{
|
||||
yield return new ValidationResult("Key 1 in invalid.", new string[] { nameof(Key1) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Key2) && Key2.Length < 12)
|
||||
{
|
||||
yield return new ValidationResult("Key 2 in invalid.", new string[] { nameof(Key2) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Key3) && Key3.Length < 12)
|
||||
{
|
||||
yield return new ValidationResult("Key 3 in invalid.", new string[] { nameof(Key3) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Key4) && Key4.Length < 12)
|
||||
{
|
||||
yield return new ValidationResult("Key 4 in invalid.", new string[] { nameof(Key4) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Key5) && Key5.Length < 12)
|
||||
{
|
||||
yield return new ValidationResult("Key 5 in invalid.", new string[] { nameof(Key5) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TwoFactorEmailRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
|
||||
public string DeviceIdentifier { get; set; }
|
||||
|
||||
public User ToUser(User extistingUser)
|
||||
{
|
||||
var providers = extistingUser.GetTwoFactorProviders();
|
||||
if (providers == null)
|
||||
{
|
||||
providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>();
|
||||
}
|
||||
else if (providers.ContainsKey(TwoFactorProviderType.Email))
|
||||
{
|
||||
providers.Remove(TwoFactorProviderType.Email);
|
||||
}
|
||||
|
||||
providers.Add(TwoFactorProviderType.Email, new TwoFactorProvider
|
||||
{
|
||||
MetaData = new Dictionary<string, object> { ["Email"] = Email.ToLowerInvariant() },
|
||||
Enabled = true
|
||||
});
|
||||
extistingUser.SetTwoFactorProviders(providers);
|
||||
return extistingUser;
|
||||
}
|
||||
}
|
||||
|
||||
public class TwoFactorWebAuthnRequestModel : TwoFactorWebAuthnDeleteRequestModel
|
||||
{
|
||||
[Required]
|
||||
public AuthenticatorAttestationRawResponse DeviceResponse { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public class TwoFactorWebAuthnDeleteRequestModel : SecretVerificationRequestModel, IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public int? Id { get; set; }
|
||||
|
||||
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
foreach (var validationResult in base.Validate(validationContext))
|
||||
{
|
||||
yield return validationResult;
|
||||
}
|
||||
|
||||
if (!Id.HasValue || Id < 0 || Id > 5)
|
||||
{
|
||||
yield return new ValidationResult("Invalid Key Id", new string[] { nameof(Id) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateTwoFactorEmailRequestModel : TwoFactorEmailRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
||||
public class TwoFactorProviderRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
[Required]
|
||||
public TwoFactorProviderType? Type { get; set; }
|
||||
}
|
||||
|
||||
public class TwoFactorRecoveryRequestModel : TwoFactorEmailRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(32)]
|
||||
public string RecoveryCode { get; set; }
|
||||
MetaData = new Dictionary<string, object> { ["Key"] = Key },
|
||||
Enabled = true
|
||||
});
|
||||
extistingUser.SetTwoFactorProviders(providers);
|
||||
return extistingUser;
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateTwoFactorDuoRequestModel : SecretVerificationRequestModel, IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string IntegrationKey { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string SecretKey { get; set; }
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Host { get; set; }
|
||||
|
||||
public User ToUser(User extistingUser)
|
||||
{
|
||||
var providers = extistingUser.GetTwoFactorProviders();
|
||||
if (providers == null)
|
||||
{
|
||||
providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>();
|
||||
}
|
||||
else if (providers.ContainsKey(TwoFactorProviderType.Duo))
|
||||
{
|
||||
providers.Remove(TwoFactorProviderType.Duo);
|
||||
}
|
||||
|
||||
providers.Add(TwoFactorProviderType.Duo, new TwoFactorProvider
|
||||
{
|
||||
MetaData = new Dictionary<string, object>
|
||||
{
|
||||
["SKey"] = SecretKey,
|
||||
["IKey"] = IntegrationKey,
|
||||
["Host"] = Host
|
||||
},
|
||||
Enabled = true
|
||||
});
|
||||
extistingUser.SetTwoFactorProviders(providers);
|
||||
return extistingUser;
|
||||
}
|
||||
|
||||
public Organization ToOrganization(Organization extistingOrg)
|
||||
{
|
||||
var providers = extistingOrg.GetTwoFactorProviders();
|
||||
if (providers == null)
|
||||
{
|
||||
providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>();
|
||||
}
|
||||
else if (providers.ContainsKey(TwoFactorProviderType.OrganizationDuo))
|
||||
{
|
||||
providers.Remove(TwoFactorProviderType.OrganizationDuo);
|
||||
}
|
||||
|
||||
providers.Add(TwoFactorProviderType.OrganizationDuo, new TwoFactorProvider
|
||||
{
|
||||
MetaData = new Dictionary<string, object>
|
||||
{
|
||||
["SKey"] = SecretKey,
|
||||
["IKey"] = IntegrationKey,
|
||||
["Host"] = Host
|
||||
},
|
||||
Enabled = true
|
||||
});
|
||||
extistingOrg.SetTwoFactorProviders(providers);
|
||||
return extistingOrg;
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (!Core.Utilities.Duo.DuoApi.ValidHost(Host))
|
||||
{
|
||||
yield return new ValidationResult("Host is invalid.", new string[] { nameof(Host) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateTwoFactorYubicoOtpRequestModel : SecretVerificationRequestModel, IValidatableObject
|
||||
{
|
||||
public string Key1 { get; set; }
|
||||
public string Key2 { get; set; }
|
||||
public string Key3 { get; set; }
|
||||
public string Key4 { get; set; }
|
||||
public string Key5 { get; set; }
|
||||
[Required]
|
||||
public bool? Nfc { get; set; }
|
||||
|
||||
public User ToUser(User extistingUser)
|
||||
{
|
||||
var providers = extistingUser.GetTwoFactorProviders();
|
||||
if (providers == null)
|
||||
{
|
||||
providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>();
|
||||
}
|
||||
else if (providers.ContainsKey(TwoFactorProviderType.YubiKey))
|
||||
{
|
||||
providers.Remove(TwoFactorProviderType.YubiKey);
|
||||
}
|
||||
|
||||
providers.Add(TwoFactorProviderType.YubiKey, new TwoFactorProvider
|
||||
{
|
||||
MetaData = new Dictionary<string, object>
|
||||
{
|
||||
["Key1"] = FormatKey(Key1),
|
||||
["Key2"] = FormatKey(Key2),
|
||||
["Key3"] = FormatKey(Key3),
|
||||
["Key4"] = FormatKey(Key4),
|
||||
["Key5"] = FormatKey(Key5),
|
||||
["Nfc"] = Nfc.Value
|
||||
},
|
||||
Enabled = true
|
||||
});
|
||||
extistingUser.SetTwoFactorProviders(providers);
|
||||
return extistingUser;
|
||||
}
|
||||
|
||||
private string FormatKey(string keyValue)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(keyValue))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return keyValue.Substring(0, 12);
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Key1) && string.IsNullOrWhiteSpace(Key2) && string.IsNullOrWhiteSpace(Key3) &&
|
||||
string.IsNullOrWhiteSpace(Key4) && string.IsNullOrWhiteSpace(Key5))
|
||||
{
|
||||
yield return new ValidationResult("A key is required.", new string[] { nameof(Key1) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Key1) && Key1.Length < 12)
|
||||
{
|
||||
yield return new ValidationResult("Key 1 in invalid.", new string[] { nameof(Key1) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Key2) && Key2.Length < 12)
|
||||
{
|
||||
yield return new ValidationResult("Key 2 in invalid.", new string[] { nameof(Key2) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Key3) && Key3.Length < 12)
|
||||
{
|
||||
yield return new ValidationResult("Key 3 in invalid.", new string[] { nameof(Key3) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Key4) && Key4.Length < 12)
|
||||
{
|
||||
yield return new ValidationResult("Key 4 in invalid.", new string[] { nameof(Key4) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Key5) && Key5.Length < 12)
|
||||
{
|
||||
yield return new ValidationResult("Key 5 in invalid.", new string[] { nameof(Key5) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TwoFactorEmailRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[StringLength(256)]
|
||||
public string Email { get; set; }
|
||||
|
||||
public string DeviceIdentifier { get; set; }
|
||||
|
||||
public User ToUser(User extistingUser)
|
||||
{
|
||||
var providers = extistingUser.GetTwoFactorProviders();
|
||||
if (providers == null)
|
||||
{
|
||||
providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>();
|
||||
}
|
||||
else if (providers.ContainsKey(TwoFactorProviderType.Email))
|
||||
{
|
||||
providers.Remove(TwoFactorProviderType.Email);
|
||||
}
|
||||
|
||||
providers.Add(TwoFactorProviderType.Email, new TwoFactorProvider
|
||||
{
|
||||
MetaData = new Dictionary<string, object> { ["Email"] = Email.ToLowerInvariant() },
|
||||
Enabled = true
|
||||
});
|
||||
extistingUser.SetTwoFactorProviders(providers);
|
||||
return extistingUser;
|
||||
}
|
||||
}
|
||||
|
||||
public class TwoFactorWebAuthnRequestModel : TwoFactorWebAuthnDeleteRequestModel
|
||||
{
|
||||
[Required]
|
||||
public AuthenticatorAttestationRawResponse DeviceResponse { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public class TwoFactorWebAuthnDeleteRequestModel : SecretVerificationRequestModel, IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public int? Id { get; set; }
|
||||
|
||||
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
foreach (var validationResult in base.Validate(validationContext))
|
||||
{
|
||||
yield return validationResult;
|
||||
}
|
||||
|
||||
if (!Id.HasValue || Id < 0 || Id > 5)
|
||||
{
|
||||
yield return new ValidationResult("Invalid Key Id", new string[] { nameof(Id) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateTwoFactorEmailRequestModel : TwoFactorEmailRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
||||
public class TwoFactorProviderRequestModel : SecretVerificationRequestModel
|
||||
{
|
||||
[Required]
|
||||
public TwoFactorProviderType? Type { get; set; }
|
||||
}
|
||||
|
||||
public class TwoFactorRecoveryRequestModel : TwoFactorEmailRequestModel
|
||||
{
|
||||
[Required]
|
||||
[StringLength(32)]
|
||||
public string RecoveryCode { get; set; }
|
||||
}
|
||||
|
@ -2,19 +2,18 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
{
|
||||
public class UpdateDomainsRequestModel
|
||||
{
|
||||
public IEnumerable<IEnumerable<string>> EquivalentDomains { get; set; }
|
||||
public IEnumerable<GlobalEquivalentDomainsType> ExcludedGlobalEquivalentDomains { get; set; }
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
public User ToUser(User existingUser)
|
||||
{
|
||||
existingUser.EquivalentDomains = EquivalentDomains != null ? JsonSerializer.Serialize(EquivalentDomains) : null;
|
||||
existingUser.ExcludedGlobalEquivalentDomains = ExcludedGlobalEquivalentDomains != null ?
|
||||
JsonSerializer.Serialize(ExcludedGlobalEquivalentDomains) : null;
|
||||
return existingUser;
|
||||
}
|
||||
public class UpdateDomainsRequestModel
|
||||
{
|
||||
public IEnumerable<IEnumerable<string>> EquivalentDomains { get; set; }
|
||||
public IEnumerable<GlobalEquivalentDomainsType> ExcludedGlobalEquivalentDomains { get; set; }
|
||||
|
||||
public User ToUser(User existingUser)
|
||||
{
|
||||
existingUser.EquivalentDomains = EquivalentDomains != null ? JsonSerializer.Serialize(EquivalentDomains) : null;
|
||||
existingUser.ExcludedGlobalEquivalentDomains = ExcludedGlobalEquivalentDomains != null ?
|
||||
JsonSerializer.Serialize(ExcludedGlobalEquivalentDomains) : null;
|
||||
return existingUser;
|
||||
}
|
||||
}
|
||||
|
@ -1,33 +1,32 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Api;
|
||||
|
||||
namespace Bit.Api.Models.Response
|
||||
namespace Bit.Api.Models.Response;
|
||||
|
||||
public class ApiKeyResponseModel : ResponseModel
|
||||
{
|
||||
public class ApiKeyResponseModel : ResponseModel
|
||||
public ApiKeyResponseModel(OrganizationApiKey organizationApiKey, string obj = "apiKey")
|
||||
: base(obj)
|
||||
{
|
||||
public ApiKeyResponseModel(OrganizationApiKey organizationApiKey, string obj = "apiKey")
|
||||
: base(obj)
|
||||
if (organizationApiKey == null)
|
||||
{
|
||||
if (organizationApiKey == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(organizationApiKey));
|
||||
}
|
||||
ApiKey = organizationApiKey.ApiKey;
|
||||
RevisionDate = organizationApiKey.RevisionDate;
|
||||
throw new ArgumentNullException(nameof(organizationApiKey));
|
||||
}
|
||||
|
||||
public ApiKeyResponseModel(User user, string obj = "apiKey")
|
||||
: base(obj)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
ApiKey = user.ApiKey;
|
||||
RevisionDate = user.RevisionDate;
|
||||
}
|
||||
|
||||
public string ApiKey { get; set; }
|
||||
public DateTime RevisionDate { get; set; }
|
||||
ApiKey = organizationApiKey.ApiKey;
|
||||
RevisionDate = organizationApiKey.RevisionDate;
|
||||
}
|
||||
|
||||
public ApiKeyResponseModel(User user, string obj = "apiKey")
|
||||
: base(obj)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
ApiKey = user.ApiKey;
|
||||
RevisionDate = user.RevisionDate;
|
||||
}
|
||||
|
||||
public string ApiKey { get; set; }
|
||||
public DateTime RevisionDate { get; set; }
|
||||
}
|
||||
|
@ -5,49 +5,48 @@ using Bit.Core.Models.Data;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Response
|
||||
namespace Bit.Api.Models.Response;
|
||||
|
||||
public class AttachmentResponseModel : ResponseModel
|
||||
{
|
||||
public class AttachmentResponseModel : ResponseModel
|
||||
public AttachmentResponseModel(AttachmentResponseData data) : base("attachment")
|
||||
{
|
||||
public AttachmentResponseModel(AttachmentResponseData data) : base("attachment")
|
||||
Id = data.Id;
|
||||
Url = data.Url;
|
||||
FileName = data.Data.FileName;
|
||||
Key = data.Data.Key;
|
||||
Size = data.Data.Size;
|
||||
SizeName = CoreHelpers.ReadableBytesSize(data.Data.Size);
|
||||
}
|
||||
|
||||
public AttachmentResponseModel(string id, CipherAttachment.MetaData data, Cipher cipher,
|
||||
IGlobalSettings globalSettings)
|
||||
: base("attachment")
|
||||
{
|
||||
Id = id;
|
||||
Url = $"{globalSettings.Attachment.BaseUrl}/{cipher.Id}/{id}";
|
||||
FileName = data.FileName;
|
||||
Key = data.Key;
|
||||
Size = data.Size;
|
||||
SizeName = CoreHelpers.ReadableBytesSize(data.Size);
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public string Key { get; set; }
|
||||
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
|
||||
public long Size { get; set; }
|
||||
public string SizeName { get; set; }
|
||||
|
||||
public static IEnumerable<AttachmentResponseModel> FromCipher(Cipher cipher, IGlobalSettings globalSettings)
|
||||
{
|
||||
var attachments = cipher.GetAttachments();
|
||||
if (attachments == null)
|
||||
{
|
||||
Id = data.Id;
|
||||
Url = data.Url;
|
||||
FileName = data.Data.FileName;
|
||||
Key = data.Data.Key;
|
||||
Size = data.Data.Size;
|
||||
SizeName = CoreHelpers.ReadableBytesSize(data.Data.Size);
|
||||
return null;
|
||||
}
|
||||
|
||||
public AttachmentResponseModel(string id, CipherAttachment.MetaData data, Cipher cipher,
|
||||
IGlobalSettings globalSettings)
|
||||
: base("attachment")
|
||||
{
|
||||
Id = id;
|
||||
Url = $"{globalSettings.Attachment.BaseUrl}/{cipher.Id}/{id}";
|
||||
FileName = data.FileName;
|
||||
Key = data.Key;
|
||||
Size = data.Size;
|
||||
SizeName = CoreHelpers.ReadableBytesSize(data.Size);
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public string Key { get; set; }
|
||||
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
|
||||
public long Size { get; set; }
|
||||
public string SizeName { get; set; }
|
||||
|
||||
public static IEnumerable<AttachmentResponseModel> FromCipher(Cipher cipher, IGlobalSettings globalSettings)
|
||||
{
|
||||
var attachments = cipher.GetAttachments();
|
||||
if (attachments == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return attachments.Select(a => new AttachmentResponseModel(a.Key, a.Value, cipher, globalSettings));
|
||||
}
|
||||
return attachments.Select(a => new AttachmentResponseModel(a.Key, a.Value, cipher, globalSettings));
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,15 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api;
|
||||
|
||||
namespace Bit.Api.Models.Response
|
||||
{
|
||||
public class AttachmentUploadDataResponseModel : ResponseModel
|
||||
{
|
||||
public string AttachmentId { get; set; }
|
||||
public string Url { get; set; }
|
||||
public FileUploadType FileUploadType { get; set; }
|
||||
public CipherResponseModel CipherResponse { get; set; }
|
||||
public CipherMiniResponseModel CipherMiniResponse { get; set; }
|
||||
namespace Bit.Api.Models.Response;
|
||||
|
||||
public AttachmentUploadDataResponseModel() : base("attachment-fileUpload") { }
|
||||
}
|
||||
public class AttachmentUploadDataResponseModel : ResponseModel
|
||||
{
|
||||
public string AttachmentId { get; set; }
|
||||
public string Url { get; set; }
|
||||
public FileUploadType FileUploadType { get; set; }
|
||||
public CipherResponseModel CipherResponse { get; set; }
|
||||
public CipherMiniResponseModel CipherMiniResponse { get; set; }
|
||||
|
||||
public AttachmentUploadDataResponseModel() : base("attachment-fileUpload") { }
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Models.Business;
|
||||
|
||||
namespace Bit.Api.Models.Response
|
||||
namespace Bit.Api.Models.Response;
|
||||
|
||||
public class BillingHistoryResponseModel : ResponseModel
|
||||
{
|
||||
public class BillingHistoryResponseModel : ResponseModel
|
||||
public BillingHistoryResponseModel(BillingInfo billing)
|
||||
: base("billingHistory")
|
||||
{
|
||||
public BillingHistoryResponseModel(BillingInfo billing)
|
||||
: base("billingHistory")
|
||||
{
|
||||
Transactions = billing.Transactions?.Select(t => new BillingTransaction(t));
|
||||
Invoices = billing.Invoices?.Select(i => new BillingInvoice(i));
|
||||
}
|
||||
public IEnumerable<BillingInvoice> Invoices { get; set; }
|
||||
public IEnumerable<BillingTransaction> Transactions { get; set; }
|
||||
Transactions = billing.Transactions?.Select(t => new BillingTransaction(t));
|
||||
Invoices = billing.Invoices?.Select(i => new BillingInvoice(i));
|
||||
}
|
||||
public IEnumerable<BillingInvoice> Invoices { get; set; }
|
||||
public IEnumerable<BillingTransaction> Transactions { get; set; }
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Models.Business;
|
||||
|
||||
namespace Bit.Api.Models.Response
|
||||
{
|
||||
public class BillingPaymentResponseModel : ResponseModel
|
||||
{
|
||||
public BillingPaymentResponseModel(BillingInfo billing)
|
||||
: base("billingPayment")
|
||||
{
|
||||
Balance = billing.Balance;
|
||||
PaymentSource = billing.PaymentSource != null ? new BillingSource(billing.PaymentSource) : null;
|
||||
}
|
||||
namespace Bit.Api.Models.Response;
|
||||
|
||||
public decimal Balance { get; set; }
|
||||
public BillingSource PaymentSource { get; set; }
|
||||
public class BillingPaymentResponseModel : ResponseModel
|
||||
{
|
||||
public BillingPaymentResponseModel(BillingInfo billing)
|
||||
: base("billingPayment")
|
||||
{
|
||||
Balance = billing.Balance;
|
||||
PaymentSource = billing.PaymentSource != null ? new BillingSource(billing.PaymentSource) : null;
|
||||
}
|
||||
|
||||
public decimal Balance { get; set; }
|
||||
public BillingSource PaymentSource { get; set; }
|
||||
}
|
||||
|
@ -2,82 +2,81 @@
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Models.Business;
|
||||
|
||||
namespace Bit.Api.Models.Response
|
||||
namespace Bit.Api.Models.Response;
|
||||
|
||||
public class BillingResponseModel : ResponseModel
|
||||
{
|
||||
public class BillingResponseModel : ResponseModel
|
||||
public BillingResponseModel(BillingInfo billing)
|
||||
: base("billing")
|
||||
{
|
||||
public BillingResponseModel(BillingInfo billing)
|
||||
: base("billing")
|
||||
{
|
||||
Balance = billing.Balance;
|
||||
PaymentSource = billing.PaymentSource != null ? new BillingSource(billing.PaymentSource) : null;
|
||||
Transactions = billing.Transactions?.Select(t => new BillingTransaction(t));
|
||||
Invoices = billing.Invoices?.Select(i => new BillingInvoice(i));
|
||||
}
|
||||
|
||||
public decimal Balance { get; set; }
|
||||
public BillingSource PaymentSource { get; set; }
|
||||
public IEnumerable<BillingInvoice> Invoices { get; set; }
|
||||
public IEnumerable<BillingTransaction> Transactions { get; set; }
|
||||
Balance = billing.Balance;
|
||||
PaymentSource = billing.PaymentSource != null ? new BillingSource(billing.PaymentSource) : null;
|
||||
Transactions = billing.Transactions?.Select(t => new BillingTransaction(t));
|
||||
Invoices = billing.Invoices?.Select(i => new BillingInvoice(i));
|
||||
}
|
||||
|
||||
public class BillingSource
|
||||
{
|
||||
public BillingSource(BillingInfo.BillingSource source)
|
||||
{
|
||||
Type = source.Type;
|
||||
CardBrand = source.CardBrand;
|
||||
Description = source.Description;
|
||||
NeedsVerification = source.NeedsVerification;
|
||||
}
|
||||
|
||||
public PaymentMethodType Type { get; set; }
|
||||
public string CardBrand { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool NeedsVerification { get; set; }
|
||||
}
|
||||
|
||||
public class BillingInvoice
|
||||
{
|
||||
public BillingInvoice(BillingInfo.BillingInvoice inv)
|
||||
{
|
||||
Amount = inv.Amount;
|
||||
Date = inv.Date;
|
||||
Url = inv.Url;
|
||||
PdfUrl = inv.PdfUrl;
|
||||
Number = inv.Number;
|
||||
Paid = inv.Paid;
|
||||
}
|
||||
|
||||
public decimal Amount { get; set; }
|
||||
public DateTime? Date { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string PdfUrl { get; set; }
|
||||
public string Number { get; set; }
|
||||
public bool Paid { get; set; }
|
||||
}
|
||||
|
||||
public class BillingTransaction
|
||||
{
|
||||
public BillingTransaction(BillingInfo.BillingTransaction transaction)
|
||||
{
|
||||
CreatedDate = transaction.CreatedDate;
|
||||
Amount = transaction.Amount;
|
||||
Refunded = transaction.Refunded;
|
||||
RefundedAmount = transaction.RefundedAmount;
|
||||
PartiallyRefunded = transaction.PartiallyRefunded;
|
||||
Type = transaction.Type;
|
||||
PaymentMethodType = transaction.PaymentMethodType;
|
||||
Details = transaction.Details;
|
||||
}
|
||||
|
||||
public DateTime CreatedDate { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public bool? Refunded { get; set; }
|
||||
public bool? PartiallyRefunded { get; set; }
|
||||
public decimal? RefundedAmount { get; set; }
|
||||
public TransactionType Type { get; set; }
|
||||
public PaymentMethodType? PaymentMethodType { get; set; }
|
||||
public string Details { get; set; }
|
||||
}
|
||||
public decimal Balance { get; set; }
|
||||
public BillingSource PaymentSource { get; set; }
|
||||
public IEnumerable<BillingInvoice> Invoices { get; set; }
|
||||
public IEnumerable<BillingTransaction> Transactions { get; set; }
|
||||
}
|
||||
|
||||
public class BillingSource
|
||||
{
|
||||
public BillingSource(BillingInfo.BillingSource source)
|
||||
{
|
||||
Type = source.Type;
|
||||
CardBrand = source.CardBrand;
|
||||
Description = source.Description;
|
||||
NeedsVerification = source.NeedsVerification;
|
||||
}
|
||||
|
||||
public PaymentMethodType Type { get; set; }
|
||||
public string CardBrand { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool NeedsVerification { get; set; }
|
||||
}
|
||||
|
||||
public class BillingInvoice
|
||||
{
|
||||
public BillingInvoice(BillingInfo.BillingInvoice inv)
|
||||
{
|
||||
Amount = inv.Amount;
|
||||
Date = inv.Date;
|
||||
Url = inv.Url;
|
||||
PdfUrl = inv.PdfUrl;
|
||||
Number = inv.Number;
|
||||
Paid = inv.Paid;
|
||||
}
|
||||
|
||||
public decimal Amount { get; set; }
|
||||
public DateTime? Date { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string PdfUrl { get; set; }
|
||||
public string Number { get; set; }
|
||||
public bool Paid { get; set; }
|
||||
}
|
||||
|
||||
public class BillingTransaction
|
||||
{
|
||||
public BillingTransaction(BillingInfo.BillingTransaction transaction)
|
||||
{
|
||||
CreatedDate = transaction.CreatedDate;
|
||||
Amount = transaction.Amount;
|
||||
Refunded = transaction.Refunded;
|
||||
RefundedAmount = transaction.RefundedAmount;
|
||||
PartiallyRefunded = transaction.PartiallyRefunded;
|
||||
Type = transaction.Type;
|
||||
PaymentMethodType = transaction.PaymentMethodType;
|
||||
Details = transaction.Details;
|
||||
}
|
||||
|
||||
public DateTime CreatedDate { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public bool? Refunded { get; set; }
|
||||
public bool? PartiallyRefunded { get; set; }
|
||||
public decimal? RefundedAmount { get; set; }
|
||||
public TransactionType Type { get; set; }
|
||||
public PaymentMethodType? PaymentMethodType { get; set; }
|
||||
public string Details { get; set; }
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user