//-----------------------------------------------------------------------
//
// Copyright (c) Outercurve Foundation. All rights reserved.
//
//-----------------------------------------------------------------------
namespace RelyingPartyLogic {
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.EntityClient;
using System.Data.Objects;
using System.Data.SqlClient;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using DotNetOpenAuth.OpenId;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
public static class Utilities {
internal const string DefaultNamespace = "RelyingPartyLogic";
///
/// Gets the full URI of the web application root. Guaranteed to end in a slash.
///
public static Uri ApplicationRoot {
get {
string appRoot = HttpContext.Current.Request.ApplicationPath;
if (!appRoot.EndsWith("/", StringComparison.Ordinal)) {
appRoot += "/";
}
return new Uri(HttpContext.Current.Request.Url, appRoot);
}
}
public static void CreateDatabase(Identifier claimedId, string friendlyId, string databaseName) {
const string SqlFormat = @"
{0}
GO
EXEC [dbo].[AddUser] 'admin', 'admin', '{1}', '{2}'
GO
";
var removeSnippets = new string[] { @"
IF IS_SRVROLEMEMBER(N'sysadmin') = 1
BEGIN
IF EXISTS (SELECT 1
FROM [master].[dbo].[sysdatabases]
WHERE [name] = N'$(DatabaseName)')
BEGIN
EXECUTE sp_executesql N'ALTER DATABASE [$(DatabaseName)]
SET HONOR_BROKER_PRIORITY OFF
WITH ROLLBACK IMMEDIATE';
END
END
ELSE
BEGIN
PRINT N'The database settings cannot be modified. You must be a SysAdmin to apply these settings.';
END
GO" };
string databasePath = HttpContext.Current.Server.MapPath("~/App_Data/" + databaseName + ".mdf");
StringBuilder schemaSqlBuilder = new StringBuilder();
using (var sr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(DefaultNamespace + ".CreateDatabase.sql"))) {
schemaSqlBuilder.Append(sr.ReadToEnd());
}
foreach (string remove in removeSnippets) {
schemaSqlBuilder.Replace(remove, string.Empty);
}
schemaSqlBuilder.Replace("Path1_Placeholder", HttpContext.Current.Server.MapPath("~/App_Data/"));
schemaSqlBuilder.Replace("WEBROOT", databasePath);
schemaSqlBuilder.Replace("$(DatabaseName)", databaseName);
string sql = string.Format(CultureInfo.InvariantCulture, SqlFormat, schemaSqlBuilder, claimedId, "Admin");
var serverConnection = new ServerConnection(".\\sqlexpress");
try {
serverConnection.ExecuteNonQuery(sql);
} finally {
try {
var server = new Server(serverConnection);
server.DetachDatabase(databaseName, true);
} catch (FailedOperationException) {
}
serverConnection.Disconnect();
}
}
public static int ExecuteCommand(this ObjectContext objectContext, string command) {
// Try to automatically add the appropriate transaction if one is known.
EntityTransaction transaction = null;
if (Database.IsDataContextInitialized && Database.DataContext == objectContext) {
transaction = Database.DataContextTransaction;
}
return ExecuteCommand(objectContext, transaction, command);
}
///
/// Executes a SQL command against the SQL connection.
///
/// The object context.
/// The transaction to use, if any.
/// The command to execute.
/// The result of executing the command.
public static int ExecuteCommand(this ObjectContext objectContext, EntityTransaction transaction, string command) {
if (objectContext == null) {
throw new ArgumentNullException("objectContext");
}
if (string.IsNullOrEmpty(command)) {
throw new ArgumentNullException("command");
}
DbConnection connection = (EntityConnection)objectContext.Connection;
bool opening = connection.State == ConnectionState.Closed;
if (opening) {
connection.Open();
}
DbCommand cmd = connection.CreateCommand();
cmd.Transaction = transaction;
cmd.CommandText = command;
cmd.CommandType = CommandType.StoredProcedure;
try {
return cmd.ExecuteNonQuery();
} finally {
if (opening && connection.State == ConnectionState.Open) {
connection.Close();
}
}
}
internal static void VerifyThrowNotLocalTime(DateTime value) {
// When we want UTC time, we have to accept Unspecified kind
// because that's how it is set to us in the database.
if (value.Kind == DateTimeKind.Local) {
throw new ArgumentException("DateTime must be given in UTC time but was " + value.Kind.ToString());
}
}
///
/// Ensures that local times are converted to UTC times. Unspecified kinds are recast to UTC with no conversion.
///
/// The date-time to convert.
/// The date-time in UTC time.
internal static DateTime AsUtc(this DateTime value) {
if (value.Kind == DateTimeKind.Unspecified) {
return new DateTime(value.Ticks, DateTimeKind.Utc);
}
return value.ToUniversalTime();
}
}
}