diff --git a/src/Core/Models/Api/Public/CollectionBaseModel.cs b/src/Core/Models/Api/Public/CollectionBaseModel.cs
new file mode 100644
index 0000000000..0b5a3c60cd
--- /dev/null
+++ b/src/Core/Models/Api/Public/CollectionBaseModel.cs
@@ -0,0 +1,14 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Bit.Core.Models.Api.Public
+{
+ public abstract class CollectionBaseModel
+ {
+ ///
+ /// External identifier for reference or linking this collection to another system.
+ ///
+ /// external_id_123456
+ [StringLength(300)]
+ public string ExternalId { get; set; }
+ }
+}
diff --git a/src/Core/Models/Api/Public/GroupBaseModel.cs b/src/Core/Models/Api/Public/GroupBaseModel.cs
index 8500341a74..d748db23e3 100644
--- a/src/Core/Models/Api/Public/GroupBaseModel.cs
+++ b/src/Core/Models/Api/Public/GroupBaseModel.cs
@@ -18,7 +18,7 @@ namespace Bit.Core.Models.Api.Public
[Required]
public bool? AccessAll { get; set; }
///
- /// External identifier linking this group to another system, such as a user directory.
+ /// External identifier for reference or linking this group to another system, such as a user directory.
///
/// external_id_123456
[StringLength(300)]
diff --git a/src/Core/Models/Api/Public/MemberBaseModel.cs b/src/Core/Models/Api/Public/MemberBaseModel.cs
index a8745de7ed..63bb46ea28 100644
--- a/src/Core/Models/Api/Public/MemberBaseModel.cs
+++ b/src/Core/Models/Api/Public/MemberBaseModel.cs
@@ -46,7 +46,7 @@ namespace Bit.Core.Models.Api.Public
[Required]
public bool? AccessAll { get; set; }
///
- /// External identifier linking this member to another system, such as a user directory.
+ /// External identifier for reference or linking this member to another system, such as a user directory.
///
/// external_id_123456
[StringLength(300)]
diff --git a/src/Core/Models/Api/Public/Request/CollectionUpdateRequestModel.cs b/src/Core/Models/Api/Public/Request/CollectionUpdateRequestModel.cs
index 5836d938ee..f86764f3ac 100644
--- a/src/Core/Models/Api/Public/Request/CollectionUpdateRequestModel.cs
+++ b/src/Core/Models/Api/Public/Request/CollectionUpdateRequestModel.cs
@@ -3,7 +3,7 @@ using Bit.Core.Models.Table;
namespace Bit.Core.Models.Api.Public
{
- public class CollectionUpdateRequestModel
+ public class CollectionUpdateRequestModel : CollectionBaseModel
{
///
/// The associated groups that this collection is assigned to.
@@ -12,8 +12,7 @@ namespace Bit.Core.Models.Api.Public
public Collection ToCollection(Collection existingCollection)
{
- // TODO
- // existingCollection.ExternalId = ExternalId;
+ existingCollection.ExternalId = ExternalId;
return existingCollection;
}
}
diff --git a/src/Core/Models/Api/Public/Response/CollectionResponseModel.cs b/src/Core/Models/Api/Public/Response/CollectionResponseModel.cs
index 25155bc996..690ac11d64 100644
--- a/src/Core/Models/Api/Public/Response/CollectionResponseModel.cs
+++ b/src/Core/Models/Api/Public/Response/CollectionResponseModel.cs
@@ -10,7 +10,7 @@ namespace Bit.Core.Models.Api.Public
///
/// A collection.
///
- public class CollectionResponseModel : IResponseModel
+ public class CollectionResponseModel : CollectionBaseModel, IResponseModel
{
public CollectionResponseModel(Collection collection, IEnumerable groups)
{
@@ -20,7 +20,7 @@ namespace Bit.Core.Models.Api.Public
}
Id = collection.Id;
- // ExternalId = group.ExternalId; TODO: Add external is for referencing purposes
+ ExternalId = collection.ExternalId;
Groups = groups?.Select(c => new AssociationWithPermissionsResponseModel(c));
}
diff --git a/src/Core/Models/Api/Request/CollectionRequestModel.cs b/src/Core/Models/Api/Request/CollectionRequestModel.cs
index b912927dd5..551aadf940 100644
--- a/src/Core/Models/Api/Request/CollectionRequestModel.cs
+++ b/src/Core/Models/Api/Request/CollectionRequestModel.cs
@@ -13,6 +13,8 @@ namespace Bit.Core.Models.Api
[EncryptedString]
[EncryptedStringLength(1000)]
public string Name { get; set; }
+ [StringLength(300)]
+ public string ExternalId { get; set; }
public IEnumerable Groups { get; set; }
public Collection ToCollection(Guid orgId)
@@ -26,6 +28,7 @@ namespace Bit.Core.Models.Api
public Collection ToCollection(Collection existingCollection)
{
existingCollection.Name = Name;
+ existingCollection.ExternalId = ExternalId;
return existingCollection;
}
}
diff --git a/src/Core/Models/Api/Response/CollectionResponseModel.cs b/src/Core/Models/Api/Response/CollectionResponseModel.cs
index 6458455361..ce2508660e 100644
--- a/src/Core/Models/Api/Response/CollectionResponseModel.cs
+++ b/src/Core/Models/Api/Response/CollectionResponseModel.cs
@@ -19,11 +19,13 @@ namespace Bit.Core.Models.Api
Id = collection.Id.ToString();
OrganizationId = collection.OrganizationId.ToString();
Name = collection.Name;
+ ExternalId = collection.ExternalId;
}
public string Id { get; set; }
public string OrganizationId { get; set; }
public string Name { get; set; }
+ public string ExternalId { get; set; }
}
public class CollectionDetailsResponseModel : CollectionResponseModel
diff --git a/src/Core/Models/Table/Collection.cs b/src/Core/Models/Table/Collection.cs
index d6a0bdecf6..369592789e 100644
--- a/src/Core/Models/Table/Collection.cs
+++ b/src/Core/Models/Table/Collection.cs
@@ -8,6 +8,7 @@ namespace Bit.Core.Models.Table
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
public string Name { get; set; }
+ public string ExternalId { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
diff --git a/src/Sql/dbo/Stored Procedures/Collection_Create.sql b/src/Sql/dbo/Stored Procedures/Collection_Create.sql
index b939fb4146..c9e2f11853 100644
--- a/src/Sql/dbo/Stored Procedures/Collection_Create.sql
+++ b/src/Sql/dbo/Stored Procedures/Collection_Create.sql
@@ -2,6 +2,7 @@
@Id UNIQUEIDENTIFIER,
@OrganizationId UNIQUEIDENTIFIER,
@Name VARCHAR(MAX),
+ @ExternalId NVARCHAR(300),
@CreationDate DATETIME2(7),
@RevisionDate DATETIME2(7)
AS
@@ -13,6 +14,7 @@ BEGIN
[Id],
[OrganizationId],
[Name],
+ [ExternalId],
[CreationDate],
[RevisionDate]
)
@@ -21,6 +23,7 @@ BEGIN
@Id,
@OrganizationId,
@Name,
+ @ExternalId,
@CreationDate,
@RevisionDate
)
diff --git a/src/Sql/dbo/Stored Procedures/Collection_CreateWithGroups.sql b/src/Sql/dbo/Stored Procedures/Collection_CreateWithGroups.sql
index c4f90cd782..b0475a4a73 100644
--- a/src/Sql/dbo/Stored Procedures/Collection_CreateWithGroups.sql
+++ b/src/Sql/dbo/Stored Procedures/Collection_CreateWithGroups.sql
@@ -2,6 +2,7 @@
@Id UNIQUEIDENTIFIER,
@OrganizationId UNIQUEIDENTIFIER,
@Name VARCHAR(MAX),
+ @ExternalId NVARCHAR(300),
@CreationDate DATETIME2(7),
@RevisionDate DATETIME2(7),
@Groups AS [dbo].[SelectionReadOnlyArray] READONLY
@@ -9,7 +10,7 @@ AS
BEGIN
SET NOCOUNT ON
- EXEC [dbo].[Collection_Create] @Id, @OrganizationId, @Name, @CreationDate, @RevisionDate
+ EXEC [dbo].[Collection_Create] @Id, @OrganizationId, @Name, @ExternalId, @CreationDate, @RevisionDate
;WITH [AvailableGroupsCTE] AS(
SELECT
diff --git a/src/Sql/dbo/Stored Procedures/Collection_Update.sql b/src/Sql/dbo/Stored Procedures/Collection_Update.sql
index b6e7dbfc8c..e75f088d7d 100644
--- a/src/Sql/dbo/Stored Procedures/Collection_Update.sql
+++ b/src/Sql/dbo/Stored Procedures/Collection_Update.sql
@@ -2,6 +2,7 @@
@Id UNIQUEIDENTIFIER,
@OrganizationId UNIQUEIDENTIFIER,
@Name VARCHAR(MAX),
+ @ExternalId NVARCHAR(300),
@CreationDate DATETIME2(7),
@RevisionDate DATETIME2(7)
AS
@@ -13,6 +14,7 @@ BEGIN
SET
[OrganizationId] = @OrganizationId,
[Name] = @Name,
+ [ExternalId] = @ExternalId,
[CreationDate] = @CreationDate,
[RevisionDate] = @RevisionDate
WHERE
diff --git a/src/Sql/dbo/Stored Procedures/Collection_UpdateWithGroups.sql b/src/Sql/dbo/Stored Procedures/Collection_UpdateWithGroups.sql
index 6a4d23d6e7..f11231dc71 100644
--- a/src/Sql/dbo/Stored Procedures/Collection_UpdateWithGroups.sql
+++ b/src/Sql/dbo/Stored Procedures/Collection_UpdateWithGroups.sql
@@ -2,6 +2,7 @@
@Id UNIQUEIDENTIFIER,
@OrganizationId UNIQUEIDENTIFIER,
@Name VARCHAR(MAX),
+ @ExternalId NVARCHAR(300),
@CreationDate DATETIME2(7),
@RevisionDate DATETIME2(7),
@Groups AS [dbo].[SelectionReadOnlyArray] READONLY
@@ -9,7 +10,7 @@ AS
BEGIN
SET NOCOUNT ON
- EXEC [dbo].[Collection_Update] @Id, @OrganizationId, @Name, @CreationDate, @RevisionDate
+ EXEC [dbo].[Collection_Update] @Id, @OrganizationId, @Name, @ExternalId, @CreationDate, @RevisionDate
;WITH [AvailableGroupsCTE] AS(
SELECT
diff --git a/src/Sql/dbo/Tables/Collection.sql b/src/Sql/dbo/Tables/Collection.sql
index 02f011a023..0106f341df 100644
--- a/src/Sql/dbo/Tables/Collection.sql
+++ b/src/Sql/dbo/Tables/Collection.sql
@@ -2,6 +2,7 @@
[Id] UNIQUEIDENTIFIER NOT NULL,
[OrganizationId] UNIQUEIDENTIFIER NOT NULL,
[Name] VARCHAR (MAX) NOT NULL,
+ [ExternalId] NVARCHAR (300) NULL,
[CreationDate] DATETIME2 (7) NOT NULL,
[RevisionDate] DATETIME2 (7) NOT NULL,
CONSTRAINT [PK_Collection] PRIMARY KEY CLUSTERED ([Id] ASC),
diff --git a/util/Setup/DbScripts/2019-03-01_00_OrgApi.sql b/util/Setup/DbScripts/2019-03-01_00_OrgApi.sql
index 2f24377914..5e7c93eae2 100644
--- a/util/Setup/DbScripts/2019-03-01_00_OrgApi.sql
+++ b/util/Setup/DbScripts/2019-03-01_00_OrgApi.sql
@@ -384,3 +384,199 @@ BEGIN
[OrganizationUserId] = @Id
END
GO
+
+IF COL_LENGTH('[dbo].[Collection]', 'ExternalId') IS NULL
+BEGIN
+ ALTER TABLE
+ [dbo].[Collection]
+ ADD
+ [ExternalId] NVARCHAR(300) NULL
+END
+GO
+
+IF OBJECT_ID('[dbo].[Collection_Create]') IS NOT NULL
+BEGIN
+ DROP PROCEDURE [dbo].[Collection_Create]
+END
+GO
+
+CREATE PROCEDURE [dbo].[Collection_Create]
+ @Id UNIQUEIDENTIFIER,
+ @OrganizationId UNIQUEIDENTIFIER,
+ @Name VARCHAR(MAX),
+ @ExternalId NVARCHAR(300),
+ @CreationDate DATETIME2(7),
+ @RevisionDate DATETIME2(7)
+AS
+BEGIN
+ SET NOCOUNT ON
+
+ INSERT INTO [dbo].[Collection]
+ (
+ [Id],
+ [OrganizationId],
+ [Name],
+ [ExternalId],
+ [CreationDate],
+ [RevisionDate]
+ )
+ VALUES
+ (
+ @Id,
+ @OrganizationId,
+ @Name,
+ @ExternalId,
+ @CreationDate,
+ @RevisionDate
+ )
+
+ EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @Id, @OrganizationId
+END
+GO
+
+IF OBJECT_ID('[dbo].[Collection_Update]') IS NOT NULL
+BEGIN
+ DROP PROCEDURE [dbo].[Collection_Update]
+END
+GO
+
+CREATE PROCEDURE [dbo].[Collection_Update]
+ @Id UNIQUEIDENTIFIER,
+ @OrganizationId UNIQUEIDENTIFIER,
+ @Name VARCHAR(MAX),
+ @ExternalId NVARCHAR(300),
+ @CreationDate DATETIME2(7),
+ @RevisionDate DATETIME2(7)
+AS
+BEGIN
+ SET NOCOUNT ON
+
+ UPDATE
+ [dbo].[Collection]
+ SET
+ [OrganizationId] = @OrganizationId,
+ [Name] = @Name,
+ [ExternalId] = @ExternalId,
+ [CreationDate] = @CreationDate,
+ [RevisionDate] = @RevisionDate
+ WHERE
+ [Id] = @Id
+
+ EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @Id, @OrganizationId
+END
+GO
+
+IF OBJECT_ID('[dbo].[Collection_CreateWithGroups]') IS NOT NULL
+BEGIN
+ DROP PROCEDURE [dbo].[Collection_CreateWithGroups]
+END
+GO
+
+CREATE PROCEDURE [dbo].[Collection_CreateWithGroups]
+ @Id UNIQUEIDENTIFIER,
+ @OrganizationId UNIQUEIDENTIFIER,
+ @Name VARCHAR(MAX),
+ @ExternalId NVARCHAR(300),
+ @CreationDate DATETIME2(7),
+ @RevisionDate DATETIME2(7),
+ @Groups AS [dbo].[SelectionReadOnlyArray] READONLY
+AS
+BEGIN
+ SET NOCOUNT ON
+
+ EXEC [dbo].[Collection_Create] @Id, @OrganizationId, @Name, @ExternalId, @CreationDate, @RevisionDate
+
+ ;WITH [AvailableGroupsCTE] AS(
+ SELECT
+ [Id]
+ FROM
+ [dbo].[Group]
+ WHERE
+ [OrganizationId] = @OrganizationId
+ )
+ INSERT INTO [dbo].[CollectionGroup]
+ (
+ [CollectionId],
+ [GroupId],
+ [ReadOnly]
+ )
+ SELECT
+ @Id,
+ [Id],
+ [ReadOnly]
+ FROM
+ @Groups
+ WHERE
+ [Id] IN (SELECT [Id] FROM [AvailableGroupsCTE])
+
+ EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId
+END
+GO
+
+IF OBJECT_ID('[dbo].[Collection_UpdateWithGroups]') IS NOT NULL
+BEGIN
+ DROP PROCEDURE [dbo].[Collection_UpdateWithGroups]
+END
+GO
+
+CREATE PROCEDURE [dbo].[Collection_UpdateWithGroups]
+ @Id UNIQUEIDENTIFIER,
+ @OrganizationId UNIQUEIDENTIFIER,
+ @Name VARCHAR(MAX),
+ @ExternalId NVARCHAR(300),
+ @CreationDate DATETIME2(7),
+ @RevisionDate DATETIME2(7),
+ @Groups AS [dbo].[SelectionReadOnlyArray] READONLY
+AS
+BEGIN
+ SET NOCOUNT ON
+
+ EXEC [dbo].[Collection_Update] @Id, @OrganizationId, @Name, @ExternalId, @CreationDate, @RevisionDate
+
+ ;WITH [AvailableGroupsCTE] AS(
+ SELECT
+ Id
+ FROM
+ [dbo].[Group]
+ WHERE
+ OrganizationId = @OrganizationId
+ )
+ MERGE
+ [dbo].[CollectionGroup] AS [Target]
+ USING
+ @Groups AS [Source]
+ ON
+ [Target].[CollectionId] = @Id
+ AND [Target].[GroupId] = [Source].[Id]
+ WHEN NOT MATCHED BY TARGET
+ AND [Source].[Id] IN (SELECT [Id] FROM [AvailableGroupsCTE]) THEN
+ INSERT VALUES
+ (
+ @Id,
+ [Source].[Id],
+ [Source].[ReadOnly]
+ )
+ WHEN MATCHED AND [Target].[ReadOnly] != [Source].[ReadOnly] THEN
+ UPDATE SET [Target].[ReadOnly] = [Source].[ReadOnly]
+ WHEN NOT MATCHED BY SOURCE
+ AND [Target].[CollectionId] = @Id THEN
+ DELETE
+ ;
+
+ EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @Id, @OrganizationId
+END
+GO
+
+IF EXISTS(SELECT * FROM sys.views WHERE [Name] = 'CollectionView')
+BEGIN
+ DROP VIEW [dbo].[CollectionView]
+END
+GO
+
+CREATE VIEW [dbo].[CollectionView]
+AS
+SELECT
+ *
+FROM
+ [dbo].[Collection]
+GO