Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@ -0,0 +1,39 @@
@* Generator: WebPage *@
@using System.Web.WebPages.Administration.PackageManager;
@{
Page.Title = AdminResources.Modules;
var adminModules = from p in SiteAdmin.Modules
where !p.StartPageVirtualPath.Equals(SiteAdmin.AdminVirtualPath, StringComparison.OrdinalIgnoreCase)
orderby p.DisplayName
select p;
}
@if (!adminModules.Any() && !PackageManagerModule.Available) {
<h3>@AdminResources.NoAdminModulesInstalled</h3>
}
else if (PackageManagerModule.Available && !adminModules.Any()) {
// If no other module is available, take the user directly to the package manager
Response.Redirect(Href("packages"));
return;
}
else {
<ul class="modules">
@if (PackageManagerModule.Available) {
<li>
<a href="@Href("packages")" title="@PackageManagerModule.ModuleName"><strong>@PackageManagerModule.ModuleName</strong></a>
<div class="description">@PackageManagerModule.ModuleDescription</div>
</li>
}
@if (adminModules.Any()) {
foreach (var module in adminModules) {
<li>
<a href="@Href(module.StartPageVirtualPath)"><strong>@module.DisplayName</strong></a>
<div class="description">
@module.Description
</div>
</li>
}
}
</ul>
}

View File

