Merge remote-tracking branch 'origin/netcore/netcore' into netcore/task/6666-auth-policies
# Conflicts: # src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs # src/Umbraco.Web.Common/Filters/UmbracoMemberAuthorizeFilter.cs
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
namespace Umbraco.Core.Models.Security
|
||||
{
|
||||
public class LoginModel : PostRedirectModel
|
||||
{
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Web.Models
|
||||
|
||||
[Required]
|
||||
[DataMember(Name = "password", IsRequired = true)]
|
||||
[StringLength(maximumLength:256)]
|
||||
[StringLength(maximumLength: 256)]
|
||||
public string Password { get; set; }
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Umbraco.Web.Models
|
||||
namespace Umbraco.Core.Models.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// A base model containing a value to indicate to Umbraco where to redirect to after Posting if
|
||||
@@ -2,36 +2,15 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Web.Mvc;
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
namespace Umbraco.Core.Models.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// A readonly member profile model
|
||||
/// </summary>
|
||||
[ModelBinder(typeof(ProfileModelBinder))]
|
||||
public class ProfileModel : PostRedirectModel
|
||||
{
|
||||
|
||||
public static ProfileModel CreateModel()
|
||||
{
|
||||
var model = new ProfileModel(false);
|
||||
return model;
|
||||
}
|
||||
|
||||
private ProfileModel(bool doLookup)
|
||||
{
|
||||
MemberProperties = new List<UmbracoProperty>();
|
||||
if (doLookup && Current.UmbracoContext != null)
|
||||
{
|
||||
var helper = Current.MembershipHelper;
|
||||
var model = helper.GetCurrentMemberProfileModel();
|
||||
MemberProperties = model.MemberProperties;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Required]
|
||||
[RegularExpression(@"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
|
||||
ErrorMessage = "Please enter a valid e-mail address")]
|
||||
@@ -81,18 +60,6 @@ namespace Umbraco.Web.Models
|
||||
/// <remarks>
|
||||
/// Adding items to this list on the front-end will not add properties to the member in the database.
|
||||
/// </remarks>
|
||||
public List<UmbracoProperty> MemberProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A custom model binder for MVC because the default ctor performs a lookup!
|
||||
/// </summary>
|
||||
internal class ProfileModelBinder : DefaultModelBinder
|
||||
{
|
||||
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
|
||||
{
|
||||
return ProfileModel.CreateModel();
|
||||
}
|
||||
|
||||
}
|
||||
public List<UmbracoProperty> MemberProperties { get; set; } = new List<UmbracoProperty>();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
namespace Umbraco.Core.Models.Security
|
||||
{
|
||||
[ModelBinder(typeof(RegisterModelBinder))]
|
||||
public class RegisterModel : PostRedirectModel
|
||||
{
|
||||
/// <summary>
|
||||
@@ -27,7 +24,6 @@ namespace Umbraco.Web.Models
|
||||
CreatePersistentLoginCookie = true;
|
||||
}
|
||||
|
||||
|
||||
[Required]
|
||||
[RegularExpression(@"[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?",
|
||||
ErrorMessage = "Please enter a valid e-mail address")]
|
||||
@@ -74,16 +70,5 @@ namespace Umbraco.Web.Models
|
||||
/// Default is true to create a persistent cookie if LoginOnSuccess is true
|
||||
/// </summary>
|
||||
public bool CreatePersistentLoginCookie { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A custom model binder for MVC because the default ctor performs a lookup!
|
||||
/// </summary>
|
||||
internal class RegisterModelBinder : DefaultModelBinder
|
||||
{
|
||||
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
|
||||
{
|
||||
return RegisterModel.CreateModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Serialization;
|
||||
|
||||
namespace Umbraco.Core
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a data type configuration editor.
|
||||
@@ -25,7 +25,7 @@ namespace Umbraco.Core.PropertyEditors
|
||||
//TODO: We will need to change this once we support tracking via variants/segments
|
||||
// for now, we are tracking values from ALL variants
|
||||
|
||||
foreach(var propertyVal in p.Values)
|
||||
foreach (var propertyVal in p.Values)
|
||||
{
|
||||
var val = propertyVal.EditedValue;
|
||||
|
||||
@@ -33,9 +33,9 @@ namespace Umbraco.Core.PropertyEditors
|
||||
if (valueEditor is IDataValueReference reference)
|
||||
{
|
||||
var refs = reference.GetReferences(val);
|
||||
foreach(var r in refs)
|
||||
foreach (var r in refs)
|
||||
trackedRelations.Add(r);
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over collection that may be add to existing property editors
|
||||
// implementation of GetReferences in IDataValueReference.
|
||||
@@ -48,14 +48,11 @@ namespace Umbraco.Core.PropertyEditors
|
||||
// in the dataeditor/property has referecnes to media/content items
|
||||
if (item.IsForEditor(editor))
|
||||
{
|
||||
foreach(var r in item.GetDataValueReference().GetReferences(val))
|
||||
foreach (var r in item.GetDataValueReference().GetReferences(val))
|
||||
trackedRelations.Add(r);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return trackedRelations;
|
||||
@@ -1,5 +1,4 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.PropertyEditors.Validators;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
@@ -7,7 +6,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// A custom pre-value editor class to deal with the legacy way that the pre-value data is stored.
|
||||
/// </summary>
|
||||
internal class DecimalConfigurationEditor : ConfigurationEditor
|
||||
public class DecimalConfigurationEditor : ConfigurationEditor
|
||||
{
|
||||
public DecimalConfigurationEditor()
|
||||
{
|
||||
@@ -13,6 +13,6 @@ namespace Umbraco.Core.PropertyEditors
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<UmbracoEntityReference> GetReferences(object value);
|
||||
IEnumerable<UmbracoEntityReference> GetReferences(object value);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the DataValueReference lookup supports a datatype (data editor).
|
||||
/// </summary>
|
||||
/// <param name="dataType">The datatype.</param>
|
||||
/// <param name="dataEditor"></param>
|
||||
/// <returns>A value indicating whether the converter supports a datatype.</returns>
|
||||
bool IsForEditor(IDataEditor dataEditor);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.PropertyEditors.Validators;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
@@ -7,7 +6,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// A custom pre-value editor class to deal with the legacy way that the pre-value data is stored.
|
||||
/// </summary>
|
||||
internal class IntegerConfigurationEditor : ConfigurationEditor
|
||||
public class IntegerConfigurationEditor : ConfigurationEditor
|
||||
{
|
||||
public IntegerConfigurationEditor()
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
@@ -31,7 +31,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
new Layout { Name = "grid", Icon = "icon-thumbnails-small", IsSystem = 1, Selected = true, Path = "views/propertyeditors/listview/layouts/grid/grid.html" }
|
||||
};
|
||||
|
||||
IncludeProperties = new []
|
||||
IncludeProperties = new[]
|
||||
{
|
||||
new Property { Alias = "sortOrder", Header = "Sort order", IsSystem = 1 },
|
||||
new Property { Alias = "updateDate", Header = "Last edited", IsSystem = 1 },
|
||||
@@ -41,7 +41,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
|
||||
[ConfigurationField("pageSize", "Page Size", "number", Description = "Number of items per page")]
|
||||
public int PageSize { get; set; }
|
||||
|
||||
|
||||
[ConfigurationField("orderBy", "Order By", "views/propertyeditors/listview/sortby.prevalues.html",
|
||||
Description = "The default sort order for the list")]
|
||||
public string OrderBy { get; set; }
|
||||
@@ -69,54 +69,57 @@ namespace Umbraco.Web.PropertyEditors
|
||||
[ConfigurationField("showContentFirst", "Show Content App First", "boolean", Description = "Enable this to show the content app by default instead of the list view app")]
|
||||
public bool ShowContentFirst { get; set; }
|
||||
|
||||
[DataContract]
|
||||
public class Property
|
||||
{
|
||||
[JsonProperty("alias")]
|
||||
[DataMember(Name = "alias")]
|
||||
public string Alias { get; set; }
|
||||
|
||||
[JsonProperty("header")]
|
||||
[DataMember(Name = "header")]
|
||||
public string Header { get; set; }
|
||||
|
||||
[JsonProperty("nameTemplate")]
|
||||
[DataMember(Name = "nameTemplate")]
|
||||
public string Template { get; set; }
|
||||
|
||||
[JsonProperty("isSystem")]
|
||||
[DataMember(Name = "isSystem")]
|
||||
public int IsSystem { get; set; } // TODO: bool
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
public class Layout
|
||||
{
|
||||
[JsonProperty("name")]
|
||||
[DataMember(Name = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("path")]
|
||||
[DataMember(Name = "path")]
|
||||
public string Path { get; set; }
|
||||
|
||||
[JsonProperty("icon")]
|
||||
[DataMember(Name = "icon")]
|
||||
public string Icon { get; set; }
|
||||
|
||||
[JsonProperty("isSystem")]
|
||||
[DataMember(Name = "isSystem")]
|
||||
public int IsSystem { get; set; } // TODO: bool
|
||||
|
||||
[JsonProperty("selected")]
|
||||
[DataMember(Name = "selected")]
|
||||
public bool Selected { get; set; }
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
public class BulkActionPermissionSettings
|
||||
{
|
||||
[JsonProperty("allowBulkPublish")]
|
||||
[DataMember(Name = "allowBulkPublish")]
|
||||
public bool AllowBulkPublish { get; set; } = true;
|
||||
|
||||
[JsonProperty("allowBulkUnpublish")]
|
||||
[DataMember(Name = "allowBulkUnpublish")]
|
||||
public bool AllowBulkUnpublish { get; set; } = true;
|
||||
|
||||
[JsonProperty("allowBulkCopy")]
|
||||
[DataMember(Name = "allowBulkCopy")]
|
||||
public bool AllowBulkCopy { get; set; } = true;
|
||||
|
||||
[JsonProperty("allowBulkMove")]
|
||||
[DataMember(Name = "allowBulkMove")]
|
||||
public bool AllowBulkMove { get; set; } = true;
|
||||
|
||||
[JsonProperty("allowBulkDelete")]
|
||||
[DataMember(Name = "allowBulkDelete")]
|
||||
public bool AllowBulkDelete { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the 'startNode' value for the <see cref="Umbraco.Web.PropertyEditors.MultiNodePickerConfiguration"/>
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class MultiNodePickerConfigurationTreeSource
|
||||
{
|
||||
[DataMember(Name = "type")]
|
||||
public string ObjectType { get; set; }
|
||||
|
||||
[DataMember(Name = "query")]
|
||||
public string StartNodeQuery { get; set; }
|
||||
|
||||
[DataMember(Name = "id")]
|
||||
public Udi StartNodeId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
@@ -27,15 +27,17 @@ namespace Umbraco.Web.PropertyEditors
|
||||
[ConfigurationField("hideLabel", "Hide Label", "boolean", Description = "Hide the property label and let the item list span the full width of the editor window.")]
|
||||
public bool HideLabel { get; set; }
|
||||
|
||||
|
||||
[DataContract]
|
||||
public class ContentType
|
||||
{
|
||||
[JsonProperty("ncAlias")]
|
||||
[DataMember(Name = "ncAlias")]
|
||||
public string Alias { get; set; }
|
||||
|
||||
[JsonProperty("ncTabAlias")]
|
||||
[DataMember(Name = "ncTabAlias")]
|
||||
public string TabAlias { get; set; }
|
||||
|
||||
[JsonProperty("nameTemplate")]
|
||||
[DataMember(Name = "nameTemplate")]
|
||||
public string Template { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
@@ -27,7 +27,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
=> propertyType.EditorAlias.Equals(Constants.PropertyEditors.Aliases.ContentPicker);
|
||||
|
||||
public override Type GetPropertyValueType(IPublishedPropertyType propertyType)
|
||||
=> typeof (IPublishedContent);
|
||||
=> typeof(IPublishedContent);
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
|
||||
=> PropertyCacheLevel.Elements;
|
||||
@@ -65,9 +65,9 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
if (source is decimal sourceDecimal) return sourceDecimal;
|
||||
if (source is string sourceDecimalString)
|
||||
return decimal.TryParse(sourceDecimalString, NumberStyles.Any, CultureInfo.InvariantCulture, out var d) ? d : 0;
|
||||
if (source is double sourceDouble)
|
||||
return Convert.ToDecimal(sourceDouble);
|
||||
return (decimal) 0;
|
||||
if (source is double sourceDouble)
|
||||
return Convert.ToDecimal(sourceDouble);
|
||||
return (decimal)0;
|
||||
case ValueTypes.Integer:
|
||||
if (source is int sourceInt) return sourceInt;
|
||||
if (source is string sourceIntString)
|
||||
@@ -76,7 +76,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
case ValueTypes.Bigint:
|
||||
if (source is string sourceLongString)
|
||||
return long.TryParse(sourceLongString, out var i) ? i : 0;
|
||||
return (long) 0;
|
||||
return (long)0;
|
||||
default: // everything else is a string
|
||||
return source?.ToString() ?? string.Empty;
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
{
|
||||
/// <summary>
|
||||
@@ -67,7 +68,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
{
|
||||
var isMultiple = IsMultipleDataType(propertyType.DataType);
|
||||
|
||||
var udis = (Udi[]) source;
|
||||
var udis = (Udi[])source;
|
||||
var mediaItems = new List<IPublishedContent>();
|
||||
|
||||
if (source == null) return isMultiple ? mediaItems : null;
|
||||
@@ -14,7 +14,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
=> propertyType.EditorAlias == Constants.PropertyEditors.Aliases.TinyMce;
|
||||
|
||||
public override Type GetPropertyValueType(IPublishedPropertyType propertyType)
|
||||
=> typeof (IHtmlEncodedString);
|
||||
=> typeof(IHtmlEncodedString);
|
||||
|
||||
// PropertyCacheLevel.Content is ok here because that converter does not parse {locallink} nor executes macros
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
|
||||
@@ -2,10 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration.Models;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Core
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
|
||||
public class HybridBackofficeSecurityAccessor : HybridAccessorBase<IBackOfficeSecurity>, IBackOfficeSecurityAccessor
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HybridUmbracoContextAccessor"/> class.
|
||||
/// Initializes a new instance of the <see cref="HybridBackofficeSecurityAccessor"/> class.
|
||||
/// </summary>
|
||||
public HybridBackofficeSecurityAccessor(IRequestCache requestCache)
|
||||
: base(requestCache)
|
||||
@@ -19,7 +16,7 @@ namespace Umbraco.Core
|
||||
protected override string ItemKey => "Umbraco.Web.HybridBackofficeSecurityAccessor";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="BackOfficeSecurity"/> object.
|
||||
/// Gets or sets the <see cref="IBackOfficeSecurity"/> object.
|
||||
/// </summary>
|
||||
public IBackOfficeSecurity BackOfficeSecurity
|
||||
{
|
||||
@@ -0,0 +1,28 @@
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Web;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
|
||||
public class HybridUmbracoWebsiteSecurityAccessor : HybridAccessorBase<IUmbracoWebsiteSecurity>, IUmbracoWebsiteSecurityAccessor
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HybridUmbracoWebsiteSecurityAccessor"/> class.
|
||||
/// </summary>
|
||||
public HybridUmbracoWebsiteSecurityAccessor(IRequestCache requestCache)
|
||||
: base(requestCache)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string ItemKey => "Umbraco.Web.HybridUmbracoWebsiteSecurityAccessor";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IUmbracoWebsiteSecurity"/> object.
|
||||
/// </summary>
|
||||
public IUmbracoWebsiteSecurity WebsiteSecurity
|
||||
{
|
||||
get => Value;
|
||||
set => Value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/Umbraco.Core/Security/IUmbracoWebsiteSecurity.cs
Normal file
55
src/Umbraco.Core/Security/IUmbracoWebsiteSecurity.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core.Models.Security;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
public interface IUmbracoWebsiteSecurity
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers a new member.
|
||||
/// </summary>
|
||||
/// <param name="model">Register member model.</param>
|
||||
/// <param name="logMemberIn">Flag for whether to log the member in upon successful registration.</param>
|
||||
/// <returns>Result of registration operation.</returns>
|
||||
Task<RegisterMemberStatus> RegisterMemberAsync(RegisterModel model, bool logMemberIn = true);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the currently logged in member's profile.
|
||||
/// </summary>
|
||||
/// <param name="model">Update member profile model.</param>
|
||||
/// <returns>Result of update profile operation.</returns>
|
||||
Task<UpdateMemberProfileResult> UpdateMemberProfileAsync(ProfileModel model);
|
||||
|
||||
/// <summary>
|
||||
/// A helper method to perform the validation and logging in of a member.
|
||||
/// </summary>
|
||||
/// <param name="username">The username.</param>
|
||||
/// <param name="password">The password.</param>
|
||||
/// <returns>Result of login operation.</returns>
|
||||
Task<bool> LoginAsync(string username, string password);
|
||||
|
||||
/// <summary>
|
||||
/// Check if a member is logged in
|
||||
/// </summary>
|
||||
/// <returns>True if logged in, false if not.</returns>
|
||||
bool IsLoggedIn();
|
||||
|
||||
/// <summary>
|
||||
/// Logs out the current member.
|
||||
/// </summary>
|
||||
Task LogOutAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current member is authorized based on the parameters provided.
|
||||
/// </summary>
|
||||
/// <param name="allowTypes">Allowed types.</param>
|
||||
/// <param name="allowGroups">Allowed groups.</param>
|
||||
/// <param name="allowMembers">Allowed individual members.</param>
|
||||
/// <returns>True or false if the currently logged in member is authorized</returns>
|
||||
bool IsMemberAuthorized(
|
||||
IEnumerable<string> allowTypes = null,
|
||||
IEnumerable<string> allowGroups = null,
|
||||
IEnumerable<int> allowMembers = null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
public interface IUmbracoWebsiteSecurityAccessor
|
||||
{
|
||||
IUmbracoWebsiteSecurity WebsiteSecurity { get; set; }
|
||||
}
|
||||
}
|
||||
13
src/Umbraco.Core/Security/RegisterMemberStatus.cs
Normal file
13
src/Umbraco.Core/Security/RegisterMemberStatus.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
public enum RegisterMemberStatus
|
||||
{
|
||||
Success,
|
||||
InvalidUserName,
|
||||
InvalidPassword,
|
||||
InvalidEmail,
|
||||
DuplicateUserName,
|
||||
DuplicateEmail,
|
||||
Error,
|
||||
}
|
||||
}
|
||||
24
src/Umbraco.Core/Security/UpdateMemberProfileResult.cs
Normal file
24
src/Umbraco.Core/Security/UpdateMemberProfileResult.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
public class UpdateMemberProfileResult
|
||||
{
|
||||
private UpdateMemberProfileResult()
|
||||
{
|
||||
}
|
||||
|
||||
public UpdateMemberProfileStatus Status { get; private set; }
|
||||
|
||||
public string ErrorMessage { get; private set; }
|
||||
|
||||
public static UpdateMemberProfileResult Success()
|
||||
{
|
||||
return new UpdateMemberProfileResult { Status = UpdateMemberProfileStatus.Success };
|
||||
}
|
||||
|
||||
public static UpdateMemberProfileResult Error(string message)
|
||||
{
|
||||
return new UpdateMemberProfileResult { Status = UpdateMemberProfileStatus.Error, ErrorMessage = message };
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
8
src/Umbraco.Core/Security/UpdateMemberProfileStatus.cs
Normal file
8
src/Umbraco.Core/Security/UpdateMemberProfileStatus.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
public enum UpdateMemberProfileStatus
|
||||
{
|
||||
Success,
|
||||
Error,
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the 'startNode' value for the <see cref="MultiNodePickerConfiguration"/>
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
public class MultiNodePickerConfigurationTreeSource
|
||||
{
|
||||
[JsonProperty("type")]
|
||||
public string ObjectType {get;set;}
|
||||
|
||||
[JsonProperty("query")]
|
||||
public string StartNodeQuery {get;set;}
|
||||
|
||||
[JsonProperty("id")]
|
||||
public Udi StartNodeId {get;set;}
|
||||
}
|
||||
}
|
||||
@@ -3,17 +3,19 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.BackOffice;
|
||||
using Umbraco.Core.Configuration.Models;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Models.Security;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Extensions;
|
||||
@@ -25,11 +27,10 @@ using Umbraco.Web.Common.Controllers;
|
||||
using Umbraco.Web.Common.Exceptions;
|
||||
using Umbraco.Web.Common.Filters;
|
||||
using Umbraco.Web.Common.Security;
|
||||
using Umbraco.Web.Editors.Filters;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Security;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Umbraco.Web.Common.Authorization;
|
||||
|
||||
|
||||
@@ -250,7 +250,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
/// <param name="culture">The culture to fetch the URL for</param>
|
||||
/// <returns>The URL or path to the item</returns>
|
||||
[DetermineAmbiguousActionByPassingParameters]
|
||||
public HttpResponseMessage GetUrl(Udi udi, string culture = "*")
|
||||
public IActionResult GetUrl(Udi udi, string culture = "*")
|
||||
{
|
||||
var intId = _entityService.GetId(udi);
|
||||
if (!intId.Success)
|
||||
@@ -284,7 +284,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
/// We are not restricting this with security because there is no sensitive data
|
||||
/// </remarks>
|
||||
[DetermineAmbiguousActionByPassingParameters]
|
||||
public HttpResponseMessage GetUrl(int id, UmbracoEntityTypes type, string culture = null)
|
||||
public IActionResult GetUrl(int id, UmbracoEntityTypes type, string culture = null)
|
||||
{
|
||||
culture = culture ?? ClientCulture();
|
||||
|
||||
@@ -297,10 +297,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
{
|
||||
returnUrl = foundUrl;
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent(returnUrl)
|
||||
};
|
||||
return Ok(returnUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,10 +311,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
|
||||
returnUrl = "/" + string.Join("/", ancestors.Select(x => x.Name));
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent(returnUrl)
|
||||
};
|
||||
return Ok(returnUrl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public HttpResponseMessage CreatePartialViewMacroWithFile(CreatePartialViewMacroWithFileModel model)
|
||||
public IActionResult CreatePartialViewMacroWithFile(CreatePartialViewMacroWithFileModel model)
|
||||
{
|
||||
if (model == null) throw new ArgumentNullException("model");
|
||||
if (string.IsNullOrWhiteSpace(model.Filename)) throw new ArgumentException("Filename cannot be null or whitespace", "model.Filename");
|
||||
@@ -173,7 +173,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
};
|
||||
|
||||
_macroService.Save(macro); // may throw
|
||||
return new HttpResponseMessage(HttpStatusCode.OK);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
public class CreatePartialViewMacroWithFileModel
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Web.Common.Filters
|
||||
@@ -13,6 +14,12 @@ namespace Umbraco.Web.Common.Filters
|
||||
public class UmbracoMemberAuthorizeFilter : IAuthorizationFilter
|
||||
{
|
||||
// TODO: Lets revisit this when we get members done and the front-end working and whether it can be replaced or moved to an authz policy
|
||||
private readonly IUmbracoWebsiteSecurity _websiteSecurity;
|
||||
|
||||
public UmbracoMemberAuthorizeFilter(IUmbracoWebsiteSecurity websiteSecurity)
|
||||
{
|
||||
_websiteSecurity = websiteSecurity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Comma delimited list of allowed member types
|
||||
@@ -29,9 +36,7 @@ namespace Umbraco.Web.Common.Filters
|
||||
/// </summary>
|
||||
public string AllowMembers { get; private set; }
|
||||
|
||||
|
||||
private UmbracoMemberAuthorizeFilter(
|
||||
string allowType, string allowGroup, string allowMembers)
|
||||
private UmbracoMemberAuthorizeFilter(string allowType, string allowGroup, string allowMembers)
|
||||
{
|
||||
AllowType = allowType;
|
||||
AllowGroup = allowGroup;
|
||||
@@ -50,11 +55,19 @@ namespace Umbraco.Web.Common.Filters
|
||||
private bool IsAuthorized()
|
||||
{
|
||||
if (AllowMembers.IsNullOrWhiteSpace())
|
||||
AllowMembers = "";
|
||||
{
|
||||
AllowMembers = string.Empty;
|
||||
}
|
||||
|
||||
if (AllowGroup.IsNullOrWhiteSpace())
|
||||
AllowGroup = "";
|
||||
{
|
||||
AllowGroup = string.Empty;
|
||||
}
|
||||
|
||||
if (AllowType.IsNullOrWhiteSpace())
|
||||
AllowType = "";
|
||||
{
|
||||
AllowType = string.Empty;
|
||||
}
|
||||
|
||||
var members = new List<int>();
|
||||
foreach (var s in AllowMembers.Split(','))
|
||||
@@ -65,7 +78,7 @@ namespace Umbraco.Web.Common.Filters
|
||||
}
|
||||
}
|
||||
|
||||
return false;// TODO reintroduce when members are implemented: _memberHelper.IsMemberAuthorized(AllowType.Split(','), AllowGroup.Split(','), members);
|
||||
return _websiteSecurity.IsMemberAuthorized(AllowType.Split(','), AllowGroup.Split(','), members);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,9 +74,12 @@ namespace Umbraco.Web.Common.Runtime
|
||||
|
||||
// register the umbraco context factory
|
||||
composition.Services.AddUnique<IUmbracoContextFactory, UmbracoContextFactory>();
|
||||
|
||||
composition.Services.AddUnique<IBackOfficeSecurityFactory, BackOfficeSecurityFactory>();
|
||||
composition.Services.AddUnique<IBackOfficeSecurityAccessor, HybridBackofficeSecurityAccessor>();
|
||||
|
||||
composition.Services.AddUnique<IUmbracoWebsiteSecurityAccessor, HybridUmbracoWebsiteSecurityAccessor>();
|
||||
|
||||
//register the install components
|
||||
composition.ComposeInstaller();
|
||||
|
||||
|
||||
@@ -21,7 +21,13 @@ namespace Umbraco.Web.Website.Controllers
|
||||
// [MergeParentContextViewData]
|
||||
public abstract class SurfaceController : PluginController
|
||||
{
|
||||
private readonly IPublishedUrlProvider _publishedUrlProvider;
|
||||
protected SurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider)
|
||||
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger)
|
||||
{
|
||||
PublishedUrlProvider = publishedUrlProvider;
|
||||
}
|
||||
|
||||
protected IPublishedUrlProvider PublishedUrlProvider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current page.
|
||||
@@ -39,12 +45,6 @@ namespace Umbraco.Web.Website.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
protected SurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider)
|
||||
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger)
|
||||
{
|
||||
_publishedUrlProvider = publishedUrlProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirects to the Umbraco page with the given id
|
||||
/// </summary>
|
||||
@@ -52,7 +52,7 @@ namespace Umbraco.Web.Website.Controllers
|
||||
/// <returns></returns>
|
||||
protected RedirectToUmbracoPageResult RedirectToUmbracoPage(Guid contentKey)
|
||||
{
|
||||
return new RedirectToUmbracoPageResult(contentKey, _publishedUrlProvider, UmbracoContextAccessor);
|
||||
return new RedirectToUmbracoPageResult(contentKey, PublishedUrlProvider, UmbracoContextAccessor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -63,7 +63,7 @@ namespace Umbraco.Web.Website.Controllers
|
||||
/// <returns></returns>
|
||||
protected RedirectToUmbracoPageResult RedirectToUmbracoPage(Guid contentKey, QueryString queryString)
|
||||
{
|
||||
return new RedirectToUmbracoPageResult(contentKey, queryString, _publishedUrlProvider, UmbracoContextAccessor);
|
||||
return new RedirectToUmbracoPageResult(contentKey, queryString, PublishedUrlProvider, UmbracoContextAccessor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -73,7 +73,7 @@ namespace Umbraco.Web.Website.Controllers
|
||||
/// <returns></returns>
|
||||
protected RedirectToUmbracoPageResult RedirectToUmbracoPage(IPublishedContent publishedContent)
|
||||
{
|
||||
return new RedirectToUmbracoPageResult(publishedContent, _publishedUrlProvider, UmbracoContextAccessor);
|
||||
return new RedirectToUmbracoPageResult(publishedContent, PublishedUrlProvider, UmbracoContextAccessor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -84,7 +84,7 @@ namespace Umbraco.Web.Website.Controllers
|
||||
/// <returns></returns>
|
||||
protected RedirectToUmbracoPageResult RedirectToUmbracoPage(IPublishedContent publishedContent, QueryString queryString)
|
||||
{
|
||||
return new RedirectToUmbracoPageResult(publishedContent, queryString, _publishedUrlProvider, UmbracoContextAccessor);
|
||||
return new RedirectToUmbracoPageResult(publishedContent, queryString, PublishedUrlProvider, UmbracoContextAccessor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -93,7 +93,7 @@ namespace Umbraco.Web.Website.Controllers
|
||||
/// <returns></returns>
|
||||
protected RedirectToUmbracoPageResult RedirectToCurrentUmbracoPage()
|
||||
{
|
||||
return new RedirectToUmbracoPageResult(CurrentPage, _publishedUrlProvider, UmbracoContextAccessor);
|
||||
return new RedirectToUmbracoPageResult(CurrentPage, PublishedUrlProvider, UmbracoContextAccessor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -103,7 +103,7 @@ namespace Umbraco.Web.Website.Controllers
|
||||
/// <returns></returns>
|
||||
protected RedirectToUmbracoPageResult RedirectToCurrentUmbracoPage(QueryString queryString)
|
||||
{
|
||||
return new RedirectToUmbracoPageResult(CurrentPage, queryString, _publishedUrlProvider, UmbracoContextAccessor);
|
||||
return new RedirectToUmbracoPageResult(CurrentPage, queryString, PublishedUrlProvider, UmbracoContextAccessor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
60
src/Umbraco.Web.Website/Controllers/UmbLoginController.cs
Normal file
60
src/Umbraco.Web.Website/Controllers/UmbLoginController.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Security;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Common.Filters;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
namespace Umbraco.Web.Website.Controllers
|
||||
{
|
||||
public class UmbLoginController : SurfaceController
|
||||
{
|
||||
private readonly IUmbracoWebsiteSecurityAccessor _websiteSecurityAccessor;
|
||||
|
||||
public UmbLoginController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory,
|
||||
ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider,
|
||||
IUmbracoWebsiteSecurityAccessor websiteSecurityAccessor)
|
||||
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
|
||||
{
|
||||
_websiteSecurityAccessor = websiteSecurityAccessor;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
[ValidateUmbracoFormRouteString]
|
||||
public async Task<IActionResult> HandleLogin([Bind(Prefix = "loginModel")]LoginModel model)
|
||||
{
|
||||
if (ModelState.IsValid == false)
|
||||
{
|
||||
return CurrentUmbracoPage();
|
||||
}
|
||||
|
||||
if (await _websiteSecurityAccessor.WebsiteSecurity.LoginAsync(model.Username, model.Password) == false)
|
||||
{
|
||||
// Don't add a field level error, just model level.
|
||||
ModelState.AddModelError("loginModel", "Invalid username or password");
|
||||
return CurrentUmbracoPage();
|
||||
}
|
||||
|
||||
TempData["LoginSuccess"] = true;
|
||||
|
||||
// If there is a specified path to redirect to then use it.
|
||||
if (model.RedirectUrl.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
// Validate the redirect url.
|
||||
// If it's not a local url we'll redirect to the root of the current site.
|
||||
return Redirect(Url.IsLocalUrl(model.RedirectUrl)
|
||||
? model.RedirectUrl
|
||||
: CurrentPage.AncestorOrSelf(1).Url(PublishedUrlProvider));
|
||||
}
|
||||
|
||||
// Redirect to current page by default.
|
||||
return RedirectToCurrentUmbracoPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +1,54 @@
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Security;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Security;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Security;
|
||||
using Umbraco.Web.Common.Filters;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
namespace Umbraco.Web.Controllers
|
||||
namespace Umbraco.Web.Website.Controllers
|
||||
{
|
||||
[MemberAuthorize]
|
||||
[UmbracoMemberAuthorize]
|
||||
public class UmbLoginStatusController : SurfaceController
|
||||
{
|
||||
private readonly MembershipHelper _membershipHelper;
|
||||
|
||||
public UmbLoginStatusController()
|
||||
{
|
||||
}
|
||||
private readonly IUmbracoWebsiteSecurityAccessor _websiteSecurityAccessor;
|
||||
|
||||
public UmbLoginStatusController(IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches,
|
||||
IProfilingLogger profilingLogger, MembershipHelper membershipHelper)
|
||||
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger)
|
||||
IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider, IUmbracoWebsiteSecurityAccessor websiteSecurityAccessor)
|
||||
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
|
||||
{
|
||||
_membershipHelper = membershipHelper;
|
||||
_websiteSecurityAccessor = websiteSecurityAccessor;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
[ValidateUmbracoFormRouteString]
|
||||
public ActionResult HandleLogout([Bind(Prefix = "logoutModel")]PostRedirectModel model)
|
||||
public async Task<IActionResult> HandleLogout([Bind(Prefix = "logoutModel")]PostRedirectModel model)
|
||||
{
|
||||
if (ModelState.IsValid == false)
|
||||
{
|
||||
return CurrentUmbracoPage();
|
||||
}
|
||||
|
||||
if (_membershipHelper.IsLoggedIn())
|
||||
if (_websiteSecurityAccessor.WebsiteSecurity.IsLoggedIn())
|
||||
{
|
||||
FormsAuthentication.SignOut();
|
||||
await _websiteSecurityAccessor.WebsiteSecurity.LogOutAsync();
|
||||
}
|
||||
|
||||
TempData["LogoutSuccess"] = true;
|
||||
|
||||
//if there is a specified path to redirect to then use it
|
||||
// If there is a specified path to redirect to then use it.
|
||||
if (model.RedirectUrl.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
return Redirect(model.RedirectUrl);
|
||||
}
|
||||
|
||||
//redirect to current page by default
|
||||
|
||||
// Redirect to current page by default.
|
||||
return RedirectToCurrentUmbracoPage();
|
||||
}
|
||||
}
|
||||
64
src/Umbraco.Web.Website/Controllers/UmbProfileController.cs
Normal file
64
src/Umbraco.Web.Website/Controllers/UmbProfileController.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Security;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Common.Filters;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
namespace Umbraco.Web.Website.Controllers
|
||||
{
|
||||
[UmbracoMemberAuthorize]
|
||||
public class UmbProfileController : SurfaceController
|
||||
{
|
||||
private readonly IUmbracoWebsiteSecurityAccessor _websiteSecurityAccessor;
|
||||
|
||||
public UmbProfileController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory,
|
||||
ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger,
|
||||
IPublishedUrlProvider publishedUrlProvider, IUmbracoWebsiteSecurityAccessor websiteSecurityAccessor)
|
||||
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
|
||||
{
|
||||
_websiteSecurityAccessor = websiteSecurityAccessor;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
[ValidateUmbracoFormRouteString]
|
||||
public async Task<IActionResult> HandleUpdateProfile([Bind(Prefix = "profileModel")] ProfileModel model)
|
||||
{
|
||||
if (ModelState.IsValid == false)
|
||||
{
|
||||
return CurrentUmbracoPage();
|
||||
}
|
||||
|
||||
var result = await _websiteSecurityAccessor.WebsiteSecurity.UpdateMemberProfileAsync(model);
|
||||
switch (result.Status)
|
||||
{
|
||||
case UpdateMemberProfileStatus.Success:
|
||||
break;
|
||||
case UpdateMemberProfileStatus.Error:
|
||||
// Don't add a field level error, just model level.
|
||||
ModelState.AddModelError("profileModel", result.ErrorMessage);
|
||||
return CurrentUmbracoPage();
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
TempData["ProfileUpdateSuccess"] = true;
|
||||
|
||||
// If there is a specified path to redirect to then use it.
|
||||
if (model.RedirectUrl.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
return Redirect(model.RedirectUrl);
|
||||
}
|
||||
|
||||
// Redirect to current page by default.
|
||||
return RedirectToCurrentUmbracoPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,34 @@
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Security;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Security;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.Security;
|
||||
using Umbraco.Web.Common.Filters;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
namespace Umbraco.Web.Controllers
|
||||
namespace Umbraco.Web.Website.Controllers
|
||||
{
|
||||
public class UmbRegisterController : SurfaceController
|
||||
{
|
||||
private readonly MembershipHelper _membershipHelper;
|
||||
|
||||
public UmbRegisterController()
|
||||
{
|
||||
}
|
||||
private readonly IUmbracoWebsiteSecurityAccessor _websiteSecurityAccessor;
|
||||
|
||||
public UmbRegisterController(IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches,
|
||||
IProfilingLogger profilingLogger, MembershipHelper membershipHelper)
|
||||
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger)
|
||||
IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider, IUmbracoWebsiteSecurityAccessor websiteSecurityAccessor)
|
||||
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
|
||||
{
|
||||
_membershipHelper = membershipHelper;
|
||||
_websiteSecurityAccessor = websiteSecurityAccessor;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
[ValidateUmbracoFormRouteString]
|
||||
public ActionResult HandleRegisterMember([Bind(Prefix = "registerModel")]RegisterModel model)
|
||||
public async Task<IActionResult> HandleRegisterMember([Bind(Prefix = "registerModel")]RegisterModel model)
|
||||
{
|
||||
if (ModelState.IsValid == false)
|
||||
{
|
||||
@@ -39,60 +36,52 @@ namespace Umbraco.Web.Controllers
|
||||
}
|
||||
|
||||
// U4-10762 Server error with "Register Member" snippet (Cannot save member with empty name)
|
||||
// If name field is empty, add the email address instead
|
||||
// If name field is empty, add the email address instead.
|
||||
if (string.IsNullOrEmpty(model.Name) && string.IsNullOrEmpty(model.Email) == false)
|
||||
{
|
||||
model.Name = model.Email;
|
||||
}
|
||||
|
||||
MembershipCreateStatus status;
|
||||
var member = _membershipHelper.RegisterMember(model, out status, model.LoginOnSuccess);
|
||||
var result = await _websiteSecurityAccessor.WebsiteSecurity.RegisterMemberAsync(model, model.LoginOnSuccess);
|
||||
|
||||
switch (status)
|
||||
switch (result)
|
||||
{
|
||||
case MembershipCreateStatus.Success:
|
||||
case RegisterMemberStatus.Success:
|
||||
|
||||
TempData["FormSuccess"] = true;
|
||||
|
||||
//if there is a specified path to redirect to then use it
|
||||
// If there is a specified path to redirect to then use it.
|
||||
if (model.RedirectUrl.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
return Redirect(model.RedirectUrl);
|
||||
}
|
||||
//redirect to current page by default
|
||||
|
||||
// Redirect to current page by default.
|
||||
return RedirectToCurrentUmbracoPage();
|
||||
case MembershipCreateStatus.InvalidUserName:
|
||||
case RegisterMemberStatus.InvalidUserName:
|
||||
ModelState.AddModelError((model.UsernameIsEmail || model.Username == null)
|
||||
? "registerModel.Email"
|
||||
: "registerModel.Username",
|
||||
"Username is not valid");
|
||||
break;
|
||||
case MembershipCreateStatus.InvalidPassword:
|
||||
case RegisterMemberStatus.InvalidPassword:
|
||||
ModelState.AddModelError("registerModel.Password", "The password is not strong enough");
|
||||
break;
|
||||
case MembershipCreateStatus.InvalidQuestion:
|
||||
case MembershipCreateStatus.InvalidAnswer:
|
||||
// TODO: Support q/a http://issues.umbraco.org/issue/U4-3213
|
||||
throw new NotImplementedException(status.ToString());
|
||||
case MembershipCreateStatus.InvalidEmail:
|
||||
case RegisterMemberStatus.InvalidEmail:
|
||||
ModelState.AddModelError("registerModel.Email", "Email is invalid");
|
||||
break;
|
||||
case MembershipCreateStatus.DuplicateUserName:
|
||||
case RegisterMemberStatus.DuplicateUserName:
|
||||
ModelState.AddModelError((model.UsernameIsEmail || model.Username == null)
|
||||
? "registerModel.Email"
|
||||
: "registerModel.Username",
|
||||
"A member with this username already exists.");
|
||||
break;
|
||||
case MembershipCreateStatus.DuplicateEmail:
|
||||
case RegisterMemberStatus.DuplicateEmail:
|
||||
ModelState.AddModelError("registerModel.Email", "A member with this e-mail address already exists");
|
||||
break;
|
||||
case MembershipCreateStatus.UserRejected:
|
||||
case MembershipCreateStatus.InvalidProviderUserKey:
|
||||
case MembershipCreateStatus.DuplicateProviderUserKey:
|
||||
case MembershipCreateStatus.ProviderError:
|
||||
//don't add a field level error, just model level
|
||||
ModelState.AddModelError("registerModel", "An error occurred creating the member: " + status);
|
||||
case RegisterMemberStatus.Error:
|
||||
// Don't add a field level error, just model level.
|
||||
ModelState.AddModelError("registerModel", $"An error occurred creating the member: {result}");
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
@@ -100,6 +89,5 @@ namespace Umbraco.Web.Controllers
|
||||
|
||||
return CurrentUmbracoPage();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using Umbraco.Web.Website.ViewEngines;
|
||||
|
||||
namespace Umbraco.Extensions
|
||||
{
|
||||
public static class UmbracoWebstiteServiceCollectionExtensions
|
||||
public static class UmbracoWebsiteServiceCollectionExtensions
|
||||
{
|
||||
public static void AddUmbracoWebsite(this IServiceCollection services)
|
||||
{
|
||||
57
src/Umbraco.Web.Website/Security/UmbracoWebsiteSecurity.cs
Normal file
57
src/Umbraco.Web.Website/Security/UmbracoWebsiteSecurity.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Umbraco.Core.Models.Security;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Web.Website.Security
|
||||
{
|
||||
public class UmbracoWebsiteSecurity : IUmbracoWebsiteSecurity
|
||||
{
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public UmbracoWebsiteSecurity(IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<RegisterMemberStatus> RegisterMemberAsync(RegisterModel model, bool logMemberIn = true)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<UpdateMemberProfileResult> UpdateMemberProfileAsync(ProfileModel model)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsLoggedIn()
|
||||
{
|
||||
var httpContext = _httpContextAccessor.HttpContext;
|
||||
return httpContext?.User != null && httpContext.User.Identity.IsAuthenticated;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<bool> LoginAsync(string username, string password)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task LogOutAsync()
|
||||
{
|
||||
await _httpContextAccessor.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsMemberAuthorized(IEnumerable<string> allowTypes = null, IEnumerable<string> allowGroups = null, IEnumerable<int> allowMembers = null)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Web.Controllers
|
||||
{
|
||||
public class UmbLoginController : SurfaceController
|
||||
{
|
||||
private readonly MembershipHelper _membershipHelper;
|
||||
|
||||
public UmbLoginController()
|
||||
{
|
||||
}
|
||||
|
||||
public UmbLoginController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory,
|
||||
ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger,
|
||||
MembershipHelper membershipHelper)
|
||||
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger)
|
||||
{
|
||||
_membershipHelper = membershipHelper;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
[ValidateUmbracoFormRouteString]
|
||||
public ActionResult HandleLogin([Bind(Prefix = "loginModel")]LoginModel model)
|
||||
{
|
||||
if (ModelState.IsValid == false)
|
||||
{
|
||||
return CurrentUmbracoPage();
|
||||
}
|
||||
|
||||
if (_membershipHelper.Login(model.Username, model.Password) == false)
|
||||
{
|
||||
//don't add a field level error, just model level
|
||||
ModelState.AddModelError("loginModel", "Invalid username or password");
|
||||
return CurrentUmbracoPage();
|
||||
}
|
||||
|
||||
TempData["LoginSuccess"] = true;
|
||||
|
||||
//if there is a specified path to redirect to then use it
|
||||
if (model.RedirectUrl.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
// validate the redirect url
|
||||
// if it's not a local url we'll redirect to the root of the current site
|
||||
return Redirect(Url.IsLocalUrl(model.RedirectUrl)
|
||||
? model.RedirectUrl
|
||||
: CurrentPage.AncestorOrSelf(1).Url());
|
||||
}
|
||||
|
||||
//redirect to current page by default
|
||||
|
||||
return RedirectToCurrentUmbracoPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Web.Controllers
|
||||
{
|
||||
[MemberAuthorize]
|
||||
public class UmbProfileController : SurfaceController
|
||||
{
|
||||
private readonly MembershipHelper _membershipHelper;
|
||||
|
||||
public UmbProfileController()
|
||||
{ }
|
||||
|
||||
public UmbProfileController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory,
|
||||
ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger,
|
||||
MembershipHelper membershipHelper)
|
||||
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger)
|
||||
{
|
||||
_membershipHelper = membershipHelper;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
[ValidateUmbracoFormRouteString]
|
||||
public ActionResult HandleUpdateProfile([Bind(Prefix = "profileModel")] ProfileModel model)
|
||||
{
|
||||
if (ModelState.IsValid == false)
|
||||
{
|
||||
return CurrentUmbracoPage();
|
||||
}
|
||||
|
||||
var updateAttempt = _membershipHelper.UpdateMemberProfile(model);
|
||||
if (updateAttempt.Success == false)
|
||||
{
|
||||
//don't add a field level error, just model level
|
||||
ModelState.AddModelError("profileModel", updateAttempt.Exception.Message);
|
||||
return CurrentUmbracoPage();
|
||||
}
|
||||
|
||||
TempData["ProfileUpdateSuccess"] = true;
|
||||
|
||||
//if there is a specified path to redirect to then use it
|
||||
if (model.RedirectUrl.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
return Redirect(model.RedirectUrl);
|
||||
}
|
||||
|
||||
//redirect to current page by default
|
||||
return RedirectToCurrentUmbracoPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Web.Security;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Models.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Security.Providers;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Umbraco.Web.Security
|
||||
{
|
||||
@@ -443,7 +443,7 @@ namespace Umbraco.Web.Security
|
||||
return null;
|
||||
}
|
||||
|
||||
var model = ProfileModel.CreateModel();
|
||||
var model = new ProfileModel();
|
||||
model.Name = member.Name;
|
||||
model.MemberTypeAlias = member.ContentTypeAlias;
|
||||
|
||||
@@ -458,7 +458,6 @@ namespace Umbraco.Web.Security
|
||||
model.LastActivityDate = membershipUser.LastActivityDate;
|
||||
model.LastPasswordChangedDate = membershipUser.LastPasswordChangedDate;
|
||||
|
||||
|
||||
var memberType = _memberTypeService.Get(member.ContentTypeId);
|
||||
|
||||
var builtIns = ConventionsHelper.GetStandardPropertyTypeStubs(_shortStringHelper).Select(x => x.Key).ToArray();
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
<Compile Include="Macros\MemberUserKeyProvider.cs" />
|
||||
<Compile Include="Mvc\IRenderController.cs" />
|
||||
<Compile Include="Mvc\IRenderMvcController.cs" />
|
||||
<Compile Include="Mvc\MemberAuthorizeAttribute.cs" />
|
||||
<Compile Include="Mvc\RenderMvcController.cs" />
|
||||
<Compile Include="Mvc\UmbracoViewPageOfTModel.cs" />
|
||||
<Compile Include="Security\IdentityFactoryMiddleware.cs" />
|
||||
@@ -220,8 +221,6 @@
|
||||
<Compile Include="WebAssets\CDF\UmbracoClientDependencyLoader.cs" />
|
||||
<Compile Include="UmbracoDefaultOwinStartup.cs" />
|
||||
<Compile Include="Mvc\ProfilingView.cs" />
|
||||
<Compile Include="Controllers\UmbProfileController.cs" />
|
||||
<Compile Include="Controllers\UmbLoginStatusController.cs" />
|
||||
<Compile Include="GridTemplateExtensions.cs" />
|
||||
<Compile Include="Mvc\NotFoundHandler.cs" />
|
||||
<Compile Include="Mvc\RedirectToUmbracoUrlResult.cs" />
|
||||
@@ -236,13 +235,10 @@
|
||||
<Compile Include="WebApi\AngularJsonOnlyConfigurationAttribute.cs" />
|
||||
<Compile Include="WebApi\Filters\AngularAntiForgeryHelper.cs" />
|
||||
<Compile Include="WebApi\Filters\ValidateAngularAntiForgeryTokenAttribute.cs" />
|
||||
<Compile Include="Controllers\UmbRegisterController.cs" />
|
||||
<Compile Include="Models\ProfileModel.cs" />
|
||||
<Compile Include="Models\LoginStatusModel.cs" />
|
||||
<Compile Include="PublishedPropertyExtension.cs" />
|
||||
<Compile Include="Mvc\MergeParentContextViewDataAttribute.cs" />
|
||||
<Compile Include="Mvc\ViewDataDictionaryExtensions.cs" />
|
||||
<Compile Include="Models\RegisterModel.cs" />
|
||||
<Compile Include="Security\MembershipHelper.cs" />
|
||||
<Compile Include="HttpCookieExtensions.cs" />
|
||||
<Compile Include="Security\Providers\MembersMembershipProvider.cs" />
|
||||
@@ -253,10 +249,8 @@
|
||||
<Compile Include="Macros\PartialViewMacroPage.cs" />
|
||||
<Compile Include="Mvc\AreaRegistrationExtensions.cs" />
|
||||
<Compile Include="Mvc\QueryStringFilterAttribute.cs" />
|
||||
<Compile Include="Mvc\MemberAuthorizeAttribute.cs" />
|
||||
<Compile Include="Mvc\ControllerFactoryExtensions.cs" />
|
||||
<Compile Include="Mvc\SurfaceRouteHandler.cs" />
|
||||
<Compile Include="Controllers\UmbLoginController.cs" />
|
||||
<Compile Include="UrlHelperExtensions.cs" />
|
||||
<Compile Include="UrlHelperRenderExtensions.cs" />
|
||||
<Compile Include="WebApi\IsBackOfficeAttribute.cs" />
|
||||
|
||||
205
src/umbraco-netcore-only.sln
Normal file
205
src/umbraco-netcore-only.sln
Normal file
@@ -0,0 +1,205 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29209.152
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{2849E9D4-3B4E-40A3-A309-F3CB4F0E125F}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\build\build-bootstrap.ps1 = ..\build\build-bootstrap.ps1
|
||||
..\build\build.ps1 = ..\build\build.ps1
|
||||
..\NuGet.Config = ..\NuGet.Config
|
||||
SolutionInfo.cs = SolutionInfo.cs
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{FD962632-184C-4005-A5F3-E705D92FC645}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\.github\BUILD.md = ..\.github\BUILD.md
|
||||
..\.github\CLEAR.md = ..\.github\CLEAR.md
|
||||
..\.github\CODE_OF_CONDUCT.md = ..\.github\CODE_OF_CONDUCT.md
|
||||
..\.github\CONTRIBUTING.md = ..\.github\CONTRIBUTING.md
|
||||
..\.github\CONTRIBUTING_DETAILED.md = ..\.github\CONTRIBUTING_DETAILED.md
|
||||
..\.github\CONTRIBUTION_GUIDELINES.md = ..\.github\CONTRIBUTION_GUIDELINES.md
|
||||
..\.github\PULL_REQUEST_TEMPLATE.md = ..\.github\PULL_REQUEST_TEMPLATE.md
|
||||
..\.github\README.md = ..\.github\README.md
|
||||
..\.github\REVIEW_PROCESS.md = ..\.github\REVIEW_PROCESS.md
|
||||
..\.github\V8_GETTING_STARTED.md = ..\.github\V8_GETTING_STARTED.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B5BD12C1-A454-435E-8A46-FF4A364C0382}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuSpecs", "NuSpecs", "{227C3B55-80E5-4E7E-A802-BE16C5128B9D}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\build\NuSpecs\UmbracoCms.Core.nuspec = ..\build\NuSpecs\UmbracoCms.Core.nuspec
|
||||
..\build\NuSpecs\UmbracoCms.nuspec = ..\build\NuSpecs\UmbracoCms.nuspec
|
||||
..\build\NuSpecs\UmbracoCms.SqlCe.nuspec = ..\build\NuSpecs\UmbracoCms.SqlCe.nuspec
|
||||
..\build\NuSpecs\UmbracoCms.Web.nuspec = ..\build\NuSpecs\UmbracoCms.Web.nuspec
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Web.UI.Client", "http://localhost:3961", "{3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}"
|
||||
ProjectSection(WebsiteProperties) = preProject
|
||||
UseIISExpress = "true"
|
||||
TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.5"
|
||||
Debug.AspNetCompiler.VirtualPath = "/localhost_3961"
|
||||
Debug.AspNetCompiler.PhysicalPath = "Umbraco.Web.UI.Client\"
|
||||
Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_3961\"
|
||||
Debug.AspNetCompiler.Updateable = "true"
|
||||
Debug.AspNetCompiler.ForceOverwrite = "true"
|
||||
Debug.AspNetCompiler.FixedNames = "false"
|
||||
Debug.AspNetCompiler.Debug = "True"
|
||||
Release.AspNetCompiler.VirtualPath = "/localhost_3961"
|
||||
Release.AspNetCompiler.PhysicalPath = "Umbraco.Web.UI.Client\"
|
||||
Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_3961\"
|
||||
Release.AspNetCompiler.Updateable = "true"
|
||||
Release.AspNetCompiler.ForceOverwrite = "true"
|
||||
Release.AspNetCompiler.FixedNames = "false"
|
||||
Release.AspNetCompiler.Debug = "False"
|
||||
SlnRelativePath = "Umbraco.Web.UI.Client\"
|
||||
DefaultWebSiteLanguage = "Visual C#"
|
||||
StartServerOnDebug = "false"
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Tests.AcceptanceTest", "http://localhost:58896", "{9E4C8A12-FBE0-4673-8CE2-DF99D5D57817}"
|
||||
ProjectSection(WebsiteProperties) = preProject
|
||||
UseIISExpress = "true"
|
||||
TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.5"
|
||||
Debug.AspNetCompiler.VirtualPath = "/localhost_62926"
|
||||
Debug.AspNetCompiler.PhysicalPath = "Umbraco.Tests.AcceptanceTest\"
|
||||
Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_62926\"
|
||||
Debug.AspNetCompiler.Updateable = "true"
|
||||
Debug.AspNetCompiler.ForceOverwrite = "true"
|
||||
Debug.AspNetCompiler.FixedNames = "false"
|
||||
Debug.AspNetCompiler.Debug = "True"
|
||||
Release.AspNetCompiler.VirtualPath = "/localhost_62926"
|
||||
Release.AspNetCompiler.PhysicalPath = "Umbraco.Tests.AcceptanceTest\"
|
||||
Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_62926\"
|
||||
Release.AspNetCompiler.Updateable = "true"
|
||||
Release.AspNetCompiler.ForceOverwrite = "true"
|
||||
Release.AspNetCompiler.FixedNames = "false"
|
||||
Release.AspNetCompiler.Debug = "False"
|
||||
SlnRelativePath = "Umbraco.Tests.AcceptanceTest\"
|
||||
DefaultWebSiteLanguage = "Visual C#"
|
||||
StartServerOnDebug = "false"
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{E3F9F378-AFE1-40A5-90BD-82833375DBFE}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\build\NuSpecs\tools\applications.config.install.xdt = ..\build\NuSpecs\tools\applications.config.install.xdt
|
||||
..\build\NuSpecs\tools\ClientDependency.config.install.xdt = ..\build\NuSpecs\tools\ClientDependency.config.install.xdt
|
||||
..\build\NuSpecs\tools\install.ps1 = ..\build\NuSpecs\tools\install.ps1
|
||||
..\build\NuSpecs\tools\Readme.txt = ..\build\NuSpecs\tools\Readme.txt
|
||||
..\build\NuSpecs\tools\ReadmeUpgrade.txt = ..\build\NuSpecs\tools\ReadmeUpgrade.txt
|
||||
..\build\NuSpecs\tools\serilog.config.install.xdt = ..\build\NuSpecs\tools\serilog.config.install.xdt
|
||||
..\build\NuSpecs\tools\Web.config.install.xdt = ..\build\NuSpecs\tools\Web.config.install.xdt
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{5B03EF4E-E0AC-4905-861B-8C3EC1A0D458}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\build\NuSpecs\build\Umbraco.Cms.props = ..\build\NuSpecs\build\Umbraco.Cms.props
|
||||
..\build\NuSpecs\build\Umbraco.Cms.targets = ..\build\NuSpecs\build\Umbraco.Cms.targets
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DocTools", "DocTools", "{53594E5B-64A2-4545-8367-E3627D266AE8}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
ApiDocs\docfx.filter.yml = ApiDocs\docfx.filter.yml
|
||||
ApiDocs\docfx.json = ApiDocs\docfx.json
|
||||
ApiDocs\index.md = ApiDocs\index.md
|
||||
ApiDocs\toc.yml = ApiDocs\toc.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IssueTemplates", "IssueTemplates", "{C7311C00-2184-409B-B506-52A5FAEA8736}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\.github\ISSUE_TEMPLATE\1_Bug.md = ..\.github\ISSUE_TEMPLATE\1_Bug.md
|
||||
..\.github\ISSUE_TEMPLATE\2_Feature_request.md = ..\.github\ISSUE_TEMPLATE\2_Feature_request.md
|
||||
..\.github\ISSUE_TEMPLATE\3_Support_question.md = ..\.github\ISSUE_TEMPLATE\3_Support_question.md
|
||||
..\.github\ISSUE_TEMPLATE\4_Documentation_issue.md = ..\.github\ISSUE_TEMPLATE\4_Documentation_issue.md
|
||||
..\.github\ISSUE_TEMPLATE\5_Security_issue.md = ..\.github\ISSUE_TEMPLATE\5_Security_issue.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Core", "Umbraco.Core\Umbraco.Core.csproj", "{29AA69D9-B597-4395-8D42-43B1263C240A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.ModelsBuilder.Embedded", "Umbraco.ModelsBuilder.Embedded\Umbraco.ModelsBuilder.Embedded.csproj", "{52AC0BA8-A60E-4E36-897B-E8B97A54ED1C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Infrastructure", "Umbraco.Infrastructure\Umbraco.Infrastructure.csproj", "{3AE7BF57-966B-45A5-910A-954D7C554441}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.PublishedCache.NuCache", "Umbraco.PublishedCache.NuCache\Umbraco.PublishedCache.NuCache.csproj", "{F6DE8DA0-07CC-4EF2-8A59-2BC81DBB3830}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.BackOffice", "Umbraco.Web.BackOffice\Umbraco.Web.BackOffice.csproj", "{9B95EEF7-63FE-4432-8C63-166BE9C1A929}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.UI.NetCore", "Umbraco.Web.UI.NetCore\Umbraco.Web.UI.NetCore.csproj", "{DCDFE97C-5630-4F6F-855D-8AEEB96556A5}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Website", "Umbraco.Web.Website\Umbraco.Web.Website.csproj", "{5A246D54-3109-4D2B-BE7D-FC0787D126AE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Common", "Umbraco.Tests.Common\Umbraco.Tests.Common.csproj", "{A499779C-1B3B-48A8-B551-458E582E6E96}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.UnitTests", "Umbraco.Tests.UnitTests\Umbraco.Tests.UnitTests.csproj", "{9102ABDF-E537-4E46-B525-C9ED4833EED0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Common", "Umbraco.Web.Common\Umbraco.Web.Common.csproj", "{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9E4C8A12-FBE0-4673-8CE2-DF99D5D57817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9E4C8A12-FBE0-4673-8CE2-DF99D5D57817}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{29AA69D9-B597-4395-8D42-43B1263C240A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{29AA69D9-B597-4395-8D42-43B1263C240A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{29AA69D9-B597-4395-8D42-43B1263C240A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{29AA69D9-B597-4395-8D42-43B1263C240A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{52AC0BA8-A60E-4E36-897B-E8B97A54ED1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{52AC0BA8-A60E-4E36-897B-E8B97A54ED1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{52AC0BA8-A60E-4E36-897B-E8B97A54ED1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{52AC0BA8-A60E-4E36-897B-E8B97A54ED1C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3AE7BF57-966B-45A5-910A-954D7C554441}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3AE7BF57-966B-45A5-910A-954D7C554441}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3AE7BF57-966B-45A5-910A-954D7C554441}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3AE7BF57-966B-45A5-910A-954D7C554441}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F6DE8DA0-07CC-4EF2-8A59-2BC81DBB3830}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F6DE8DA0-07CC-4EF2-8A59-2BC81DBB3830}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F6DE8DA0-07CC-4EF2-8A59-2BC81DBB3830}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F6DE8DA0-07CC-4EF2-8A59-2BC81DBB3830}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9B95EEF7-63FE-4432-8C63-166BE9C1A929}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9B95EEF7-63FE-4432-8C63-166BE9C1A929}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9B95EEF7-63FE-4432-8C63-166BE9C1A929}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9B95EEF7-63FE-4432-8C63-166BE9C1A929}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A499779C-1B3B-48A8-B551-458E582E6E96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A499779C-1B3B-48A8-B551-458E582E6E96}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A499779C-1B3B-48A8-B551-458E582E6E96}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A499779C-1B3B-48A8-B551-458E582E6E96}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9102ABDF-E537-4E46-B525-C9ED4833EED0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9102ABDF-E537-4E46-B525-C9ED4833EED0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9102ABDF-E537-4E46-B525-C9ED4833EED0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9102ABDF-E537-4E46-B525-C9ED4833EED0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{227C3B55-80E5-4E7E-A802-BE16C5128B9D} = {2849E9D4-3B4E-40A3-A309-F3CB4F0E125F}
|
||||
{9E4C8A12-FBE0-4673-8CE2-DF99D5D57817} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
|
||||
{E3F9F378-AFE1-40A5-90BD-82833375DBFE} = {227C3B55-80E5-4E7E-A802-BE16C5128B9D}
|
||||
{5B03EF4E-E0AC-4905-861B-8C3EC1A0D458} = {227C3B55-80E5-4E7E-A802-BE16C5128B9D}
|
||||
{53594E5B-64A2-4545-8367-E3627D266AE8} = {FD962632-184C-4005-A5F3-E705D92FC645}
|
||||
{C7311C00-2184-409B-B506-52A5FAEA8736} = {FD962632-184C-4005-A5F3-E705D92FC645}
|
||||
{A499779C-1B3B-48A8-B551-458E582E6E96} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
|
||||
{9102ABDF-E537-4E46-B525-C9ED4833EED0} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {7A0F2E34-D2AF-4DAB-86A0-7D7764B3D0EC}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Reference in New Issue
Block a user