Port 7.7 - WIP
This commit is contained in:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user