Files
Umbraco-CMS/src/umbraco.businesslogic/BasePages/UmbracoEnsuredPage.cs

166 lines
6.7 KiB
C#

using System;
using Umbraco.Core.Logging;
using System.Linq;
using System.Web;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using umbraco.BusinessLogic;
using umbraco.businesslogic.Exceptions;
using Umbraco.Core.Security;
namespace umbraco.BasePages
{
/// <summary>
/// UmbracoEnsuredPage is the standard protected page in the umbraco backend, and forces authentication.
/// </summary>
[Obsolete("This class has been superceded by Umbraco.Web.UI.Pages.UmbracoEnsuredPage")]
public class UmbracoEnsuredPage : BasePage
{
/// <summary>
/// Checks if the page exists outside of the /umbraco route, in which case the request will not have been authenticated for the back office
/// so we'll force authentication.
/// </summary>
/// <param name="e"></param>
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
//If this is not a back office request, then the module won't have authenticated it, in this case we
// need to do the auth manually and since this is an UmbracoEnsuredPage, this is the anticipated behavior
// TODO: When we implement Identity, this process might not work anymore, will be an interesting challenge
if (Context.Request.Url.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath) == false)
{
var http = new HttpContextWrapper(Context);
var ticket = http.GetUmbracoAuthTicket();
http.AuthenticateCurrentRequest(ticket, true);
}
}
/// <summary>
/// Gets/sets the app for which this page belongs to so that we can validate the current user's security against it
/// </summary>
/// <remarks>
/// If no app is specified then all logged in users will have access to the page
/// </remarks>
public string CurrentApp { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoEnsuredPage"/> class.
/// </summary>
public UmbracoEnsuredPage()
{
//Assign security automatically if the attribute is found
var treeAuth = this.GetType().GetCustomAttribute<WebformsPageTreeAuthorizeAttribute>(true);
if (treeAuth != null)
{
var treeByAlias = ApplicationContext.Current.Services.ApplicationTreeService
.GetByAlias(treeAuth.TreeAlias);
if (treeByAlias != null)
{
CurrentApp = treeByAlias.ApplicationAlias;
}
}
}
[Obsolete("This constructor is not used and will be removed from the codebase in the future")]
public UmbracoEnsuredPage(string hest) : this()
{
}
/// <summary>
/// If true then umbraco will force any window/frame to reload umbraco in the main window
/// </summary>
public bool RedirectToUmbraco { get; set; }
/// <summary>
/// Validates the user for access to a certain application
/// </summary>
/// <param name="app">The application alias.</param>
/// <returns></returns>
public bool ValidateUserApp(string app)
{
return getUser().Applications.Any(uApp => uApp.alias.InvariantEquals(app));
}
/// <summary>
/// Validates the user node tree permissions.
/// </summary>
/// <param name="Path">The path.</param>
/// <param name="Action">The action.</param>
/// <returns></returns>
public bool ValidateUserNodeTreePermissions(string Path, string Action)
{
string permissions = getUser().GetPermissions(Path);
if (permissions.IndexOf(Action) > -1 && (Path.Contains("-20") || ("," + Path + ",").Contains("," + getUser().StartNodeId.ToString() + ",")))
return true;
var user = getUser();
LogHelper.Info<UmbracoEnsuredPage>("User {0} has insufficient permissions in UmbracoEnsuredPage: '{1}', '{2}', '{3}'", () => user.Name, () => Path, () => permissions, () => Action);
return false;
}
/// <summary>
/// Gets the current user.
/// </summary>
/// <value>The current user.</value>
public static User CurrentUser
{
get
{
return BusinessLogic.User.GetCurrent();
}
}
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.Init"></see> event to initialize the page.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
try
{
ensureContext();
if (!string.IsNullOrEmpty(CurrentApp))
{
if (!ValidateUserApp(CurrentApp))
throw new UserAuthorizationException(String.Format("The current user doesn't have access to the section/app '{0}'", CurrentApp));
}
}
catch (UserAuthorizationException ex)
{
LogHelper.Warn<UmbracoEnsuredPage>(string.Format("{0} tried to access '{1}'", CurrentUser.Id, CurrentApp));
throw;
}
catch
{
// Clear content as .NET transfers rendered content.
Response.Clear();
// Some umbraco pages should not be loaded on timeout, but instead reload the main application in the top window. Like the treeview for instance
if (RedirectToUmbraco)
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?t=" + umbracoUserContextID, true);
else
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl) + "&t=" + umbracoUserContextID, true);
}
}
/// <summary>
/// Used to assign a webforms page's security to a specific tree which will in turn check to see
/// if the current user has access to the specified tree's registered section
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class WebformsPageTreeAuthorizeAttribute : Attribute
{
public string TreeAlias { get; private set; }
public WebformsPageTreeAuthorizeAttribute(string treeAlias)
{
TreeAlias = treeAlias;
}
}
}
}