namespace MvcRelyingParty.Controllers { using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net; using System.Security.Principal; using System.Web; using System.Web.Mvc; using System.Web.Security; using System.Web.UI; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.Messages; using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; using DotNetOpenAuth.OpenId.RelyingParty; using MvcRelyingParty.Models; using RelyingPartyLogic; [HandleError] public class AccountController : Controller { [Authorize] public ActionResult Edit() { return View(GetAccountInfoModel()); } /// /// Updates the user's account information. /// /// The first name. /// The last name. /// The email address. /// An updated view showing the new profile. /// /// This action accepts PUT because this operation is idempotent in nature. /// [Authorize, AcceptVerbs(HttpVerbs.Put), ValidateAntiForgeryToken] public ActionResult Update(string firstName, string lastName, string emailAddress) { Database.LoggedInUser.FirstName = firstName; Database.LoggedInUser.LastName = lastName; if (Database.LoggedInUser.EmailAddress != emailAddress) { Database.LoggedInUser.EmailAddress = emailAddress; Database.LoggedInUser.EmailAddressVerified = false; } return PartialView("EditFields", GetAccountInfoModel()); } [Authorize] public ActionResult Authorize() { var pendingRequest = OAuthServiceProvider.AuthorizationServer.ReadAuthorizationRequest(); if (pendingRequest == null) { return RedirectToAction("Edit"); } var requestingClient = Database.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier); // Consider auto-approving if safe to do so. if (((OAuthAuthorizationServer)OAuthServiceProvider.AuthorizationServer.AuthorizationServer).CanBeAutoApproved(pendingRequest)) { OAuthServiceProvider.AuthorizationServer.ApproveAuthorizationRequest(pendingRequest, HttpContext.User.Identity.Name); } var model = new AccountAuthorizeModel { ClientApp = requestingClient.Name, Scope = pendingRequest.Scope, }; return View(model); } [Authorize, AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken] public ActionResult Authorize(bool isApproved) { var getRequest = new HttpRequestInfo("GET", this.Request.Url, this.Request.RawUrl, new WebHeaderCollection(), null); var pendingRequest = OAuthServiceProvider.AuthorizationServer.ReadAuthorizationRequest(getRequest); var requestingClient = Database.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier); IDirectedProtocolMessage response; if (isApproved) { Database.LoggedInUser.ClientAuthorizations.Add( new ClientAuthorization() { Client = requestingClient, Scope = string.Join(" ", pendingRequest.Scope.ToArray()), User = Database.LoggedInUser, CreatedOnUtc = DateTime.UtcNow.CutToSecond(), }); response = OAuthServiceProvider.AuthorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, HttpContext.User.Identity.Name); } else { response = OAuthServiceProvider.AuthorizationServer.PrepareRejectAuthorizationRequest(pendingRequest); } return OAuthServiceProvider.AuthorizationServer.Channel.PrepareResponse(response).AsActionResult(); } [Authorize, AcceptVerbs(HttpVerbs.Delete)] // ValidateAntiForgeryToken would be GREAT here, but it's not a FORM POST operation so that doesn't work. public ActionResult RevokeAuthorization(int authorizationId) { var tokenEntity = Database.DataContext.ClientAuthorizations.Where(auth => auth.User.UserId == Database.LoggedInUser.UserId && auth.AuthorizationId == authorizationId).FirstOrDefault(); if (tokenEntity == null) { throw new ArgumentOutOfRangeException("id", "The logged in user does not have a token with this name to revoke."); } Database.DataContext.DeleteObject(tokenEntity); Database.DataContext.SaveChanges(); // make changes now so the model we fill up reflects the change return PartialView("AuthorizedApps", GetAccountInfoModel()); } private static AccountInfoModel GetAccountInfoModel() { var authorizedApps = from auth in Database.DataContext.ClientAuthorizations where auth.User.UserId == Database.LoggedInUser.UserId select new AccountInfoModel.AuthorizedApp { AppName = auth.Client.Name, AuthorizationId = auth.AuthorizationId, Scope = auth.Scope }; Database.LoggedInUser.AuthenticationTokens.Load(); var model = new AccountInfoModel { FirstName = Database.LoggedInUser.FirstName, LastName = Database.LoggedInUser.LastName, EmailAddress = Database.LoggedInUser.EmailAddress, AuthorizedApps = authorizedApps.ToList(), AuthenticationTokens = Database.LoggedInUser.AuthenticationTokens.ToList(), }; return model; } } }