1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-30 15:13:24 +00:00

refactoring code for login => cipher support

This commit is contained in:
Kyle Spearrin
2017-10-18 20:55:33 -04:00
parent 37f05f0a12
commit 1d6ec0f953
46 changed files with 731 additions and 410 deletions

View File

@@ -0,0 +1,12 @@
namespace Bit.App.Models.Api
{
public class CardDataModel : CipherDataModel
{
public string CardholderName { get; set; }
public string Brand { get; set; }
public string Number { get; set; }
public string ExpMonth { get; set; }
public string ExpYear { get; set; }
public string Code { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
namespace Bit.App.Models.Api
{
public class IdentityDataModel : CipherDataModel
{
public string Title { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string Company { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string SSN { get; set; }
public string Username { get; set; }
public string PassportNumber { get; set; }
public string LicenseNumber { get; set; }
}
}

View File

@@ -6,18 +6,18 @@ namespace Bit.App.Models.Api
{
public class CipherRequest
{
public CipherRequest(Login login)
public CipherRequest(Cipher cipher)
{
Type = CipherType.Login;
OrganizationId = login.OrganizationId;
FolderId = login.FolderId;
Name = login.Name?.EncryptedString;
Notes = login.Notes?.EncryptedString;
Favorite = login.Favorite;
Type = cipher.Type;
OrganizationId = cipher.OrganizationId;
FolderId = cipher.FolderId;
Name = cipher.Name?.EncryptedString;
Notes = cipher.Notes?.EncryptedString;
Favorite = cipher.Favorite;
if(login.Fields != null)
if(cipher.Fields != null)
{
Fields = login.Fields.Select(f => new FieldDataModel
Fields = cipher.Fields.Select(f => new FieldDataModel
{
Name = f.Name?.EncryptedString,
Value = f.Value?.EncryptedString,
@@ -28,7 +28,16 @@ namespace Bit.App.Models.Api
switch(Type)
{
case CipherType.Login:
Login = new LoginType(login);
Login = new LoginType(cipher);
break;
case CipherType.Card:
Card = new CardType(cipher);
break;
case CipherType.Identity:
Identity = new IdentityType(cipher);
break;
case CipherType.SecureNote:
SecureNote = new SecureNoteType(cipher);
break;
default:
break;
@@ -42,16 +51,20 @@ namespace Bit.App.Models.Api
public string Name { get; set; }
public string Notes { get; set; }
public IEnumerable<FieldDataModel> Fields { get; set; }
public LoginType Login { get; set; }
public CardType Card { get; set; }
public IdentityType Identity { get; set; }
public SecureNoteType SecureNote { get; set; }
public class LoginType
{
public LoginType(Login login)
public LoginType(Cipher cipher)
{
Uri = login.Uri?.EncryptedString;
Username = login.Username?.EncryptedString;
Password = login.Password?.EncryptedString;
Totp = login.Totp?.EncryptedString;
Uri = cipher.Login.Uri?.EncryptedString;
Username = cipher.Login.Username?.EncryptedString;
Password = cipher.Login.Password?.EncryptedString;
Totp = cipher.Login.Totp?.EncryptedString;
}
public string Uri { get; set; }
@@ -59,5 +72,79 @@ namespace Bit.App.Models.Api
public string Password { get; set; }
public string Totp { get; set; }
}
public class CardType
{
public CardType(Cipher cipher)
{
CardholderName = cipher.Card.CardholderName?.EncryptedString;
Brand = cipher.Card.Brand?.EncryptedString;
Number = cipher.Card.Number?.EncryptedString;
ExpMonth = cipher.Card.ExpMonth?.EncryptedString;
ExpYear = cipher.Card.ExpYear?.EncryptedString;
Code = cipher.Card.Code?.EncryptedString;
}
public string CardholderName { get; set; }
public string Brand { get; set; }
public string Number { get; set; }
public string ExpMonth { get; set; }
public string ExpYear { get; set; }
public string Code { get; set; }
}
public class IdentityType
{
public IdentityType(Cipher cipher)
{
Title = cipher.Identity.Title?.EncryptedString;
FirstName = cipher.Identity.FirstName?.EncryptedString;
MiddleName = cipher.Identity.MiddleName?.EncryptedString;
LastName = cipher.Identity.LastName?.EncryptedString;
Address1 = cipher.Identity.Address1?.EncryptedString;
Address2 = cipher.Identity.Address2?.EncryptedString;
Address3 = cipher.Identity.Address3?.EncryptedString;
City = cipher.Identity.City?.EncryptedString;
State = cipher.Identity.State?.EncryptedString;
PostalCode = cipher.Identity.PostalCode?.EncryptedString;
Country = cipher.Identity.Country?.EncryptedString;
Company = cipher.Identity.Company?.EncryptedString;
Email = cipher.Identity.Email?.EncryptedString;
Phone = cipher.Identity.Phone?.EncryptedString;
SSN = cipher.Identity.SSN?.EncryptedString;
Username = cipher.Identity.Username?.EncryptedString;
PassportNumber = cipher.Identity.PassportNumber?.EncryptedString;
LicenseNumber = cipher.Identity.LicenseNumber?.EncryptedString;
}
public string Title { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string Company { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string SSN { get; set; }
public string Username { get; set; }
public string PassportNumber { get; set; }
public string LicenseNumber { get; set; }
}
public class SecureNoteType
{
public SecureNoteType(Cipher cipher)
{
Type = cipher.SecureNote.Type;
}
public Enums.SecureNoteType Type { get; set; }
}
}
}

View File

@@ -0,0 +1,9 @@
using Bit.App.Enums;
namespace Bit.App.Models.Api
{
public class SecureNoteDataModel : CipherDataModel
{
public SecureNoteType Type { get; set; }
}
}

29
src/App/Models/Card.cs Normal file
View File

@@ -0,0 +1,29 @@
using Bit.App.Models.Api;
using Bit.App.Models.Data;
using Newtonsoft.Json;
namespace Bit.App.Models
{
public class Card
{
public Card(CipherData data)
{
var deserializedData = JsonConvert.DeserializeObject<CardDataModel>(data.Data);
CardholderName = deserializedData.CardholderName != null ?
new CipherString(deserializedData.CardholderName) : null;
Brand = deserializedData.Brand != null ? new CipherString(deserializedData.Brand) : null;
Number = deserializedData.Number != null ? new CipherString(deserializedData.Number) : null;
ExpMonth = deserializedData.ExpMonth != null ? new CipherString(deserializedData.ExpMonth) : null;
ExpYear = deserializedData.ExpYear != null ? new CipherString(deserializedData.ExpYear) : null;
Code = deserializedData.Code != null ? new CipherString(deserializedData.Code) : null;
}
public CipherString CardholderName { get; set; }
public CipherString Brand { get; set; }
public CipherString Number { get; set; }
public CipherString ExpMonth { get; set; }
public CipherString ExpYear { get; set; }
public CipherString Code { get; set; }
}
}

76
src/App/Models/Cipher.cs Normal file
View File

@@ -0,0 +1,76 @@
using Bit.App.Enums;
using Bit.App.Models.Api;
using Bit.App.Models.Data;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
namespace Bit.App.Models
{
public class Cipher
{
public Cipher()
{ }
public Cipher(CipherData data, IEnumerable<AttachmentData> attachments = null)
{
Id = data.Id;
UserId = data.UserId;
OrganizationId = data.OrganizationId;
FolderId = data.FolderId;
Type = data.Type;
Name = data.Name != null ? new CipherString(data.Name) : null;
Notes = data.Notes != null ? new CipherString(data.Notes) : null;
Favorite = data.Favorite;
Edit = data.Edit;
OrganizationUseTotp = data.OrganizationUseTotp;
Attachments = attachments?.Select(a => new Attachment(a));
switch(Type)
{
case CipherType.Login:
Login = new Login(data);
break;
case CipherType.SecureNote:
SecureNote = new SecureNote(data);
break;
case CipherType.Card:
Card = new Card(data);
break;
case CipherType.Identity:
Identity = new Identity(data);
break;
default:
break;
}
if(!string.IsNullOrWhiteSpace(data.Fields))
{
try
{
var fieldModels = JsonConvert.DeserializeObject<IEnumerable<FieldDataModel>>(data.Fields);
Fields = fieldModels?.Select(f => new Field(f));
}
catch(JsonSerializationException) { }
}
}
public string Id { get; set; }
public string UserId { get; set; }
public string OrganizationId { get; set; }
public string FolderId { get; set; }
public CipherType Type { get; set; }
public CipherString Name { get; set; }
public CipherString Notes { get; set; }
public IEnumerable<Field> Fields { get; set; }
public bool Favorite { get; set; }
public bool Edit { get; set; }
public bool OrganizationUseTotp { get; set; }
public IEnumerable<Attachment> Attachments { get; set; }
public Login Login { get; set; }
public Identity Identity { get; set; }
public Card Card { get; set; }
public SecureNote SecureNote { get; set; }
}
}

View File

@@ -10,20 +10,20 @@ namespace Bit.App.Models.Data
public AttachmentData()
{ }
public AttachmentData(Attachment attachment, string loginId)
public AttachmentData(Attachment attachment, string cipherId)
{
Id = attachment.Id;
LoginId = loginId;
LoginId = cipherId;
Url = attachment.Url;
FileName = attachment.FileName?.EncryptedString;
Size = attachment.Size.ToString();
SizeName = attachment.SizeName;
}
public AttachmentData(AttachmentResponse response, string loginId)
public AttachmentData(AttachmentResponse response, string cipherId)
{
Id = response.Id;
LoginId = loginId;
LoginId = cipherId;
Url = response.Url;
FileName = response.FileName;
Size = response.Size;
@@ -32,6 +32,7 @@ namespace Bit.App.Models.Data
[PrimaryKey]
public string Id { get; set; }
// Really should be called CipherId
[Indexed]
public string LoginId { get; set; }
public string Url { get; set; }

View File

@@ -0,0 +1,100 @@
using System;
using SQLite;
using Bit.App.Abstractions;
using Bit.App.Models.Api;
using Newtonsoft.Json;
using System.Linq;
using Bit.App.Enums;
namespace Bit.App.Models.Data
{
// Old table that has just carried over for backward compat. sake. Should really be "Cipher"
[Table("Site")]
public class CipherData : IDataObject<string>
{
public CipherData()
{ }
public CipherData(CipherResponse cipher, string userId)
{
Id = cipher.Id;
FolderId = cipher.FolderId;
UserId = userId;
OrganizationId = cipher.OrganizationId;
Favorite = cipher.Favorite;
Edit = cipher.Edit;
OrganizationUseTotp = cipher.OrganizationUseTotp;
RevisionDateTime = cipher.RevisionDate;
Type = cipher.Type;
Data = JsonConvert.SerializeObject(cipher.Data);
CipherDataModel cipherData = null;
switch(cipher.Type)
{
case CipherType.Login:
var loginData = cipher.Data.ToObject<LoginDataModel>();
cipherData = loginData;
Uri = loginData.Uri;
Username = loginData.Username;
Password = loginData.Password;
Totp = loginData.Totp;
break;
case CipherType.SecureNote:
var noteData = cipher.Data.ToObject<SecureNoteDataModel>();
cipherData = noteData;
SecureNoteType = noteData.Type;
break;
case CipherType.Card:
var cardData = cipher.Data.ToObject<CardDataModel>();
cipherData = cardData;
break;
case CipherType.Identity:
var idData = cipher.Data.ToObject<IdentityDataModel>();
cipherData = idData;
break;
default:
throw new ArgumentException(nameof(cipher.Type));
}
Name = cipherData.Name;
Notes = cipherData.Notes;
if(cipherData.Fields != null && cipherData.Fields.Any())
{
try
{
Fields = JsonConvert.SerializeObject(cipherData.Fields);
}
catch(JsonSerializationException) { }
}
}
[PrimaryKey]
public string Id { get; set; }
public string FolderId { get; set; }
[Indexed]
public string UserId { get; set; }
public string OrganizationId { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public string Fields { get; set; }
public bool Favorite { get; set; }
public bool Edit { get; set; }
public bool OrganizationUseTotp { get; set; }
public DateTime RevisionDateTime { get; set; } = DateTime.UtcNow;
[Indexed]
public CipherType Type { get; set; } = CipherType.Login;
public string Data { get; set; }
// Login metadata
public string Uri { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Totp { get; set; }
// Secure Note metadata
public SecureNoteType? SecureNoteType { get; set; }
}
}

View File

@@ -1,73 +0,0 @@
using System;
using SQLite;
using Bit.App.Abstractions;
using Bit.App.Models.Api;
using Newtonsoft.Json;
using System.Linq;
namespace Bit.App.Models.Data
{
[Table("Site")]
public class LoginData : IDataObject<string>
{
public LoginData()
{ }
public LoginData(CipherResponse cipher, string userId)
{
if(cipher.Type != Enums.CipherType.Login)
{
throw new ArgumentException(nameof(cipher.Type));
}
var data = cipher.Data.ToObject<LoginDataModel>();
Id = cipher.Id;
FolderId = cipher.FolderId;
UserId = userId;
OrganizationId = cipher.OrganizationId;
Name = data.Name;
Uri = data.Uri;
Username = data.Username;
Password = data.Password;
Notes = data.Notes;
Totp = data.Totp;
Favorite = cipher.Favorite;
Edit = cipher.Edit;
OrganizationUseTotp = cipher.OrganizationUseTotp;
RevisionDateTime = cipher.RevisionDate;
if(data.Fields != null && data.Fields.Any())
{
try
{
Fields = JsonConvert.SerializeObject(data.Fields);
}
catch(JsonSerializationException) { }
}
}
[PrimaryKey]
public string Id { get; set; }
public string FolderId { get; set; }
[Indexed]
public string UserId { get; set; }
public string OrganizationId { get; set; }
public string Name { get; set; }
public string Uri { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Notes { get; set; }
public string Totp { get; set; }
public string Fields { get; set; }
public bool Favorite { get; set; }
public bool Edit { get; set; }
public bool OrganizationUseTotp { get; set; }
public DateTime RevisionDateTime { get; set; } = DateTime.UtcNow;
public Login ToLogin()
{
return new Login(this);
}
}
}

View File

@@ -0,0 +1,54 @@
using Bit.App.Models.Api;
using Bit.App.Models.Data;
using Newtonsoft.Json;
namespace Bit.App.Models
{
public class Identity
{
public Identity(CipherData data)
{
var deserializedData = JsonConvert.DeserializeObject<IdentityDataModel>(data.Data);
Title = deserializedData.Title != null ? new CipherString(deserializedData.Title) : null;
FirstName = deserializedData.FirstName != null ? new CipherString(deserializedData.FirstName) : null;
MiddleName = deserializedData.MiddleName != null ? new CipherString(deserializedData.MiddleName) : null;
LastName = deserializedData.LastName != null ? new CipherString(deserializedData.LastName) : null;
Address1 = deserializedData.Address1 != null ? new CipherString(deserializedData.Address1) : null;
Address2 = deserializedData.Address2 != null ? new CipherString(deserializedData.Address2) : null;
Address3 = deserializedData.Address3 != null ? new CipherString(deserializedData.Address3) : null;
City = deserializedData.City != null ? new CipherString(deserializedData.City) : null;
State = deserializedData.State != null ? new CipherString(deserializedData.State) : null;
PostalCode = deserializedData.PostalCode != null ? new CipherString(deserializedData.PostalCode) : null;
Country = deserializedData.Country != null ? new CipherString(deserializedData.Country) : null;
Company = deserializedData.Company != null ? new CipherString(deserializedData.Company) : null;
Email = deserializedData.Email != null ? new CipherString(deserializedData.Email) : null;
Phone = deserializedData.Phone != null ? new CipherString(deserializedData.Phone) : null;
SSN = deserializedData.SSN != null ? new CipherString(deserializedData.SSN) : null;
Username = deserializedData.Username != null ? new CipherString(deserializedData.Username) : null;
PassportNumber = deserializedData.PassportNumber != null ?
new CipherString(deserializedData.PassportNumber) : null;
LicenseNumber = deserializedData.LicenseNumber != null ?
new CipherString(deserializedData.LicenseNumber) : null;
}
public CipherString Title { get; set; }
public CipherString FirstName { get; set; }
public CipherString MiddleName { get; set; }
public CipherString LastName { get; set; }
public CipherString Address1 { get; set; }
public CipherString Address2 { get; set; }
public CipherString Address3 { get; set; }
public CipherString City { get; set; }
public CipherString State { get; set; }
public CipherString PostalCode { get; set; }
public CipherString Country { get; set; }
public CipherString Company { get; set; }
public CipherString Email { get; set; }
public CipherString Phone { get; set; }
public CipherString SSN { get; set; }
public CipherString Username { get; set; }
public CipherString PassportNumber { get; set; }
public CipherString LicenseNumber { get; set; }
}
}

View File

@@ -1,58 +1,22 @@
using Bit.App.Models.Api;
using Bit.App.Models.Data;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using Bit.App.Models.Data;
namespace Bit.App.Models
{
public class Login
{
public Login()
{ }
public Login() { }
public Login(LoginData data, IEnumerable<AttachmentData> attachments = null)
public Login(CipherData data)
{
Id = data.Id;
UserId = data.UserId;
OrganizationId = data.OrganizationId;
FolderId = data.FolderId;
Name = data.Name != null ? new CipherString(data.Name) : null;
Uri = data.Uri != null ? new CipherString(data.Uri) : null;
Username = data.Username != null ? new CipherString(data.Username) : null;
Password = data.Password != null ? new CipherString(data.Password) : null;
Notes = data.Notes != null ? new CipherString(data.Notes) : null;
Totp = data.Totp != null ? new CipherString(data.Totp) : null;
Favorite = data.Favorite;
Edit = data.Edit;
OrganizationUseTotp = data.OrganizationUseTotp;
Attachments = attachments?.Select(a => new Attachment(a));
if(!string.IsNullOrWhiteSpace(data.Fields))
{
try
{
var fieldModels = JsonConvert.DeserializeObject<IEnumerable<FieldDataModel>>(data.Fields);
Fields = fieldModels?.Select(f => new Field(f));
}
catch(JsonSerializationException) { }
}
}
public string Id { get; set; }
public string UserId { get; set; }
public string OrganizationId { get; set; }
public string FolderId { get; set; }
public CipherString Name { get; set; }
public CipherString Uri { get; set; }
public CipherString Username { get; set; }
public CipherString Password { get; set; }
public CipherString Notes { get; set; }
public CipherString Totp { get; set; }
public IEnumerable<Field> Fields { get; set; }
public bool Favorite { get; set; }
public bool Edit { get; set; }
public bool OrganizationUseTotp { get; set; }
public IEnumerable<Attachment> Attachments { get; set; }
}
}

View File

@@ -9,17 +9,17 @@ namespace Bit.App.Models.Page
{
public class Login
{
public Login(Models.Login login)
public Login(Models.Cipher cipher)
{
Id = login.Id;
Shared = !string.IsNullOrWhiteSpace(login.OrganizationId);
HasAttachments = login.Attachments?.Any() ?? false;
FolderId = login.FolderId;
Name = login.Name?.Decrypt(login.OrganizationId);
Username = login.Username?.Decrypt(login.OrganizationId) ?? " ";
Password = new Lazy<string>(() => login.Password?.Decrypt(login.OrganizationId));
Uri = new Lazy<string>(() => login.Uri?.Decrypt(login.OrganizationId));
Totp = new Lazy<string>(() => login.Totp?.Decrypt(login.OrganizationId));
Id = cipher.Id;
Shared = !string.IsNullOrWhiteSpace(cipher.OrganizationId);
HasAttachments = cipher.Attachments?.Any() ?? false;
FolderId = cipher.FolderId;
Name = cipher.Name?.Decrypt(cipher.OrganizationId);
Username = cipher.Login?.Username?.Decrypt(cipher.OrganizationId) ?? " ";
Password = new Lazy<string>(() => cipher.Login?.Password?.Decrypt(cipher.OrganizationId));
Uri = new Lazy<string>(() => cipher.Login?.Uri?.Decrypt(cipher.OrganizationId));
Totp = new Lazy<string>(() => cipher.Login?.Totp?.Decrypt(cipher.OrganizationId));
}
public string Id { get; set; }
@@ -35,7 +35,7 @@ namespace Bit.App.Models.Page
public class AutofillLogin : Login
{
public AutofillLogin(Models.Login login, bool fuzzy = false)
public AutofillLogin(Models.Cipher login, bool fuzzy = false)
: base(login)
{
Fuzzy = fuzzy;

View File

@@ -201,23 +201,23 @@ namespace Bit.App.Models.Page
}
public bool ShowFields => (Fields?.Count ?? 0) > 0;
public void Update(Login login)
public void Update(Cipher cipher)
{
Name = login.Name?.Decrypt(login.OrganizationId);
Username = login.Username?.Decrypt(login.OrganizationId);
Password = login.Password?.Decrypt(login.OrganizationId);
Uri = login.Uri?.Decrypt(login.OrganizationId);
Notes = login.Notes?.Decrypt(login.OrganizationId);
Name = cipher.Name?.Decrypt(cipher.OrganizationId);
Username = cipher.Login?.Username?.Decrypt(cipher.OrganizationId);
Password = cipher.Login?.Password?.Decrypt(cipher.OrganizationId);
Uri = cipher.Login?.Uri?.Decrypt(cipher.OrganizationId);
Notes = cipher.Notes?.Decrypt(cipher.OrganizationId);
if(login.Attachments != null)
if(cipher.Attachments != null)
{
var attachments = new List<Attachment>();
foreach(var attachment in login.Attachments)
foreach(var attachment in cipher.Attachments)
{
attachments.Add(new Attachment
{
Id = attachment.Id,
Name = attachment.FileName?.Decrypt(login.OrganizationId),
Name = attachment.FileName?.Decrypt(cipher.OrganizationId),
SizeName = attachment.SizeName,
Size = attachment.Size,
Url = attachment.Url
@@ -227,18 +227,18 @@ namespace Bit.App.Models.Page
}
else
{
login.Attachments = null;
cipher.Attachments = null;
}
if(login.Fields != null)
if(cipher.Fields != null)
{
var fields = new List<Field>();
foreach(var field in login.Fields)
foreach(var field in cipher.Fields)
{
fields.Add(new Field
{
Name = field.Name?.Decrypt(login.OrganizationId),
Value = field.Value?.Decrypt(login.OrganizationId),
Name = field.Name?.Decrypt(cipher.OrganizationId),
Value = field.Value?.Decrypt(cipher.OrganizationId),
Type = field.Type
});
}
@@ -246,7 +246,7 @@ namespace Bit.App.Models.Page
}
else
{
login.Fields = null;
cipher.Fields = null;
}
}

View File

@@ -0,0 +1,15 @@
using Bit.App.Enums;
using Bit.App.Models.Data;
namespace Bit.App.Models
{
public class SecureNote
{
public SecureNote(CipherData data)
{
Type = data.SecureNoteType.Value;
}
public SecureNoteType Type { get; set; }
}
}