Puts back in some old APIs that were removed to maintain some backwards compat with < 7.7 for users
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
@@ -16,7 +17,11 @@ namespace Umbraco.Core.Models.Membership
|
||||
int SessionTimeout { get; set; }
|
||||
int[] StartContentIds { get; set; }
|
||||
int[] StartMediaIds { get; set; }
|
||||
string Language { get; set; }
|
||||
string Language { get; set; }
|
||||
|
||||
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
IUserType UserType { get; set; }
|
||||
|
||||
DateTime? EmailConfirmedDate { get; set; }
|
||||
DateTime? InvitedDate { get; set; }
|
||||
@@ -32,6 +37,14 @@ namespace Umbraco.Core.Models.Membership
|
||||
|
||||
IEnumerable<string> AllowedSections { get; }
|
||||
|
||||
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void RemoveAllowedSection(string sectionAlias);
|
||||
|
||||
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void AddAllowedSection(string sectionAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the basic profile data
|
||||
/// </summary>
|
||||
|
||||
17
src/Umbraco.Core/Models/Membership/IUserType.cs
Normal file
17
src/Umbraco.Core/Models/Membership/IUserType.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public interface IUserType : IAggregateRoot
|
||||
{
|
||||
string Alias { get; set; }
|
||||
string Name { get; set; }
|
||||
IEnumerable<string> Permissions { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
@@ -162,7 +164,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
get { return Id; }
|
||||
set { throw new NotSupportedException("Cannot set the provider user key for a user"); }
|
||||
}
|
||||
|
||||
|
||||
[DataMember]
|
||||
public DateTime? EmailConfirmedDate
|
||||
{
|
||||
@@ -278,6 +280,165 @@ namespace Umbraco.Core.Models.Membership
|
||||
get { return _allowedSections ?? (_allowedSections = new List<string>(_userGroups.SelectMany(x => x.AllowedSections).Distinct())); }
|
||||
}
|
||||
|
||||
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
IUserType IUser.UserType
|
||||
{
|
||||
get
|
||||
{
|
||||
//the best we can do here is to return the user's first user group as a IUserType object
|
||||
//but we should attempt to return any group that is the built in ones first
|
||||
var groups = Groups.ToArray();
|
||||
if (groups.Length == 0)
|
||||
{
|
||||
//In backwards compatibility land, a user type cannot be null! so we need to return a fake one.
|
||||
return new UserType
|
||||
{
|
||||
Alias = "temp",
|
||||
Id = int.MinValue,
|
||||
Key = Guid.Empty,
|
||||
CreateDate = default(DateTime),
|
||||
DeletedDate = null,
|
||||
Name = "Temp",
|
||||
Permissions = new List<string>(),
|
||||
UpdateDate = default(DateTime)
|
||||
};
|
||||
}
|
||||
var builtIns = new[] { Constants.Security.AdminGroupAlias, "writer", "editor", "translator" };
|
||||
var foundBuiltIn = groups.FirstOrDefault(x => builtIns.Contains(x.Alias));
|
||||
IUserGroup realGroup;
|
||||
if (foundBuiltIn != null)
|
||||
{
|
||||
//if the group isn't IUserGroup we'll need to look it up
|
||||
realGroup = foundBuiltIn as IUserGroup ?? ApplicationContext.Current.Services.UserService.GetUserGroupById(foundBuiltIn.Id);
|
||||
|
||||
//return a mapped version of the group
|
||||
return new UserType
|
||||
{
|
||||
Alias = realGroup.Alias,
|
||||
Id = realGroup.Id,
|
||||
Key = realGroup.Key,
|
||||
CreateDate = realGroup.CreateDate,
|
||||
DeletedDate = realGroup.DeletedDate,
|
||||
Name = realGroup.Name,
|
||||
Permissions = realGroup.Permissions,
|
||||
UpdateDate = realGroup.UpdateDate
|
||||
};
|
||||
}
|
||||
|
||||
//otherwise return the first
|
||||
//if the group isn't IUserGroup we'll need to look it up
|
||||
realGroup = groups[0] as IUserGroup ?? ApplicationContext.Current.Services.UserService.GetUserGroupById(groups[0].Id);
|
||||
//return a mapped version of the group
|
||||
return new UserType
|
||||
{
|
||||
Alias = realGroup.Alias,
|
||||
Id = realGroup.Id,
|
||||
Key = realGroup.Key,
|
||||
CreateDate = realGroup.CreateDate,
|
||||
DeletedDate = realGroup.DeletedDate,
|
||||
Name = realGroup.Name,
|
||||
Permissions = realGroup.Permissions,
|
||||
UpdateDate = realGroup.UpdateDate
|
||||
};
|
||||
}
|
||||
set
|
||||
{
|
||||
//if old APIs are still using this lets first check if the user is part of the user group with the alias specified
|
||||
if (Groups.Any(x => x.Alias == value.Alias))
|
||||
return;
|
||||
|
||||
//the only other option we have here is to lookup the group (and we'll need to use singletons here :( )
|
||||
var found = ApplicationContext.Current.Services.UserService.GetUserGroupByAlias(value.Alias);
|
||||
if (found == null)
|
||||
throw new InvalidOperationException("No user group was found with the alias " + value.Alias + ", this API (IUser.UserType) is obsolete, use user groups instead");
|
||||
|
||||
//if it's found, all we can do is add it, we can't really replace them
|
||||
AddGroup(found.ToReadOnlyGroup());
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IUser.RemoveAllowedSection(string sectionAlias)
|
||||
{
|
||||
//don't do anything if they aren't allowed it already
|
||||
if (AllowedSections.Contains(sectionAlias) == false)
|
||||
return;
|
||||
|
||||
var groups = Groups.ToArray();
|
||||
//our only option here is to check if a custom group is created for this user, if so we can remove it from that group, otherwise we'll throw
|
||||
//now we'll check if the user has a special 1:1 user group created for itself. This will occur if this method is used and also during an upgrade.
|
||||
//this comes in the alias form of userName + 'Group'
|
||||
var customUserGroup = groups.FirstOrDefault(x => x.Alias == (Username + "Group"));
|
||||
if (customUserGroup != null)
|
||||
{
|
||||
//if the group isn't IUserGroup we'll need to look it up
|
||||
var realGroup = customUserGroup as IUserGroup ?? ApplicationContext.Current.Services.UserService.GetUserGroupById(customUserGroup.Id);
|
||||
realGroup.RemoveAllowedSection(sectionAlias);
|
||||
//now we need to flag this for saving (hack!)
|
||||
GroupsToSave.Add(realGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Cannot remove the allowed section using this obsolete API. Modify the user's groups instead");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IUser.AddAllowedSection(string sectionAlias)
|
||||
{
|
||||
//don't do anything if they are allowed it already
|
||||
if (AllowedSections.Contains(sectionAlias))
|
||||
return;
|
||||
|
||||
//This is here for backwards compat only.
|
||||
//First we'll check if the user is part of the 'admin' group. If so then we can ensure that the admin group has this section available to it.
|
||||
//otherwise, the only thing we can do is create a custom user group for this user and add this section.
|
||||
//We are checking for admin here because if the user is an admin and an allowed section is being added, then it's assumed it's to be added
|
||||
//for the whole admin group (i.e. Forms installer does this for admins)
|
||||
var groups = Groups.ToArray();
|
||||
var admin = groups.FirstOrDefault(x => x.Alias == Constants.Security.AdminGroupAlias);
|
||||
if (admin != null)
|
||||
{
|
||||
//if the group isn't IUserGroup we'll need to look it up
|
||||
var realGroup = admin as IUserGroup ?? ApplicationContext.Current.Services.UserService.GetUserGroupById(admin.Id);
|
||||
realGroup.AddAllowedSection(sectionAlias);
|
||||
//now we need to flag this for saving (hack!)
|
||||
GroupsToSave.Add(realGroup);
|
||||
}
|
||||
|
||||
//now we'll check if the user has a special 1:1 user group created for itself. This will occur if this method is used and also during an upgrade.
|
||||
//this comes in the alias form of userName + 'Group'
|
||||
var customUserGroup = groups.FirstOrDefault(x => x.Alias == (Username + "Group"));
|
||||
if (customUserGroup != null)
|
||||
{
|
||||
//if the group isn't IUserGroup we'll need to look it up
|
||||
var realGroup = customUserGroup as IUserGroup ?? ApplicationContext.Current.Services.UserService.GetUserGroupById(customUserGroup.Id);
|
||||
realGroup.AddAllowedSection(sectionAlias);
|
||||
//now we need to flag this for saving (hack!)
|
||||
GroupsToSave.Add(realGroup);
|
||||
}
|
||||
|
||||
//ok, so the user doesn't have a 1:1 group, we'll need to flag it for creation
|
||||
var newUserGroup = new UserGroup
|
||||
{
|
||||
Alias = Username + "Group",
|
||||
Name = "Group for " + Username
|
||||
};
|
||||
newUserGroup.AddAllowedSection(sectionAlias);
|
||||
GroupsToSave.Add(newUserGroup);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This used purely for hacking backwards compatibility into this class for < 7.7 compat
|
||||
/// </summary>
|
||||
[DoNotClone]
|
||||
[IgnoreDataMember]
|
||||
internal List<IUserGroup> GroupsToSave = new List<IUserGroup>();
|
||||
|
||||
public IProfile ProfileData
|
||||
{
|
||||
get { return new WrappedUserProfile(this); }
|
||||
|
||||
68
src/Umbraco.Core/Models/Membership/UserType.cs
Normal file
68
src/Umbraco.Core/Models/Membership/UserType.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Strings;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class UserType : Entity, IUserType
|
||||
{
|
||||
private string _alias;
|
||||
private string _name;
|
||||
private IEnumerable<string> _permissions;
|
||||
private static readonly Lazy<PropertySelectors> Ps = new Lazy<PropertySelectors>();
|
||||
private class PropertySelectors
|
||||
{
|
||||
public readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<UserType, string>(x => x.Name);
|
||||
public readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<UserType, string>(x => x.Alias);
|
||||
public readonly PropertyInfo PermissionsSelector = ExpressionHelper.GetPropertyInfo<UserType, IEnumerable<string>>(x => x.Permissions);
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string Alias
|
||||
{
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(
|
||||
value.ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase),
|
||||
ref _alias,
|
||||
Ps.Value.AliasSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set { SetPropertyValueAndDetectChanges(value, ref _name, Ps.Value.NameSelector); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The set of default permissions for the user type
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default each permission is simply a single char but we've made this an enumerable{string} to support a more flexible permissions structure in the future.
|
||||
/// </remarks>
|
||||
[DataMember]
|
||||
public IEnumerable<string> Permissions
|
||||
{
|
||||
get { return _permissions; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(value, ref _permissions, Ps.Value.PermissionsSelector,
|
||||
//Custom comparer for enumerable
|
||||
new DelegateEqualityComparer<IEnumerable<string>>(
|
||||
(enum1, enum2) => enum1.UnsortedSequenceEqual(enum2),
|
||||
enum1 => enum1.GetHashCode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,6 +295,18 @@ namespace Umbraco.Core.Services
|
||||
|
||||
var repository = RepositoryFactory.CreateUserRepository(uow);
|
||||
repository.AddOrUpdate(entity);
|
||||
|
||||
//Now we have to check for backwards compat hacks
|
||||
var explicitUser = entity as User;
|
||||
if (explicitUser != null && explicitUser.GroupsToSave.Count > 0)
|
||||
{
|
||||
var groupRepository = RepositoryFactory.CreateUserGroupRepository(uow);
|
||||
foreach (var userGroup in explicitUser.GroupsToSave)
|
||||
{
|
||||
groupRepository.AddOrUpdate(userGroup);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// try to flush the unit of work
|
||||
@@ -340,17 +352,28 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
var repository = RepositoryFactory.CreateUserRepository(uow);
|
||||
foreach (var member in asArray)
|
||||
var groupRepository = RepositoryFactory.CreateUserGroupRepository(uow);
|
||||
foreach (var user in asArray)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(member.Username))
|
||||
if (string.IsNullOrWhiteSpace(user.Username))
|
||||
{
|
||||
throw new ArgumentException("Cannot save user with empty username.");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(member.Name))
|
||||
if (string.IsNullOrWhiteSpace(user.Name))
|
||||
{
|
||||
throw new ArgumentException("Cannot save user with empty name.");
|
||||
}
|
||||
repository.AddOrUpdate(member);
|
||||
repository.AddOrUpdate(user);
|
||||
|
||||
//Now we have to check for backwards compat hacks
|
||||
var explicitUser = user as User;
|
||||
if (explicitUser != null && explicitUser.GroupsToSave.Count > 0)
|
||||
{
|
||||
foreach (var userGroup in explicitUser.GroupsToSave)
|
||||
{
|
||||
groupRepository.AddOrUpdate(userGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
//commit the whole lot in one go
|
||||
uow.Commit();
|
||||
|
||||
@@ -351,10 +351,12 @@
|
||||
<Compile Include="Models\Membership\ContentPermissionSet.cs" />
|
||||
<Compile Include="Models\Membership\EntityPermissionCollection.cs" />
|
||||
<Compile Include="Models\Membership\IReadOnlyUserGroup.cs" />
|
||||
<Compile Include="Models\Membership\IUserType.cs" />
|
||||
<Compile Include="Models\Membership\ReadOnlyUserGroup.cs" />
|
||||
<Compile Include="Models\Membership\UserGroupExtensions.cs" />
|
||||
<Compile Include="Models\Membership\UserProfile.cs" />
|
||||
<Compile Include="Models\Membership\UserState.cs" />
|
||||
<Compile Include="Models\Membership\UserType.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedContentTypeConverter.cs" />
|
||||
<Compile Include="Models\Rdbms\UserStartNodeDto.cs" />
|
||||
<Compile Include="Models\UserControl.cs" />
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
@@ -24,6 +26,12 @@ namespace Umbraco.Web.Models.ContentEditing
|
||||
[DataMember(Name = "emailHash")]
|
||||
public string EmailHash { get; set; }
|
||||
|
||||
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[ReadOnly(true)]
|
||||
[DataMember(Name = "userType")]
|
||||
public string UserType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the number of seconds for the user's auth ticket to expire
|
||||
/// </summary>
|
||||
|
||||
@@ -315,7 +315,34 @@ namespace Umbraco.Web.Models.Mapping
|
||||
.ForMember(
|
||||
detail => detail.EmailHash,
|
||||
opt => opt.MapFrom(user => user.Email.ToLowerInvariant().Trim().GenerateHash()))
|
||||
.ForMember(detail => detail.SecondsUntilTimeout, opt => opt.Ignore());
|
||||
.ForMember(detail => detail.SecondsUntilTimeout, opt => opt.Ignore())
|
||||
.AfterMap((user, detail) =>
|
||||
{
|
||||
//we need to map the legacy UserType
|
||||
//the best we can do here is to return the user's first user group as a IUserType object
|
||||
//but we should attempt to return any group that is the built in ones first
|
||||
var groups = user.Groups.ToArray();
|
||||
if (groups.Length == 0)
|
||||
{
|
||||
//In backwards compatibility land, a user type cannot be null! so we need to return a fake one.
|
||||
detail.UserType = "temp";
|
||||
}
|
||||
else
|
||||
{
|
||||
var builtIns = new[] { Constants.Security.AdminGroupAlias, "writer", "editor", "translator" };
|
||||
var foundBuiltIn = groups.FirstOrDefault(x => builtIns.Contains(x.Alias));
|
||||
if (foundBuiltIn != null)
|
||||
{
|
||||
detail.UserType = foundBuiltIn.Alias;
|
||||
}
|
||||
else
|
||||
{
|
||||
//otherwise return the first
|
||||
detail.UserType = groups[0].Alias;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
config.CreateMap<IProfile, UserProfile>()
|
||||
.ForMember(detail => detail.UserId, opt => opt.MapFrom(profile => GetIntId(profile.Id)));
|
||||
|
||||
Reference in New Issue
Block a user