publicizes user stuff, changes the IUser.Id to an int - no need for it to be an object and casted everywhere. Updates the login logic to perform the mapping logic for custom membership providers with an extension method.
This commit is contained in:
@@ -3,6 +3,10 @@
|
||||
/// <summary>
|
||||
/// Defines the the Profile interface
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This interface is pretty useless but has been exposed publicly from 6.x so we're stuck with it. It would make more sense
|
||||
/// if the Id was an int but since it's not people have to cast it to int all of the time!
|
||||
/// </remarks>
|
||||
public interface IProfile
|
||||
{
|
||||
object Id { get; set; }
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// <remarks>Will be left internal until a proper Membership implementation is part of the roadmap</remarks>
|
||||
public interface IUser : IMembershipUser, IProfile
|
||||
{
|
||||
new object Id { get; set; }
|
||||
new int Id { get; set; }
|
||||
|
||||
int SessionTimeout { get; set; }
|
||||
int StartContentId { get; set; }
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class User : TracksChangesEntityBase, IUser
|
||||
public class User : TracksChangesEntityBase, IUser
|
||||
{
|
||||
public User(IUserType userType)
|
||||
{
|
||||
@@ -45,7 +45,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
|
||||
private readonly IUserType _userType;
|
||||
private bool _hasIdentity;
|
||||
private object _id;
|
||||
private int _id;
|
||||
private string _name;
|
||||
private Type _userTypeKey;
|
||||
private readonly List<string> _addedSections;
|
||||
@@ -242,6 +242,12 @@ namespace Umbraco.Core.Models.Membership
|
||||
|
||||
#region Implementation of IProfile
|
||||
|
||||
object IProfile.Id
|
||||
{
|
||||
get { return Id; }
|
||||
set { Id = (int)value; }
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string Name
|
||||
{
|
||||
@@ -355,7 +361,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public object Id
|
||||
public int Id
|
||||
{
|
||||
get { return _id; }
|
||||
set
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Defines the UserService, which is an easy access to operations involving <see cref="IProfile"/> and eventually Users.
|
||||
/// </summary>
|
||||
internal interface IUserService : IMembershipUserService
|
||||
public interface IUserService : IMembershipUserService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an IProfile by User Id.
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Web.Security;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
@@ -16,7 +15,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Represents the UserService, which is an easy access to operations involving <see cref="IProfile"/>, <see cref="IMembershipUser"/> and eventually Backoffice Users.
|
||||
/// </summary>
|
||||
internal class UserService : IUserService
|
||||
public class UserService : IUserService
|
||||
{
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
|
||||
52
src/Umbraco.Core/Services/UserServiceExtensions.cs
Normal file
52
src/Umbraco.Core/Services/UserServiceExtensions.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Web.Security;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
internal static class UserServiceExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Maps a custom provider's information to an umbraco user account
|
||||
/// </summary>
|
||||
/// <param name="userService"></param>
|
||||
/// <param name="member"></param>
|
||||
/// <remarks>
|
||||
/// To maintain compatibility we have to check the login name if the provider key lookup fails but otherwise
|
||||
/// we'll store the provider user key in the login column.
|
||||
/// </remarks>
|
||||
public static IUser CreateUserMappingForCustomProvider(this IUserService userService, MembershipUser member)
|
||||
{
|
||||
if (member == null) throw new ArgumentNullException("member");
|
||||
|
||||
|
||||
var valToLookup = member.ProviderUserKey == null ? member.UserName : member.ProviderUserKey.ToString();
|
||||
var found = userService.GetByUsername(valToLookup);
|
||||
if (found == null && member.ProviderUserKey != null)
|
||||
{
|
||||
//try by username
|
||||
found = userService.GetByUsername(member.UserName);
|
||||
}
|
||||
|
||||
if (found == null)
|
||||
{
|
||||
var writer = userService.GetUserTypeByAlias("writer");
|
||||
if (writer == null)
|
||||
{
|
||||
throw new InvalidOperationException("Could not map the custom user to an Umbraco user, no 'writer' user type could be found");
|
||||
}
|
||||
var user = new User(
|
||||
member.UserName,
|
||||
member.Email ?? Guid.NewGuid().ToString("N") + "@example.com", //email cannot be empty
|
||||
member.ProviderUserKey == null ? member.UserName : member.ProviderUserKey.ToString(),
|
||||
Guid.NewGuid().ToString("N"), //pass cannot be empty
|
||||
writer);
|
||||
user.AddAllowedSection(Constants.Applications.Content);
|
||||
userService.Save(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -787,6 +787,7 @@
|
||||
<Compile Include="Services\PackagingService.cs" />
|
||||
<Compile Include="Services\ServiceContext.cs" />
|
||||
<Compile Include="Services\UserService.cs" />
|
||||
<Compile Include="Services\UserServiceExtensions.cs" />
|
||||
<Compile Include="Standalone\ServiceContextManager.cs" />
|
||||
<Compile Include="Standalone\StandaloneCoreApplication.cs" />
|
||||
<Compile Include="Standalone\StandaloneCoreBootManager.cs" />
|
||||
|
||||
@@ -11,14 +11,17 @@ using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Web.UI.HtmlControls;
|
||||
using Umbraco.Core.Logging;
|
||||
using umbraco.BusinessLogic;
|
||||
using System.Web.Security;
|
||||
using umbraco.businesslogic.Exceptions;
|
||||
using Umbraco.Core.IO;
|
||||
using umbraco.cms.businesslogic.web;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web;
|
||||
using User = umbraco.BusinessLogic.User;
|
||||
|
||||
namespace umbraco.cms.presentation
|
||||
{
|
||||
@@ -83,40 +86,51 @@ namespace umbraco.cms.presentation
|
||||
// Authenticate users by using the provider specified in umbracoSettings.config
|
||||
if (BackOfficeProvider.ValidateUser(lname.Text, passw.Text))
|
||||
{
|
||||
IUser user;
|
||||
if (BackOfficeProvider.IsUmbracoUsersProvider() == false)
|
||||
{
|
||||
CustomProviderMapping(lname.Text, BackOfficeProvider.GetUser(lname.Text, false).Email);
|
||||
user = ApplicationContext.Services.UserService.CreateUserMappingForCustomProvider(
|
||||
BackOfficeProvider.GetUser(lname.Text, false));
|
||||
}
|
||||
|
||||
|
||||
var u = new User(lname.Text);
|
||||
doLogin(u);
|
||||
else
|
||||
{
|
||||
user = ApplicationContext.Services.UserService.GetByUsername(lname.Text);
|
||||
if (user == null)
|
||||
{
|
||||
throw new InvalidOperationException("No IUser found with username " + lname.Text);
|
||||
}
|
||||
}
|
||||
|
||||
//do the login
|
||||
UmbracoContext.Current.Security.PerformLogin(user.Id);
|
||||
|
||||
// Check if the user should be redirected to live editing
|
||||
if (UmbracoSettings.EnableCanvasEditing && u.DefaultToLiveEditing)
|
||||
if (UmbracoSettings.EnableCanvasEditing)
|
||||
{
|
||||
int startNode = u.StartNodeId;
|
||||
// If the startnode is -1 (access to all content), we'll redirect to the top root node
|
||||
if (startNode == -1)
|
||||
//if live editing is enabled, we have to check if we need to redirect there but it is not supported
|
||||
// on the new IUser so we need to get the legacy user object to check
|
||||
var u = new User(user.Id);
|
||||
if (u.DefaultToLiveEditing)
|
||||
{
|
||||
if (Document.CountLeafNodes(-1, Document._objectType) > 0)
|
||||
var startNode = u.StartNodeId;
|
||||
// If the startnode is -1 (access to all content), we'll redirect to the top root node
|
||||
if (startNode == -1)
|
||||
{
|
||||
//get the first document
|
||||
var firstNodeId = Document.TopMostNodeIds(Document._objectType).First();
|
||||
startNode = new Document(firstNodeId).Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("There's currently no content to edit. Please contact your system administrator");
|
||||
if (Document.CountLeafNodes(-1, Document._objectType) > 0)
|
||||
{
|
||||
//get the first document
|
||||
var firstNodeId = Document.TopMostNodeIds(Document._objectType).First();
|
||||
startNode = new Document(firstNodeId).Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("There's currently no content to edit. Please contact your system administrator");
|
||||
}
|
||||
}
|
||||
var redir = String.Format("{0}/canvas.aspx?redir=/{1}.aspx", SystemDirectories.Umbraco, startNode);
|
||||
Response.Redirect(redir, true);
|
||||
}
|
||||
string redir = String.Format("{0}/canvas.aspx?redir=/{1}.aspx", SystemDirectories.Umbraco, startNode);
|
||||
Response.Redirect(redir, true);
|
||||
}
|
||||
else if (u.DefaultToLiveEditing)
|
||||
{
|
||||
throw new UserAuthorizationException("Canvas editing isn't enabled. It can be enabled via the UmbracoSettings.config");
|
||||
}
|
||||
}
|
||||
|
||||
if (hf_height.Value != "undefined")
|
||||
{
|
||||
@@ -173,24 +187,7 @@ namespace umbraco.cms.presentation
|
||||
&& Uri.IsWellFormedUriString(url, UriKind.Relative);
|
||||
return isLocal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a custom provider's information to an umbraco user account
|
||||
/// </summary>
|
||||
/// <param name="loginName">Name of the login.</param>
|
||||
/// <param name="email">Email address of the user</param>
|
||||
private static void CustomProviderMapping(string loginName, string email)
|
||||
{
|
||||
// Password is not copied over because it is stored in active directory for security!
|
||||
// The user is create with default access to content and as a writer user type
|
||||
if (BusinessLogic.User.getUserId(loginName) == -1)
|
||||
{
|
||||
BusinessLogic.User.MakeNew(loginName, loginName, string.Empty, email ?? "", UserType.GetUserType(2));
|
||||
var u = new User(loginName);
|
||||
u.addApplication(Constants.Applications.Content);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ClientLoader control.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user