diff --git a/Areas/admin/Controllers/baseController.cs b/Areas/admin/Controllers/baseController.cs new file mode 100644 index 0000000..7889f69 --- /dev/null +++ b/Areas/admin/Controllers/baseController.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; + +namespace BuildFeed.Areas.admin.Controllers +{ + [Authorize(Users = "hounsell")] + public class baseController : Controller + { + // GET: admin/base + public ActionResult index() + { + return View(); + } + } +} \ No newline at end of file diff --git a/Areas/admin/Controllers/usersController.cs b/Areas/admin/Controllers/usersController.cs index 655c803..f07bb10 100644 --- a/Areas/admin/Controllers/usersController.cs +++ b/Areas/admin/Controllers/usersController.cs @@ -12,19 +12,19 @@ namespace BuildFeed.Areas.admin.Controllers public class usersController : Controller { // GET: admin/users - public ActionResult Index() + public ActionResult index() { - return View(Membership.GetAllUsers().Cast().OrderBy(m => m.IsApproved).ThenBy(m => m.UserName)); + return View(Membership.GetAllUsers().Cast().OrderByDescending(m => m.IsApproved).ThenBy(m => m.UserName)); } - public ActionResult Approve(Guid id) + public ActionResult approve(Guid id) { var provider = (Membership.Provider as RedisMembershipProvider); provider.ChangeApproval(id, true); return RedirectToAction("Index"); } - public ActionResult Unapprove(Guid id) + public ActionResult unapprove(Guid id) { var provider = (Membership.Provider as RedisMembershipProvider); provider.ChangeApproval(id, false); diff --git a/Areas/admin/Views/base/index.cshtml b/Areas/admin/Views/base/index.cshtml new file mode 100644 index 0000000..1657a20 --- /dev/null +++ b/Areas/admin/Views/base/index.cshtml @@ -0,0 +1,11 @@ + +@{ + ViewBag.Title = "Administration | BuildFeed"; +} + +

Administration

+ + + diff --git a/Areas/admin/Views/users/index.cshtml b/Areas/admin/Views/users/index.cshtml index 588d8fd..dcb2a53 100644 --- a/Areas/admin/Views/users/index.cshtml +++ b/Areas/admin/Views/users/index.cshtml @@ -6,7 +6,7 @@

User Administration

- +
+ @@ -26,6 +29,9 @@ +
Username @@ -14,6 +14,9 @@ Email Address + Last Login Time +
@Html.DisplayFor(modelItem => mu.Email) + @Html.DisplayFor(modelItem => mu.LastLoginDate) + @if (mu.IsApproved) { diff --git a/Areas/admin/adminAreaRegistration.cs b/Areas/admin/adminAreaRegistration.cs index b56f645..2f0dfa1 100644 --- a/Areas/admin/adminAreaRegistration.cs +++ b/Areas/admin/adminAreaRegistration.cs @@ -15,9 +15,9 @@ public override string AreaName public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( - "admin_default", + "Admin (Default)", "admin/{controller}/{action}/{id}", - new { action = "Index", id = UrlParameter.Optional } + new { action = "index", controller = "base", id = UrlParameter.Optional } ); } } diff --git a/Auth/RedisMembershipProvider.cs b/Auth/RedisMembershipProvider.cs index 7faeb45..47f3073 100644 --- a/Auth/RedisMembershipProvider.cs +++ b/Auth/RedisMembershipProvider.cs @@ -355,6 +355,12 @@ public override bool ValidateUser(string username, string password) isFail |= (hash[i] != rm.PassHash[i]); } + if(!isFail) + { + rm.LastLoginDate = DateTime.Now; + client.Store(rm); + } + return !isFail; } } diff --git a/BuildFeed.csproj b/BuildFeed.csproj index 9990f53..3e7caa9 100644 --- a/BuildFeed.csproj +++ b/BuildFeed.csproj @@ -145,6 +145,7 @@ + @@ -165,6 +166,7 @@ + @@ -177,6 +179,7 @@ + @@ -215,6 +218,7 @@ + diff --git a/Controllers/buildController.cs b/Controllers/buildController.cs index e248445..ebf2672 100644 --- a/Controllers/buildController.cs +++ b/Controllers/buildController.cs @@ -10,7 +10,7 @@ namespace BuildFeed.Controllers { public class buildController : Controller { - public int pageSize { get { return 15; } } + public static int pageSize { get { return 15; } } // // GET: /build/ @@ -103,6 +103,7 @@ public ActionResult create(Build build) try { build.Added = DateTime.Now; + build.Modified = DateTime.Now; Build.Insert(build); } catch diff --git a/Controllers/rssController.cs b/Controllers/rssController.cs index b500d44..7662e03 100644 --- a/Controllers/rssController.cs +++ b/Controllers/rssController.cs @@ -85,12 +85,7 @@ public async Task added() public async Task version() { - var builds = Build.Select() - .OrderByDescending(b => b.MajorVersion) - .ThenByDescending(b => b.MinorVersion) - .ThenByDescending(b => b.Number) - .ThenByDescending(b => b.Revision) - .ThenByDescending(b => b.BuildTime) + var builds = Build.SelectInVersionOrder() .Take(20); diff --git a/Controllers/supportController.cs b/Controllers/supportController.cs index 5253517..f9c257b 100644 --- a/Controllers/supportController.cs +++ b/Controllers/supportController.cs @@ -3,7 +3,9 @@ using System.Linq; using System.Web; using System.Web.Mvc; +using System.Web.Routing; using System.Web.Security; +using BuildFeed.Models; using BuildFeed.Models.ViewModel; namespace BuildFeed.Controllers @@ -116,5 +118,103 @@ public ActionResult rss() { return View(); } + + public ActionResult sitemap() + { + IEnumerable builds = Build.SelectInVersionOrder(); + Dictionary actions = new Dictionary(); + + actions.Add("Pages", new SitemapPagedAction[] { new SitemapPagedAction() + { + UrlParams = new RouteValueDictionary(new { + controller = "build", + action = "index", + page = 1 + }), + Pages = (builds.Count() + (buildController.pageSize - 1)) / buildController.pageSize + } }); + + actions.Add("Versions", (from b in builds + group b by new BuildVersion() { Major = b.MajorVersion, Minor = b.MinorVersion } into bv + orderby bv.Key.Major descending, + bv.Key.Minor descending + select new SitemapPagedAction() + { + Name = string.Format("Windows NT {0}.{1}", bv.Key.Major, bv.Key.Minor), + UrlParams = new RouteValueDictionary(new + { + controller = "build", + action = "version", + major = bv.Key.Major, + minor = bv.Key.Minor, + page = 1 + }), + Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize + }).ToArray()); + + actions.Add("Labs", (from b in builds + where !string.IsNullOrEmpty(b.Lab) + group b by b.Lab into bv + orderby bv.Key + select new SitemapPagedAction() + { + Name = bv.Key, + UrlParams = new RouteValueDictionary(new + { + controller = "build", + action = "version", + lab = bv.Key, + page = 1 + }), + Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize + }).ToArray()); + + actions.Add("Years", (from b in builds + where b.BuildTime.HasValue + group b by b.BuildTime.Value.Year into bv + orderby bv.Key + select new SitemapPagedAction() + { + Name = bv.Key.ToString(), + UrlParams = new RouteValueDictionary(new + { + controller = "build", + action = "year", + year = bv.Key, + page = 1 + }), + Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize + }).ToArray()); + + actions.Add("Sources", (from b in builds + group b by b.SourceType into bv + orderby bv.Key + select new SitemapPagedAction() + { + Name = DisplayHelpers.GetDisplayTextForEnum(bv.Key), + UrlParams = new RouteValueDictionary(new + { + controller = "build", + action = "version", + source = bv.Key, + page = 1 + }), + Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize + }).ToArray()); + + SitemapData model = new SitemapData() + { + Builds = (from b in builds + select new SitemapDataBuild() + { + Id = b.Id, + Name = b.FullBuildString + }).ToArray(), + + Actions = actions + }; + + return View(model); + } } } \ No newline at end of file diff --git a/Models/Build.cs b/Models/Build.cs index 8534fc7..5e137a1 100644 --- a/Models/Build.cs +++ b/Models/Build.cs @@ -45,9 +45,13 @@ public class Build : IHasId [@Required] - [DisplayName("Time Added")] + [DisplayName("Time Created")] public DateTime Added { get; set; } + [@Required] + [DisplayName("Time Modified")] + public DateTime Modified { get; set; } + [@Required] [DisplayName("Source Type")] [EnumDataType(typeof(TypeOfSource))] @@ -85,7 +89,7 @@ public bool IsLeaked { get { - switch(SourceType) + switch (SourceType) { case TypeOfSource.PublicRelease: case TypeOfSource.InternalLeak: @@ -158,6 +162,21 @@ public static IEnumerable SelectInBuildOrder() } } + [DataObjectMethod(DataObjectMethodType.Select, false)] + public static IEnumerable SelectInVersionOrder() + { + using (RedisClient rClient = new RedisClient(DatabaseConfig.Host, DatabaseConfig.Port, db: DatabaseConfig.Database)) + { + var client = rClient.As(); + return client.GetAll() + .OrderByDescending(b => b.MajorVersion) + .ThenByDescending(b => b.MinorVersion) + .ThenByDescending(b => b.Number) + .ThenByDescending(b => b.Revision) + .ThenByDescending(b => b.BuildTime); + } + } + [DataObjectMethod(DataObjectMethodType.Select, false)] public static IEnumerable SelectBuildVersions() { @@ -235,6 +254,7 @@ public static void Update(Build item) { Build old = Build.SelectById(item.Id); item.Added = old.Added; + item.Modified = DateTime.Now; using (RedisClient rClient = new RedisClient(DatabaseConfig.Host, DatabaseConfig.Port, db: DatabaseConfig.Database)) { diff --git a/Models/ViewModel/SitemapData.cs b/Models/ViewModel/SitemapData.cs new file mode 100644 index 0000000..6c26672 --- /dev/null +++ b/Models/ViewModel/SitemapData.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Routing; + +namespace BuildFeed.Models.ViewModel +{ + public class SitemapData + { + public SitemapDataBuild[] Builds { get; set; } + public Dictionary Actions { get; set; } + } + + public class SitemapDataBuild + { + public long Id { get; set; } + public string Name { get; set; } + } + + public class SitemapPagedAction + { + public string Name { get; set; } + public RouteValueDictionary UrlParams { get; set; } + public int Pages { get; set; } + + public string Action + { + get { return UrlParams["action"].ToString(); } + } + + public string UniqueId + { + get { return UrlParams.GetHashCode().ToString("X8").ToLower(); } + } + } +} \ No newline at end of file diff --git a/Views/build/index.cshtml b/Views/build/index.cshtml index 956cead..e878438 100644 --- a/Views/build/index.cshtml +++ b/Views/build/index.cshtml @@ -214,6 +214,11 @@