@ -0,0 +1,149 @@
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.225
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace System.Web.WebPages.Administration
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Helpers;
using System.Web.Security;
using System.Web.UI;
using System.Web.WebPages;
using System.Web.WebPages.Html;
using System.Web.WebPages.Administration.PackageManager;
[System.Web.WebPages.PageVirtualPathAttribute("~/Default.cshtml")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("RazorSingleFileGenerator", "1.0.0.0")]
public class Default_cshtml : System.Web.WebPages.WebPage
{
#line hidden
// Resolve package relative syntax
// Also, if it comes from a static embedded resource, change the path accordingly
public override string Href(string virtualPath, params object[] pathParts) {
virtualPath = ApplicationPart.ProcessVirtualPath(GetType().Assembly, VirtualPath, virtualPath);
return base.Href(virtualPath, pathParts);
}
public Default_cshtml()
{
}
protected System.Web.HttpApplication ApplicationInstance
{
get
{
return ((System.Web.HttpApplication)(Context.ApplicationInstance));
}
}
public override void Execute()
{
WriteLiteral("\r\n\r\n");
Page.Title = AdminResources.Modules;
var adminModules = from p in SiteAdmin.Modules
where !p.StartPageVirtualPath.Equals(SiteAdmin.AdminVirtualPath, StringComparison.OrdinalIgnoreCase)
orderby p.DisplayName
select p;
WriteLiteral("\r\n");
if (!adminModules.Any() && !PackageManagerModule.Available) {
WriteLiteral(" <h3>");
Write(AdminResources.NoAdminModulesInstalled);
WriteLiteral("</h3>\r\n");
}
else if (PackageManagerModule.Available && !adminModules.Any()) {
// If no other module is available, take the user directly to the package manager
Response.Redirect(Href("packages"));
return;
}
else {
WriteLiteral(" <ul class=\"modules\">\r\n");
if (PackageManagerModule.Available) {
WriteLiteral(" <li> \r\n <a href=\"");
Write(Href("packages"));
WriteLiteral("\" title=\"");
Write(PackageManagerModule.ModuleName);
WriteLiteral("\"><strong>");
Write(PackageManagerModule.ModuleName);
WriteLiteral("</strong></a>\r\n <div class=\"description\">");
Write(PackageManagerModule.ModuleDescription);
WriteLiteral("</div>\r\n </li>\r\n");
}
if (adminModules.Any()) {
foreach (var module in adminModules) {
WriteLiteral(" <li>\r\n <a href=\"");
Write(Href(module.StartPageVirtualPath));
WriteLiteral("\"><strong>");
Write(module.DisplayName);
WriteLiteral("</strong></a>\r\n <div class=\"description\">\r\n ");
Write(module.Description);
WriteLiteral("\r\n </div>\r\n </li>\r\n");
}
}
WriteLiteral(" </ul>\r\n");
}
}
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,21 @@
@* Generator: WebPage *@
@using System.Globalization;
@{
Page.Title = AdminResources.SecurityTitle;
if(AdminSecurity.HasAdminPassword()) {
SiteAdmin.RedirectToHome(Response);
return;
}
string url = SiteAdmin.GetRedirectUrl(SiteAdmin.AdminVirtualPath);
}
@Html.Raw(AdminResources.EnableInstructions)
<br />
<p>
@Html.Raw(String.Format(CultureInfo.CurrentCulture, AdminResources.ContinueAfterEnableText, Html.Encode(Href(url))))
</p>

View File

@ -0,0 +1,86 @@
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.225
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace System.Web.WebPages.Administration
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Helpers;
using System.Web.Security;
using System.Web.UI;
using System.Web.WebPages;
using System.Web.WebPages.Html;
using System.Globalization;
[System.Web.WebPages.PageVirtualPathAttribute("~/EnableInstructions.cshtml")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("RazorSingleFileGenerator", "1.0.0.0")]
public class EnableInstructions_cshtml : System.Web.WebPages.WebPage
{
#line hidden
// Resolve package relative syntax
// Also, if it comes from a static embedded resource, change the path accordingly
public override string Href(string virtualPath, params object[] pathParts) {
virtualPath = ApplicationPart.ProcessVirtualPath(GetType().Assembly, VirtualPath, virtualPath);
return base.Href(virtualPath, pathParts);
}
public EnableInstructions_cshtml()
{
}
protected System.Web.HttpApplication ApplicationInstance
{
get
{
return ((System.Web.HttpApplication)(Context.ApplicationInstance));
}
}
public override void Execute()
{
WriteLiteral("\r\n\r\n");
WriteLiteral("\r\n");
Page.Title = AdminResources.SecurityTitle;
if(AdminSecurity.HasAdminPassword()) {
SiteAdmin.RedirectToHome(Response);
return;
}
string url = SiteAdmin.GetRedirectUrl(SiteAdmin.AdminVirtualPath);
WriteLiteral("\r\n");
Write(Html.Raw(AdminResources.EnableInstructions));
WriteLiteral("\r\n<br />\r\n<p>\r\n ");
Write(Html.Raw(String.Format(CultureInfo.CurrentCulture, AdminResources.ContinueAfterEnableText, Html.Encode(Href(url)))));
WriteLiteral("\r\n</p>\r\n\r\n");
}
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,260 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Web.Helpers;
using System.Web.Hosting;
using System.Web.Security;
namespace System.Web.WebPages.Administration
{
internal static class AdminSecurity
{
private const string AuthCookieName = ".ASPXADMINAUTH";
private const string AdminUserNameToken = "ADMIN";
// Bug941370: Renamed the file to .config to prevent IIS6 from serving this files.
internal static readonly string AdminPasswordFile = VirtualPathUtility.Combine(SiteAdmin.AdminSettingsFolder, "Password.config");
internal static readonly string TemporaryPasswordFile = VirtualPathUtility.Combine(SiteAdmin.AdminSettingsFolder, "_Password.config");
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "We catch all exceptions to prevent any decryption failure results from being exposed.")]
internal static bool IsAuthenticated(HttpRequestBase request)
{
HttpCookie authCookie = request.Cookies[AuthCookieName];
// Not authenticated if there is no cookie
if (authCookie == null)
{
return false;
}
try
{
return IsValidAuthCookie(authCookie);
}
catch
{
// If decryption fails, it may be a bad cookie
return false;
}
}
private static bool IsValidAuthCookie(HttpCookie authCookie)
{
// Decrypt the cookie and check the expired flag
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
// Ensure that the ticket hasn't expired and that the custom UserData string is our AdminUserNameToken
return !ticket.Expired && ticket.UserData != null && ticket.UserData.Equals(AdminUserNameToken);
}
internal static void SetAuthCookie(HttpResponseBase response)
{
// Get an auth admin cookie
HttpCookie cookie = GetAuthCookie();
// Set the name to our auth cookie name
cookie.Name = AuthCookieName;
// Add it to the response
response.Cookies.Add(cookie);
}
internal static HttpCookie GetAuthCookie()
{
// Create a new forms auth ticket for the admin section
// Add the admin user name as user data so that we distinguish between a regular
// ticket issued by ASP.NET's auth system versus our own
var ticket = new FormsAuthenticationTicket(2,
AdminUserNameToken,
DateTime.Now,
DateTime.Now.Add(FormsAuthentication.Timeout),
false,
AdminUserNameToken,
FormsAuthentication.FormsCookiePath);
// Encrypt the ticket and create the cookie
string encryptedValue = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(AuthCookieName, encryptedValue);
cookie.HttpOnly = true;
cookie.Path = ticket.CookiePath;
return cookie;
}
internal static void DeleteAuthCookie(HttpResponseBase response)
{
// Expire the cookie
var cookie = new HttpCookie(AuthCookieName);
cookie.Expires = DateTime.Now.AddDays(-1);
response.Cookies.Add(cookie);
}
internal static bool HasAdminPassword()
{
return HasAdminPassword(HostingEnvironment.VirtualPathProvider);
}
internal static bool HasAdminPassword(VirtualPathProvider vpp)
{
// REVIEW: Do we need to check for content as well?
return vpp.FileExists(AdminPasswordFile);
}
internal static bool HasTemporaryPassword()
{
return HasTemporaryPassword(HostingEnvironment.VirtualPathProvider);
}
internal static bool HasTemporaryPassword(VirtualPathProvider vpp)
{
// REVIEW: Do we need to check for content as well?
return vpp.FileExists(TemporaryPasswordFile);
}
internal static bool SaveTemporaryPassword(string password)
{
// When saving the admin password we store it in a dummy file so that we don't enable to the admin UI by default
return SaveTemporaryPassword(password, GetTemporaryPasswordFileStream);
}
private static Stream GetTemporaryPasswordFileStream()
{
// Get the password directory and file name
string passwordFilePath = HostingEnvironment.MapPath(TemporaryPasswordFile);
string passwordFileDir = Path.GetDirectoryName(passwordFilePath);
// Ensure password directory exists
Directory.CreateDirectory(passwordFileDir);
// Return the stream
return File.OpenWrite(passwordFilePath);
}
internal static bool SaveTemporaryPassword(string password, Func<Stream> getPasswordFileStream)
{
Stream stream = null;
try
{
// Get the password file stream
stream = getPasswordFileStream();
}
catch (UnauthorizedAccessException)
{
// The user doesn't have write access to App_Data or the site root
return false;
}
using (var writer = new StreamWriter(stream))
{
// Write the salty password
writer.WriteLine(Crypto.HashPassword(password));
}
return true;
}
internal static bool CheckPassword(string password)
{
return CheckPassword(password, () =>
{
VirtualFile passwordFile = HostingEnvironment.VirtualPathProvider.GetFile(AdminPasswordFile);
Debug.Assert(passwordFile != null, "password file should not be null");
return passwordFile.Open();
});
}
internal static bool CheckPassword(string password, Func<Stream> getPasswordFileStream)
{
string saltyPassword = null;
Stream stream = getPasswordFileStream();
using (StreamReader reader = new StreamReader(stream))
{
// Read the salted password
saltyPassword = reader.ReadLine();
}
return Crypto.VerifyHashedPassword(saltyPassword, password);
}
/// <summary>
/// Ensure that the current request is authorized.
/// If the request is authenticated, then we skip all other checks.
/// </summary>
internal static void Authorize(StartPage page)
{
Authorize(page, HostingEnvironment.VirtualPathProvider, VirtualPathUtility.ToAppRelative);
}
internal static void Authorize(StartPage page, VirtualPathProvider vpp, Func<string, string> makeAppRelative)
{
if (!IsAuthenticated(page.Request))
{
if (HasAdminPassword(vpp))
{
// If there is a password file (Password.config) then we redirect to the login page
RedirectSafe(page, SiteAdmin.LoginVirtualPath, makeAppRelative);
}
else if (HasTemporaryPassword(vpp))
{
// Dev 10 941521: Admin: Pass through returnurl into page that tells the user to rename _password.config
// If there is a disabled password file (_Password.config) then we redirect to the instructions page
RedirectSafe(page, SiteAdmin.EnableInstructionsVirtualPath, makeAppRelative);
}
else
{
// The user hasn't done anything so redirect to the register page.
RedirectSafe(page, SiteAdmin.RegisterVirtualPath, makeAppRelative);
}
}
}
/// <summary>
/// Doesn't do a redirect if the requesting page is itself the same as the virtual path.
/// We need to do this since it is called from the _pagestart.cshtml which always runs.
/// </summary>
private static void RedirectSafe(StartPage page, string virtualPath, Func<string, string> makeAppRelative)
{
// Make sure we get the virtual path
virtualPath = SiteAdmin.GetVirtualPath(virtualPath);
if (!IsRequestingPage(page, virtualPath))
{
// Append the redirect url querystring
virtualPath = SiteAdmin.GetRedirectUrl(page.Request, virtualPath, makeAppRelative);
page.Context.Response.Redirect(virtualPath);
}
}
/// <summary>
/// Determines if the specified virtualPath is being requested. We do this by walking the page hierarchy
/// and comparing the virtualPath with the child page's VirtualPath property (which in the case of ApplicationParts are compiled into the assembly
/// using the PageVirtualPath attribute).
/// </summary>
internal static bool IsRequestingPage(this StartPage page, string virtualPath)
{
WebPageRenderingBase webPage = GetRootPage(page);
return webPage.VirtualPath.Equals(virtualPath, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Walks the page hierarcy to find the requested page.
/// </summary>
private static WebPageRenderingBase GetRootPage(StartPage page)
{
WebPageRenderingBase currentPage = null;
while (page != null)
{
currentPage = page.ChildPage;
page = currentPage as StartPage;
}
Debug.Assert(currentPage != null, "Should never be null");
return currentPage;
}
}
}

View File

@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.ComponentModel;
namespace System.Web.WebPages.Administration
{
[EditorBrowsable(EditorBrowsableState.Never)]
public static class PreApplicationStartCode
{
// NOTE: Do not add public fields, methods, or other members to this class.
// This class does not show up in Intellisense so members on it will not be
// discoverable by users. Place new members on more appropriate classes that
// relate to the public API (for example, a LoginUrl property should go on a
// membership-related class).
private static bool _startWasCalled;
public static void Start()
{
// Even though ASP.NET will only call each PreAppStart once, we sometimes internally call one PreAppStart from
// another PreAppStart to ensure that things get initialized in the right order. ASP.NET does not guarantee the
// order so we have to guard against multiple calls.
// All Start calls are made on same thread, so no lock needed here.
if (_startWasCalled)
{
return;
}
_startWasCalled = true;
// Register the admin module
SiteAdmin.RegisterAdminModule();
}
}
}

View File

@ -0,0 +1,232 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
namespace System.Web.WebPages.Administration
{
public class SiteAdmin
{
internal const string DefaultAdminVirtualPath = "~/_Admin/";
internal const string AdminSettingsFolder = "~/App_Data/Admin/";
// Configuration settings
private const string AdminVirtualPathAppSettingsKey = "asp:AdminFolderVirtualPath";
private const string AdminEnabledAppSettingsKey = "asp:AdminManagerEnabled";
private const string ReturnUrlQueryString = "ReturnUrl";
// Virtual paths excluded from security. These urls are the same as the ones in the PageVirtulPath attribute.
internal const string LoginVirtualPath = "~/Login.cshtml";
internal const string LogoutVirtualPath = "~/Logout.cshtml";
internal const string RegisterVirtualPath = "~/Register.cshtml";
internal const string EnableInstructionsVirtualPath = "~/EnableInstructions.cshtml";
private static ConcurrentDictionary<string, SiteAdmin> _adminModules = new ConcurrentDictionary<string, SiteAdmin>();
// These only needs to be computed once per app domain
private static readonly Lazy<bool?> _adminEnabled = new Lazy<bool?>(GetAdminEnabledSetting);
private static readonly Lazy<string> _adminVirtualPath = new Lazy<string>(GetDefaultVirtualPath);
private SiteAdmin(string startPageVirtualPath, string displayName, string description)
{
Debug.Assert(startPageVirtualPath != null, "startPageVirtualPath can't be null");
Debug.Assert(displayName != null, "displayName can't be null");
StartPageVirtualPath = startPageVirtualPath;
DisplayName = displayName;
Description = description;
}
public static string AdminVirtualPath
{
get { return _adminVirtualPath.Value; }
}
public string StartPageVirtualPath { get; private set; }
public string DisplayName { get; private set; }
public string Description { get; private set; }
internal static bool Available
{
get
{
HttpContext context = HttpContext.Current;
if (context != null && context.Request.IsLocal)
{
// Check the configuration setting if there is any
if (_adminEnabled.Value != null)
{
return _adminEnabled.Value.Value;
}
// There was no setting so localhost is enough to verify availability
return true;
}
// If we're not on localhost then nothing is available
return false;
}
}
public static IEnumerable<SiteAdmin> Modules
{
get { return _adminModules.Values; }
}
internal static void RegisterAdminModule()
{
// Add a admin module as an application module (precompiled)
ApplicationPart.Register(new ApplicationPart(typeof(SiteAdmin).Assembly, AdminVirtualPath));
}
private static bool? GetAdminEnabledSetting()
{
bool enabled;
if (Boolean.TryParse(ConfigurationManager.AppSettings[AdminEnabledAppSettingsKey], out enabled))
{
return enabled;
}
return null;
}
public static string GetVirtualPath(string virtualPath)
{
if (virtualPath == null)
{
throw new ArgumentNullException("virtualPath");
}
// Don't add the virtual path more than once
if (virtualPath.StartsWith(AdminVirtualPath, StringComparison.OrdinalIgnoreCase))
{
return virtualPath;
}
if (virtualPath.StartsWith("~/", StringComparison.OrdinalIgnoreCase))
{
virtualPath = virtualPath.Substring(2);
}
if (virtualPath.StartsWith("/", StringComparison.OrdinalIgnoreCase))
{
virtualPath = virtualPath.Substring(1);
}
return VirtualPathUtility.Combine(AdminVirtualPath, virtualPath);
}
public static void Register(string startPageVirtualPath, string displayName, string description)
{
if (startPageVirtualPath == null)
{
throw new ArgumentNullException("startPageVirtualPath");
}
if (displayName == null)
{
throw new ArgumentNullException("displayName");
}
// Get the virtual path relative to the admin virtual path
string virtualPath = GetVirtualPath(startPageVirtualPath);
// Register that under the admin root
Register(new SiteAdmin(virtualPath, displayName, description));
}
private static string GetDefaultVirtualPath()
{
string virtualPath = ConfigurationManager.AppSettings[AdminVirtualPathAppSettingsKey];
if (String.IsNullOrEmpty(virtualPath))
{
virtualPath = DefaultAdminVirtualPath;
}
if (!virtualPath.EndsWith("/", StringComparison.OrdinalIgnoreCase))
{
virtualPath += "/";
}
return virtualPath;
}
internal static void RedirectToLogin(HttpResponseBase response)
{
response.Redirect(GetVirtualPath(LoginVirtualPath));
}
internal static void RedirectToRegister(HttpResponseBase response)
{
response.Redirect(GetVirtualPath(RegisterVirtualPath));
}
internal static void RedirectToHome(HttpResponseBase response)
{
response.Redirect(AdminVirtualPath);
}
internal static void Register(SiteAdmin module)
{
if (_adminModules.ContainsKey(module.StartPageVirtualPath))
{
throw new InvalidOperationException(
String.Format(CultureInfo.CurrentCulture,
AdminResources.ModuleAlreadyRegistered, module.StartPageVirtualPath));
}
// Add to the list of registered modules
_adminModules.TryAdd(module.StartPageVirtualPath, module);
}
internal static string GetReturnUrl(HttpRequestBase request)
{
// REVIEW: FormsAuthentication.GetReturlUrl also checks the form for the return url
// do we need that?
string returnUrl = request.QueryString[ReturnUrlQueryString];
// If the return url query string doesn't exist or is empty
// return the admin root virtual path
if (String.IsNullOrEmpty(returnUrl))
{
return null;
}
// REVIEW: FormsAuthentication.GetReturnUrl checks if the url is dangerous
// i.e it uses an internal helper in System.Web CrossSiteScriptingValidation.IsDangerousUrl.
// Should we copy that behavior?
if (!VirtualPathUtility.IsAppRelative(returnUrl))
{
// We only put app relative return urls in the query string (i.e starts with ~/)
throw new InvalidOperationException(AdminResources.InvalidReturnUrl);
}
return returnUrl;
}
internal static string GetRedirectUrl(string redirectUrl)
{
var request = new HttpRequestWrapper(HttpContext.Current.Request);
return GetRedirectUrl(request, redirectUrl, VirtualPathUtility.ToAppRelative);
}
internal static string GetRedirectUrl(HttpRequestBase request, string redirectUrl, Func<string, string> makeAppRelative)
{
// If there's already a return url then use it, otherwise the app relative url of the
// current request to redirect to after signing in
string returnUrl = GetReturnUrl(request) ?? makeAppRelative(request.RawUrl);
// Get the app relative path to the redirect url
redirectUrl = GetVirtualPath(redirectUrl);
// Get the current page with return url
redirectUrl += "?" + ReturnUrlQueryString + "=" + HttpUtility.UrlEncode(returnUrl);
return redirectUrl;
}
}
}

View File

@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
namespace System.Web.WebPages.Administration.PackageManager
{
public interface IPackagesSourceFile
{
bool Exists();
void WriteSources(IEnumerable<WebPackageSource> sources);
IEnumerable<WebPackageSource> ReadSources();
}
}

View File

@ -0,0 +1,76 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using NuGet;
namespace System.Web.WebPages.Administration.PackageManager
{
[EditorBrowsable(EditorBrowsableState.Never)]
public interface IWebProjectManager
{
/// <summary>
/// The repository where packages are installed.
/// </summary>
IPackageRepository LocalRepository { get; }
/// <summary>
/// Remote feed to fetch packages from.
/// </summary>
IPackageRepository SourceRepository { get; }
/// <summary>
/// Gets packages from the SourceRepository
/// </summary>
/// <param name="searchTerms">One or more terms separated by a whitespace used to filter packages.</param>
/// <param name="filterPreferred">Determines if packages are filtered by tag identifying packages for Asp.Net WebPages.</param>
IQueryable<IPackage> GetRemotePackages(string searchTerms, bool filterPreferred);
/// <summary>
/// Gets packages from the LocalRepository.
/// </summary>
/// <param name="searchTerms">One or more terms separated by a whitespace used to filter packages.</param>
IQueryable<IPackage> GetInstalledPackages(string searchTerms);
/// <summary>
/// Gets packages from the RemoteRepository that are updates to installed packages.
/// </summary>
/// <param name="searchTerms">One or more terms separated by a whitespace used to filter packages.</param>
/// <param name="filterPreferredPackages"></param>
IEnumerable<IPackage> GetPackagesWithUpdates(string searchTerms, bool filterPreferredPackages);
/// <summary>
/// Installs the package to the LocalRepository.
/// </summary>
/// <param name="package">The package to be installed.</param>
/// <param name="appDomain">The AppDomain that is used to determine binding redirects. If null, the current AppDomain would be used.</param>
/// <returns>A sequence of errors that occurred during the operation.</returns>
IEnumerable<string> InstallPackage(IPackage package, AppDomain appDomain);
/// <summary>
/// Updates the package in the LocalRepository.
/// </summary>
/// <param name="package">The package to be installed.</param>
/// <param name="appDomain">The AppDomain that is used to determine binding redirects. If null, the current AppDomain would be used.</param>
/// <returns>A sequence of errors that occurred during the operation.</returns>
IEnumerable<string> UpdatePackage(IPackage package, AppDomain appDomain);
/// <summary>
/// Removes the package from the LocalRepository.
/// </summary>
/// <returns>A sequence of errors that occurred during the operation.</returns>
IEnumerable<string> UninstallPackage(IPackage package, bool removeDependencies);
/// <summary>
/// Gets the latest version of the package.
/// </summary>
/// <param name="package">The package to find updates for.</param>
IPackage GetUpdate(IPackage package);
/// <summary>
/// Determines if any version of a package is installed in the LocalRepository.
/// </summary>
bool IsPackageInstalled(IPackage package);
}
}

View File

@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using NuGet;
namespace System.Web.WebPages.Administration.PackageManager
{
internal static class PackageExtensions
{
public static string GetDisplayName(this IPackage package)
{
string name = String.IsNullOrEmpty(package.Title) ? package.Id : package.Title;
return String.Concat(name, ' ', package.Version);
}
}
}

View File

@ -0,0 +1,167 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Web.Hosting;
namespace System.Web.WebPages.Administration.PackageManager
{
internal static class PackageManagerModule
{
private const string DefaultSourceUrl = @"http://go.microsoft.com/fwlink/?LinkID=226946";
private const string NuGetSourceUrl = @"http://go.microsoft.com/fwlink/?LinkID=226948";
internal static readonly string PackageSourceFilePath = VirtualPathUtility.Combine(SiteAdmin.AdminSettingsFolder, "PackageSources.config");
private static readonly object _sourceFileLock = new object();
private static readonly IEnumerable<WebPackageSource> _defaultSources = new[]
{
new WebPackageSource(name: PackageManagerResources.DefaultPackageSourceName, source: DefaultSourceUrl) { FilterPreferredPackages = true },
new WebPackageSource(name: PackageManagerResources.NuGetFeed, source: NuGetSourceUrl) { FilterPreferredPackages = false }
};
private static readonly PackageSourceFile _sourceFile = new PackageSourceFile(PackageSourceFilePath);
private static ISet<WebPackageSource> _packageSources;
public static IEnumerable<WebPackageSource> PackageSources
{
get
{
Debug.Assert(_packageSources != null, "InitFeedsFile must be called before Feeds can be accessed.");
return _packageSources.Any() ? _packageSources : _defaultSources;
}
}
/// <summary>
/// Gets the first available PackageSource
/// </summary>
public static WebPackageSource ActiveSource
{
get { return PackageSources.First(); }
}
public static IEnumerable<WebPackageSource> DefaultSources
{
get { return _defaultSources; }
}
public static string ModuleName
{
get { return PackageManagerResources.ModuleTitle; }
}
public static string ModuleDescription
{
get { return PackageManagerResources.ModuleDesc; }
}
internal static string SiteRoot
{
get { return HostingEnvironment.MapPath("~/"); }
}
internal static bool Available
{
get { return (HttpContext.Current != null) && HttpContext.Current.Request.IsLocal; }
}
public static bool InitPackageSourceFile()
{
return InitPackageSourceFile(_sourceFile, ref _packageSources);
}
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Any exception that occurs indicates that the source file cannot be initialized.")]
public static bool InitPackageSourceFile(IPackagesSourceFile sourceFile, ref ISet<WebPackageSource> packageSources)
{
if (packageSources != null)
{
return true;
}
try
{
lock (_sourceFileLock)
{
// This method is invoked from Page_Start and ensures we have a feed file to read/write.
// The call needs to be guarded against multiple simultaneous requests.
if (!sourceFile.Exists())
{
packageSources = new HashSet<WebPackageSource>(_defaultSources);
sourceFile.WriteSources(_packageSources);
}
else
{
packageSources = new HashSet<WebPackageSource>(sourceFile.ReadSources());
}
}
}
catch
{
return false;
}
return true;
}
public static WebPackageSource GetSource(string sourceName)
{
Debug.Assert(_packageSources != null, "InitFeedsFile must be called before this method can be called.");
return GetSource(PackageSources, sourceName);
}
public static WebPackageSource GetSource(IEnumerable<WebPackageSource> packageSources, string sourceName)
{
lock (_sourceFileLock)
{
return packageSources.Where(source => source.Name.Equals(sourceName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
}
}
public static bool AddPackageSource(string source, string name)
{
Debug.Assert(_packageSources != null, "InitFeedsFile must be called before this method can be called.");
name = String.IsNullOrEmpty(name) ? source.ToString() : name;
var packageSource = new WebPackageSource(source: source, name: name);
return AddPackageSource(_sourceFile, _packageSources, packageSource);
}
public static bool AddPackageSource(WebPackageSource packageSource)
{
Debug.Assert(!String.IsNullOrEmpty(packageSource.Name) && !String.IsNullOrEmpty(packageSource.Source));
return AddPackageSource(_sourceFile, _packageSources, packageSource);
}
public static bool AddPackageSource(IPackagesSourceFile sourceFile, ISet<WebPackageSource> packageSources, WebPackageSource packageSource)
{
if (GetSource(packageSources, packageSource.Name) != null)
{
return false;
}
lock (_sourceFileLock)
{
packageSources.Add(packageSource);
sourceFile.WriteSources(packageSources);
}
return true;
}
public static void RemovePackageSource(string sourceName)
{
Debug.Assert(_packageSources != null, "InitFeedsFile must be called before this method can be called.");
RemovePackageSource(_sourceFile, _packageSources, sourceName);
}
public static void RemovePackageSource(IPackagesSourceFile sourceFile, ISet<WebPackageSource> packageSources, string name)
{
var packageSource = GetSource(packageSources, name);
lock (_sourceFileLock)
{
if (packageSource == null)
{
return;
}
packageSources.Remove(packageSource);
sourceFile.WriteSources(packageSources);
}
}
}
}

View File

@ -0,0 +1,105 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Hosting;
using System.Xml.Linq;
namespace System.Web.WebPages.Administration.PackageManager
{
/// <summary>
/// Provides an abstraction for reading and writing feeds to disk.
/// Calls to this file must be externally guarded against multiple threads.
/// </summary>
internal class PackageSourceFile : IPackagesSourceFile
{
private const string UrlAttribute = "url";
private const string NameAttribute = "displayname";
private const string FilterPreferredAttribute = "filterpreferred";
private readonly string _fileName;
public PackageSourceFile(string fileName)
{
_fileName = fileName;
}
public void WriteSources(IEnumerable<WebPackageSource> sources)
{
WriteFeeds(sources, () => GetStreamForWrite());
}
public IEnumerable<WebPackageSource> ReadSources()
{
return ReadFeeds(() => GetStreamForRead());
}
public bool Exists()
{
return HostingEnvironment.VirtualPathProvider.FileExists(_fileName);
}
internal static IEnumerable<WebPackageSource> ReadFeeds(Func<Stream> getStream)
{
using (var stream = getStream())
{
var document = XDocument.Load(stream);
var root = document.Root;
return (from element in root.Elements()
select ParsePackageSource(element)).ToList();
}
}
internal static void WriteFeeds(IEnumerable<WebPackageSource> sources, Func<Stream> getStream)
{
var xmlTree = from item in sources
select new XElement("source",
new XAttribute(UrlAttribute, item.Source),
new XAttribute(NameAttribute, item.Name),
new XAttribute(FilterPreferredAttribute, item.FilterPreferredPackages));
using (Stream stream = getStream())
{
new XDocument(new XElement("sources", xmlTree)).Save(stream);
}
}
internal static WebPackageSource ParsePackageSource(XElement element)
{
var urlAttribute = element.Attribute(UrlAttribute);
var nameAttribute = element.Attribute(NameAttribute);
var filterPreferredAttribute = element.Attribute(FilterPreferredAttribute);
// Throw if the file was tampered externally
if (urlAttribute == null || nameAttribute == null)
{
throw new FormatException();
}
Uri feedUrl;
if (!Uri.TryCreate(urlAttribute.Value, UriKind.Absolute, out feedUrl))
{
throw new FormatException();
}
return new WebPackageSource(feedUrl.OriginalString, nameAttribute.Value) { FilterPreferredPackages = filterPreferredAttribute != null && filterPreferredAttribute.Value.AsBool(false) };
}
private Stream GetStreamForRead()
{
var vpp = HostingEnvironment.VirtualPathProvider;
return vpp.GetFile(_fileName).Open();
}
private Stream GetStreamForWrite()
{
string mappedPath = HostingEnvironment.MapPath(_fileName);
if (!File.Exists(_fileName))
{
Directory.CreateDirectory(Path.GetDirectoryName(mappedPath));
return File.Create(mappedPath);
}
return File.Open(mappedPath, FileMode.Truncate);
}
}
}

View File

@ -0,0 +1,82 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Text;
namespace System.Web.WebPages.Administration.PackageManager
{
internal static class PageUtils
{
private const string WebPagesPreferredTag = " aspnetwebpages ";
internal static string GetPackagesHome()
{
return SiteAdmin.GetVirtualPath("~/packages");
}
internal static string GetPageVirtualPath(string page)
{
return SiteAdmin.GetVirtualPath("~/packages/" + page);
}
internal static WebPackageSource GetPackageSource(string name)
{
if (String.IsNullOrEmpty(name))
{
return PackageManagerModule.ActiveSource;
}
// If no source is found for the specified name, default to the ActiveSource
return PackageManagerModule.GetSource(name) ?? PackageManagerModule.ActiveSource;
}
internal static string GetFilterValue(HttpRequestBase request, string cookieName, string key)
{
var value = request.QueryString[key];
if (String.IsNullOrEmpty(value))
{
var cookie = request.Cookies[cookieName];
if (cookie != null)
{
value = cookie[key];
}
}
return value;
}
internal static void PersistFilter(HttpResponseBase response, string cookieName, IDictionary<string, string> filterItems)
{
var cookie = response.Cookies[cookieName];
if (cookie == null)
{
cookie = new HttpCookie(cookieName);
response.Cookies.Add(cookie);
}
foreach (var item in filterItems)
{
cookie[item.Key] = item.Value;
}
}
internal static bool IsValidLicenseUrl(Uri licenseUri)
{
return Uri.UriSchemeHttp.Equals(licenseUri.Scheme, StringComparison.OrdinalIgnoreCase) ||
Uri.UriSchemeHttps.Equals(licenseUri.Scheme, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Constructs a query string from an IDictionary
/// </summary>
internal static string BuildQueryString(IDictionary<string, string> parameters)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (var param in parameters)
{
stringBuilder.Append(stringBuilder.Length == 0 ? '?' : '&')
.Append(HttpUtility.UrlEncode(param.Key))
.Append('=')
.Append(HttpUtility.UrlEncode(param.Value));
}
return stringBuilder.ToString();
}
}
}

View File

@ -0,0 +1,200 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web.WebPages.Deployment;
using NuGet.Runtime;
namespace System.Web.WebPages.Administration.PackageManager
{
// We need to make changes to NuGet.Core once we ship Beta so that this type is removed.
internal class RemoteAssembly : MarshalByRefObject, IAssembly, IEquatable<RemoteAssembly>, IComparable<RemoteAssembly>
{
private readonly List<IAssembly> _referencedAssemblies = new List<IAssembly>();
internal RemoteAssembly()
{
}
internal RemoteAssembly(string name, Version version, string publicKeyToken, string culture)
{
Name = name;
Version = version;
PublicKeyToken = publicKeyToken;
Culture = culture;
}
public string Name { get; private set; }
public Version Version { get; private set; }
public string PublicKeyToken { get; private set; }
public string Culture { get; private set; }
public IEnumerable<IAssembly> ReferencedAssemblies
{
get { return _referencedAssemblies; }
}
public void Load(string assemblyString, bool isPath)
{
Assembly assembly;
if (isPath)
{
assembly = Assembly.ReflectionOnlyLoadFrom(assemblyString);
}
else
{
assembly = Assembly.ReflectionOnlyLoad(assemblyString);
}
// Get the assembly name and set the properties on this object
CopyAssemblyProperties(assembly.GetName(), this);
// Do the same for referenced assemblies
foreach (AssemblyName referencedAssemblyName in assembly.GetReferencedAssemblies())
{
// Copy the properties to the referenced assembly
var referencedAssembly = new RemoteAssembly();
_referencedAssemblies.Add(CopyAssemblyProperties(referencedAssemblyName, referencedAssembly));
}
}
private static RemoteAssembly CopyAssemblyProperties(AssemblyName assemblyName, RemoteAssembly assembly)
{
assembly.Name = assemblyName.Name;
assembly.Version = assemblyName.Version;
assembly.PublicKeyToken = assemblyName.GetPublicKeyTokenString();
string culture = assemblyName.CultureInfo.ToString();
if (String.IsNullOrEmpty(culture))
{
assembly.Culture = "neutral";
}
else
{
assembly.Culture = culture;
}
return assembly;
}
internal static IAssembly LoadAssembly(string assemblyString, AppDomain domain, bool isPath)
{
if (domain != AppDomain.CurrentDomain)
{
var crossDomainAssembly = domain.CreateInstance<RemoteAssembly>();
crossDomainAssembly.Load(assemblyString, isPath);
return crossDomainAssembly;
}
var assembly = new RemoteAssembly();
assembly.Load(assemblyString, isPath);
return assembly;
}
public static IEnumerable<IAssembly> GetAssembliesForBindingRedirect(AppDomain appDomain, string binDirectoryPath)
{
return GetAssembliesForBindingRedirect(appDomain, binDirectoryPath, GetBinAssemblies);
}
internal static IEnumerable<IAssembly> GetAssembliesForBindingRedirect(AppDomain appDomain, string binDirectoryPath, Func<AppDomain, string, IEnumerable<IAssembly>> getBinAssemblies)
{
var binAssemblies = getBinAssemblies(appDomain, binDirectoryPath).ToList();
if (!binAssemblies.Any())
{
return binAssemblies;
}
var webPagesAssemblies = from asm in WebPagesDeployment.GetWebPagesAssemblies()
select LoadAssembly(asm.FullName, appDomain, isPath: false);
return webPagesAssemblies.Concat(binAssemblies)
.Distinct()
.ToList();
}
private static IEnumerable<IAssembly> GetBinAssemblies(AppDomain appDomain, string binDirectoryPath)
{
if (!Directory.Exists(binDirectoryPath))
{
yield break;
}
var extensions = new[] { "*.dll", "*.exe" };
foreach (var extension in extensions)
{
foreach (var path in Directory.EnumerateFiles(binDirectoryPath, extension))
{
IAssembly assembly = LoadAssemblyFromSafe(appDomain, path);
if (assembly != null)
{
yield return assembly;
}
}
}
}
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "We're loading arbitrary binaries from the bin and some of them might not be native. Catch all to prevent this from throwing.")]
private static IAssembly LoadAssemblyFromSafe(AppDomain appDomain, string path)
{
try
{
return LoadAssembly(path, appDomain, isPath: true);
}
catch
{
// We don't want to throw from this method.
}
return null;
}
public override bool Equals(object obj)
{
var otherAssembly = obj as RemoteAssembly;
return otherAssembly != null && Equals(otherAssembly);
}
public bool Equals(RemoteAssembly other)
{
return CompareTo(other) == 0;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
public int CompareTo(RemoteAssembly other)
{
return Compare(this, other);
}
internal static int Compare(IAssembly a, IAssembly b)
{
if (b == null)
{
return 1;
}
var nameDiff = StringComparer.OrdinalIgnoreCase.Compare(a.Name, b.Name);
if (nameDiff != 0)
{
return nameDiff;
}
var versionDiff = a.Version.CompareTo(b.Version);
if (versionDiff != 0)
{
return versionDiff;
}
var publicKeyDiff = StringComparer.OrdinalIgnoreCase.Compare(a.PublicKeyToken, b.PublicKeyToken);
if (publicKeyDiff != 0)
{
return publicKeyDiff;
}
return StringComparer.OrdinalIgnoreCase.Compare(a.Culture, b.Culture);
}
}
}

View File

@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using NuGet;
namespace System.Web.WebPages.Administration.PackageManager
{
public class WebPackageSource : PackageSource
{
public WebPackageSource(string source, string name)
: base(source, name)
{
}
public bool FilterPreferredPackages { get; set; }
public override bool Equals(object obj)
{
WebPackageSource other = obj as WebPackageSource;
return base.Equals(other) && FilterPreferredPackages == other.FilterPreferredPackages;
}
public override int GetHashCode()
{
return base.GetHashCode() ^ (FilterPreferredPackages ? 1 : 0);
}
}
}

View File

@ -0,0 +1,268 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using Microsoft.Internal.Web.Utils;
using NuGet;
using NuGet.Runtime;
namespace System.Web.WebPages.Administration.PackageManager
{
[EditorBrowsable(EditorBrowsableState.Never)]
public class WebProjectManager : IWebProjectManager
{
private const string WebPagesPreferredTag = " aspnetwebpages ";
private readonly IProjectManager _projectManager;
private readonly string _siteRoot;
public WebProjectManager(string remoteSource, string siteRoot)
{
if (String.IsNullOrEmpty(remoteSource))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "remoteSource");
}
if (String.IsNullOrEmpty(siteRoot))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "siteRoot");
}
_siteRoot = siteRoot;
string webRepositoryDirectory = GetWebRepositoryDirectory(siteRoot);
_projectManager = new ProjectManager(sourceRepository: PackageRepositoryFactory.Default.CreateRepository(remoteSource),
pathResolver: new DefaultPackagePathResolver(webRepositoryDirectory),
localRepository: PackageRepositoryFactory.Default.CreateRepository(webRepositoryDirectory),
project: new WebProjectSystem(siteRoot));
}
internal WebProjectManager(IProjectManager projectManager, string siteRoot)
{
if (String.IsNullOrEmpty(siteRoot))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "siteRoot");
}
if (projectManager == null)
{
throw new ArgumentNullException("projectManager");
}
_siteRoot = siteRoot;
_projectManager = projectManager;
}
public IPackageRepository LocalRepository
{
get { return _projectManager.LocalRepository; }
}
public IPackageRepository SourceRepository
{
get { return _projectManager.SourceRepository; }
}
internal bool DoNotAddBindingRedirects { get; set; }
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#",
Justification = "We want to ensure we get server-side counts for the IQueryable which can only be performed before we collapse versions.")]
public virtual IQueryable<IPackage> GetRemotePackages(string searchTerms, bool filterPreferred)
{
var packages = GetPackages(SourceRepository, searchTerms);
if (filterPreferred)
{
packages = packages.Where(p => p.Tags.ToLower().Contains(WebPagesPreferredTag));
}
// Order by download count and Id to allow collapsing
return packages.OrderByDescending(p => p.DownloadCount)
.ThenBy(p => p.Id);
}
public IQueryable<IPackage> GetInstalledPackages(string searchTerms)
{
return GetPackages(LocalRepository, searchTerms);
}
public IEnumerable<IPackage> GetPackagesWithUpdates(string searchTerms, bool filterPreferredPackages)
{
var packagesToUpdate = GetPackages(LocalRepository, searchTerms);
if (filterPreferredPackages)
{
packagesToUpdate = packagesToUpdate.Where(p => p.Tags.ToLower().Contains(WebPagesPreferredTag));
}
return SourceRepository.GetUpdates(packagesToUpdate, includePrerelease: false).AsQueryable();
}
internal IEnumerable<string> InstallPackage(IPackage package)
{
return InstallPackage(package, AppDomain.CurrentDomain);
}
/// <summary>
/// Installs and adds a package reference to the project
/// </summary>
/// <returns>Warnings encountered when installing the package.</returns>
public IEnumerable<string> InstallPackage(IPackage package, AppDomain appDomain)
{
IEnumerable<string> result = PerformLoggedAction(() =>
{
_projectManager.AddPackageReference(package.Id, package.Version, ignoreDependencies: false, allowPrereleaseVersions: false);
AddBindingRedirects(appDomain);
});
return result;
}
internal IEnumerable<string> UpdatePackage(IPackage package)
{
return UpdatePackage(package, AppDomain.CurrentDomain);
}
/// <summary>
/// Updates a package reference. Installs the package to the App_Data repository if it does not already exist.
/// </summary>
/// <returns>Warnings encountered when updating the package.</returns>
public IEnumerable<string> UpdatePackage(IPackage package, AppDomain appDomain)
{
return PerformLoggedAction(() =>
{
_projectManager.UpdatePackageReference(package.Id, package.Version, updateDependencies: true, allowPrereleaseVersions: false);
AddBindingRedirects(appDomain);
});
}
/// <summary>
/// Removes a package reference and uninstalls the package
/// </summary>
/// <returns>Warnings encountered when uninstalling the package.</returns>
public IEnumerable<string> UninstallPackage(IPackage package, bool removeDependencies)
{
return PerformLoggedAction(() =>
{
_projectManager.RemovePackageReference(package.Id, forceRemove: false, removeDependencies: removeDependencies);
});
}
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "It seems more appropriate to deal with IPackages")]
public bool IsPackageInstalled(IPackage package)
{
return LocalRepository.Exists(package);
}
public IPackage GetUpdate(IPackage package)
{
return SourceRepository.GetUpdates(new[] { package }, includePrerelease: false).SingleOrDefault();
}
private void AddBindingRedirects(AppDomain appDomain)
{
if (DoNotAddBindingRedirects)
{
return;
}
// We can't use HttpRuntime.BinDirectory since there is no runtime when installing via WebMatrix.
var binDirectory = Path.Combine(_siteRoot, "bin");
var assemblies = RemoteAssembly.GetAssembliesForBindingRedirect(appDomain, binDirectory);
var bindingRedirects = BindingRedirectResolver.GetBindingRedirects(assemblies);
if (bindingRedirects.Any())
{
// NuGet ends up reading our web.config file regardless of if any bindingRedirects are needed.
var bindingRedirectManager = new BindingRedirectManager(_projectManager.Project, "web.config");
bindingRedirectManager.AddBindingRedirects(bindingRedirects);
}
}
private IEnumerable<string> PerformLoggedAction(Action action)
{
ErrorLogger logger = new ErrorLogger();
_projectManager.Logger = logger;
try
{
action();
}
finally
{
_projectManager.Logger = null;
}
return logger.Errors;
}
/// <remarks>
/// Ensure that some form of sorting is applied to the IQueryable before this method is invoked.
/// </remarks>
/// <returns>A sequence with the most recent version for each package.</returns>
public static IEnumerable<IPackage> CollapseVersions(IQueryable<IPackage> packages)
{
const int BufferSize = 30;
return packages.Where(package => package.IsLatestVersion)
.AsBufferedEnumerable(BufferSize)
.DistinctLast(PackageEqualityComparer.Id, PackageComparer.Version);
}
internal IEnumerable<IPackage> GetPackagesRequiringLicenseAcceptance(IPackage package)
{
return GetPackagesRequiringLicenseAcceptance(package, localRepository: LocalRepository, sourceRepository: SourceRepository);
}
internal static IEnumerable<IPackage> GetPackagesRequiringLicenseAcceptance(IPackage package, IPackageRepository localRepository, IPackageRepository sourceRepository)
{
var dependencies = GetPackageDependencies(package, localRepository, sourceRepository);
return from p in dependencies
where p.RequireLicenseAcceptance
select p;
}
private static IEnumerable<IPackage> GetPackageDependencies(IPackage package, IPackageRepository localRepository, IPackageRepository sourceRepository)
{
InstallWalker walker = new InstallWalker(localRepository: localRepository, sourceRepository: sourceRepository, logger: NullLogger.Instance,
ignoreDependencies: false, allowPrereleaseVersions: false);
IEnumerable<PackageOperation> operations = walker.ResolveOperations(package);
return from operation in operations
where operation.Action == PackageAction.Install
select operation.Package;
}
internal static IQueryable<IPackage> GetPackages(IPackageRepository repository, string searchTerm)
{
return GetPackages(repository.GetPackages(), searchTerm);
}
internal static IQueryable<IPackage> GetPackages(IQueryable<IPackage> packages, string searchTerm)
{
if (!String.IsNullOrEmpty(searchTerm))
{
searchTerm = searchTerm.Trim();
packages = packages.Find(searchTerm);
}
return packages;
}
internal static string GetWebRepositoryDirectory(string siteRoot)
{
return Path.Combine(siteRoot, "App_Data", "packages");
}
private class ErrorLogger : ILogger
{
private readonly IList<string> _errors = new List<string>();
public IEnumerable<string> Errors
{
get { return _errors; }
}
public void Log(MessageLevel level, string message, params object[] args)
{
if (level == MessageLevel.Warning)
{
_errors.Add(String.Format(CultureInfo.CurrentCulture, message, args));
}
}
}
}
}

