diff --git a/src/Umbraco.Core/Models/Membership/IProfile.cs b/src/Umbraco.Core/Models/Membership/IProfile.cs
index fbbff85e7d..749c3371b8 100644
--- a/src/Umbraco.Core/Models/Membership/IProfile.cs
+++ b/src/Umbraco.Core/Models/Membership/IProfile.cs
@@ -3,6 +3,10 @@
///
/// Defines the the Profile interface
///
+ ///
+ /// 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!
+ ///
public interface IProfile
{
object Id { get; set; }
diff --git a/src/Umbraco.Core/Models/Membership/IUser.cs b/src/Umbraco.Core/Models/Membership/IUser.cs
index b15e5845e5..ab9c02b1b2 100644
--- a/src/Umbraco.Core/Models/Membership/IUser.cs
+++ b/src/Umbraco.Core/Models/Membership/IUser.cs
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.Membership
/// Will be left internal until a proper Membership implementation is part of the roadmap
public interface IUser : IMembershipUser, IProfile
{
- new object Id { get; set; }
+ new int Id { get; set; }
int SessionTimeout { get; set; }
int StartContentId { get; set; }
diff --git a/src/Umbraco.Core/Models/Membership/User.cs b/src/Umbraco.Core/Models/Membership/User.cs
index 52350b3748..b35fd04bba 100644
--- a/src/Umbraco.Core/Models/Membership/User.cs
+++ b/src/Umbraco.Core/Models/Membership/User.cs
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Models.Membership
///
[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 _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
diff --git a/src/Umbraco.Core/Services/IUserService.cs b/src/Umbraco.Core/Services/IUserService.cs
index 840cd9a685..a55bd4b771 100644
--- a/src/Umbraco.Core/Services/IUserService.cs
+++ b/src/Umbraco.Core/Services/IUserService.cs
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Services
///
/// Defines the UserService, which is an easy access to operations involving and eventually Users.
///
- internal interface IUserService : IMembershipUserService
+ public interface IUserService : IMembershipUserService
{
///
/// Gets an IProfile by User Id.
diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs
index 5ac259cafb..8939101ac8 100644
--- a/src/Umbraco.Core/Services/UserService.cs
+++ b/src/Umbraco.Core/Services/UserService.cs
@@ -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
///
/// Represents the UserService, which is an easy access to operations involving , and eventually Backoffice Users.
///
- internal class UserService : IUserService
+ public class UserService : IUserService
{
private readonly RepositoryFactory _repositoryFactory;
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
diff --git a/src/Umbraco.Core/Services/UserServiceExtensions.cs b/src/Umbraco.Core/Services/UserServiceExtensions.cs
new file mode 100644
index 0000000000..b97a40ace8
--- /dev/null
+++ b/src/Umbraco.Core/Services/UserServiceExtensions.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Web.Security;
+using Umbraco.Core.Models.Membership;
+
+namespace Umbraco.Core.Services
+{
+ internal static class UserServiceExtensions
+ {
+ ///
+ /// Maps a custom provider's information to an umbraco user account
+ ///
+ ///
+ ///
+ ///
+ /// 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.
+ ///
+ 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 0c7025fe00..c31a353390 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -787,6 +787,7 @@
+
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs
index 36008e7fac..3773e1ffab 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.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;
}
-
- ///
- /// Maps a custom provider's information to an umbraco user account
- ///
- /// Name of the login.
- /// Email address of the user
- 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);
- }
- }
-
+
///
/// ClientLoader control.
///