mirror of
https://github.com/bitwarden/server.git
synced 2024-11-21 12:05:42 +01:00
[BEEEP] Integration tests (#1945)
* Add api integration tests * Add some stuff * Make program mockable * Work on IntegrationTests for Identity * Formatting * Update packages.lock.json * Update more packages.lock.json * Update all packages.lock.json * Fix InMemory configuration * Actually fix test configuration * Fix tests for CI * Fix event service * Force EF EventRepository * Add client_credentials test * Remove Api.IntegrationTest * Remove Api Program changes * Cleanup * Add more Auth-Email tests * Run formatting * Address some PR feedback * Move integration stuff to it's own common project * Ran linter * Add shared project to test solution * Remove sln changes * Clean usings * Add more coverage * Address PR feedback
This commit is contained in:
parent
98546a65ea
commit
719abc7e61
@ -86,6 +86,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Billing.Test", "test\Billin
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity.Test", "test\Identity.Test\Identity.Test.csproj", "{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity.Test", "test\Identity.Test\Identity.Test.csproj", "{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity.IntegrationTest", "test\Identity.IntegrationTest\Identity.IntegrationTest.csproj", "{0D3B2BD2-53F3-421D-AD8F-C19B954C796B}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationTestCommon", "test\IntegrationTestCommon\IntegrationTestCommon.csproj", "{0923DE59-5FB1-44F2-9302-A09D2236B470}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -162,14 +166,6 @@ Global
|
|||||||
{C7BA2255-C1B1-4789-8BB9-C27540DA6FB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C7BA2255-C1B1-4789-8BB9-C27540DA6FB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C7BA2255-C1B1-4789-8BB9-C27540DA6FB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C7BA2255-C1B1-4789-8BB9-C27540DA6FB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C7BA2255-C1B1-4789-8BB9-C27540DA6FB8}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C7BA2255-C1B1-4789-8BB9-C27540DA6FB8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{BDC1D592-5947-47ED-9903-7CDBB12A50C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{BDC1D592-5947-47ED-9903-7CDBB12A50C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{BDC1D592-5947-47ED-9903-7CDBB12A50C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{BDC1D592-5947-47ED-9903-7CDBB12A50C8}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F72E0229-2EF7-49B3-9004-FF4C0043816E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F72E0229-2EF7-49B3-9004-FF4C0043816E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F72E0229-2EF7-49B3-9004-FF4C0043816E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F72E0229-2EF7-49B3-9004-FF4C0043816E}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{EDC0D688-D58C-4CE1-AA07-3606AC6874B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{EDC0D688-D58C-4CE1-AA07-3606AC6874B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{EDC0D688-D58C-4CE1-AA07-3606AC6874B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{EDC0D688-D58C-4CE1-AA07-3606AC6874B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{EDC0D688-D58C-4CE1-AA07-3606AC6874B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{EDC0D688-D58C-4CE1-AA07-3606AC6874B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@ -178,6 +174,14 @@ Global
|
|||||||
{0E99A21B-684B-4C59-9831-90F775CAB6F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{0E99A21B-684B-4C59-9831-90F775CAB6F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{0E99A21B-684B-4C59-9831-90F775CAB6F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{0E99A21B-684B-4C59-9831-90F775CAB6F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{0E99A21B-684B-4C59-9831-90F775CAB6F7}.Release|Any CPU.Build.0 = Release|Any CPU
|
{0E99A21B-684B-4C59-9831-90F775CAB6F7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{BDC1D592-5947-47ED-9903-7CDBB12A50C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{BDC1D592-5947-47ED-9903-7CDBB12A50C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{BDC1D592-5947-47ED-9903-7CDBB12A50C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{BDC1D592-5947-47ED-9903-7CDBB12A50C8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{F72E0229-2EF7-49B3-9004-FF4C0043816E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{F72E0229-2EF7-49B3-9004-FF4C0043816E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{F72E0229-2EF7-49B3-9004-FF4C0043816E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F72E0229-2EF7-49B3-9004-FF4C0043816E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{17DA09D7-0212-4009-879E-6B9CFDE5FA60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{17DA09D7-0212-4009-879E-6B9CFDE5FA60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{17DA09D7-0212-4009-879E-6B9CFDE5FA60}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{17DA09D7-0212-4009-879E-6B9CFDE5FA60}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{17DA09D7-0212-4009-879E-6B9CFDE5FA60}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{17DA09D7-0212-4009-879E-6B9CFDE5FA60}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@ -202,6 +206,14 @@ Global
|
|||||||
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{0D3B2BD2-53F3-421D-AD8F-C19B954C796B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{0D3B2BD2-53F3-421D-AD8F-C19B954C796B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{0D3B2BD2-53F3-421D-AD8F-C19B954C796B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{0D3B2BD2-53F3-421D-AD8F-C19B954C796B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{0923DE59-5FB1-44F2-9302-A09D2236B470}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{0923DE59-5FB1-44F2-9302-A09D2236B470}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{0923DE59-5FB1-44F2-9302-A09D2236B470}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{0923DE59-5FB1-44F2-9302-A09D2236B470}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -224,16 +236,18 @@ Global
|
|||||||
{860DE301-0B3E-4717-9C21-A9B4C3C2B121} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
{860DE301-0B3E-4717-9C21-A9B4C3C2B121} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||||
{4866AF64-6640-4C65-A662-A31E02FF9064} = {4FDB6543-F68B-4202-9EA6-7FEA984D2D0A}
|
{4866AF64-6640-4C65-A662-A31E02FF9064} = {4FDB6543-F68B-4202-9EA6-7FEA984D2D0A}
|
||||||
{C7BA2255-C1B1-4789-8BB9-C27540DA6FB8} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
{C7BA2255-C1B1-4789-8BB9-C27540DA6FB8} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||||
{BDC1D592-5947-47ED-9903-7CDBB12A50C8} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
|
||||||
{F72E0229-2EF7-49B3-9004-FF4C0043816E} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
|
||||||
{EDC0D688-D58C-4CE1-AA07-3606AC6874B8} = {4FDB6543-F68B-4202-9EA6-7FEA984D2D0A}
|
{EDC0D688-D58C-4CE1-AA07-3606AC6874B8} = {4FDB6543-F68B-4202-9EA6-7FEA984D2D0A}
|
||||||
{0E99A21B-684B-4C59-9831-90F775CAB6F7} = {287CFF34-BBDB-4BC4-AF88-1E19A5A4679B}
|
{0E99A21B-684B-4C59-9831-90F775CAB6F7} = {287CFF34-BBDB-4BC4-AF88-1E19A5A4679B}
|
||||||
|
{BDC1D592-5947-47ED-9903-7CDBB12A50C8} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
||||||
|
{F72E0229-2EF7-49B3-9004-FF4C0043816E} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
||||||
{17DA09D7-0212-4009-879E-6B9CFDE5FA60} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
{17DA09D7-0212-4009-879E-6B9CFDE5FA60} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||||
{AD933445-27CE-4D30-A6ED-9065309464AD} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{AD933445-27CE-4D30-A6ED-9065309464AD} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{713D44C0-1BC1-4024-96A3-A98A49F33908} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{713D44C0-1BC1-4024-96A3-A98A49F33908} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{ED880735-0250-43C7-9662-FDC7C7416E7F} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{ED880735-0250-43C7-9662-FDC7C7416E7F} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{B8639B10-2157-44BC-8CE1-D9EB4B50971F} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
{B8639B10-2157-44BC-8CE1-D9EB4B50971F} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||||
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||||
|
{0D3B2BD2-53F3-421D-AD8F-C19B954C796B} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||||
|
{0923DE59-5FB1-44F2-9302-A09D2236B470} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {E01CBF68-2E20-425F-9EDB-E0A6510CA92F}
|
SolutionGuid = {E01CBF68-2E20-425F-9EDB-E0A6510CA92F}
|
||||||
|
@ -3392,7 +3392,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3401,7 +3401,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3411,9 +3411,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3541,26 +3541,26 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Azure.Messaging.EventGrid": "4.7.0",
|
"Azure.Messaging.EventGrid": "4.7.0",
|
||||||
"CommCore": "1.47.1",
|
"CommCore": "1.48.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
||||||
"SharedWeb": "1.47.1",
|
"SharedWeb": "1.48.1",
|
||||||
"Swashbuckle.AspNetCore": "6.2.3"
|
"Swashbuckle.AspNetCore": "6.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commcore": {
|
"commcore": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1"
|
"Core": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Api": "1.47.1",
|
"Api": "1.48.1",
|
||||||
"AutoFixture.AutoNSubstitute": "4.14.0",
|
"AutoFixture.AutoNSubstitute": "4.14.0",
|
||||||
"AutoFixture.Xunit2": "4.14.0",
|
"AutoFixture.Xunit2": "4.14.0",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
||||||
"Microsoft.NET.Test.Sdk": "16.6.1",
|
"Microsoft.NET.Test.Sdk": "16.6.1",
|
||||||
"NSubstitute": "4.2.2",
|
"NSubstitute": "4.2.2",
|
||||||
@ -3609,11 +3609,11 @@
|
|||||||
"core.test": {
|
"core.test": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Api": "1.47.1",
|
"Api": "1.48.1",
|
||||||
"AutoFixture.AutoNSubstitute": "4.14.0",
|
"AutoFixture.AutoNSubstitute": "4.14.0",
|
||||||
"AutoFixture.Xunit2": "4.14.0",
|
"AutoFixture.Xunit2": "4.14.0",
|
||||||
"Common": "1.47.1",
|
"Common": "1.48.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
||||||
"Microsoft.NET.Test.Sdk": "16.6.1",
|
"Microsoft.NET.Test.Sdk": "16.6.1",
|
||||||
"Moq": "4.16.1",
|
"Moq": "4.16.1",
|
||||||
@ -3624,7 +3624,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3633,7 +3633,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3643,9 +3643,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3416,7 +3416,7 @@
|
|||||||
"commcore": {
|
"commcore": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1"
|
"Core": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"core": {
|
"core": {
|
||||||
@ -3461,7 +3461,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3470,7 +3470,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3480,7 +3480,7 @@
|
|||||||
"migrator": {
|
"migrator": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.Extensions.Logging": "5.0.0",
|
"Microsoft.Extensions.Logging": "5.0.0",
|
||||||
"dbup-sqlserver": "4.4.0"
|
"dbup-sqlserver": "4.4.0"
|
||||||
}
|
}
|
||||||
@ -3488,9 +3488,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3355,7 +3355,7 @@
|
|||||||
"commcore": {
|
"commcore": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1"
|
"Core": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"core": {
|
"core": {
|
||||||
@ -3400,7 +3400,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3409,7 +3409,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3419,9 +3419,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3424,7 +3424,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3433,7 +3433,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3443,9 +3443,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3333,7 +3333,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3342,7 +3342,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3352,9 +3352,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3333,7 +3333,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3342,7 +3342,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3352,9 +3352,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3342,7 +3342,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.46.2",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3351,7 +3351,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.46.2",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3361,9 +3361,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.46.2",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.46.2",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.46.2"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,14 @@ namespace Bit.Identity
|
|||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
Host
|
CreateHostBuilder(args)
|
||||||
|
.Build()
|
||||||
|
.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHostBuilder CreateHostBuilder(string[] args)
|
||||||
|
{
|
||||||
|
return Host
|
||||||
.CreateDefaultBuilder(args)
|
.CreateDefaultBuilder(args)
|
||||||
.ConfigureCustomAppConfiguration(args)
|
.ConfigureCustomAppConfiguration(args)
|
||||||
.ConfigureWebHostDefaults(webBuilder =>
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
@ -34,9 +41,7 @@ namespace Bit.Identity
|
|||||||
|
|
||||||
return e.Level >= LogEventLevel.Error;
|
return e.Level >= LogEventLevel.Error;
|
||||||
}));
|
}));
|
||||||
})
|
});
|
||||||
.Build()
|
|
||||||
.Run();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3333,7 +3333,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3342,7 +3342,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3352,9 +3352,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3427,7 +3427,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3436,7 +3436,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3446,9 +3446,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3333,7 +3333,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.46.2",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3342,7 +3342,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.46.2",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
|
@ -3534,26 +3534,26 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Azure.Messaging.EventGrid": "4.7.0",
|
"Azure.Messaging.EventGrid": "4.7.0",
|
||||||
"CommCore": "1.47.1",
|
"CommCore": "1.48.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
||||||
"SharedWeb": "1.47.1",
|
"SharedWeb": "1.48.1",
|
||||||
"Swashbuckle.AspNetCore": "6.2.3"
|
"Swashbuckle.AspNetCore": "6.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commcore": {
|
"commcore": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1"
|
"Core": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Api": "1.47.1",
|
"Api": "1.48.1",
|
||||||
"AutoFixture.AutoNSubstitute": "4.14.0",
|
"AutoFixture.AutoNSubstitute": "4.14.0",
|
||||||
"AutoFixture.Xunit2": "4.14.0",
|
"AutoFixture.Xunit2": "4.14.0",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
||||||
"Microsoft.NET.Test.Sdk": "16.6.1",
|
"Microsoft.NET.Test.Sdk": "16.6.1",
|
||||||
"NSubstitute": "4.2.2",
|
"NSubstitute": "4.2.2",
|
||||||
@ -3602,7 +3602,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3611,7 +3611,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3621,9 +3621,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3625,34 +3625,34 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Azure.Messaging.EventGrid": "4.7.0",
|
"Azure.Messaging.EventGrid": "4.7.0",
|
||||||
"CommCore": "1.47.1",
|
"CommCore": "1.48.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
||||||
"SharedWeb": "1.47.1",
|
"SharedWeb": "1.48.1",
|
||||||
"Swashbuckle.AspNetCore": "6.2.3"
|
"Swashbuckle.AspNetCore": "6.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"billing": {
|
"billing": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.VisualStudio.Web.CodeGeneration.Design": "5.0.2",
|
"Microsoft.VisualStudio.Web.CodeGeneration.Design": "5.0.2",
|
||||||
"SharedWeb": "1.47.1"
|
"SharedWeb": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commcore": {
|
"commcore": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1"
|
"Core": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Api": "1.47.1",
|
"Api": "1.48.1",
|
||||||
"AutoFixture.AutoNSubstitute": "4.14.0",
|
"AutoFixture.AutoNSubstitute": "4.14.0",
|
||||||
"AutoFixture.Xunit2": "4.14.0",
|
"AutoFixture.Xunit2": "4.14.0",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
||||||
"Microsoft.NET.Test.Sdk": "16.6.1",
|
"Microsoft.NET.Test.Sdk": "16.6.1",
|
||||||
"NSubstitute": "4.2.2",
|
"NSubstitute": "4.2.2",
|
||||||
@ -3701,7 +3701,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3710,7 +3710,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3720,9 +3720,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Xunit.Sdk;
|
using Xunit.Sdk;
|
||||||
|
|
||||||
@ -84,6 +87,116 @@ namespace Bit.Test.Common.Helpers
|
|||||||
return subElement;
|
return subElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void AssertEqualJson(JsonElement a, JsonElement b)
|
||||||
|
{
|
||||||
|
switch (a.ValueKind)
|
||||||
|
{
|
||||||
|
case JsonValueKind.Array:
|
||||||
|
Assert.Equal(JsonValueKind.Array, b.ValueKind);
|
||||||
|
AssertEqualJsonArray(a, b);
|
||||||
|
break;
|
||||||
|
case JsonValueKind.Object:
|
||||||
|
Assert.Equal(JsonValueKind.Object, b.ValueKind);
|
||||||
|
AssertEqualJsonObject(a, b);
|
||||||
|
break;
|
||||||
|
case JsonValueKind.False:
|
||||||
|
Assert.Equal(JsonValueKind.False, b.ValueKind);
|
||||||
|
break;
|
||||||
|
case JsonValueKind.True:
|
||||||
|
Assert.Equal(JsonValueKind.True, b.ValueKind);
|
||||||
|
break;
|
||||||
|
case JsonValueKind.Number:
|
||||||
|
Assert.Equal(JsonValueKind.Number, b.ValueKind);
|
||||||
|
Assert.Equal(a.GetDouble(), b.GetDouble());
|
||||||
|
break;
|
||||||
|
case JsonValueKind.String:
|
||||||
|
Assert.Equal(JsonValueKind.String, b.ValueKind);
|
||||||
|
Assert.Equal(a.GetString(), b.GetString());
|
||||||
|
break;
|
||||||
|
case JsonValueKind.Null:
|
||||||
|
Assert.Equal(JsonValueKind.Null, b.ValueKind);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new XunitException($"Bad JsonValueKind '{a.ValueKind}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AssertEqualJsonObject(JsonElement a, JsonElement b)
|
||||||
|
{
|
||||||
|
Debug.Assert(a.ValueKind == JsonValueKind.Object && b.ValueKind == JsonValueKind.Object);
|
||||||
|
|
||||||
|
var aObjectEnumerator = a.EnumerateObject();
|
||||||
|
var bObjectEnumerator = b.EnumerateObject();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var aCanMove = aObjectEnumerator.MoveNext();
|
||||||
|
var bCanMove = bObjectEnumerator.MoveNext();
|
||||||
|
|
||||||
|
if (aCanMove)
|
||||||
|
{
|
||||||
|
Assert.True(bCanMove, $"a was able to enumerate over object '{a}' but b was NOT able to '{b}'");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.False(bCanMove, $"a was NOT able to enumerate over object '{a}' but b was able to '{b}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aCanMove == false && bCanMove == false)
|
||||||
|
{
|
||||||
|
// They both can't continue to enumerate at the same time, that is valid
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var aProp = aObjectEnumerator.Current;
|
||||||
|
var bProp = bObjectEnumerator.Current;
|
||||||
|
|
||||||
|
Assert.Equal(aProp.Name, bProp.Name);
|
||||||
|
// Recursion!
|
||||||
|
AssertEqualJson(aProp.Value, bProp.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AssertEqualJsonArray(JsonElement a, JsonElement b)
|
||||||
|
{
|
||||||
|
Debug.Assert(a.ValueKind == JsonValueKind.Array && b.ValueKind == JsonValueKind.Array);
|
||||||
|
|
||||||
|
var aArrayEnumerator = a.EnumerateArray();
|
||||||
|
var bArrayEnumerator = b.EnumerateArray();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var aCanMove = aArrayEnumerator.MoveNext();
|
||||||
|
var bCanMove = bArrayEnumerator.MoveNext();
|
||||||
|
|
||||||
|
if (aCanMove)
|
||||||
|
{
|
||||||
|
Assert.True(bCanMove, $"a was able to enumerate over array '{a}' but b was NOT able to '{b}'");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.False(bCanMove, $"a was NOT able to enumerate over array '{a}' but b was able to '{b}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aCanMove == false && bCanMove == false)
|
||||||
|
{
|
||||||
|
// They both can't continue to enumerate at the same time, that is valid
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var aElement = aArrayEnumerator.Current;
|
||||||
|
var bElement = bArrayEnumerator.Current;
|
||||||
|
|
||||||
|
// Recursion!
|
||||||
|
AssertEqualJson(aElement, bElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async static Task<T> AssertResponseTypeIs<T>(HttpContext context)
|
||||||
|
{
|
||||||
|
return await JsonSerializer.DeserializeAsync<T>(context.Response.Body);
|
||||||
|
}
|
||||||
|
|
||||||
public static TimeSpan AssertRecent(DateTime dateTime, int skewSeconds = 2)
|
public static TimeSpan AssertRecent(DateTime dateTime, int skewSeconds = 2)
|
||||||
=> AssertRecent(dateTime, TimeSpan.FromSeconds(skewSeconds));
|
=> AssertRecent(dateTime, TimeSpan.FromSeconds(skewSeconds));
|
||||||
|
|
||||||
|
@ -3530,17 +3530,17 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Azure.Messaging.EventGrid": "4.7.0",
|
"Azure.Messaging.EventGrid": "4.7.0",
|
||||||
"CommCore": "1.47.1",
|
"CommCore": "1.48.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
||||||
"SharedWeb": "1.47.1",
|
"SharedWeb": "1.48.1",
|
||||||
"Swashbuckle.AspNetCore": "6.2.3"
|
"Swashbuckle.AspNetCore": "6.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commcore": {
|
"commcore": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1"
|
"Core": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"core": {
|
"core": {
|
||||||
@ -3585,7 +3585,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3594,7 +3594,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3604,9 +3604,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using AutoFixture;
|
using AutoFixture;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
@ -13,6 +14,9 @@ using Bit.Infrastructure.Dapper;
|
|||||||
using Bit.Test.Common.AutoFixture;
|
using Bit.Test.Common.AutoFixture;
|
||||||
using Bit.Test.Common.AutoFixture.Attributes;
|
using Bit.Test.Common.AutoFixture.Attributes;
|
||||||
using IdentityModel;
|
using IdentityModel;
|
||||||
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
using NSubstitute;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Bit.Core.Test.Utilities
|
namespace Bit.Core.Test.Utilities
|
||||||
@ -390,6 +394,47 @@ namespace Bit.Core.Test.Utilities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> TokenIsValidData()
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
"first_part 476669d4-9642-4af8-9b29-9366efad4ed3 test@email.com {0}", // unprotectedTokenTemplate
|
||||||
|
"first_part", // firstPart
|
||||||
|
"test@email.com", // email
|
||||||
|
Guid.Parse("476669d4-9642-4af8-9b29-9366efad4ed3"), // id
|
||||||
|
DateTime.UtcNow.AddHours(-1), // creationTime
|
||||||
|
12, // expirationInHours
|
||||||
|
true, // isValid
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(TokenIsValidData))]
|
||||||
|
public void TokenIsValid_Success(string unprotectedTokenTemplate, string firstPart, string userEmail, Guid id, DateTime creationTime, double expirationInHours, bool isValid)
|
||||||
|
{
|
||||||
|
var protector = new TestDataProtector(string.Format(unprotectedTokenTemplate, CoreHelpers.ToEpocMilliseconds(creationTime)));
|
||||||
|
|
||||||
|
Assert.Equal(isValid, CoreHelpers.TokenIsValid(firstPart, protector, "protected_token", userEmail, id, expirationInHours));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestDataProtector : IDataProtector
|
||||||
|
{
|
||||||
|
private readonly string _token;
|
||||||
|
public TestDataProtector(string token)
|
||||||
|
{
|
||||||
|
_token = token;
|
||||||
|
}
|
||||||
|
public IDataProtector CreateProtector(string purpose) => throw new NotImplementedException();
|
||||||
|
public byte[] Protect(byte[] plaintext) => throw new NotImplementedException();
|
||||||
|
public byte[] Unprotect(byte[] protectedData)
|
||||||
|
{
|
||||||
|
return Encoding.UTF8.GetBytes(_token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("hi@email.com", "hi@email.com")] // Short email with no room to obfuscate
|
[InlineData("hi@email.com", "hi@email.com")] // Short email with no room to obfuscate
|
||||||
[InlineData("name@email.com", "na**@email.com")] // Can obfuscate
|
[InlineData("name@email.com", "na**@email.com")] // Can obfuscate
|
||||||
|
@ -3546,26 +3546,26 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Azure.Messaging.EventGrid": "4.7.0",
|
"Azure.Messaging.EventGrid": "4.7.0",
|
||||||
"CommCore": "1.47.1",
|
"CommCore": "1.48.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
||||||
"SharedWeb": "1.47.1",
|
"SharedWeb": "1.48.1",
|
||||||
"Swashbuckle.AspNetCore": "6.2.3"
|
"Swashbuckle.AspNetCore": "6.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commcore": {
|
"commcore": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1"
|
"Core": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Api": "1.47.1",
|
"Api": "1.48.1",
|
||||||
"AutoFixture.AutoNSubstitute": "4.14.0",
|
"AutoFixture.AutoNSubstitute": "4.14.0",
|
||||||
"AutoFixture.Xunit2": "4.14.0",
|
"AutoFixture.Xunit2": "4.14.0",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
||||||
"Microsoft.NET.Test.Sdk": "16.6.1",
|
"Microsoft.NET.Test.Sdk": "16.6.1",
|
||||||
"NSubstitute": "4.2.2",
|
"NSubstitute": "4.2.2",
|
||||||
@ -3614,7 +3614,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3623,7 +3623,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3633,9 +3633,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3473,14 +3473,14 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AngleSharp": "0.14.0",
|
"AngleSharp": "0.14.0",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"SharedWeb": "1.47.1"
|
"SharedWeb": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3489,7 +3489,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3499,9 +3499,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Models.Api.Request.Accounts;
|
||||||
|
using Bit.IntegrationTestCommon.Factories;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Bit.Identity.IntegrationTest.Controllers
|
||||||
|
{
|
||||||
|
public class AccountsControllerTests : IClassFixture<IdentityApplicationFactory>
|
||||||
|
{
|
||||||
|
private readonly IdentityApplicationFactory _factory;
|
||||||
|
|
||||||
|
public AccountsControllerTests(IdentityApplicationFactory factory)
|
||||||
|
{
|
||||||
|
_factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PostRegister_Success()
|
||||||
|
{
|
||||||
|
var context = await _factory.RegisterAsync(new RegisterRequestModel
|
||||||
|
{
|
||||||
|
Email = "test+register@email.com",
|
||||||
|
MasterPasswordHash = "master_password_hash"
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
|
||||||
|
|
||||||
|
var database = _factory.GetDatabaseContext();
|
||||||
|
var user = await database.Users
|
||||||
|
.SingleAsync(u => u.Email == "test+register@email.com");
|
||||||
|
|
||||||
|
Assert.NotNull(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
454
test/Identity.IntegrationTest/Endpoints/IdentityServerTests.cs
Normal file
454
test/Identity.IntegrationTest/Endpoints/IdentityServerTests.cs
Normal file
@ -0,0 +1,454 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Entities;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Models.Api.Request.Accounts;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
|
using Bit.IntegrationTestCommon.Factories;
|
||||||
|
using Bit.Test.Common.AutoFixture.Attributes;
|
||||||
|
using Bit.Test.Common.Helpers;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Bit.Identity.IntegrationTest.Endpoints
|
||||||
|
{
|
||||||
|
public class IdentityServerTests : IClassFixture<IdentityApplicationFactory>
|
||||||
|
{
|
||||||
|
private const int SecondsInMinute = 60;
|
||||||
|
private const int MinutesInHour = 60;
|
||||||
|
private const int SecondsInHour = SecondsInMinute * MinutesInHour;
|
||||||
|
private readonly IdentityApplicationFactory _factory;
|
||||||
|
|
||||||
|
public IdentityServerTests(IdentityApplicationFactory factory)
|
||||||
|
{
|
||||||
|
_factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task WellKnownEndpoint_Success()
|
||||||
|
{
|
||||||
|
var context = await _factory.Server.GetAsync("/.well-known/openid-configuration");
|
||||||
|
|
||||||
|
using var body = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context);
|
||||||
|
var endpointRoot = body.RootElement;
|
||||||
|
|
||||||
|
// WARNING: Edits to this file should NOT just be made to "get the test to work" they should be made when intentional
|
||||||
|
// changes were made to this endpoint and proper testing will take place to ensure clients are backwards compatible
|
||||||
|
// or loss of functionality is properly noted.
|
||||||
|
await using var fs = File.OpenRead("openid-configuration.json");
|
||||||
|
using var knownConfiguration = await JsonSerializer.DeserializeAsync<JsonDocument>(fs);
|
||||||
|
var knownConfigurationRoot = knownConfiguration.RootElement;
|
||||||
|
|
||||||
|
AssertHelper.AssertEqualJson(endpointRoot, knownConfigurationRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypePassword_Success()
|
||||||
|
{
|
||||||
|
var deviceId = "92b9d953-b9b6-4eaf-9d3e-11d57144dfeb";
|
||||||
|
var username = "test+tokenpassword@email.com";
|
||||||
|
|
||||||
|
await _factory.RegisterAsync(new RegisterRequestModel
|
||||||
|
{
|
||||||
|
Email = username,
|
||||||
|
MasterPasswordHash = "master_password_hash"
|
||||||
|
});
|
||||||
|
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "scope", "api offline_access" },
|
||||||
|
{ "client_id", "web" },
|
||||||
|
{ "deviceType", DeviceTypeAsString(DeviceType.FirefoxBrowser) },
|
||||||
|
{ "deviceIdentifier", deviceId },
|
||||||
|
{ "deviceName", "firefox" },
|
||||||
|
{ "grant_type", "password" },
|
||||||
|
{ "username", username },
|
||||||
|
{ "password", "master_password_hash" },
|
||||||
|
}), context => context.Request.Headers.Add("Auth-Email", CoreHelpers.Base64UrlEncodeString(username)));
|
||||||
|
|
||||||
|
using var body = await AssertDefaultTokenBodyAsync(context);
|
||||||
|
var root = body.RootElement;
|
||||||
|
AssertRefreshTokenExists(root);
|
||||||
|
AssertHelper.AssertJsonProperty(root, "ForcePasswordReset", JsonValueKind.False);
|
||||||
|
AssertHelper.AssertJsonProperty(root, "ResetMasterPassword", JsonValueKind.False);
|
||||||
|
var kdf = AssertHelper.AssertJsonProperty(root, "Kdf", JsonValueKind.Number).GetInt32();
|
||||||
|
Assert.Equal(0, kdf);
|
||||||
|
var kdfIterations = AssertHelper.AssertJsonProperty(root, "KdfIterations", JsonValueKind.Number).GetInt32();
|
||||||
|
Assert.Equal(5000, kdfIterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypePassword_NoAuthEmailHeader_Fails()
|
||||||
|
{
|
||||||
|
var deviceId = "92b9d953-b9b6-4eaf-9d3e-11d57144dfeb";
|
||||||
|
var username = "test+noauthemailheader@email.com";
|
||||||
|
|
||||||
|
await _factory.RegisterAsync(new RegisterRequestModel
|
||||||
|
{
|
||||||
|
Email = username,
|
||||||
|
MasterPasswordHash = "master_password_hash",
|
||||||
|
});
|
||||||
|
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "scope", "api offline_access" },
|
||||||
|
{ "client_id", "web" },
|
||||||
|
{ "deviceType", DeviceTypeAsString(DeviceType.FirefoxBrowser) },
|
||||||
|
{ "deviceIdentifier", deviceId },
|
||||||
|
{ "deviceName", "firefox" },
|
||||||
|
{ "grant_type", "password" },
|
||||||
|
{ "username", username },
|
||||||
|
{ "password", "master_password_hash" },
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
|
||||||
|
|
||||||
|
var body = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context);
|
||||||
|
var root = body.RootElement;
|
||||||
|
|
||||||
|
var error = AssertHelper.AssertJsonProperty(root, "error", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("invalid_grant", error);
|
||||||
|
AssertHelper.AssertJsonProperty(root, "error_description", JsonValueKind.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypePassword_InvalidBase64AuthEmailHeader_Fails()
|
||||||
|
{
|
||||||
|
var deviceId = "92b9d953-b9b6-4eaf-9d3e-11d57144dfeb";
|
||||||
|
var username = "test+badauthheader@email.com";
|
||||||
|
|
||||||
|
await _factory.RegisterAsync(new RegisterRequestModel
|
||||||
|
{
|
||||||
|
Email = username,
|
||||||
|
MasterPasswordHash = "master_password_hash",
|
||||||
|
});
|
||||||
|
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "scope", "api offline_access" },
|
||||||
|
{ "client_id", "web" },
|
||||||
|
{ "deviceType", DeviceTypeAsString(DeviceType.FirefoxBrowser) },
|
||||||
|
{ "deviceIdentifier", deviceId },
|
||||||
|
{ "deviceName", "firefox" },
|
||||||
|
{ "grant_type", "password" },
|
||||||
|
{ "username", username },
|
||||||
|
{ "password", "master_password_hash" },
|
||||||
|
}), context => context.Request.Headers.Add("Auth-Email", "bad_value"));
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
|
||||||
|
|
||||||
|
var body = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context);
|
||||||
|
var root = body.RootElement;
|
||||||
|
|
||||||
|
var error = AssertHelper.AssertJsonProperty(root, "error", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("invalid_grant", error);
|
||||||
|
AssertHelper.AssertJsonProperty(root, "error_description", JsonValueKind.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypePassword_WrongAuthEmailHeader_Fails()
|
||||||
|
{
|
||||||
|
var deviceId = "92b9d953-b9b6-4eaf-9d3e-11d57144dfeb";
|
||||||
|
var username = "test+badauthheader@email.com";
|
||||||
|
|
||||||
|
await _factory.RegisterAsync(new RegisterRequestModel
|
||||||
|
{
|
||||||
|
Email = username,
|
||||||
|
MasterPasswordHash = "master_password_hash",
|
||||||
|
});
|
||||||
|
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "scope", "api offline_access" },
|
||||||
|
{ "client_id", "web" },
|
||||||
|
{ "deviceType", DeviceTypeAsString(DeviceType.FirefoxBrowser) },
|
||||||
|
{ "deviceIdentifier", deviceId },
|
||||||
|
{ "deviceName", "firefox" },
|
||||||
|
{ "grant_type", "password" },
|
||||||
|
{ "username", username },
|
||||||
|
{ "password", "master_password_hash" },
|
||||||
|
}), context => context.Request.Headers.Add("Auth-Email", CoreHelpers.Base64UrlEncodeString("bad_value")));
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
|
||||||
|
|
||||||
|
var body = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context);
|
||||||
|
var root = body.RootElement;
|
||||||
|
|
||||||
|
var error = AssertHelper.AssertJsonProperty(root, "error", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("invalid_grant", error);
|
||||||
|
AssertHelper.AssertJsonProperty(root, "error_description", JsonValueKind.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypeRefreshToken_Success()
|
||||||
|
{
|
||||||
|
var deviceId = "5a7b19df-0c9d-46bf-a104-8034b5a17182";
|
||||||
|
var username = "test+tokenrefresh@email.com";
|
||||||
|
|
||||||
|
await _factory.RegisterAsync(new RegisterRequestModel
|
||||||
|
{
|
||||||
|
Email = username,
|
||||||
|
MasterPasswordHash = "master_password_hash",
|
||||||
|
});
|
||||||
|
|
||||||
|
var (_, refreshToken) = await _factory.TokenFromPasswordAsync(username, "master_password_hash", deviceId);
|
||||||
|
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "grant_type", "refresh_token" },
|
||||||
|
{ "client_id", "web" },
|
||||||
|
{ "refresh_token", refreshToken },
|
||||||
|
}));
|
||||||
|
|
||||||
|
using var body = await AssertDefaultTokenBodyAsync(context);
|
||||||
|
AssertRefreshTokenExists(body.RootElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypeClientCredentials_Success()
|
||||||
|
{
|
||||||
|
var username = "test+tokenclientcredentials@email.com";
|
||||||
|
var deviceId = "8f14a393-edfe-40ba-8c67-a856cb89c509";
|
||||||
|
|
||||||
|
await _factory.RegisterAsync(new RegisterRequestModel
|
||||||
|
{
|
||||||
|
Email = username,
|
||||||
|
MasterPasswordHash = "master_password_hash",
|
||||||
|
});
|
||||||
|
|
||||||
|
var database = _factory.GetDatabaseContext();
|
||||||
|
var user = await database.Users
|
||||||
|
.FirstAsync(u => u.Email == username);
|
||||||
|
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "grant_type", "client_credentials" },
|
||||||
|
{ "client_id", $"user.{user.Id}" },
|
||||||
|
{ "client_secret", user.ApiKey },
|
||||||
|
{ "scope", "api" },
|
||||||
|
{ "DeviceIdentifier", deviceId },
|
||||||
|
{ "DeviceType", DeviceTypeAsString(DeviceType.FirefoxBrowser) },
|
||||||
|
{ "DeviceName", "firefox" },
|
||||||
|
}));
|
||||||
|
|
||||||
|
await AssertDefaultTokenBodyAsync(context, "api");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData]
|
||||||
|
public async Task TokenEndpoint_GrantTypeClientCredentials_AsOrganization_Success(Organization organization, OrganizationApiKey organizationApiKey)
|
||||||
|
{
|
||||||
|
var orgRepo = _factory.Services.GetRequiredService<IOrganizationRepository>();
|
||||||
|
organization = await orgRepo.CreateAsync(organization);
|
||||||
|
organizationApiKey.OrganizationId = organization.Id;
|
||||||
|
organizationApiKey.Type = OrganizationApiKeyType.Default;
|
||||||
|
|
||||||
|
var orgApiKeyRepo = _factory.Services.GetRequiredService<IOrganizationApiKeyRepository>();
|
||||||
|
await orgApiKeyRepo.CreateAsync(organizationApiKey);
|
||||||
|
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "grant_type", "client_credentials" },
|
||||||
|
{ "client_id", $"organization.{organization.Id}" },
|
||||||
|
{ "client_secret", organizationApiKey.ApiKey },
|
||||||
|
{ "scope", "api.organization" },
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
|
||||||
|
|
||||||
|
await AssertDefaultTokenBodyAsync(context, "api.organization");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypeClientCredentials_AsOrganization_BadOrgId_Fails()
|
||||||
|
{
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "grant_type", "client_credentials" },
|
||||||
|
{ "client_id", "organization.bad_guid_zz&" },
|
||||||
|
{ "client_secret", "something" },
|
||||||
|
{ "scope", "api.organization" },
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
|
||||||
|
|
||||||
|
var errorBody = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context);
|
||||||
|
var error = AssertHelper.AssertJsonProperty(errorBody.RootElement, "error", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("invalid_client", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This test currently does not test any code that is not covered by other tests but
|
||||||
|
/// it shows that we probably have some dead code in <see cref="Core.IdentityServer.ClientStore"/>
|
||||||
|
/// for installation, organization, and user they split on a <c>'.'</c> but have already checked that at least one
|
||||||
|
/// <c>'.'</c> exists in the <c>client_id</c> by checking it with <see cref="string.StartsWith(string)"/>
|
||||||
|
/// I believe that idParts.Length > 1 will ALWAYS return true
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypeClientCredentials_AsOrganization_NoIdPart_Fails()
|
||||||
|
{
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "grant_type", "client_credentials" },
|
||||||
|
{ "client_id", "organization." },
|
||||||
|
{ "client_secret", "something" },
|
||||||
|
{ "scope", "api.organization" },
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
|
||||||
|
|
||||||
|
var errorBody = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context);
|
||||||
|
var error = AssertHelper.AssertJsonProperty(errorBody.RootElement, "error", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("invalid_client", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypeClientCredentials_AsOrganization_OrgDoesNotExist_Fails()
|
||||||
|
{
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "grant_type", "client_credentials" },
|
||||||
|
{ "client_id", $"organization.{Guid.NewGuid()}" },
|
||||||
|
{ "client_secret", "something" },
|
||||||
|
{ "scope", "api.organization" },
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
|
||||||
|
|
||||||
|
var errorBody = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context);
|
||||||
|
var error = AssertHelper.AssertJsonProperty(errorBody.RootElement, "error", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("invalid_client", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData]
|
||||||
|
public async Task TokenEndpoint_GrantTypeClientCredentials_AsInstallation_InstallationExists_Succeeds(Installation installation)
|
||||||
|
{
|
||||||
|
var installationRepo = _factory.Services.GetRequiredService<IInstallationRepository>();
|
||||||
|
installation = await installationRepo.CreateAsync(installation);
|
||||||
|
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "grant_type", "client_credentials" },
|
||||||
|
{ "client_id", $"installation.{installation.Id}" },
|
||||||
|
{ "client_secret", installation.Key },
|
||||||
|
{ "scope", "api.push" },
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
|
||||||
|
await AssertDefaultTokenBodyAsync(context, "api.push", 24 * SecondsInHour);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypeClientCredentials_AsInstallation_InstallationDoesNotExist_Fails()
|
||||||
|
{
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "grant_type", "client_credentials" },
|
||||||
|
{ "client_id", $"installation.{Guid.NewGuid()}" },
|
||||||
|
{ "client_secret", "something" },
|
||||||
|
{ "scope", "api.push" },
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
|
||||||
|
|
||||||
|
var errorBody = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context);
|
||||||
|
var error = AssertHelper.AssertJsonProperty(errorBody.RootElement, "error", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("invalid_client", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypeClientCredentials_AsInstallation_BadInsallationId_Fails()
|
||||||
|
{
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "grant_type", "client_credentials" },
|
||||||
|
{ "client_id", "organization.bad_guid_zz&" },
|
||||||
|
{ "client_secret", "something" },
|
||||||
|
{ "scope", "api.organization" },
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
|
||||||
|
|
||||||
|
var errorBody = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context);
|
||||||
|
var error = AssertHelper.AssertJsonProperty(errorBody.RootElement, "error", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("invalid_client", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="TokenEndpoint_GrantTypeClientCredentials_AsOrganization_NoIdPart_Fails"/>
|
||||||
|
[Fact]
|
||||||
|
public async Task TokenEndpoint_GrantTypeClientCredentials_AsInstallation_NoIdPart_Fails()
|
||||||
|
{
|
||||||
|
var context = await _factory.Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "grant_type", "client_credentials" },
|
||||||
|
{ "client_id", "installation." },
|
||||||
|
{ "client_secret", "something" },
|
||||||
|
{ "scope", "api.push" },
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
|
||||||
|
|
||||||
|
var errorBody = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context);
|
||||||
|
var error = AssertHelper.AssertJsonProperty(errorBody.RootElement, "error", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("invalid_client", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string DeviceTypeAsString(DeviceType deviceType)
|
||||||
|
{
|
||||||
|
return ((int)deviceType).ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<JsonDocument> AssertDefaultTokenBodyAsync(HttpContext httpContext, string expectedScope = "api offline_access", int expectedExpiresIn = SecondsInHour * 1)
|
||||||
|
{
|
||||||
|
var body = await AssertHelper.AssertResponseTypeIs<JsonDocument>(httpContext);
|
||||||
|
var root = body.RootElement;
|
||||||
|
|
||||||
|
Assert.Equal(JsonValueKind.Object, root.ValueKind);
|
||||||
|
AssertAccessTokenExists(root);
|
||||||
|
AssertExpiresIn(root, expectedExpiresIn);
|
||||||
|
AssertTokenType(root);
|
||||||
|
AssertScope(root, expectedScope);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AssertTokenType(JsonElement tokenResponse)
|
||||||
|
{
|
||||||
|
var tokenTypeProperty = AssertHelper.AssertJsonProperty(tokenResponse, "token_type", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("Bearer", tokenTypeProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int AssertExpiresIn(JsonElement tokenResponse, int expectedExpiresIn = 3600)
|
||||||
|
{
|
||||||
|
var expiresIn = AssertHelper.AssertJsonProperty(tokenResponse, "expires_in", JsonValueKind.Number).GetInt32();
|
||||||
|
Assert.Equal(expectedExpiresIn, expiresIn);
|
||||||
|
return expiresIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string AssertAccessTokenExists(JsonElement tokenResponse)
|
||||||
|
{
|
||||||
|
return AssertHelper.AssertJsonProperty(tokenResponse, "access_token", JsonValueKind.String).GetString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string AssertRefreshTokenExists(JsonElement tokenResponse)
|
||||||
|
{
|
||||||
|
return AssertHelper.AssertJsonProperty(tokenResponse, "refresh_token", JsonValueKind.String).GetString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string AssertScopeExists(JsonElement tokenResponse)
|
||||||
|
{
|
||||||
|
return AssertHelper.AssertJsonProperty(tokenResponse, "scope", JsonValueKind.String).GetString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AssertScope(JsonElement tokenResponse, string expectedScope)
|
||||||
|
{
|
||||||
|
var actualScope = AssertScopeExists(tokenResponse);
|
||||||
|
Assert.Equal(expectedScope, actualScope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.0.3">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.15" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
|
||||||
|
<PackageReference Include="NSubstitute" Version="4.2.2" />
|
||||||
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.2">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="AutoFixture.Xunit2" Version="4.14.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Identity\Identity.csproj" />
|
||||||
|
<ProjectReference Include="..\Common\Common.csproj" />
|
||||||
|
<ProjectReference Include="..\IntegrationTestCommon\IntegrationTestCommon.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
12
test/Identity.IntegrationTest/Properties/launchSettings.json
Normal file
12
test/Identity.IntegrationTest/Properties/launchSettings.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"Identity.IntegrationTest": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": false,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"applicationUrl": "https://localhost:55088;http://localhost:55089"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
test/Identity.IntegrationTest/openid-configuration.json
Normal file
69
test/Identity.IntegrationTest/openid-configuration.json
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"issuer": "http://localhost",
|
||||||
|
"jwks_uri": "http://localhost:33656/.well-known/openid-configuration/jwks",
|
||||||
|
"authorization_endpoint": "http://localhost:33656/connect/authorize",
|
||||||
|
"token_endpoint": "http://localhost:33656/connect/token",
|
||||||
|
"device_authorization_endpoint": "http://localhost:33656/connect/deviceauthorization",
|
||||||
|
"scopes_supported": [
|
||||||
|
"api",
|
||||||
|
"api.push",
|
||||||
|
"api.licensing",
|
||||||
|
"api.organization",
|
||||||
|
"api.installation",
|
||||||
|
"internal",
|
||||||
|
"offline_access"
|
||||||
|
],
|
||||||
|
"claims_supported": [
|
||||||
|
"name",
|
||||||
|
"email",
|
||||||
|
"email_verified",
|
||||||
|
"sstamp",
|
||||||
|
"premium",
|
||||||
|
"device",
|
||||||
|
"orgowner",
|
||||||
|
"orgadmin",
|
||||||
|
"orgmanager",
|
||||||
|
"orguser",
|
||||||
|
"orgcustom",
|
||||||
|
"providerprovideradmin",
|
||||||
|
"providerserviceuser",
|
||||||
|
"sub"
|
||||||
|
],
|
||||||
|
"grant_types_supported": [
|
||||||
|
"authorization_code",
|
||||||
|
"client_credentials",
|
||||||
|
"refresh_token",
|
||||||
|
"implicit",
|
||||||
|
"password",
|
||||||
|
"urn:ietf:params:oauth:grant-type:device_code"
|
||||||
|
],
|
||||||
|
"response_types_supported": [
|
||||||
|
"code",
|
||||||
|
"token",
|
||||||
|
"id_token",
|
||||||
|
"id_token token",
|
||||||
|
"code id_token",
|
||||||
|
"code token",
|
||||||
|
"code id_token token"
|
||||||
|
],
|
||||||
|
"response_modes_supported": [
|
||||||
|
"form_post",
|
||||||
|
"query",
|
||||||
|
"fragment"
|
||||||
|
],
|
||||||
|
"token_endpoint_auth_methods_supported": [
|
||||||
|
"client_secret_basic",
|
||||||
|
"client_secret_post"
|
||||||
|
],
|
||||||
|
"id_token_signing_alg_values_supported": [
|
||||||
|
"RS256"
|
||||||
|
],
|
||||||
|
"subject_types_supported": [
|
||||||
|
"public"
|
||||||
|
],
|
||||||
|
"code_challenge_methods_supported": [
|
||||||
|
"plain",
|
||||||
|
"S256"
|
||||||
|
],
|
||||||
|
"request_parameter_supported": true
|
||||||
|
}
|
3768
test/Identity.IntegrationTest/packages.lock.json
Normal file
3768
test/Identity.IntegrationTest/packages.lock.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -3534,26 +3534,26 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Azure.Messaging.EventGrid": "4.7.0",
|
"Azure.Messaging.EventGrid": "4.7.0",
|
||||||
"CommCore": "1.47.1",
|
"CommCore": "1.48.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
||||||
"SharedWeb": "1.47.1",
|
"SharedWeb": "1.48.1",
|
||||||
"Swashbuckle.AspNetCore": "6.2.3"
|
"Swashbuckle.AspNetCore": "6.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commcore": {
|
"commcore": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1"
|
"Core": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Api": "1.47.1",
|
"Api": "1.48.1",
|
||||||
"AutoFixture.AutoNSubstitute": "4.14.0",
|
"AutoFixture.AutoNSubstitute": "4.14.0",
|
||||||
"AutoFixture.Xunit2": "4.14.0",
|
"AutoFixture.Xunit2": "4.14.0",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
"Kralizek.AutoFixture.Extensions.MockHttp": "1.2.0",
|
||||||
"Microsoft.NET.Test.Sdk": "16.6.1",
|
"Microsoft.NET.Test.Sdk": "16.6.1",
|
||||||
"NSubstitute": "4.2.2",
|
"NSubstitute": "4.2.2",
|
||||||
@ -3602,14 +3602,14 @@
|
|||||||
"identity": {
|
"identity": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"SharedWeb": "1.47.1"
|
"SharedWeb": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3618,7 +3618,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3628,9 +3628,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Models.Api.Request.Accounts;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
|
using Bit.Identity;
|
||||||
|
using Bit.Test.Common.Helpers;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
namespace Bit.IntegrationTestCommon.Factories
|
||||||
|
{
|
||||||
|
public class IdentityApplicationFactory : WebApplicationFactoryBase<Startup>
|
||||||
|
{
|
||||||
|
public const string DefaultDeviceIdentifier = "92b9d953-b9b6-4eaf-9d3e-11d57144dfeb";
|
||||||
|
|
||||||
|
public async Task<HttpContext> RegisterAsync(RegisterRequestModel model)
|
||||||
|
{
|
||||||
|
return await Server.PostAsync("/accounts/register", JsonContent.Create(model));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(string Token, string RefreshToken)> TokenFromPasswordAsync(string username,
|
||||||
|
string password,
|
||||||
|
string deviceIdentifier = DefaultDeviceIdentifier,
|
||||||
|
string clientId = "web",
|
||||||
|
DeviceType deviceType = DeviceType.FirefoxBrowser,
|
||||||
|
string deviceName = "firefox")
|
||||||
|
{
|
||||||
|
var context = await Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "scope", "api offline_access" },
|
||||||
|
{ "client_id", clientId },
|
||||||
|
{ "deviceType", ((int)deviceType).ToString() },
|
||||||
|
{ "deviceIdentifier", deviceIdentifier },
|
||||||
|
{ "deviceName", deviceName },
|
||||||
|
{ "grant_type", "password" },
|
||||||
|
{ "username", username },
|
||||||
|
{ "password", password },
|
||||||
|
}), context => context.Request.Headers.Add("Auth-Email", CoreHelpers.Base64UrlEncodeString(username)));
|
||||||
|
|
||||||
|
using var body = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context);
|
||||||
|
var root = body.RootElement;
|
||||||
|
|
||||||
|
return (root.GetProperty("access_token").GetString(), root.GetProperty("refresh_token").GetString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using AspNetCoreRateLimit;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
|
using Bit.Infrastructure.EntityFramework.Repositories;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Testing;
|
||||||
|
using Microsoft.AspNetCore.TestHost;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Bit.IntegrationTestCommon.Factories
|
||||||
|
{
|
||||||
|
public static class FactoryConstants
|
||||||
|
{
|
||||||
|
public const string DefaultDatabaseName = "test_database";
|
||||||
|
public const string WhitelistedIp = "1.1.1.1";
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class WebApplicationFactoryBase<T> : WebApplicationFactory<T>
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The database name to use for this instance of the factory. By default it will use a shared database name so all instances will connect to the same database during it's lifetime.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This will need to be set BEFORE using the <c>Server</c> property
|
||||||
|
/// </remarks>
|
||||||
|
public string DatabaseName { get; set; } = FactoryConstants.DefaultDatabaseName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configure the web host to use an EF in memory database
|
||||||
|
/// </summary>
|
||||||
|
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
||||||
|
{
|
||||||
|
builder.ConfigureAppConfiguration(c =>
|
||||||
|
{
|
||||||
|
c.AddInMemoryCollection(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
// Manually insert a EF provider so that ConfigureServices will add EF repositories but we will override
|
||||||
|
// DbContextOptions to use an in memory database
|
||||||
|
{ "globalSettings:databaseProvider", "postgres" },
|
||||||
|
{ "globalSettings:postgreSql:connectionString", "Host=localhost;Username=test;Password=test;Database=test" },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.ConfigureTestServices(services =>
|
||||||
|
{
|
||||||
|
var dbContextOptions = services.First(sd => sd.ServiceType == typeof(DbContextOptions<DatabaseContext>));
|
||||||
|
services.Remove(dbContextOptions);
|
||||||
|
services.AddScoped(_ =>
|
||||||
|
{
|
||||||
|
return new DbContextOptionsBuilder<DatabaseContext>()
|
||||||
|
.UseInMemoryDatabase(DatabaseName)
|
||||||
|
.Options;
|
||||||
|
});
|
||||||
|
|
||||||
|
// QUESTION: The normal licensing service should run fine on developer machines but not in CI
|
||||||
|
// should we have a fork here to leave the normal service for developers?
|
||||||
|
// TODO: Eventually add the license file to CI
|
||||||
|
var licensingService = services.First(sd => sd.ServiceType == typeof(ILicensingService));
|
||||||
|
services.Remove(licensingService);
|
||||||
|
services.AddSingleton<ILicensingService, NoopLicensingService>();
|
||||||
|
|
||||||
|
// FUTURE CONSIDERATION: Add way to run this self hosted/cloud, for now it is cloud only
|
||||||
|
var pushRegistrationService = services.First(sd => sd.ServiceType == typeof(IPushRegistrationService));
|
||||||
|
services.Remove(pushRegistrationService);
|
||||||
|
services.AddSingleton<IPushRegistrationService, NoopPushRegistrationService>();
|
||||||
|
|
||||||
|
// Even though we are cloud we currently set this up as cloud, we can use the EF/selfhosted service
|
||||||
|
// instead of using Noop for this service
|
||||||
|
// TODO: Install and use azurite in CI pipeline
|
||||||
|
var eventWriteService = services.First(sd => sd.ServiceType == typeof(IEventWriteService));
|
||||||
|
services.Remove(eventWriteService);
|
||||||
|
services.AddSingleton<IEventWriteService, RepositoryEventWriteService>();
|
||||||
|
|
||||||
|
var eventRepositoryService = services.First(sd => sd.ServiceType == typeof(IEventRepository));
|
||||||
|
services.Remove(eventRepositoryService);
|
||||||
|
services.AddSingleton<IEventRepository, EventRepository>();
|
||||||
|
|
||||||
|
// Our Rate limiter works so well that it begins to fail tests unless we carve out
|
||||||
|
// one whitelisted ip. We should still test the rate limiter though and they should change the Ip
|
||||||
|
// to something that is NOT whitelisted
|
||||||
|
services.Configure<IpRateLimitOptions>(options =>
|
||||||
|
{
|
||||||
|
options.IpWhitelist = new List<string>
|
||||||
|
{
|
||||||
|
FactoryConstants.WhitelistedIp,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseContext GetDatabaseContext()
|
||||||
|
{
|
||||||
|
var scope = Services.CreateScope();
|
||||||
|
return scope.ServiceProvider.GetRequiredService<DatabaseContext>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.TestHost;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
|
|
||||||
|
namespace Bit.IntegrationTestCommon.Factories
|
||||||
|
{
|
||||||
|
public static class WebApplicationFactoryExtensions
|
||||||
|
{
|
||||||
|
private static async Task<HttpContext> SendAsync(this TestServer server,
|
||||||
|
HttpMethod method,
|
||||||
|
string requestUri,
|
||||||
|
HttpContent content = null,
|
||||||
|
Action<HttpContext> extraConfiguration = null)
|
||||||
|
{
|
||||||
|
return await server.SendAsync(httpContext =>
|
||||||
|
{
|
||||||
|
// Automatically set the whitelisted IP so normal tests do not run into rate limit issues
|
||||||
|
// to test rate limiter, use the extraConfiguration parameter to set Connection.RemoteIpAddress
|
||||||
|
// it runs after this so it will take precedence.
|
||||||
|
httpContext.Connection.RemoteIpAddress = IPAddress.Parse(FactoryConstants.WhitelistedIp);
|
||||||
|
|
||||||
|
httpContext.Request.Path = new PathString(requestUri);
|
||||||
|
httpContext.Request.Method = method.Method;
|
||||||
|
|
||||||
|
if (content != null)
|
||||||
|
{
|
||||||
|
foreach (var header in content.Headers)
|
||||||
|
{
|
||||||
|
httpContext.Request.Headers.Add(header.Key, new StringValues(header.Value.ToArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
httpContext.Request.Body = content.ReadAsStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
extraConfiguration?.Invoke(httpContext);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public static Task<HttpContext> PostAsync(this TestServer server,
|
||||||
|
string requestUri,
|
||||||
|
HttpContent content,
|
||||||
|
Action<HttpContext> extraConfiguration = null)
|
||||||
|
=> SendAsync(server, HttpMethod.Post, requestUri, content, extraConfiguration);
|
||||||
|
public static Task<HttpContext> GetAsync(this TestServer server,
|
||||||
|
string requestUri,
|
||||||
|
Action<HttpContext> extraConfiguration = null)
|
||||||
|
=> SendAsync(server, HttpMethod.Get, requestUri, content: null, extraConfiguration);
|
||||||
|
public static async Task<string> ReadBodyAsStringAsync(this HttpContext context)
|
||||||
|
{
|
||||||
|
using var sr = new StreamReader(context.Response.Body);
|
||||||
|
return await sr.ReadToEndAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
test/IntegrationTestCommon/IntegrationTestCommon.csproj
Normal file
17
test/IntegrationTestCommon/IntegrationTestCommon.csproj
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.15" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.15" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Identity\Identity.csproj" />
|
||||||
|
<ProjectReference Include="..\Common\Common.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
3744
test/IntegrationTestCommon/packages.lock.json
Normal file
3744
test/IntegrationTestCommon/packages.lock.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csp
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Billing.Test", "Billing.Test\Billing.Test.csproj", "{8CD044FE-3FED-4F29-858C-B06BCE70EAA6}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Billing.Test", "Billing.Test\Billing.Test.csproj", "{8CD044FE-3FED-4F29-858C-B06BCE70EAA6}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity.IntegrationTest", "Identity.IntegrationTest\Identity.IntegrationTest.csproj", "{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationTestCommon", "IntegrationTestCommon\IntegrationTestCommon.csproj", "{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -86,5 +90,29 @@ Global
|
|||||||
{8CD044FE-3FED-4F29-858C-B06BCE70EAA6}.Release|x64.Build.0 = Release|Any CPU
|
{8CD044FE-3FED-4F29-858C-B06BCE70EAA6}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{8CD044FE-3FED-4F29-858C-B06BCE70EAA6}.Release|x86.ActiveCfg = Release|Any CPU
|
{8CD044FE-3FED-4F29-858C-B06BCE70EAA6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{8CD044FE-3FED-4F29-858C-B06BCE70EAA6}.Release|x86.Build.0 = Release|Any CPU
|
{8CD044FE-3FED-4F29-858C-B06BCE70EAA6}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{E2BB0D89-4570-43AB-A2E7-C8069AD90E6A}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{41188BB8-1FAF-45F6-8DC8-F316B8A6C56B}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -3369,17 +3369,17 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Azure.Messaging.EventGrid": "4.7.0",
|
"Azure.Messaging.EventGrid": "4.7.0",
|
||||||
"CommCore": "1.47.1",
|
"CommCore": "1.48.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
||||||
"SharedWeb": "1.47.1",
|
"SharedWeb": "1.48.1",
|
||||||
"Swashbuckle.AspNetCore": "6.2.3"
|
"Swashbuckle.AspNetCore": "6.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commcore": {
|
"commcore": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1"
|
"Core": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"core": {
|
"core": {
|
||||||
@ -3424,7 +3424,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3433,7 +3433,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3443,9 +3443,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3369,17 +3369,17 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Azure.Messaging.EventGrid": "4.7.0",
|
"Azure.Messaging.EventGrid": "4.7.0",
|
||||||
"CommCore": "1.47.1",
|
"CommCore": "1.48.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
|
||||||
"SharedWeb": "1.47.1",
|
"SharedWeb": "1.48.1",
|
||||||
"Swashbuckle.AspNetCore": "6.2.3"
|
"Swashbuckle.AspNetCore": "6.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commcore": {
|
"commcore": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1"
|
"Core": "1.48.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"core": {
|
"core": {
|
||||||
@ -3424,7 +3424,7 @@
|
|||||||
"infrastructure.dapper": {
|
"infrastructure.dapper": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Dapper": "2.0.123",
|
"Dapper": "2.0.123",
|
||||||
"System.Data.SqlClient": "4.8.3"
|
"System.Data.SqlClient": "4.8.3"
|
||||||
}
|
}
|
||||||
@ -3433,7 +3433,7 @@
|
|||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
|
||||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
|
||||||
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
|
||||||
@ -3443,9 +3443,9 @@
|
|||||||
"sharedweb": {
|
"sharedweb": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.47.1",
|
"Core": "1.48.1",
|
||||||
"Infrastructure.Dapper": "1.47.1",
|
"Infrastructure.Dapper": "1.48.1",
|
||||||
"Infrastructure.EntityFramework": "1.47.1"
|
"Infrastructure.EntityFramework": "1.48.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3282,7 +3282,7 @@
|
|||||||
"migrator": {
|
"migrator": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Core": "1.46.2",
|
"Core": "1.48.1",
|
||||||
"Microsoft.Extensions.Logging": "5.0.0",
|
"Microsoft.Extensions.Logging": "5.0.0",
|
||||||
"dbup-sqlserver": "4.4.0"
|
"dbup-sqlserver": "4.4.0"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user