Files
Umbraco-CMS/src/Umbraco.Web/Editors/AuthenticationController.cs

148 lines
6.0 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Helpers;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Security;
2013-08-26 11:28:15 +10:00
using AutoMapper;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.Membership;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Models.Mapping;
using Umbraco.Web.Mvc;
using Umbraco.Core.Security;
using Umbraco.Web.Security;
using Umbraco.Web.WebApi;
using Umbraco.Web.WebApi.Filters;
using umbraco.providers;
namespace Umbraco.Web.Editors
{
/// <summary>
/// The API controller used for editing content
/// </summary>
[PluginController("UmbracoApi")]
[ValidationFilter]
[AngularJsonOnlyConfiguration]
public class AuthenticationController : UmbracoApiController
{
/// <summary>
/// This is a special method that will return the current users' remaining session seconds, the reason
/// it is special is because this route is ignored in the UmbracoModule so that the auth ticket doesn't get
/// updated with a new timeout.
/// </summary>
/// <returns></returns>
[WebApi.UmbracoAuthorize]
2013-12-03 11:36:17 +11:00
[ValidateAngularAntiForgeryToken]
public double GetRemainingTimeoutSeconds()
{
var httpContextAttempt = TryGetHttpContext();
if (httpContextAttempt.Success)
{
return httpContextAttempt.Result.GetRemainingAuthSeconds();
}
//we need an http context
throw new NotSupportedException("An HttpContext is required for this request");
}
/// <summary>
/// Checks if the current user's cookie is valid and if so returns OK or a 400 (BadRequest)
/// </summary>
/// <returns></returns>
[HttpGet]
public HttpResponseMessage IsAuthenticated()
{
var attempt = UmbracoContext.Security.AuthorizeRequest();
if (attempt == ValidateRequestAttempt.Success)
{
return Request.CreateResponse(HttpStatusCode.OK);
}
//return BadRequest (400), we don't want to return a 401 because that get's intercepted
// by our angular helper because it thinks that we need to re-perform the request once we are
// authorized and we don't want to return a 403 because angular will show a warning msg indicating
// that the user doesn't have access to perform this function, we just want to return a normal invalid msg.
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
/// <summary>
/// Returns the currently logged in Umbraco user
/// </summary>
/// <returns></returns>
/// <remarks>
/// We have the attribute [SetAngularAntiForgeryTokens] applied because this method is called initially to determine if the user
/// is valid before the login screen is displayed. The Auth cookie can be persisted for up to a day but the csrf cookies are only session
/// cookies which means that the auth cookie could be valid but the csrf cookies are no longer there, in that case we need to re-set the csrf cookies.
/// </remarks>
[WebApi.UmbracoAuthorize]
[SetAngularAntiForgeryTokens]
public UserDetail GetCurrentUser()
{
var user = Services.UserService.GetUserById(UmbracoContext.Security.GetUserId());
var result = Mapper.Map<UserDetail>(user);
var httpContextAttempt = TryGetHttpContext();
if (httpContextAttempt.Success)
{
//set their remaining seconds
result.SecondsUntilTimeout = httpContextAttempt.Result.GetRemainingAuthSeconds();
}
return result;
}
/// <summary>
/// Logs a user in
/// </summary>
/// <param name="username"></param>
/// <param name="password"></param>
/// <returns></returns>
2013-12-03 11:36:17 +11:00
[SetAngularAntiForgeryTokens]
public UserDetail PostLogin(string username, string password)
{
if (UmbracoContext.Security.ValidateBackOfficeCredentials(username, password))
{
var user = Security.GetBackOfficeUser(username);
//TODO: Clean up the int cast!
2013-12-03 11:36:17 +11:00
var ticket = UmbracoContext.Security.PerformLogin(user);
var http = this.TryGetHttpContext();
if (http.Success == false)
{
throw new InvalidOperationException("This method requires that an HttpContext be active");
}
http.Result.AuthenticateCurrentRequest(ticket, false);
var result = Mapper.Map<UserDetail>(user);
//set their remaining seconds
2013-12-03 11:36:17 +11:00
result.SecondsUntilTimeout = ticket.GetRemainingAuthSeconds();
return result;
}
//return BadRequest (400), we don't want to return a 401 because that get's intercepted
// by our angular helper because it thinks that we need to re-perform the request once we are
// authorized and we don't want to return a 403 because angular will show a warning msg indicating
// that the user doesn't have access to perform this function, we just want to return a normal invalid msg.
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
/// <summary>
/// Logs the current user out
/// </summary>
/// <returns></returns>
[UmbracoBackOfficeLogout]
[ClearAngularAntiForgeryToken]
2013-12-03 11:36:17 +11:00
[ValidateAngularAntiForgeryToken]
public HttpResponseMessage PostLogout()
{
return Request.CreateResponse(HttpStatusCode.OK);
}
}
}