mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 10:42:08 +00:00
Add seed db c# project
This commit is contained in:
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"version": 1,
|
|
||||||
"isRoot": true,
|
|
||||||
"tools": {
|
|
||||||
"csharpier": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"commands": [
|
|
||||||
"csharpier"
|
|
||||||
],
|
|
||||||
"rollForward": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
10
.csharpierrc.json
Normal file
10
.csharpierrc.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/belav/csharpier/main/src/CSharpier.Cli/schema.json",
|
||||||
|
"printWidth": 80,
|
||||||
|
"useTabs": false,
|
||||||
|
"tabWidth": 4,
|
||||||
|
"endOfLine": "auto",
|
||||||
|
"indentStyle": "space",
|
||||||
|
"lineEndings": "auto",
|
||||||
|
"wrapLineLength": 80
|
||||||
|
}
|
||||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"dotnet.defaultSolution": "SeedDB.sln"
|
||||||
|
}
|
||||||
218
SeedDB/Program.cs
Normal file
218
SeedDB/Program.cs
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
using System.Data;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using Konscious.Security.Cryptography;
|
||||||
|
using Microsoft.Data.SqlClient;
|
||||||
|
|
||||||
|
// @todo store this securely using environment variables or a secret manager
|
||||||
|
const string connectionString =
|
||||||
|
@"Data Source=AARONPC\INFO5052;Integrated Security=True;
|
||||||
|
Persist Security Info=False;Pooling=False;
|
||||||
|
MultipleActiveResultSets=False;Encrypt=True;
|
||||||
|
TrustServerCertificate=True;Connection Timeout=30;";
|
||||||
|
|
||||||
|
static async Task BuildSchema(SqlConnection connection)
|
||||||
|
{
|
||||||
|
string sql = await File.ReadAllTextAsync(GetScriptPath("schema.sql"));
|
||||||
|
await ExecuteScriptAsync(connection, sql);
|
||||||
|
Console.WriteLine("Database schema created or updated successfully.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task AddStoredProcs(SqlConnection connection)
|
||||||
|
{
|
||||||
|
string sql = await File.ReadAllTextAsync(
|
||||||
|
GetScriptPath("SeedStoredProcs.sql")
|
||||||
|
);
|
||||||
|
await ExecuteScriptAsync(connection, sql);
|
||||||
|
Console.WriteLine("Stored procedures added or updated successfully.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task RunSeedAsync(SqlConnection connection)
|
||||||
|
{
|
||||||
|
await ExecuteStoredProcedureAsync(connection, "dbo.USP_AddTestUsers");
|
||||||
|
Console.WriteLine("Inserted or refreshed test users.");
|
||||||
|
|
||||||
|
DataTable credentialRows = await BuildCredentialTableAsync(connection);
|
||||||
|
if (credentialRows.Rows.Count > 0)
|
||||||
|
{
|
||||||
|
await ExecuteCredentialProcedureAsync(connection, credentialRows);
|
||||||
|
Console.WriteLine(
|
||||||
|
$"Generated {credentialRows.Rows.Count} credential hashes."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("No new credentials required.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await ExecuteStoredProcedureAsync(
|
||||||
|
connection,
|
||||||
|
"dbo.USP_CreateUserVerification"
|
||||||
|
);
|
||||||
|
Console.WriteLine("Ensured verification rows exist for all users.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task ExecuteStoredProcedureAsync(
|
||||||
|
SqlConnection connection,
|
||||||
|
string storedProcedureName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
await using SqlCommand command = new SqlCommand(
|
||||||
|
storedProcedureName,
|
||||||
|
connection
|
||||||
|
);
|
||||||
|
command.CommandType = CommandType.StoredProcedure;
|
||||||
|
await command.ExecuteNonQueryAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task ExecuteCredentialProcedureAsync(
|
||||||
|
SqlConnection connection,
|
||||||
|
DataTable credentialTable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
await using SqlCommand command = new SqlCommand(
|
||||||
|
"dbo.USP_AddUserCredentials",
|
||||||
|
connection
|
||||||
|
);
|
||||||
|
command.CommandType = CommandType.StoredProcedure;
|
||||||
|
|
||||||
|
SqlParameter tvpParameter = command.Parameters.Add(
|
||||||
|
"@Hash",
|
||||||
|
SqlDbType.Structured
|
||||||
|
);
|
||||||
|
tvpParameter.TypeName = "dbo.TblUserHashes";
|
||||||
|
tvpParameter.Value = credentialTable;
|
||||||
|
|
||||||
|
await command.ExecuteNonQueryAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task<DataTable> BuildCredentialTableAsync(SqlConnection connection)
|
||||||
|
{
|
||||||
|
const string sql = """
|
||||||
|
SELECT ua.UserAccountID,
|
||||||
|
ua.Username
|
||||||
|
FROM dbo.UserAccount AS ua
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM dbo.UserCredential AS uc
|
||||||
|
WHERE uc.UserAccountID = ua.UserAccountID);
|
||||||
|
""";
|
||||||
|
|
||||||
|
await using SqlCommand command = new(sql, connection);
|
||||||
|
await using SqlDataReader reader = await command.ExecuteReaderAsync();
|
||||||
|
|
||||||
|
DataTable table = new();
|
||||||
|
table.Columns.Add("UserAccountId", typeof(Guid));
|
||||||
|
table.Columns.Add("Hash", typeof(string));
|
||||||
|
|
||||||
|
while (await reader.ReadAsync())
|
||||||
|
{
|
||||||
|
Guid userId = reader.GetGuid(0);
|
||||||
|
string username = reader.GetString(1);
|
||||||
|
|
||||||
|
string password = CreatePlainTextPassword(username);
|
||||||
|
string hash = GeneratePasswordHash(password);
|
||||||
|
|
||||||
|
DataRow row = table.NewRow();
|
||||||
|
row["UserAccountId"] = userId;
|
||||||
|
row["Hash"] = hash;
|
||||||
|
table.Rows.Add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
static string CreatePlainTextPassword(string username) => $"{username}#2025!";
|
||||||
|
|
||||||
|
static string GeneratePasswordHash(string password)
|
||||||
|
{
|
||||||
|
byte[] salt = RandomNumberGenerator.GetBytes(16);
|
||||||
|
|
||||||
|
var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password))
|
||||||
|
{
|
||||||
|
Salt = salt,
|
||||||
|
DegreeOfParallelism = Math.Max(Environment.ProcessorCount, 1),
|
||||||
|
MemorySize = 65536,
|
||||||
|
Iterations = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
byte[] hash = argon2.GetBytes(32);
|
||||||
|
string saltBase64 = Convert.ToBase64String(salt);
|
||||||
|
string hashBase64 = Convert.ToBase64String(hash);
|
||||||
|
|
||||||
|
// Store salt and hash together so verification can rebuild the key material.
|
||||||
|
return $"{saltBase64}:{hashBase64}";
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task ExecuteScriptAsync(SqlConnection connection, string sql)
|
||||||
|
{
|
||||||
|
foreach (string batch in SplitSqlBatches(sql))
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(batch))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await using SqlCommand command = new(batch, connection);
|
||||||
|
await command.ExecuteNonQueryAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static IEnumerable<string> SplitSqlBatches(string sql)
|
||||||
|
{
|
||||||
|
using StringReader reader = new(sql);
|
||||||
|
StringBuilder buffer = new();
|
||||||
|
|
||||||
|
string? line;
|
||||||
|
while ((line = reader.ReadLine()) is not null)
|
||||||
|
{
|
||||||
|
if (line.Trim().Equals("GO", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
yield return buffer.ToString();
|
||||||
|
buffer.Clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.AppendLine(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer.Length > 0)
|
||||||
|
{
|
||||||
|
yield return buffer.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static string GetScriptPath(string fileName)
|
||||||
|
{
|
||||||
|
string projectRoot = Path.GetFullPath(
|
||||||
|
Path.Combine(AppContext.BaseDirectory, "..", "..", "..")
|
||||||
|
);
|
||||||
|
string candidate = Path.Combine(projectRoot, fileName);
|
||||||
|
|
||||||
|
if (File.Exists(candidate))
|
||||||
|
{
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new FileNotFoundException(
|
||||||
|
$"SQL script '{fileName}' was not found.",
|
||||||
|
candidate
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await using SqlConnection connection = new(connectionString);
|
||||||
|
await connection.OpenAsync();
|
||||||
|
Console.WriteLine("Connection to database established successfully.");
|
||||||
|
|
||||||
|
await BuildSchema(connection);
|
||||||
|
await AddStoredProcs(connection);
|
||||||
|
await RunSeedAsync(connection);
|
||||||
|
Console.WriteLine("Seeding complete.");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"Seeding failed: {ex.Message}");
|
||||||
|
Environment.ExitCode = 1;
|
||||||
|
}
|
||||||
15
SeedDB/SeedDB.csproj
Normal file
15
SeedDB/SeedDB.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference
|
||||||
|
Include="Konscious.Security.Cryptography.Argon2"
|
||||||
|
Version="1.3.1"
|
||||||
|
/>
|
||||||
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -136,28 +136,35 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
GO
|
GO
|
||||||
|
|
||||||
-- -- Stored procedure to insert Argon2 hashes
|
CREATE TYPE TblUserHashes AS TABLE
|
||||||
-- CREATE OR ALTER PROCEDURE dbo.USP_AddUserCredentials
|
(
|
||||||
-- (
|
UserAccountId UNIQUEIDENTIFIER NOT NULL,
|
||||||
-- @Hash dbo.TblUserHashes READONLY
|
Hash NVARCHAR(MAX) NOT NULL
|
||||||
-- )
|
);
|
||||||
-- AS
|
GO
|
||||||
-- BEGIN
|
|
||||||
-- SET NOCOUNT ON;
|
|
||||||
-- SET XACT_ABORT ON;
|
|
||||||
|
|
||||||
-- BEGIN TRANSACTION;
|
-- Stored procedure to insert Argon2 hashes
|
||||||
|
CREATE OR ALTER PROCEDURE dbo.USP_AddUserCredentials
|
||||||
|
(
|
||||||
|
@Hash dbo.TblUserHashes READONLY
|
||||||
|
)
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON;
|
||||||
|
SET XACT_ABORT ON;
|
||||||
|
|
||||||
-- INSERT INTO dbo.UserCredential
|
BEGIN TRANSACTION;
|
||||||
-- (UserAccountId, Hash)
|
|
||||||
-- SELECT
|
|
||||||
-- uah.UserAccountId,
|
|
||||||
-- uah.Hash
|
|
||||||
-- FROM @Hash AS uah;
|
|
||||||
|
|
||||||
-- COMMIT TRANSACTION;
|
INSERT INTO dbo.UserCredential
|
||||||
-- END;
|
(UserAccountId, Hash)
|
||||||
-- GO
|
SELECT
|
||||||
|
uah.UserAccountId,
|
||||||
|
uah.Hash
|
||||||
|
FROM @Hash AS uah;
|
||||||
|
|
||||||
|
COMMIT TRANSACTION;
|
||||||
|
END;
|
||||||
|
GO
|
||||||
|
|
||||||
CREATE OR ALTER PROCEDURE dbo.USP_CreateUserVerification
|
CREATE OR ALTER PROCEDURE dbo.USP_CreateUserVerification
|
||||||
AS
|
AS
|
||||||
@@ -174,11 +181,13 @@ BEGIN
|
|||||||
FROM dbo.UserAccount AS ua
|
FROM dbo.UserAccount AS ua
|
||||||
WHERE NOT EXISTS
|
WHERE NOT EXISTS
|
||||||
(SELECT 1
|
(SELECT 1
|
||||||
FROM dbo.UserVerification AS uv
|
FROM dbo.UserVerification AS uv
|
||||||
WHERE uv.UserAccountId = ua.UserAccountID);
|
WHERE uv.UserAccountId = ua.UserAccountID);
|
||||||
|
|
||||||
|
|
||||||
IF (SELECT COUNT(*) FROM dbo.UserVerification) != (SELECT COUNT(*) FROM dbo.UserAccount)
|
IF (SELECT COUNT(*)
|
||||||
|
FROM dbo.UserVerification) != (SELECT COUNT(*)
|
||||||
|
FROM dbo.UserAccount)
|
||||||
BEGIN
|
BEGIN
|
||||||
RAISERROR('UserVerification count does not match UserAccount count after insertion.', 16, 1);
|
RAISERROR('UserVerification count does not match UserAccount count after insertion.', 16, 1);
|
||||||
ROLLBACK TRANSACTION;
|
ROLLBACK TRANSACTION;
|
||||||
@@ -188,23 +197,3 @@ BEGIN
|
|||||||
COMMIT TRANSACTION;
|
COMMIT TRANSACTION;
|
||||||
END
|
END
|
||||||
GO
|
GO
|
||||||
|
|
||||||
BEGIN TRY
|
|
||||||
EXEC dbo.USP_AddTestUsers;
|
|
||||||
PRINT 'AddTestUsers completed.';
|
|
||||||
|
|
||||||
EXEC dbo.USP_CreateUserVerification;
|
|
||||||
PRINT 'CreateUserVerification completed.';
|
|
||||||
END TRY
|
|
||||||
BEGIN CATCH
|
|
||||||
PRINT ERROR_MESSAGE();
|
|
||||||
END CATCH
|
|
||||||
GO
|
|
||||||
|
|
||||||
|
|
||||||
SELECT *
|
|
||||||
FROM dbo.UserAccount;
|
|
||||||
|
|
||||||
SELECT *
|
|
||||||
FROM dbo.UserVerification;
|
|
||||||
GO
|
|
||||||
@@ -164,7 +164,7 @@ CREATE TABLE UserCredential -- delete credentials when user account is deleted
|
|||||||
Expiry DATETIME
|
Expiry DATETIME
|
||||||
CONSTRAINT DF_UserCredential_Expiry DEFAULT DATEADD(DAY, 90, GETDATE()) NOT NULL,
|
CONSTRAINT DF_UserCredential_Expiry DEFAULT DATEADD(DAY, 90, GETDATE()) NOT NULL,
|
||||||
|
|
||||||
Hash NVARCHAR(100) NOT NULL,
|
Hash NVARCHAR(MAX) NOT NULL,
|
||||||
-- uses argon2
|
-- uses argon2
|
||||||
|
|
||||||
Timer ROWVERSION,
|
Timer ROWVERSION,
|
||||||
@@ -503,10 +503,10 @@ CREATE NONCLUSTERED INDEX IX_BeerPostComment_BeerPost
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
USE Biergarten;
|
||||||
|
SELECT *
|
||||||
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
|
FROM UserAccount;
|
||||||
dotnet add package Microsoft.EntityFrameworkCore.Tools
|
SELECT *
|
||||||
|
FROM UserCredential;
|
||||||
Scaffold-DbContext "Data Source=AARONPC\INFO5052;Integrated Security=True;Persist Security Info=False;Pooling=False;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;Database=Biergarten" Microsoft.EntityFrameworkCore.SqlServer -Context BiergartenContext -ContextDir "." -OutputDir "Entities" -UseDatabaseNames -Force
|
SELECT *
|
||||||
*/
|
FROM UserVerification;
|
||||||
@@ -3,30 +3,30 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.14.36603.0
|
VisualStudioVersion = 17.14.36603.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataAccessLayer", "DataAccessLayer\DataAccessLayer.csproj", "{A9FCCEB3-DD88-F8C0-89A3-FD31A7C54F23}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeedDB", "SeedDB\SeedDB.csproj", "{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}"
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataAccessLayer-Tests", "DataAccessLayer-Tests\DataAccessLayer-Tests.csproj", "{3638DC4E-D4C8-4DBE-CF3B-EF2C805509CE}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
schema.sql = schema.sql
|
|
||||||
test-data.sql = test-data.sql
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{A9FCCEB3-DD88-F8C0-89A3-FD31A7C54F23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A9FCCEB3-DD88-F8C0-89A3-FD31A7C54F23}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A9FCCEB3-DD88-F8C0-89A3-FD31A7C54F23}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
{A9FCCEB3-DD88-F8C0-89A3-FD31A7C54F23}.Release|Any CPU.Build.0 = Release|Any CPU
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{3638DC4E-D4C8-4DBE-CF3B-EF2C805509CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
{3638DC4E-D4C8-4DBE-CF3B-EF2C805509CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{3638DC4E-D4C8-4DBE-CF3B-EF2C805509CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{3638DC4E-D4C8-4DBE-CF3B-EF2C805509CE}.Release|Any CPU.Build.0 = Release|Any CPU
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{45F7F75E-FD8D-4862-9BDB-6E59F6941DFB}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
UserAccountID,Username,FirstName,LastName,Email,CreatedAt,UpdatedAt,DateOfBirth
|
|
||||||
b8624cea-1a90-4b2d-a12e-a71a86eb1f10,lambrosch0,Lissy,Ambrosch,lambrosch0@upenn.edu,2022-09-18,2018-12-14,1987-02-19
|
|
||||||
3954ed02-4f51-4682-99d4-703dfcfed61a,keslinger1,Knox,Eslinger,keslinger1@smugmug.com,2025-05-21,2021-04-22,1958-01-18
|
|
||||||
95c1d06f-dc6d-4dfa-a4e3-4e29b412b043,mtrobey2,Manuel,Trobey,mtrobey2@wp.com,2016-09-25,2011-01-05,1993-01-06
|
|
||||||
7ceb8774-9cbe-4da3-b697-98ea14b3a86d,kgadsden3,Kerianne,Gadsden,kgadsden3@tinypic.com,2018-12-16,2011-12-11,1950-05-01
|
|
||||||
04957847-0564-4b8b-8b4a-cdce1c387914,mvane4,Mord,Vane,mvane4@booking.com,2014-08-31,2025-05-07,1928-08-28
|
|
||||||
1b53e41e-60e4-4c81-b162-473d036fd40e,iklimowski5,Ileana,Klimowski,iklimowski5@mtv.com,2024-11-28,2014-05-17,1933-07-20
|
|
||||||
cba032ba-ba35-415d-aff0-14936d73b23a,mvickars6,Mischa,Vickars,mvickars6@census.gov,2012-08-06,2014-04-03,1991-03-06
|
|
||||||
5a05b977-f6d8-4e9f-b700-ef74e0d4cd79,cbarrus7,Charin,Barrus,cbarrus7@digg.com,2019-08-01,2017-02-26,1984-10-19
|
|
||||||
c36f23b6-1af0-4525-9078-03f7285f11fd,gbroady8,Gerri,Broady,gbroady8@cafepress.com,2015-03-23,2021-12-15,1986-09-22
|
|
||||||
9eee230d-8e88-4ab7-ad3a-08909f0f179f,jwoolf9,Justis,Woolf,jwoolf9@oakley.com,2020-10-29,2018-07-03,1984-04-13
|
|
||||||
4db300d3-8dae-4efb-8be6-2ee31e10489b,agrigsa,Annabell,Grigs,agrigsa@behance.net,2014-09-08,2020-07-17,1932-06-23
|
|
||||||
0bdce4af-77e9-495c-b96e-447d6020e851,lmilkinb,Lucia,Milkin,lmilkinb@yahoo.com,2019-07-02,2016-06-04,1975-09-07
|
|
||||||
7a815e7c-baa8-4eef-aab8-0e2c394191b0,ahumbatchc,Alvira,Humbatch,ahumbatchc@hc360.com,2015-06-18,2012-04-04,2004-05-13
|
|
||||||
50454152-ece0-489f-a1c1-1db8d03b3ce6,ttackd,Teodoro,Tack,ttackd@ucsd.edu,2012-04-25,2022-05-20,1975-05-13
|
|
||||||
cf775ced-ecd9-4291-9bc4-ab0cd3ea2ccf,rscholarde,Rip,Scholard,rscholarde@paginegialle.it,2011-09-15,2014-01-13,1975-11-18
|
|
||||||
8157d559-2e7c-448f-a845-c649302b8f36,pwarlandf,Phaedra,Warland,pwarlandf@gravatar.com,2024-03-21,2016-09-07,1929-05-29
|
|
||||||
c3b257e1-9d79-4494-982e-2fb44a28a7f9,sshallog,Selia,Shallo,sshallog@google.ca,2014-07-19,2021-07-23,1935-06-20
|
|
||||||
8dc3f85f-a3bb-46b2-83d5-475c0d33f533,carensonh,Consolata,Arenson,carensonh@jalbum.net,2023-08-26,2024-06-06,1940-03-13
|
|
||||||
f39db8d5-d2a7-4726-bcee-aeb1c88a6340,fsushamsi,Falito,Sushams,fsushamsi@indiatimes.com,2022-11-07,2024-09-05,1989-02-06
|
|
||||||
97460048-226d-4124-b545-730d0a45fcbf,cschutzej,Creighton,Schutze,cschutzej@seattletimes.com,2010-05-28,2019-05-01,1945-01-12
|
|
||||||
183d0825-b6b4-4184-8128-6b1b3ee9c34e,pivanuschkak,Park,Ivanuschka,pivanuschkak@unblog.fr,2017-04-04,2018-02-02,1961-08-10
|
|
||||||
75b72f28-7f12-435e-9347-e7026724255d,sgodardl,Stanfield,Godard,sgodardl@statcounter.com,2014-08-02,2020-06-01,1978-03-03
|
|
||||||
82b57935-4d01-4eee-a95c-5f7660bc1308,sdeversm,Shaylah,Devers,sdeversm@sbwire.com,2017-07-21,2015-08-20,1963-06-21
|
|
||||||
5a76558c-77d2-4698-9aa2-91adf09c3e40,nakessn,Noellyn,Akess,nakessn@sakura.ne.jp,2012-07-28,2023-01-08,1947-02-26
|
|
||||||
b2dc17ab-31cc-40c5-9a7c-d95e790fecea,jdumbello,Jobie,Dumbell,jdumbello@google.de,2015-02-01,2013-08-27,1941-04-22
|
|
||||||
0c35296a-4833-499f-9c27-2469ba2d41e6,dbiggsp,Dacia,Biggs,dbiggsp@paginegialle.it,2020-07-06,2025-05-25,1921-10-26
|
|
||||||
9a0c0852-2db8-4824-8395-97485edf3fc3,ctraiteq,Chan,Traite,ctraiteq@ibm.com,2021-12-02,2018-05-21,1952-03-05
|
|
||||||
3d7005b0-7ad0-45a8-a958-184686430af2,lcowlinr,Lorant,Cowlin,lcowlinr@soup.io,2012-01-10,2015-05-22,1947-04-25
|
|
||||||
9ab507dd-a0af-4ccd-99b9-ab9077aabf96,csmewings,Corissa,Smewing,csmewings@friendfeed.com,2016-11-15,2020-05-13,1989-12-20
|
|
||||||
f0a6c3da-465e-4ff3-9069-4383dcb0e0f6,renderbyt,Rancell,Enderby,renderbyt@quantcast.com,2013-06-07,2023-07-26,1970-05-13
|
|
||||||
|
Reference in New Issue
Block a user