View File

@ -0,0 +1,227 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Versioning;
using System.Xml.Linq;
using NuGet;
namespace System.Web.WebPages.Administration.PackageManager
{
public class WebProjectSystem : PhysicalFileSystem, IProjectSystem
{
private const string BinDir = "bin";
private const string AppCodeFolder = "App_Code";
private static readonly string[] _generatedFilesFolder = new[] { "Generated___Files" };
private static readonly string[] _sourceFileExtensions = new[] { ".cs", ".vb" };
/// <summary>
/// Keys taken from the 4.0 RedistList.
/// </summary>
private static readonly string[] _knownPublicKeys = new[] { "b03f5f7f11d50a3a", "b77a5c561934e089", "31bf3856ad364e35" };
public WebProjectSystem(string root)
: base(root)
{
}
public string ProjectName
{
get { return Root; }
}
public FrameworkName TargetFramework
{
get { return VersionUtility.DefaultTargetFramework; }
}
public void AddReference(string referencePath, Stream stream)
{
// Copy to bin by default
string referenceName = Path.GetFileName(referencePath);
string dest = GetFullPath(GetReferencePath(referenceName));
// Copy the reference over
AddFile(dest, stream);
}
public dynamic GetPropertyValue(string propertyName)
{
if (propertyName == null)
{
return null;
}
// Return empty string for the root namespace of this project.
if (propertyName.Equals("RootNamespace", StringComparison.OrdinalIgnoreCase))
{
return String.Empty;
}
return null;
}
public bool IsSupportedFile(string path)
{
return !Path.GetFileName(path).Equals("app.config", StringComparison.OrdinalIgnoreCase);
}
public bool ReferenceExists(string name)
{
string path = GetReferencePath(name);
return FileExists(path);
}
public void RemoveReference(string name)
{
DeleteFile(GetReferencePath(name));
// Delete the bin directory if this was the last reference
if (!GetFiles(BinDir).Any())
{
DeleteDirectory(BinDir);
}
}
public void AddFrameworkReference(string name)
{
// Before we add a framework assembly to web.config, verify that it exists in the GAC. This is important because a website would be completely unusable if the assembly reference
// does not exist and is added to web.config. Since the assembly name may be a partial name, We use the ResolveAssemblyReference task in Msbuild to identify a full name and if it is
// installed in the GAC.
var fullName = ResolvePartialAssemblyName(name);
if (fullName == null)
{
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, PackageManagerResources.UnknownFrameworkReference, name));
}
AddReferencesToConfig(this, fullName);
}
public override IEnumerable<string> GetDirectories(string path)
{
if (IsUnderAppCode(path))
{
// There is an invisible folder called Generated___Files under app code that we want to exclude from our search
return base.GetDirectories(path).Except(_generatedFilesFolder, StringComparer.OrdinalIgnoreCase);
}
return base.GetDirectories(path);
}
public string ResolvePath(string path)
{
if (RequiresAppCodeRemapping(path))
{
path = Path.Combine(AppCodeFolder, path);
}
return path;
}
protected virtual string GetReferencePath(string name)
{
return Path.Combine(BinDir, name);
}
/// <summary>
/// Uses ResolveAssemblyReference to calculate a full name from a partial assembly name.
/// </summary>
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
Justification = "We never want to throw from this method. If Assembly.Load fails, the only message we want to display is that package could not be installed.")]
internal static string ResolvePartialAssemblyName(string name)
{
foreach (var key in _knownPublicKeys)
{
var assemblyFullName = String.Format(CultureInfo.InvariantCulture, "{0}, Version={1}, Culture=neutral, PublicKeyToken={2}",
name, VersionUtility.DefaultTargetFrameworkVersion, key);
try
{
Assembly.Load(assemblyFullName);
// Assembly.Load throws a FileNotFoundException if the assembly name cannot be resolved. If we managed to successfully locate the assembly, return it.
return assemblyFullName;
}
catch
{
// Do nothing. We don't want to throw from this method.
}
}
return null;
}
internal static void AddReferencesToConfig(IFileSystem fileSystem, string references)
{
var webConfigPath = Path.Combine(fileSystem.Root, "web.config");
XDocument document;
// Read the web.config file from the AppRoot if it exists.
if (fileSystem.FileExists(webConfigPath))
{
using (Stream stream = fileSystem.OpenFile(webConfigPath))
{
document = XDocument.Load(stream, LoadOptions.PreserveWhitespace);
}
}
else
{
document = new XDocument(new XElement("configuration"));
}
var assemblies = GetOrCreateChild(document.Root, "system.web/compilation/assemblies");
// Get the name of the existing references
// References are stored in the format <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
bool existingAssembly = (from item in assemblies.Elements()
where !String.IsNullOrEmpty(item.GetOptionalAttributeValue("assembly"))
let assemblyName = new AssemblyName(item.Attribute("assembly").Value).Name
where String.Equals(assemblyName, references, StringComparison.OrdinalIgnoreCase)
select item).Any();
if (!existingAssembly)
{
assemblies.Add(new XElement("add", new XAttribute("assembly", references)));
SaveDocument(fileSystem, webConfigPath, document);
}
}
private static void SaveDocument(IFileSystem fileSystem, string webConfigPath, XDocument document)
{
using (MemoryStream stream = new MemoryStream())
{
document.Save(stream);
stream.Seek(0, SeekOrigin.Begin);
fileSystem.AddFile(webConfigPath, stream);
}
}
private static XElement GetOrCreateChild(XElement element, string childName)
{
foreach (var item in childName.Split('/'))
{
XElement child = element.Element(item);
if (child == null)
{
child = new XElement(item);
element.Add(child);
}
element = child;
}
return element;
}
private static bool RequiresAppCodeRemapping(string path)
{
return !IsUnderAppCode(path) && IsSourceFile(path);
}
private static bool IsUnderAppCode(string path)
{
return path.StartsWith(AppCodeFolder + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase);
}
private static bool IsSourceFile(string path)
{
return _sourceFileExtensions.Contains(Path.GetExtension(path), StringComparer.OrdinalIgnoreCase);
}
}
}

