mirror of
https://github.com/bitwarden/server.git
synced 2024-11-25 12:45:18 +01:00
[PM-1380] Modify Device Table (#2937)
* Update Models - Add Controller Method * Add MSSQL Migration * Update SQL Proj * Update SQL Migration * Update Models * Update SQL Project * Add EF Migrations * Switch to using Identifier * Update Code Comment
This commit is contained in:
parent
5f4a303180
commit
5874ff42c3
@ -91,6 +91,22 @@ public class DevicesController : Controller
|
||||
return response;
|
||||
}
|
||||
|
||||
[HttpPut("{identifier}/keys")]
|
||||
[HttpPost("{identifier}/keys")]
|
||||
public async Task<DeviceResponseModel> PutKeys(string identifier, [FromBody] DeviceKeysRequestModel model)
|
||||
{
|
||||
var device = await _deviceRepository.GetByIdentifierAsync(identifier, _userService.GetProperUserId(User).Value);
|
||||
if (device == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
await _deviceService.SaveAsync(model.ToDevice(device));
|
||||
|
||||
var response = new DeviceResponseModel(device);
|
||||
return response;
|
||||
}
|
||||
|
||||
[HttpPut("identifier/{identifier}/token")]
|
||||
[HttpPost("identifier/{identifier}/token")]
|
||||
public async Task PutToken(string identifier, [FromBody] DeviceTokenRequestModel model)
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Request;
|
||||
|
||||
@ -47,3 +48,30 @@ public class DeviceTokenRequestModel
|
||||
return existingDevice;
|
||||
}
|
||||
}
|
||||
|
||||
public class DeviceKeysRequestModel
|
||||
{
|
||||
/// <inheritdoc cref="Device.EncryptedUserKey" />
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
public string EncryptedUserKey { get; set; }
|
||||
|
||||
/// <inheritdoc cref="Device.EncryptedPublicKey" />
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
public string EncryptedPublicKey { get; set; }
|
||||
|
||||
/// <inheritdoc cref="Device.EncryptedPrivateKey" />
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
public string EncryptedPrivateKey { get; set; }
|
||||
|
||||
public Device ToDevice(Device existingDevice)
|
||||
{
|
||||
existingDevice.EncryptedUserKey = EncryptedUserKey;
|
||||
existingDevice.EncryptedPublicKey = EncryptedPublicKey;
|
||||
existingDevice.EncryptedPrivateKey = EncryptedPrivateKey;
|
||||
|
||||
return existingDevice;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,9 @@ public class DeviceResponseModel : ResponseModel
|
||||
Type = device.Type;
|
||||
Identifier = device.Identifier;
|
||||
CreationDate = device.CreationDate;
|
||||
EncryptedUserKey = device.EncryptedUserKey;
|
||||
EncryptedPublicKey = device.EncryptedPublicKey;
|
||||
EncryptedPrivateKey = device.EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
@ -26,4 +29,7 @@ public class DeviceResponseModel : ResponseModel
|
||||
public DeviceType Type { get; set; }
|
||||
public string Identifier { get; set; }
|
||||
public DateTime CreationDate { get; set; }
|
||||
public string EncryptedUserKey { get; }
|
||||
public string EncryptedPublicKey { get; }
|
||||
public string EncryptedPrivateKey { get; }
|
||||
}
|
||||
|
@ -17,6 +17,26 @@ public class Device : ITableObject<Guid>
|
||||
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
|
||||
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// Intended to be the users symmetric key that is encrypted in some form, the current way to encrypt this is with
|
||||
/// the devices public key.
|
||||
/// </summary>
|
||||
public string EncryptedUserKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Intended to be the public key that was generated for a device upon trust and encrypted. Currenly encrypted using
|
||||
/// a users symmetric key so that when trusted and unlocked a user can decrypt the public key for all their devices.
|
||||
/// This enabled a user to rotate the keys for all of their devices.
|
||||
/// </summary>
|
||||
public string EncryptedPublicKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Intended to be the private key that was generated for a device upon trust and encrypted. Currenly encrypted with
|
||||
/// the devices key, that upon successful login a user can decrypt this value and therefor decrypt their vault.
|
||||
/// </summary>
|
||||
public string EncryptedPrivateKey { get; set; }
|
||||
|
||||
|
||||
public void SetNewId()
|
||||
{
|
||||
Id = CoreHelpers.GenerateComb();
|
||||
|
@ -6,7 +6,10 @@
|
||||
@Identifier NVARCHAR(50),
|
||||
@PushToken NVARCHAR(255),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7)
|
||||
@RevisionDate DATETIME2(7),
|
||||
@EncryptedUserKey VARCHAR(MAX) = NULL,
|
||||
@EncryptedPublicKey VARCHAR(MAX) = NULL,
|
||||
@EncryptedPrivateKey VARCHAR(MAX) = NULL
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -20,7 +23,10 @@ BEGIN
|
||||
[Identifier],
|
||||
[PushToken],
|
||||
[CreationDate],
|
||||
[RevisionDate]
|
||||
[RevisionDate],
|
||||
[EncryptedUserKey],
|
||||
[EncryptedPublicKey],
|
||||
[EncryptedPrivateKey]
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@ -31,6 +37,9 @@ BEGIN
|
||||
@Identifier,
|
||||
@PushToken,
|
||||
@CreationDate,
|
||||
@RevisionDate
|
||||
@RevisionDate,
|
||||
@EncryptedUserKey,
|
||||
@EncryptedPublicKey,
|
||||
@EncryptedPrivateKey
|
||||
)
|
||||
END
|
||||
|
@ -6,7 +6,10 @@
|
||||
@Identifier NVARCHAR(50),
|
||||
@PushToken NVARCHAR(255),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7)
|
||||
@RevisionDate DATETIME2(7),
|
||||
@EncryptedUserKey VARCHAR(MAX) = NULL,
|
||||
@EncryptedPublicKey VARCHAR(MAX) = NULL,
|
||||
@EncryptedPrivateKey VARCHAR(MAX) = NULL
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -20,7 +23,10 @@ BEGIN
|
||||
[Identifier] = @Identifier,
|
||||
[PushToken] = @PushToken,
|
||||
[CreationDate] = @CreationDate,
|
||||
[RevisionDate] = @RevisionDate
|
||||
[RevisionDate] = @RevisionDate,
|
||||
[EncryptedUserKey] = @EncryptedUserKey,
|
||||
[EncryptedPublicKey] = @EncryptedPublicKey,
|
||||
[EncryptedPrivateKey] = @EncryptedPrivateKey
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
END
|
||||
END
|
||||
|
@ -7,6 +7,9 @@
|
||||
[PushToken] NVARCHAR (255) NULL,
|
||||
[CreationDate] DATETIME2 (7) NOT NULL,
|
||||
[RevisionDate] DATETIME2 (7) NOT NULL,
|
||||
[EncryptedUserKey] VARCHAR (MAX) NULL,
|
||||
[EncryptedPublicKey] VARCHAR (MAX) NULL,
|
||||
[EncryptedPrivateKey] VARCHAR (MAX) NULL,
|
||||
CONSTRAINT [PK_Device] PRIMARY KEY CLUSTERED ([Id] ASC),
|
||||
CONSTRAINT [FK_Device_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id])
|
||||
);
|
||||
@ -20,4 +23,3 @@ CREATE UNIQUE NONCLUSTERED INDEX [UX_Device_UserId_Identifier]
|
||||
GO
|
||||
CREATE NONCLUSTERED INDEX [IX_Device_Identifier]
|
||||
ON [dbo].[Device]([Identifier] ASC);
|
||||
|
||||
|
116
util/Migrator/DbScripts/2023-05-21_00_AddKeysToDevice.sql
Normal file
116
util/Migrator/DbScripts/2023-05-21_00_AddKeysToDevice.sql
Normal file
@ -0,0 +1,116 @@
|
||||
-- Add EncryptedUserKey column to Device table
|
||||
IF COL_LENGTH('[dbo].[Device]', 'EncryptedUserKey') IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE
|
||||
[dbo].[Device]
|
||||
ADD
|
||||
[EncryptedUserKey] VARCHAR(MAX) NULL;
|
||||
END
|
||||
GO
|
||||
|
||||
-- Add EncryptedPublicKey column to Device table
|
||||
IF COL_LENGTH('[dbo].[Device]', 'EncryptedPublicKey') IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE
|
||||
[dbo].[Device]
|
||||
ADD
|
||||
[EncryptedPublicKey] VARCHAR(MAX) NULL;
|
||||
END
|
||||
GO
|
||||
|
||||
-- Add EncryptedPrivateKey column to Device table
|
||||
IF COL_LENGTH('[dbo].[Device]', 'EncryptedPrivateKey') IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE
|
||||
[dbo].[Device]
|
||||
ADD
|
||||
[EncryptedPrivateKey] VARCHAR(MAX) NULL;
|
||||
END
|
||||
GO
|
||||
|
||||
CREATE OR ALTER PROCEDURE [dbo].[Device_Create]
|
||||
@Id UNIQUEIDENTIFIER OUTPUT,
|
||||
@UserId UNIQUEIDENTIFIER,
|
||||
@Name NVARCHAR(50),
|
||||
@Type TINYINT,
|
||||
@Identifier NVARCHAR(50),
|
||||
@PushToken NVARCHAR(255),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@EncryptedUserKey VARCHAR(MAX) = NULL,
|
||||
@EncryptedPublicKey VARCHAR(MAX) = NULL,
|
||||
@EncryptedPrivateKey VARCHAR(MAX) = NULL
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
INSERT INTO [dbo].[Device]
|
||||
(
|
||||
[Id],
|
||||
[UserId],
|
||||
[Name],
|
||||
[Type],
|
||||
[Identifier],
|
||||
[PushToken],
|
||||
[CreationDate],
|
||||
[RevisionDate],
|
||||
[EncryptedUserKey],
|
||||
[EncryptedPublicKey],
|
||||
[EncryptedPrivateKey]
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@Id,
|
||||
@UserId,
|
||||
@Name,
|
||||
@Type,
|
||||
@Identifier,
|
||||
@PushToken,
|
||||
@CreationDate,
|
||||
@RevisionDate,
|
||||
@EncryptedUserKey,
|
||||
@EncryptedPublicKey,
|
||||
@EncryptedPrivateKey
|
||||
)
|
||||
END
|
||||
GO
|
||||
|
||||
CREATE OR ALTER PROCEDURE [dbo].[Device_Update]
|
||||
@Id UNIQUEIDENTIFIER,
|
||||
@UserId UNIQUEIDENTIFIER,
|
||||
@Name NVARCHAR(50),
|
||||
@Type TINYINT,
|
||||
@Identifier NVARCHAR(50),
|
||||
@PushToken NVARCHAR(255),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@EncryptedUserKey VARCHAR(MAX) = NULL,
|
||||
@EncryptedPublicKey VARCHAR(MAX) = NULL,
|
||||
@EncryptedPrivateKey VARCHAR(MAX) = NULL
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
UPDATE
|
||||
[dbo].[Device]
|
||||
SET
|
||||
[UserId] = @UserId,
|
||||
[Name] = @Name,
|
||||
[Type] = @Type,
|
||||
[Identifier] = @Identifier,
|
||||
[PushToken] = @PushToken,
|
||||
[CreationDate] = @CreationDate,
|
||||
[RevisionDate] = @RevisionDate,
|
||||
[EncryptedUserKey] = @EncryptedUserKey,
|
||||
[EncryptedPublicKey] = @EncryptedPublicKey,
|
||||
[EncryptedPrivateKey] = @EncryptedPrivateKey
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
END
|
||||
GO
|
||||
|
||||
IF OBJECT_ID('[dbo].[DeviceView]') IS NOT NULL
|
||||
BEGIN
|
||||
EXECUTE sp_refreshsqlmodule N'[dbo].[DeviceView]';
|
||||
END
|
||||
GO
|
2199
util/MySqlMigrations/Migrations/20230522030836_AddKeysToDevice.Designer.cs
generated
Normal file
2199
util/MySqlMigrations/Migrations/20230522030836_AddKeysToDevice.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Bit.MySqlMigrations.Migrations;
|
||||
|
||||
public partial class AddKeysToDevice : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "EncryptedPrivateKey",
|
||||
table: "Device",
|
||||
type: "longtext",
|
||||
nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "EncryptedPublicKey",
|
||||
table: "Device",
|
||||
type: "longtext",
|
||||
nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "EncryptedUserKey",
|
||||
table: "Device",
|
||||
type: "longtext",
|
||||
nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "EncryptedPrivateKey",
|
||||
table: "Device");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "EncryptedPublicKey",
|
||||
table: "Device");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "EncryptedUserKey",
|
||||
table: "Device");
|
||||
}
|
||||
}
|
@ -319,6 +319,15 @@ namespace Bit.MySqlMigrations.Migrations
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("EncryptedPrivateKey")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("EncryptedPublicKey")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("EncryptedUserKey")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Identifier")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
2210
util/PostgresMigrations/Migrations/20230522030830_AddKeysToDevice.Designer.cs
generated
Normal file
2210
util/PostgresMigrations/Migrations/20230522030830_AddKeysToDevice.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,44 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Bit.PostgresMigrations.Migrations;
|
||||
|
||||
public partial class AddKeysToDevice : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "EncryptedPrivateKey",
|
||||
table: "Device",
|
||||
type: "text",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "EncryptedPublicKey",
|
||||
table: "Device",
|
||||
type: "text",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "EncryptedUserKey",
|
||||
table: "Device",
|
||||
type: "text",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "EncryptedPrivateKey",
|
||||
table: "Device");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "EncryptedPublicKey",
|
||||
table: "Device");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "EncryptedUserKey",
|
||||
table: "Device");
|
||||
}
|
||||
}
|
@ -328,6 +328,15 @@ namespace Bit.PostgresMigrations.Migrations
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("EncryptedPrivateKey")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("EncryptedPublicKey")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("EncryptedUserKey")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Identifier")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
2197
util/SqliteMigrations/Migrations/20230522030842_AddKeysToDevice.Designer.cs
generated
Normal file
2197
util/SqliteMigrations/Migrations/20230522030842_AddKeysToDevice.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,44 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Bit.SqliteMigrations.Migrations;
|
||||
|
||||
public partial class AddKeysToDevice : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "EncryptedPrivateKey",
|
||||
table: "Device",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "EncryptedPublicKey",
|
||||
table: "Device",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "EncryptedUserKey",
|
||||
table: "Device",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "EncryptedPrivateKey",
|
||||
table: "Device");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "EncryptedPublicKey",
|
||||
table: "Device");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "EncryptedUserKey",
|
||||
table: "Device");
|
||||
}
|
||||
}
|
@ -317,6 +317,15 @@ namespace Bit.SqliteMigrations.Migrations
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("EncryptedPrivateKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("EncryptedPublicKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("EncryptedUserKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Identifier")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
Loading…
Reference in New Issue
Block a user