* login/logout
* change administration password
This commit is contained in:
parent
df137150ae
commit
99cb4defbe
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Linq;
|
||||||
using System.Linq;
|
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using NHibernate;
|
using NHibernate;
|
||||||
using Portoa.NHibernate;
|
using Portoa.NHibernate;
|
||||||
|
54
Src/VideoGameQuotes.Web/Controllers/AdminController.cs
Normal file
54
Src/VideoGameQuotes.Web/Controllers/AdminController.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using System.Web.Mvc;
|
||||||
|
using Portoa.Web;
|
||||||
|
using Portoa.Web.ErrorHandling;
|
||||||
|
using VideoGameQuotes.Api;
|
||||||
|
using VideoGameQuotes.Web.Models;
|
||||||
|
using VideoGameQuotes.Web.Security;
|
||||||
|
using VideoGameQuotes.Web.Services;
|
||||||
|
|
||||||
|
namespace VideoGameQuotes.Web.Controllers {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[IsValidUser(Group = UserGroup.Admin)]
|
||||||
|
public class AdminController : Controller {
|
||||||
|
private readonly ICurrentUserProvider userProvider;
|
||||||
|
private readonly IAdministrationService adminService;
|
||||||
|
|
||||||
|
public AdminController(ICurrentUserProvider userProvider, IAdministrationService adminService) {
|
||||||
|
this.userProvider = userProvider;
|
||||||
|
this.adminService = adminService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult Index() {
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public ActionResult Password() {
|
||||||
|
return View(new ChangePasswordModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public ActionResult Password(ChangePasswordModel model) {
|
||||||
|
if (!ModelState.IsValid) {
|
||||||
|
return View(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = userProvider.CurrentUser;
|
||||||
|
if (user == null) {
|
||||||
|
return View("Unknown", new ErrorModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
user.ChangePassword(model.Password);
|
||||||
|
adminService.SaveUser(user);
|
||||||
|
return View("PasswordSuccessfullyChanged");
|
||||||
|
} catch {
|
||||||
|
ControllerContext.AddModelError("password", "Unable to change password");
|
||||||
|
return View(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Net.Mail;
|
using System.Net.Mail;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
|
using Portoa.Web.Controllers;
|
||||||
|
using Portoa.Web.Security;
|
||||||
|
using VideoGameQuotes.Api;
|
||||||
using VideoGameQuotes.Web.Models;
|
using VideoGameQuotes.Web.Models;
|
||||||
|
|
||||||
namespace VideoGameQuotes.Web.Controllers {
|
namespace VideoGameQuotes.Web.Controllers {
|
||||||
public class HomeController : Controller {
|
public class HomeController : Controller {
|
||||||
|
private readonly IAuthenticationService authenticationService;
|
||||||
|
private readonly ICurrentUserProvider userProvider;
|
||||||
|
|
||||||
private static readonly string[] answers = new[] {
|
private static readonly string[] answers = new[] {
|
||||||
"I AM ERROR.",
|
"I AM ERROR.",
|
||||||
"shyron",
|
"shyron",
|
||||||
@ -19,6 +26,11 @@ namespace VideoGameQuotes.Web.Controllers {
|
|||||||
"ryu huyabasa"
|
"ryu huyabasa"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public HomeController(IAuthenticationService authenticationService, ICurrentUserProvider userProvider) {
|
||||||
|
this.authenticationService = authenticationService;
|
||||||
|
this.userProvider = userProvider;
|
||||||
|
}
|
||||||
|
|
||||||
public ActionResult Index() {
|
public ActionResult Index() {
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
@ -27,6 +39,30 @@ namespace VideoGameQuotes.Web.Controllers {
|
|||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public ActionResult Login([Required]string username, [Required]string password) {
|
||||||
|
if (!ModelState.IsValid) {
|
||||||
|
return Json(this.CreateJsonErrorResponse("Invalid request"));
|
||||||
|
}
|
||||||
|
if (!authenticationService.IsValid(username, password)) {
|
||||||
|
return Json(this.CreateJsonErrorResponse("Invalid username/password"));
|
||||||
|
}
|
||||||
|
|
||||||
|
authenticationService.Login(username);
|
||||||
|
return Json(this.CreateJsonResponse());
|
||||||
|
}
|
||||||
|
|
||||||
|
[ChildActionOnly]
|
||||||
|
public ActionResult MainMenu() {
|
||||||
|
var model = new MainMenuModel { User = userProvider.CurrentUser };
|
||||||
|
return PartialView("MainMenu", model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult Logout(string redirectUrl) {
|
||||||
|
authenticationService.Logout();
|
||||||
|
return Redirect(redirectUrl ?? "/");
|
||||||
|
}
|
||||||
|
|
||||||
public ActionResult Contact() {
|
public ActionResult Contact() {
|
||||||
var randomAnswer = GetRandomAnswer();
|
var randomAnswer = GetRandomAnswer();
|
||||||
var model = new ContactModel {
|
var model = new ContactModel {
|
||||||
|
@ -4,9 +4,9 @@ using System.Web.Mvc;
|
|||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
using Microsoft.Practices.Unity;
|
using Microsoft.Practices.Unity;
|
||||||
using Portoa.Logging;
|
using Portoa.Logging;
|
||||||
using Portoa.Persistence;
|
|
||||||
using Portoa.Web;
|
using Portoa.Web;
|
||||||
using Portoa.Web.Models;
|
using Portoa.Web.Models;
|
||||||
|
using Portoa.Web.Security;
|
||||||
using Portoa.Web.Unity;
|
using Portoa.Web.Unity;
|
||||||
using UnityGenerics;
|
using UnityGenerics;
|
||||||
using VideoGameQuotes.Api;
|
using VideoGameQuotes.Api;
|
||||||
@ -40,13 +40,18 @@ namespace VideoGameQuotes.Web {
|
|||||||
.RegisterType<ICurrentUserProvider, SessionBasedUserProvider>()
|
.RegisterType<ICurrentUserProvider, SessionBasedUserProvider>()
|
||||||
.RegisterType<IsValidUserAttribute>(new InjectionProperty<IsValidUserAttribute>(attr => attr.UserProvider))
|
.RegisterType<IsValidUserAttribute>(new InjectionProperty<IsValidUserAttribute>(attr => attr.UserProvider))
|
||||||
.RegisterType<IUserService, UserService>()
|
.RegisterType<IUserService, UserService>()
|
||||||
|
.RegisterType<IAdministrationService, AdministrationService>()
|
||||||
.RegisterType<IQuoteService, QuoteService>()
|
.RegisterType<IQuoteService, QuoteService>()
|
||||||
.RegisterType<IApiService, ApiService>()
|
.RegisterType<IApiService, ApiService>()
|
||||||
|
.RegisterType<IAuthenticationService, FormsAuthenticationService>()
|
||||||
.RegisterType<IQuoteSearcher, LuceneQuoteSearcher>()
|
.RegisterType<IQuoteSearcher, LuceneQuoteSearcher>()
|
||||||
.RegisterType<ISearchIndexLocator, SearchIndexLocator>(
|
.RegisterType<ISearchIndexLocator, SearchIndexLocator>(new ContainerControlledLifetimeManager(), new InjectionFactory(CreateIndexLocator))
|
||||||
new ContainerControlledLifetimeManager(),
|
.RegisterType<IUserRepository, UserRepository>();
|
||||||
new InjectionFactory(container => new SearchIndexLocator(((NameValueCollection)ConfigurationManager.GetSection("vgquotes"))["luceneIndexDirectory"]))
|
}
|
||||||
).RegisterType<IUserRepository, UserRepository>();
|
|
||||||
|
private static SearchIndexLocator CreateIndexLocator(IUnityContainer container) {
|
||||||
|
var indexDirectory = ((NameValueCollection)ConfigurationManager.GetSection("vgquotes"))["luceneIndexDirectory"];
|
||||||
|
return new SearchIndexLocator(indexDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AfterStartUp() {
|
protected override void AfterStartUp() {
|
||||||
@ -60,8 +65,13 @@ namespace VideoGameQuotes.Web {
|
|||||||
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
||||||
routes.IgnoreRoute("media/{*anything}");
|
routes.IgnoreRoute("media/{*anything}");
|
||||||
|
|
||||||
|
//bullshit route so that RenderAction works
|
||||||
|
routes.MapRoute("mainmenu", "home/mainmenu", new { controller = "Home", action = "MainMenu" });
|
||||||
|
|
||||||
|
routes.MapRoute("admin", "admin/{action}", new { controller = "Admin", action = "Index" });
|
||||||
|
|
||||||
routes.MapRoute("api", "api/{action}/{id}/{*criteria}", new { controller = "Api" }, new { action = "game|system|category|publisher|quote", id = @"\d+|all" });
|
routes.MapRoute("api", "api/{action}/{id}/{*criteria}", new { controller = "Api" }, new { action = "game|system|category|publisher|quote", id = @"\d+|all" });
|
||||||
routes.MapRoute("home", "{action}", new { controller = "Home", action = "Index" }, new { action = "about|contact" });
|
routes.MapRoute("home", "{action}", new { controller = "Home", action = "Index" }, new { action = "about|contact|login|logout" });
|
||||||
routes.MapRoute("best", "best/{start}-{end}/", new { controller = "Quote", action = "Best" }, new { start = @"\d+", end = @"\d+" });
|
routes.MapRoute("best", "best/{start}-{end}/", new { controller = "Quote", action = "Best" }, new { start = @"\d+", end = @"\d+" });
|
||||||
routes.MapRoute("browse", "browse/{*qualifiers}", new { controller = "Quote", action = "Browse" });
|
routes.MapRoute("browse", "browse/{*qualifiers}", new { controller = "Quote", action = "Browse" });
|
||||||
routes.MapRoute("search", "search/{*searchQuery}", new { controller = "Quote", action = "Search" });
|
routes.MapRoute("search", "search/{*searchQuery}", new { controller = "Quote", action = "Search" });
|
||||||
|
9
Src/VideoGameQuotes.Web/Models/ChangePasswordModel.cs
Normal file
9
Src/VideoGameQuotes.Web/Models/ChangePasswordModel.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace VideoGameQuotes.Web.Models {
|
||||||
|
public class ChangePasswordModel {
|
||||||
|
[Required, DisplayName("New password")]
|
||||||
|
public string Password { get; set; }
|
||||||
|
}
|
||||||
|
}
|
7
Src/VideoGameQuotes.Web/Models/MainMenuModel.cs
Normal file
7
Src/VideoGameQuotes.Web/Models/MainMenuModel.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
using VideoGameQuotes.Api;
|
||||||
|
|
||||||
|
namespace VideoGameQuotes.Web.Models {
|
||||||
|
public class MainMenuModel {
|
||||||
|
public User User { get; set; }
|
||||||
|
}
|
||||||
|
}
|
22
Src/VideoGameQuotes.Web/Services/AdministrationService.cs
Normal file
22
Src/VideoGameQuotes.Web/Services/AdministrationService.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using Portoa.Persistence;
|
||||||
|
using VideoGameQuotes.Api;
|
||||||
|
using VideoGameQuotes.Api.Persistence;
|
||||||
|
|
||||||
|
namespace VideoGameQuotes.Web.Services {
|
||||||
|
public interface IAdministrationService {
|
||||||
|
User SaveUser(User user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AdministrationService : IAdministrationService {
|
||||||
|
private readonly IUserRepository userRepository;
|
||||||
|
|
||||||
|
public AdministrationService(IUserRepository userRepository) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
|
public User SaveUser(User user) {
|
||||||
|
return userRepository.Save(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
using System.Web.Security;
|
||||||
|
using Portoa.Persistence;
|
||||||
|
using Portoa.Web.Security;
|
||||||
|
using Portoa.Web.Session;
|
||||||
|
using VideoGameQuotes.Api.Persistence;
|
||||||
|
|
||||||
|
namespace VideoGameQuotes.Web.Services {
|
||||||
|
public class FormsAuthenticationService : IAuthenticationService {
|
||||||
|
private readonly IUserRepository userRepository;
|
||||||
|
private readonly ISessionStore sessionStore;
|
||||||
|
|
||||||
|
public FormsAuthenticationService(IUserRepository userRepository, ISessionStore sessionStore) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
this.sessionStore = sessionStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
|
public void Login(string username) {
|
||||||
|
FormsAuthentication.SetAuthCookie(username, true);
|
||||||
|
sessionStore["user"] = userRepository.FindByUsername(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Logout() {
|
||||||
|
FormsAuthentication.SignOut();
|
||||||
|
sessionStore["user"] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
|
public bool IsValid(string username, string password) {
|
||||||
|
var user = userRepository.FindByUsername(username);
|
||||||
|
return user != null && user.VerifyPassword(password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -84,11 +84,14 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Controllers\AdminController.cs" />
|
||||||
<Compile Include="Controllers\ApiController.cs" />
|
<Compile Include="Controllers\ApiController.cs" />
|
||||||
<Compile Include="Controllers\HomeController.cs" />
|
<Compile Include="Controllers\HomeController.cs" />
|
||||||
<Compile Include="Models\ApiModel.cs" />
|
<Compile Include="Models\ApiModel.cs" />
|
||||||
<Compile Include="Models\BrowseModel.cs" />
|
<Compile Include="Models\BrowseModel.cs" />
|
||||||
<Compile Include="Models\BrowseModelBinder.cs" />
|
<Compile Include="Models\BrowseModelBinder.cs" />
|
||||||
|
<Compile Include="Models\ChangePasswordModel.cs" />
|
||||||
|
<Compile Include="Models\MainMenuModel.cs" />
|
||||||
<Compile Include="Models\QualifiedBrowseModel.cs" />
|
<Compile Include="Models\QualifiedBrowseModel.cs" />
|
||||||
<Compile Include="Models\PagedQuoteCollectionModel.cs" />
|
<Compile Include="Models\PagedQuoteCollectionModel.cs" />
|
||||||
<Compile Include="Models\QuoteCollectionModel.cs" />
|
<Compile Include="Models\QuoteCollectionModel.cs" />
|
||||||
@ -96,6 +99,8 @@
|
|||||||
<Compile Include="Models\ReportModel.cs" />
|
<Compile Include="Models\ReportModel.cs" />
|
||||||
<Compile Include="Models\SearchModel.cs" />
|
<Compile Include="Models\SearchModel.cs" />
|
||||||
<Compile Include="Models\VoteModel.cs" />
|
<Compile Include="Models\VoteModel.cs" />
|
||||||
|
<Compile Include="Services\AdministrationService.cs" />
|
||||||
|
<Compile Include="Services\FormsAuthenticationService.cs" />
|
||||||
<Compile Include="Validation\NonEmptyText.cs" />
|
<Compile Include="Validation\NonEmptyText.cs" />
|
||||||
<Compile Include="Security\IsValidUserAttribute.cs" />
|
<Compile Include="Security\IsValidUserAttribute.cs" />
|
||||||
<Compile Include="Controllers\QuoteController.cs" />
|
<Compile Include="Controllers\QuoteController.cs" />
|
||||||
@ -123,7 +128,11 @@
|
|||||||
<Content Include="media\css\reset.css" />
|
<Content Include="media\css\reset.css" />
|
||||||
<Content Include="media\images\favicon.png" />
|
<Content Include="media\images\favicon.png" />
|
||||||
<Content Include="media\images\search.png" />
|
<Content Include="media\images\search.png" />
|
||||||
|
<Content Include="media\js\jquery.cookie.js" />
|
||||||
<Content Include="media\js\vgquotes.js" />
|
<Content Include="media\js\vgquotes.js" />
|
||||||
|
<Content Include="Views\Admin\Index.aspx" />
|
||||||
|
<Content Include="Views\Admin\Password.aspx" />
|
||||||
|
<Content Include="Views\Admin\PasswordSuccessfullyChanged.aspx" />
|
||||||
<Content Include="Views\Home\About.aspx" />
|
<Content Include="Views\Home\About.aspx" />
|
||||||
<Content Include="Views\Home\Contact.aspx" />
|
<Content Include="Views\Home\Contact.aspx" />
|
||||||
<Content Include="Views\Home\ContactSuccess.aspx" />
|
<Content Include="Views\Home\ContactSuccess.aspx" />
|
||||||
@ -139,6 +148,7 @@
|
|||||||
<Content Include="Views\Quote\Submit.aspx" />
|
<Content Include="Views\Quote\Submit.aspx" />
|
||||||
<Content Include="Views\Shared\ExceptionView.ascx" />
|
<Content Include="Views\Shared\ExceptionView.ascx" />
|
||||||
<Content Include="Views\Shared\Forbidden.aspx" />
|
<Content Include="Views\Shared\Forbidden.aspx" />
|
||||||
|
<Content Include="Views\Shared\MainMenu.ascx" />
|
||||||
<Content Include="Views\Shared\NotFound.aspx" />
|
<Content Include="Views\Shared\NotFound.aspx" />
|
||||||
<Content Include="Views\Shared\NotFoundContent.ascx" />
|
<Content Include="Views\Shared\NotFoundContent.ascx" />
|
||||||
<Content Include="Views\Shared\RecursiveExceptionView.ascx" />
|
<Content Include="Views\Shared\RecursiveExceptionView.ascx" />
|
||||||
|
12
Src/VideoGameQuotes.Web/Views/Admin/Index.aspx
Normal file
12
Src/VideoGameQuotes.Web/Views/Admin/Index.aspx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Views/Shared/Site.Master" %>
|
||||||
|
<asp:Content runat="server" ID="Title" ContentPlaceHolderID="TitleContent">Admin</asp:Content>
|
||||||
|
<asp:Content runat="server" ID="Main" ContentPlaceHolderID="MainContent">
|
||||||
|
<h2>Site Administration</h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><%= Html.ActionLink("Create admin", "create", "admin") %></li>
|
||||||
|
<li><%= Html.ActionLink("Change password", "password", "admin") %></li>
|
||||||
|
<li><%= Html.ActionLink("View reports", "reports", "admin") %></li>
|
||||||
|
<li><%= Html.ActionLink("Manage users", "users", "admin") %></li>
|
||||||
|
</ul>
|
||||||
|
</asp:Content>
|
16
Src/VideoGameQuotes.Web/Views/Admin/Password.aspx
Normal file
16
Src/VideoGameQuotes.Web/Views/Admin/Password.aspx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<VideoGameQuotes.Web.Models.ChangePasswordModel>" MasterPageFile="~/Views/Shared/Site.Master" %>
|
||||||
|
<%@ Import Namespace="Portoa.Web.Util" %>
|
||||||
|
<asp:Content runat="server" ID="Title" ContentPlaceHolderID="TitleContent">Change Password</asp:Content>
|
||||||
|
<asp:Content runat="server" ID="Main" ContentPlaceHolderID="MainContent">
|
||||||
|
<% using (Html.BeginForm()) { %>
|
||||||
|
<p>
|
||||||
|
<%= Html.LabelFor(model => model.Password) %>
|
||||||
|
<br />
|
||||||
|
<%= Html.PasswordFor(model => model.Password) %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= Html.Submit("Change Password") %>
|
||||||
|
</p>
|
||||||
|
<% } %>
|
||||||
|
</asp:Content>
|
@ -0,0 +1,11 @@
|
|||||||
|
<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Views/Shared/Site.Master" %>
|
||||||
|
<asp:Content runat="server" ID="Title" ContentPlaceHolderID="TitleContent">Password Successfully Changed</asp:Content>
|
||||||
|
<asp:Content runat="server" ID="Main" ContentPlaceHolderID="MainContent">
|
||||||
|
<p>
|
||||||
|
Your password has been successfully changed.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= Html.ActionLink("Administer more stuff", "index", "admin") %>
|
||||||
|
</p>
|
||||||
|
</asp:Content>
|
16
Src/VideoGameQuotes.Web/Views/Shared/MainMenu.ascx
Normal file
16
Src/VideoGameQuotes.Web/Views/Shared/MainMenu.ascx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<VideoGameQuotes.Web.Models.MainMenuModel>" %>
|
||||||
|
<%@ Import Namespace="VideoGameQuotes.Api" %>
|
||||||
|
|
||||||
|
<li><%= Html.ActionLink("Recent", "recent", "Quote", null, new { title = "View most recently submitted quotes" })%></li>
|
||||||
|
<li><%= Html.RouteLink("Best", "quote", new { action = "best" }, new { title = "View the top rated quotes" })%></li>
|
||||||
|
<li><%= Html.ActionLink("Browse", "browse", "Quote", new { qualifiers = "" }, new { title = "Browse the quote database" })%></li>
|
||||||
|
<li><%= Html.ActionLink("Random", "random", "Quote", null, new { title = "View a random quote" })%></li>
|
||||||
|
<li><%= Html.ActionLink("Submit", "submit", "Quote", null, new { title = "Submit a new quote" }) %></li>
|
||||||
|
<li><%= Html.ActionLink("About", "about", "Home", null, new { title = "About the site" })%></li>
|
||||||
|
<% if (Model.User != null && Model.User.Group >= UserGroup.Admin) { %>
|
||||||
|
<li><%= Html.ActionLink("Admin", "index", "admin", null, new { title = "Perform administrative tasks" }) %></li>
|
||||||
|
<% } %>
|
||||||
|
<li class="searchbox">
|
||||||
|
<%= Html.TextBox("searchQuery", null, new { id = "search-query" })%>
|
||||||
|
<img src="/media/images/search.png" alt="search" title="search quotes" id="search-submit" />
|
||||||
|
</li>
|
@ -17,21 +17,12 @@
|
|||||||
<div id="header">
|
<div id="header">
|
||||||
<div class="content-container">
|
<div class="content-container">
|
||||||
<div id="logo">
|
<div id="logo">
|
||||||
<h1>Video Game Quotes</h1>
|
<h1><%= Html.ActionLink("Video Game Quotes", "Index", "Home") %></h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="main-menu">
|
<div id="main-menu">
|
||||||
<ul class="clearfix menu">
|
<ul class="clearfix menu">
|
||||||
<li><%= Html.ActionLink("Recent", "recent", "Quote", null, new { title = "View most recently submitted quotes" })%></li>
|
<% Html.RenderAction("MainMenu", "Home"); %>
|
||||||
<li><%= Html.RouteLink("Best", "quote", new { action = "best" }, new { title = "View the top rated quotes" })%></li>
|
|
||||||
<li><%= Html.ActionLink("Browse", "browse", "Quote", new { qualifiers = "" }, new { title = "Browse the quote database" })%></li>
|
|
||||||
<li><%= Html.ActionLink("Random", "random", "Quote", null, new { title = "View a random quote" })%></li>
|
|
||||||
<li><%= Html.ActionLink("Submit", "submit", "Quote", null, new { title = "Submit a new quote" }) %></li>
|
|
||||||
<li><%= Html.ActionLink("About", "about", "Home", null, new { title = "About the site" })%></li>
|
|
||||||
<li class="searchbox">
|
|
||||||
<%= Html.TextBox("searchQuery", null, new { id = "search-query" })%>
|
|
||||||
<img src="/media/images/search.png" alt="search" title="search quotes" id="search-submit" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -46,12 +37,17 @@
|
|||||||
<div id="footer">
|
<div id="footer">
|
||||||
<div class="content-container">
|
<div class="content-container">
|
||||||
© <%= DateTime.UtcNow.Year %> <a href="http://tommymontgomery.com/" title="Who is this man?">Tommy Montgomery</a><br />
|
© <%= DateTime.UtcNow.Year %> <a href="http://tommymontgomery.com/" title="Who is this man?">Tommy Montgomery</a><br />
|
||||||
If you steal something, I’ll murder your family.
|
<% if (!Request.IsAuthenticated) { %>
|
||||||
|
<a href="#" id="login-link">login</a>
|
||||||
|
<% } else { %>
|
||||||
|
<%= Html.ActionLink("logout", "logout", "home", new { redirectUrl = Request.Path }, null)%>
|
||||||
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/media/js/jquery.cookie.js"></script>
|
||||||
<script type="text/javascript" src="/media/js/vgquotes.js"></script>
|
<script type="text/javascript" src="/media/js/vgquotes.js"></script>
|
||||||
<asp:ContentPlaceHolder ID="DeferrableScripts" runat="server" />
|
<asp:ContentPlaceHolder ID="DeferrableScripts" runat="server" />
|
||||||
</body>
|
</body>
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
<system.web>
|
<system.web>
|
||||||
<!-- disables input validation for requests -->
|
<!-- disables input validation for requests -->
|
||||||
<httpRuntime requestValidationMode="2.0"/>
|
<httpRuntime requestValidationMode="2.0"/>
|
||||||
|
|
||||||
|
<authentication mode="Forms" />
|
||||||
|
|
||||||
<compilation debug="true" targetFramework="4.0">
|
<compilation debug="true" targetFramework="4.0">
|
||||||
<assemblies>
|
<assemblies>
|
||||||
|
@ -129,6 +129,15 @@ ul.menu li {
|
|||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#logo a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login-dialog {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
#search-submit {
|
#search-submit {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
50
Src/VideoGameQuotes.Web/media/js/jquery.cookie.js
Normal file
50
Src/VideoGameQuotes.Web/media/js/jquery.cookie.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* Cookie plugin
|
||||||
|
*
|
||||||
|
* Copyright (c) 2006 Klaus Hartl (stilbuero.de)
|
||||||
|
* Dual licensed under the MIT and GPL licenses:
|
||||||
|
* http://www.opensource.org/licenses/mit-license.php
|
||||||
|
* http://www.gnu.org/licenses/gpl.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
jQuery.cookie = function(name, value, options) {
|
||||||
|
if (typeof value != 'undefined') { // name and value given, set cookie
|
||||||
|
options = options || {};
|
||||||
|
if (value === null) {
|
||||||
|
value = '';
|
||||||
|
options.expires = -1;
|
||||||
|
}
|
||||||
|
var expires = '';
|
||||||
|
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
|
||||||
|
var date;
|
||||||
|
if (typeof options.expires == 'number') {
|
||||||
|
date = new Date();
|
||||||
|
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
|
||||||
|
} else {
|
||||||
|
date = options.expires;
|
||||||
|
}
|
||||||
|
expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
|
||||||
|
}
|
||||||
|
// CAUTION: Needed to parenthesize options.path and options.domain
|
||||||
|
// in the following expressions, otherwise they evaluate to undefined
|
||||||
|
// in the packed version for some reason...
|
||||||
|
var path = options.path ? '; path=' + (options.path) : '';
|
||||||
|
var domain = options.domain ? '; domain=' + (options.domain) : '';
|
||||||
|
var secure = options.secure ? '; secure' : '';
|
||||||
|
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
|
||||||
|
} else { // only name given, get cookie
|
||||||
|
var cookieValue = null;
|
||||||
|
if (document.cookie && document.cookie != '') {
|
||||||
|
var cookies = document.cookie.split(';');
|
||||||
|
for (var i = 0; i < cookies.length; i++) {
|
||||||
|
var cookie = jQuery.trim(cookies[i]);
|
||||||
|
// Does this cookie string begin with the name we want?
|
||||||
|
if (cookie.substring(0, name.length + 1) == (name + '=')) {
|
||||||
|
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cookieValue;
|
||||||
|
}
|
||||||
|
};
|
@ -4,7 +4,39 @@
|
|||||||
this.css("top", ($(window).height() - this.height()) / 2 + $(window).scrollTop() + "px");
|
this.css("top", ($(window).height() - this.height()) / 2 + $(window).scrollTop() + "px");
|
||||||
this.css("left", ($(window).width() - this.width()) / 2 + $(window).scrollLeft() + "px");
|
this.css("left", ($(window).width() - this.width()) / 2 + $(window).scrollLeft() + "px");
|
||||||
return this;
|
return this;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
$.vgquotes = {
|
||||||
|
refresh: function() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
var refreshCookie = "vgquotes.refreshFragment";
|
||||||
|
|
||||||
|
var refresh = function() {
|
||||||
|
var url = window.location.href;
|
||||||
|
var fragmentPosition = url.lastIndexOf("#");
|
||||||
|
if (fragmentPosition >= 0) {
|
||||||
|
if (fragmentPosition !== url.length - 1) {
|
||||||
|
$.cookie(refreshCookie, url.substring(fragmentPosition + 1)); //store the fragment in a cookie
|
||||||
|
}
|
||||||
|
url = url.substring(0, fragmentPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.href = url;
|
||||||
|
};
|
||||||
|
|
||||||
|
var applyFragmentFromCookie = function() {
|
||||||
|
var fragment = $.cookie(refreshCookie);
|
||||||
|
if (fragment !== null) {
|
||||||
|
window.location.href += "#" + fragment;
|
||||||
|
$.cookie(refreshCookie, null); //delete cookie
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$(document).ready(applyFragmentFromCookie);
|
||||||
|
$.vgquotes.refresh = refresh;
|
||||||
|
}());
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
(function(){
|
(function(){
|
||||||
@ -145,5 +177,50 @@
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//login stuff
|
||||||
|
(function(){
|
||||||
|
var showLoginForm = function() {
|
||||||
|
var $dialog = $("#login-dialog");
|
||||||
|
if ($dialog.length > 0) {
|
||||||
|
$dialog.remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $usernameInput = $("<input/>").attr({ type: "text", id: "login-username" });
|
||||||
|
var $passwordInput = $("<input/>").attr({ type: "password", id: "login-password" });
|
||||||
|
var $submit = $("<input/>").attr("type", "submit").css("display", "none");
|
||||||
|
|
||||||
|
var $form = $("<form/>").attr({ method: "post", action: "/login" }).submit(function() {
|
||||||
|
$.ajax("/login", {
|
||||||
|
type: "POST",
|
||||||
|
data: { username: $usernameInput.val(), password: $passwordInput.val() },
|
||||||
|
success: function(data, status, $xhr) {
|
||||||
|
if (data.Error !== null) {
|
||||||
|
alert(data.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.vgquotes.refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
var $dialog = $("<div/>").addClass("dialog").attr("id", "login-dialog");
|
||||||
|
|
||||||
|
$form.append($usernameInput).append($passwordInput).append($submit);
|
||||||
|
$dialog.append($form);
|
||||||
|
|
||||||
|
$("body").append($dialog);
|
||||||
|
$dialog.center();
|
||||||
|
$usernameInput.focus();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$("#login-link").click(showLoginForm);
|
||||||
|
}());
|
||||||
});
|
});
|
||||||
}(jQuery, window));
|
}(jQuery, window));
|
Loading…
Reference in New Issue
Block a user