View File

@ -0,0 +1,65 @@
@* Generator: WebPage *@
@using System.Globalization;
@{
Page.Title = AdminResources.LoginTitle;
// No admin password has been registered so redirect
if(!AdminSecurity.HasAdminPassword()) {
SiteAdmin.RedirectToRegister(Response);
return;
}
if (IsPost) {
AntiForgery.Validate();
var password = Request.Form["password"];
if (AdminSecurity.CheckPassword(password)) {
// Get the return url
var returnUrl = SiteAdmin.GetReturnUrl(Request) ?? SiteAdmin.AdminVirtualPath;
// Set the admin auth cookie
AdminSecurity.SetAuthCookie(Response);
// Redirect to the return url
Response.Redirect(returnUrl);
}
else {
ModelState.AddError("password", AdminResources.Validation_PasswordIncorrect);
}
}
}
@section Head{
<script type="text/javascript">
function showForgotPasswordInfo(){
document.getElementById('forgotPasswordInfo').style.display = '';
}
</script>
}
@Html.ValidationSummary()
<br />
<form method="post" action="">
@AntiForgery.GetHtml()
<fieldset>
<ol>
<li class="password">
<label for="password">@AdminResources.Password:</label>
@Html.Password("password") @Html.ValidationMessage("password", "*")
</ol>
<p class="form-actions">
<input type="submit" value="@AdminResources.Login" />
</p>
</fieldset>
<p>
<a href="#" onclick="showForgotPasswordInfo(); return false;">@AdminResources.ForgotPassword</a>
</p>
</form>
<br />
@{
var passwordFileLocation = AdminSecurity.AdminPasswordFile.TrimStart('~', '/');
var forgotPasswordHelp = String.Format(CultureInfo.CurrentCulture, AdminResources.AdminPasswordChangeInstructions, Html.Encode(passwordFileLocation));
}
<span id="forgotPasswordInfo" style="display: none">@Html.Raw(forgotPasswordHelp)</span>

