Registration and last login date are now tracked for users, fixes #1296

This commit is contained in:
Lombiq
2015-06-13 23:56:40 +02:00
parent e066e39070
commit de9fc2fb5b
9 changed files with 103 additions and 7 deletions

View File

@@ -155,6 +155,7 @@ namespace Orchard.Users.Controllers {
}
_authenticationService.SignIn(user, false /* createPersistentCookie */);
_userEventHandler.LoggedIn(user);
return this.RedirectLocal(returnUrl);
}

View File

@@ -87,6 +87,12 @@ namespace Orchard.Users.Controllers {
case UsersOrder.Email:
users = users.OrderBy(u => u.Email);
break;
case UsersOrder.CreatedUtc:
users = users.OrderBy(u => u.CreatedUtc);
break;
case UsersOrder.LastLoginUtc:
users = users.OrderBy(u => u.LastLoginUtc);
break;
}
var results = users

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.ContentManagement;
using Orchard.Security;
using Orchard.Services;
using Orchard.Users.Models;
namespace Orchard.Users.Events {
public class LoginUserEventHandler : IUserEventHandler {
private readonly IClock _clock;
public LoginUserEventHandler(IClock clock) {
_clock = clock;
}
public void Creating(UserContext context) { }
public void Created(UserContext context) { }
public void LoggedIn(IUser user) {
user.As<UserPart>().LastLoginUtc = _clock.UtcNow;
}
public void LoggedOut(IUser user) { }
public void AccessDenied(IUser user) { }
public void ChangedPassword(IUser user) { }
public void SentChallengeEmail(IUser user) { }
public void ConfirmedEmail(IUser user) { }
public void Approved(IUser user) { }
public void LoggingIn(string userNameOrEmail, string password) { }
public void LogInFailed(string userNameOrEmail, string password) { }
}
}

View File

@@ -1,6 +1,7 @@
using Orchard.ContentManagement.MetaData;
using Orchard.Data.Migration;
using System;
using Orchard.ContentManagement.MetaData;
using Orchard.Core.Contents.Extensions;
using Orchard.Data.Migration;
namespace Orchard.Users {
public class UsersDataMigration : DataMigrationImpl {
@@ -19,9 +20,13 @@ namespace Orchard.Users {
.Column<string>("RegistrationStatus", c => c.WithDefault("Approved"))
.Column<string>("EmailStatus", c => c.WithDefault("Approved"))
.Column<string>("EmailChallengeToken")
.Column<DateTime>("CreatedUtc")
.Column<DateTime>("LastLoginUtc")
);
return 1;
ContentDefinitionManager.AlterTypeDefinition("User", cfg => cfg.Creatable(false));
return 3;
}
public int UpdateFrom1() {
@@ -29,5 +34,15 @@ namespace Orchard.Users {
return 2;
}
public int UpdateFrom2() {
SchemaBuilder.AlterTable("UserPartRecord",
table => {
table.AddColumn<DateTime>("CreatedUtc");
table.AddColumn<DateTime>("LastLoginUtc");
});
return 3;
}
}
}

View File

@@ -1,13 +1,14 @@
using System.Web.Security;
using System;
using System.Web.Security;
using Orchard.ContentManagement;
using Orchard.Security;
namespace Orchard.Users.Models {
public sealed class UserPart : ContentPart<UserPartRecord>, IUser {
public const string EmailPattern =
public const string EmailPattern =
@"^(?![\.@])(""([^""\r\\]|\\[""\r\\])*""|([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
+ @"@([a-z0-9][\w-]*\.)+[a-z]{2,}$";
public const int MaxUserNameLength = 255;
public const int MaxEmailLength = 255;
@@ -60,5 +61,15 @@ namespace Orchard.Users.Models {
get { return Retrieve(x => x.EmailStatus); }
set { Store(x => x.EmailStatus, value); }
}
public DateTime? CreatedUtc {
get { return Retrieve(x => x.CreatedUtc); }
set { Store(x => x.CreatedUtc, value); }
}
public DateTime? LastLoginUtc {
get { return Retrieve(x => x.LastLoginUtc); }
set { Store(x => x.LastLoginUtc, value); }
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Web.Security;
using Orchard.ContentManagement.Records;
@@ -15,5 +16,7 @@ namespace Orchard.Users.Models {
public virtual UserStatus RegistrationStatus { get; set; }
public virtual UserStatus EmailStatus { get; set; }
public virtual string EmailChallengeToken { get; set; }
public virtual DateTime? CreatedUtc { get; set; }
public virtual DateTime? LastLoginUtc { get; set; }
}
}

View File

@@ -28,6 +28,7 @@ namespace Orchard.Users.Services {
private readonly IShapeFactory _shapeFactory;
private readonly IShapeDisplay _shapeDisplay;
private readonly IAppConfigurationAccessor _appConfigurationAccessor;
private readonly IClock _clock;
public MembershipService(
IOrchardServices orchardServices,
@@ -45,6 +46,7 @@ namespace Orchard.Users.Services {
_shapeFactory = shapeFactory;
_shapeDisplay = shapeDisplay;
_appConfigurationAccessor = appConfigurationAccessor;
_clock = clock;
Logger = NullLogger.Instance;
T = NullLocalizer.Instance;
}
@@ -69,6 +71,7 @@ namespace Orchard.Users.Services {
user.Email = createUserParams.Email;
user.NormalizedUserName = createUserParams.Username.ToLowerInvariant();
user.HashAlgorithm = PBKDF2;
user.CreatedUtc = _clock.UtcNow;
SetPassword(user, createUserParams.Password);
if ( registrationSettings != null ) {

View File

@@ -23,7 +23,9 @@ namespace Orchard.Users.ViewModels {
public enum UsersOrder {
Name,
Email
Email,
CreatedUtc,
LastLoginUtc
}
public enum UsersFilter {

View File

@@ -1,7 +1,10 @@
@model Orchard.Users.ViewModels.UsersIndexViewModel
@using Orchard.Core.Shapes;
@using Orchard.Users.Models;
@using Orchard.Users.ViewModels;
@{
var userIndex = 0;
@@ -36,6 +39,8 @@
<select id="sortResults" name="@Html.NameOf(m => m.Options.Order)">
@Html.SelectOption(Model.Options.Order, UsersOrder.Name, T("Name").ToString())
@Html.SelectOption(Model.Options.Order, UsersOrder.Email, T("Email").ToString())
@Html.SelectOption(Model.Options.Order, UsersOrder.CreatedUtc, T("Creation Time").ToString())
@Html.SelectOption(Model.Options.Order, UsersOrder.LastLoginUtc, T("Last Login Time").ToString())
</select>
<button type="submit" name="submit.Filter" value="@T("Filter")">@T("Filter")</button>
@@ -48,6 +53,8 @@
<th scope="col">@T("Name")</th>
<th scope="col">@T("Email")</th>
<th scope="col">@T("Actions")</th>
<th scope="col">@T("Creation Time")</th>
<th scope="col">@T("Last Login Time")</th>
</tr>
</thead>
@foreach (var entry in Model.Users) {
@@ -79,6 +86,12 @@
@Html.ActionLink(T("Send challenge E-mail").ToString(), "SendChallengeEmail", new { entry.User.Id }, new { itemprop = "UnsafeUrl" })
}
</td>
<td>
@Display(New.DateTimeRelative(dateTimeUtc: entry.User.CreatedUtc))
</td>
<td>
@Display(New.DateTimeRelative(dateTimeUtc: entry.User.LastLoginUtc))
</td>
</tr>
userIndex++;
}