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:
Shannon
2014-01-22 14:07:18 +11:00
parent fb9569d914
commit 9bd8d729fa
8 changed files with 109 additions and 50 deletions

View File

@@ -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; }

View File

@@ -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; }

View File

@@ -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

View File

@@ -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.

View File

@@ -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;

View 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;
}
}
}

View File

@@ -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" />

View File

@@ -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>