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

160 lines
6.7 KiB
C#
Raw Normal View History

2018-03-27 10:04:07 +02:00
using System;
using System.Collections;
using System.Net.Http;
2017-09-13 17:35:20 +02:00
using System.Threading.Tasks;
using System.Web.Http;
2017-09-13 17:35:20 +02:00
using AutoMapper;
using Umbraco.Core.Composing;
2017-09-12 16:22:16 +02:00
using Umbraco.Core.Services;
using Umbraco.Web.Models;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
using Umbraco.Web.WebApi;
2018-03-27 10:04:07 +02:00
using System.Linq;
using Newtonsoft.Json;
using Umbraco.Core;
2017-09-12 16:22:16 +02:00
using Umbraco.Core.Security;
using Umbraco.Web.WebApi.Filters;
namespace Umbraco.Web.Editors
{
/// <summary>
/// Controller to back the User.Resource service, used for fetching user data when already authenticated. user.service is currently used for handling authentication
/// </summary>
[PluginController("UmbracoApi")]
public class CurrentUserController : UmbracoAuthorizedJsonController
{
2018-03-27 10:04:07 +02:00
/// <summary>
/// Saves a tour status for the current user
/// </summary>
/// <param name="status"></param>
/// <returns></returns>
public IEnumerable<UserTourStatus> PostSetUserTour(UserTourStatus status)
{
if (status == null) throw new ArgumentNullException("status");
List<UserTourStatus> userTours;
if (Security.CurrentUser.TourData.IsNullOrWhiteSpace())
{
userTours = new List<UserTourStatus> {status};
Security.CurrentUser.TourData = JsonConvert.SerializeObject(userTours);
Services.UserService.Save(Security.CurrentUser);
return userTours;
}
userTours = JsonConvert.DeserializeObject<IEnumerable<UserTourStatus>>(Security.CurrentUser.TourData).ToList();
var found = userTours.FirstOrDefault(x => x.Alias == status.Alias);
if (found != null)
{
//remove it and we'll replace it next
userTours.Remove(found);
}
userTours.Add(status);
Security.CurrentUser.TourData = JsonConvert.SerializeObject(userTours);
Services.UserService.Save(Security.CurrentUser);
return userTours;
}
/// <summary>
/// Returns the user's tours
/// </summary>
/// <returns></returns>
public IEnumerable<UserTourStatus> GetUserTours()
{
if (Security.CurrentUser.TourData.IsNullOrWhiteSpace())
return Enumerable.Empty<UserTourStatus>();
var userTours = JsonConvert.DeserializeObject<IEnumerable<UserTourStatus>>(Security.CurrentUser.TourData);
return userTours;
}
2017-09-12 16:22:16 +02:00
/// <summary>
2017-09-12 16:22:16 +02:00
/// When a user is invited and they click on the invitation link, they will be partially logged in
/// where they can set their username/password
/// </summary>
2017-09-12 16:22:16 +02:00
/// <param name="newPassword"></param>
/// <returns></returns>
2017-09-12 16:22:16 +02:00
/// <remarks>
/// This only works when the user is logged in (partially)
/// </remarks>
[WebApi.UmbracoAuthorize(requireApproval: false)]
[OverrideAuthorization]
public async Task<UserDetail> PostSetInvitedUserPassword([FromBody]string newPassword)
{
2018-03-02 15:48:21 +01:00
var result = await UserManager.AddPasswordAsync(Security.GetUserId().ResultOr(0), newPassword);
2017-09-12 16:22:16 +02:00
if (result.Succeeded == false)
{
//it wasn't successful, so add the change error to the model state, we've name the property alias _umb_password on the form
// so that is why it is being used here.
ModelState.AddModelError(
"value",
string.Join(", ", result.Errors));
throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState));
}
//They've successfully set their password, we can now update their user account to be approved
Security.CurrentUser.IsApproved = true;
Services.UserService.Save(Security.CurrentUser);
//now we can return their full object since they are now really logged into the back office
var userDisplay = Mapper.Map<UserDetail>(Security.CurrentUser);
var httpContextAttempt = TryGetHttpContext();
if (httpContextAttempt.Success)
{
//set their remaining seconds
userDisplay.SecondsUntilTimeout = httpContextAttempt.Result.GetRemainingAuthSeconds();
}
return userDisplay;
}
[AppendUserModifiedHeader]
[FileUploadCleanupFilter(false)]
public async Task<HttpResponseMessage> PostSetAvatar()
{
//borrow the logic from the user controller
2018-03-02 15:48:21 +01:00
return await UsersController.PostSetAvatarInternal(Request, Services.UserService, Current.ApplicationCache.StaticCache, Security.GetUserId().ResultOr(0));
}
/// <summary>
/// Changes the users password
/// </summary>
/// <param name="data"></param>
/// <returns>
/// If the password is being reset it will return the newly reset password, otherwise will return an empty value
/// </returns>
2017-09-12 16:22:16 +02:00
public async Task<ModelWithNotifications<string>> PostChangePassword(ChangingPasswordModel data)
{
2017-09-19 16:46:49 +02:00
var passwordChanger = new PasswordChanger(Logger, Services.UserService, UmbracoContext.HttpContext);
2017-09-19 15:51:47 +02:00
var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(Security.CurrentUser, Security.CurrentUser, data, UserManager);
if (passwordChangeResult.Success)
{
2017-09-19 16:46:49 +02:00
var userMgr = this.TryGetOwinContext().Result.GetBackOfficeUserManager();
2018-03-27 10:04:07 +02:00
//raise the reset event
//TODO: I don't think this is required anymore since from 7.7 we no longer display the reset password checkbox since that didn't make sense.
2017-09-19 16:46:49 +02:00
if (data.Reset.HasValue && data.Reset.Value)
{
userMgr.RaisePasswordResetEvent(Security.CurrentUser.Id);
}
//even if we weren't resetting this, it is the correct value (null), otherwise if we were resetting then it will contain the new pword
var result = new ModelWithNotifications<string>(passwordChangeResult.Result.ResetPassword);
2016-03-11 15:43:34 +01:00
result.AddSuccessNotification(Services.TextService.Localize("user/password"), Services.TextService.Localize("user/passwordChanged"));
return result;
}
2017-09-19 15:51:47 +02:00
foreach (var memberName in passwordChangeResult.Result.ChangeError.MemberNames)
{
ModelState.AddModelError(memberName, passwordChangeResult.Result.ChangeError.ErrorMessage);
}
throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState));
}
}
}