View File

@ -0,0 +1,154 @@
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.225
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace System.Web.WebPages.Administration
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Helpers;
using System.Web.Security;
using System.Web.UI;
using System.Web.WebPages;
using System.Web.WebPages.Html;
using System.Globalization;
[System.Web.WebPages.PageVirtualPathAttribute("~/Login.cshtml")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("RazorSingleFileGenerator", "1.0.0.0")]
public class Login_cshtml : System.Web.WebPages.WebPage
{
#line hidden
// Resolve package relative syntax
// Also, if it comes from a static embedded resource, change the path accordingly
public override string Href(string virtualPath, params object[] pathParts) {
virtualPath = ApplicationPart.ProcessVirtualPath(GetType().Assembly, VirtualPath, virtualPath);
return base.Href(virtualPath, pathParts);
}
public Login_cshtml()
{
}
protected System.Web.HttpApplication ApplicationInstance
{
get
{
return ((System.Web.HttpApplication)(Context.ApplicationInstance));
}
}
public override void Execute()
{
WriteLiteral("\r\n\r\n");
Page.Title = AdminResources.LoginTitle;
// No admin password has been registered so redirect
if(!AdminSecurity.HasAdminPassword()) {
SiteAdmin.RedirectToRegister(Response);
return;
}
if (IsPost) {
AntiForgery.Validate();
var password = Request.Form["password"];
if (AdminSecurity.CheckPassword(password)) {
// Get the return url
var returnUrl = SiteAdmin.GetReturnUrl(Request) ?? SiteAdmin.AdminVirtualPath;
// Set the admin auth cookie
AdminSecurity.SetAuthCookie(Response);
// Redirect to the return url
Response.Redirect(returnUrl);
}
else {
ModelState.AddError("password", AdminResources.Validation_PasswordIncorrect);
}
}
WriteLiteral("\r\n");
DefineSection("Head", () => {
WriteLiteral("\r\n <script type=\"text/javascript\">\r\n function showForgotPasswordInfo(){\r\n " +
" document.getElementById(\'forgotPasswordInfo\').style.display = \'\';\r\n }\r\n" +
" </script>\r\n");
});
WriteLiteral("\r\n\r\n");
Write(Html.ValidationSummary());
WriteLiteral("\r\n<br />\r\n\r\n<form method=\"post\" action=\"\">\r\n ");
Write(AntiForgery.GetHtml());
WriteLiteral("\r\n <fieldset>\r\n <ol>\r\n <li class=\"password\">\r\n <label for" +
"=\"password\">");
Write(AdminResources.Password);
WriteLiteral(":</label>\r\n ");
Write(Html.Password("password"));
WriteLiteral(" ");
Write(Html.ValidationMessage("password", "*"));
WriteLiteral("\r\n </ol>\r\n <p class=\"form-actions\">\r\n <input type=\"submit\" value=\"");
Write(AdminResources.Login);
WriteLiteral("\" />\r\n </p>\r\n </fieldset>\r\n <p>\r\n <a href=\"#\" onclick=\"showForgot" +
"PasswordInfo(); return false;\">");
Write(AdminResources.ForgotPassword);
WriteLiteral("</a>\r\n </p>\r\n</form>\r\n<br />\r\n");
var passwordFileLocation = AdminSecurity.AdminPasswordFile.TrimStart('~', '/');
var forgotPasswordHelp = String.Format(CultureInfo.CurrentCulture, AdminResources.AdminPasswordChangeInstructions, Html.Encode(passwordFileLocation));
WriteLiteral("<span id=\"forgotPasswordInfo\" style=\"display: none\">");
Write(Html.Raw(forgotPasswordHelp));
WriteLiteral("</span>");
}
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,9 @@
@* Generator: WebPage *@
@{
// Delete the admin auth cookie
AdminSecurity.DeleteAuthCookie(Response);
// Redirect home
SiteAdmin.RedirectToHome(Response);
}

Some files were not shown because too many files have changed in this diff Show More