Port 7.7 - WIP

This commit is contained in:
Stephan
2017-09-12 16:22:16 +02:00
parent 1c96df83cd
commit 96c08f24ee
176 changed files with 5490 additions and 4892 deletions

View File

@@ -65,7 +65,7 @@ namespace Umbraco.Web.Security
{
get
{
//only load it once per instance!
//only load it once per instance! (but make sure groups are loaded)
if (_currentUser == null)
{
var id = GetUserId();
@@ -167,116 +167,24 @@ namespace Umbraco.Web.Security
/// <param name="username"></param>
/// <param name="password"></param>
/// <returns></returns>
/// <remarks>
/// This uses ASP.NET Identity to perform the validation
/// </remarks>
public virtual bool ValidateBackOfficeCredentials(string username, string password)
{
var membershipProvider = Core.Security.MembershipProviderExtensions.GetUsersMembershipProvider();
return membershipProvider != null && membershipProvider.ValidateUser(username, password);
//find the user by username
var user = UserManager.FindByNameAsync(username).Result;
return user != null && UserManager.CheckPasswordAsync(user, password).Result;
}
/// <summary>
/// Returns the MembershipUser from the back office membership provider
/// </summary>
/// <param name="username"></param>
/// <param name="setOnline"></param>
/// <returns></returns>
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Back office users shouldn't be resolved from the membership provider, they should be resolved usign the BackOfficeUserManager or the IUserService")]
public virtual MembershipUser GetBackOfficeMembershipUser(string username, bool setOnline)
{
var membershipProvider = Core.Security.MembershipProviderExtensions.GetUsersMembershipProvider();
return membershipProvider != null ? membershipProvider.GetUser(username, setOnline) : null;
}
/// <summary>
/// Gets (and creates if not found) the back office <see cref="IUser"/> instance for the username specified
/// </summary>
/// <param name="username"></param>
/// <returns></returns>
/// <remarks>
/// This will return an <see cref="IUser"/> instance no matter what membership provider is installed for the back office, it will automatically
/// create any missing <see cref="IUser"/> accounts if one is not found and a custom membership provider or <see cref="IBackOfficeUserPasswordChecker"/> is being used.
/// </remarks>
internal IUser GetBackOfficeUser(string username)
{
//get the membership user (set user to be 'online' in the provider too)
var membershipUser = GetBackOfficeMembershipUser(username, true);
var provider = Core.Security.MembershipProviderExtensions.GetUsersMembershipProvider();
if (membershipUser == null)
{
throw new InvalidOperationException(
"The username & password validated but the membership provider '" +
provider.Name +
"' did not return a MembershipUser with the username supplied");
}
//regarldess of the membership provider used, see if this user object already exists in the umbraco data
var user = _userService.GetByUsername(membershipUser.UserName);
//we're using the built-in membership provider so the user will already be available
if (provider.IsUmbracoUsersProvider())
{
if (user == null)
{
//this should never happen
throw new InvalidOperationException("The user '" + username + "' could not be found in the Umbraco database");
}
return user;
}
//we are using a custom membership provider for the back office, in this case we need to create user accounts for the logged in member.
//if we already have a user object in Umbraco we don't need to do anything, otherwise we need to create a mapped Umbraco account.
if (user != null) return user;
//we need to create an Umbraco IUser of a 'writer' type with access to only content - this was how v6 operates.
var writer = _userService.GetUserTypeByAlias("writer");
var email = membershipUser.Email;
if (email.IsNullOrWhiteSpace())
{
//in some cases if there is no email we have to generate one since it is required!
email = Guid.NewGuid().ToString("N") + "@example.com";
}
user = new Core.Models.Membership.User(writer)
{
Email = email,
Language = GlobalSettings.DefaultUILanguage,
Name = membershipUser.UserName,
RawPasswordValue = Guid.NewGuid().ToString("N"), //Need to set this to something - will not be used though
Username = membershipUser.UserName,
StartContentId = -1,
StartMediaId = -1,
IsLockedOut = false,
IsApproved = true
};
user.AddAllowedSection("content");
_userService.Save(user);
return user;
}
/// <summary>
/// Validates the user node tree permissions.
/// </summary>
/// <param name="umbracoUser"></param>
/// <param name="path">The path.</param>
/// <param name="action">The action.</param>
/// <returns></returns>
internal bool ValidateUserNodeTreePermissions(IUser umbracoUser, string path, string action)
{
//we only want permissions for the last node in the pat
var permission = _userService.GetPermissions(umbracoUser, path);
if (permission == null) throw new InvalidOperationException("No permissions found");
if (permission.AssignedPermissions.Contains(action, StringComparer.Ordinal) && (path.Contains("-20") || ("," + path + ",").Contains("," + umbracoUser.StartContentId + ",")))
return true;
var user = umbracoUser;
Current.Logger.Info<WebSecurity>("User {0} has insufficient permissions in UmbracoEnsuredPage: '{1}', '{2}', '{3}'", () => user.Name, () => path, () => string.Join(",", permission.AssignedPermissions), () => action);
return false;
}
/// <summary>
/// Validates the current user to see if they have access to the specified app
/// </summary>
@@ -344,16 +252,16 @@ namespace Umbraco.Web.Security
/// <returns></returns>
public virtual bool ValidateCurrentUser()
{
var result = ValidateCurrentUser(false);
return result == ValidateRequestAttempt.Success;
}
return ValidateCurrentUser(false, true) == ValidateRequestAttempt.Success;
}
/// <summary>
/// Validates the current user assigned to the request and ensures the stored user data is valid
/// </summary>
/// <param name="throwExceptions">set to true if you want exceptions to be thrown if failed</param>
/// <param name="requiresApproval">If true requires that the user is approved to be validated</param>
/// <returns></returns>
internal ValidateRequestAttempt ValidateCurrentUser(bool throwExceptions)
public virtual ValidateRequestAttempt ValidateCurrentUser(bool throwExceptions, bool requiresApproval = true)
{
//This will first check if the current user is already authenticated - which should be the case in nearly all circumstances
// since the authentication happens in the Module, that authentication also checks the ticket expiry. We don't
@@ -369,7 +277,7 @@ namespace Umbraco.Web.Security
var user = CurrentUser;
// Check for console access
if (user == null || user.IsApproved == false || (user.IsLockedOut && GlobalSettings.RequestIsInUmbracoApplication(_httpContext)))
if (user == null || (requiresApproval && user.IsApproved == false) || (user.IsLockedOut && GlobalSettings.RequestIsInUmbracoApplication(_httpContext)))
{
if (throwExceptions) throw new ArgumentException("You have no priviledges to the umbraco console. Please contact your administrator");
return ValidateRequestAttempt.FailedNoPrivileges;
@@ -400,7 +308,7 @@ namespace Umbraco.Web.Security
/// <param name="app"></param>
/// <param name="user"></param>
/// <returns></returns>
internal bool UserHasAppAccess(string app, IUser user)
internal virtual bool UserHasAppAccess(string app, IUser user)
{
var apps = user.AllowedSections;
return apps.Any(uApp => uApp.InvariantEquals(app));