2017-06-23 14:08:58 +10:00
using System.Collections.Generic ;
2013-11-12 18:07:10 +11:00
using System.Net ;
using System.Text ;
using System.Threading.Tasks ;
using System.Web.Http ;
using System.Web.Security ;
using AutoMapper ;
using Umbraco.Core.Configuration ;
2017-06-23 14:08:58 +10:00
using Umbraco.Core.Services ;
2013-11-12 18:07:10 +11:00
using Umbraco.Web.Models ;
using Umbraco.Web.Models.ContentEditing ;
using Umbraco.Web.Models.Mapping ;
using Umbraco.Web.Mvc ;
using Umbraco.Web.UI ;
using Umbraco.Web.WebApi ;
using umbraco ;
using legacyUser = umbraco . BusinessLogic . User ;
using System.Net.Http ;
using System.Collections.Specialized ;
2017-06-27 19:55:03 +10:00
using Umbraco.Core.Security ;
using Umbraco.Web.WebApi.Filters ;
2013-11-12 18:07:10 +11:00
using Constants = Umbraco . Core . Constants ;
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
{
2017-06-27 19:55:03 +10:00
/// <summary>
/// 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>
/// <param name="newPassword"></param>
/// <returns></returns>
/// <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 )
{
var result = await UserManager . AddPasswordAsync ( Security . GetUserId ( ) , newPassword ) ;
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 ;
}
2017-07-25 20:51:58 +10:00
[AppendUserModifiedHeader]
2017-06-27 19:55:03 +10:00
[FileUploadCleanupFilter(false)]
public async Task < HttpResponseMessage > PostSetAvatar ( )
{
//borrow the logic from the user controller
return await UsersController . PostSetAvatarInternal ( Request , Services . UserService , ApplicationContext . ApplicationCache . StaticCache , Security . GetUserId ( ) ) ;
}
2013-11-12 18:07:10 +11:00
/// <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-07-20 12:53:09 +10:00
public async Task < ModelWithNotifications < string > > PostChangePassword ( ChangingPasswordModel data )
2013-11-12 18:07:10 +11:00
{
2017-09-15 16:34:51 +02:00
var passwordChanger = new PasswordChanger ( Logger , Services . UserService , UmbracoContext . HttpContext ) ;
2017-09-04 22:03:03 +10:00
var passwordChangeResult = await passwordChanger . ChangePasswordWithIdentityAsync ( Security . CurrentUser , Security . CurrentUser , data , UserManager ) ;
2017-06-27 19:55:03 +10:00
2013-11-12 18:07:10 +11:00
if ( passwordChangeResult . Success )
{
2017-09-18 16:56:43 +10:00
var userMgr = this . TryGetOwinContext ( ) . Result . GetBackOfficeUserManager ( ) ;
//raise the appropriate event
if ( data . Reset . HasValue & & data . Reset . Value )
{
userMgr . RaisePasswordResetEvent ( Security . CurrentUser . Id ) ;
}
else
{
userMgr . RaisePasswordChangedEvent ( Security . CurrentUser . Id ) ;
}
2013-11-12 18:07:10 +11:00
//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 ) ;
2017-06-23 14:08:58 +10:00
result . AddSuccessNotification ( Services . TextService . Localize ( "user/password" ) , Services . TextService . Localize ( "user/passwordChanged" ) ) ;
2013-11-12 18:07:10 +11:00
return result ;
}
2017-09-04 22:03:03 +10:00
foreach ( var memberName in passwordChangeResult . Result . ChangeError . MemberNames )
{
ModelState . AddModelError ( memberName , passwordChangeResult . Result . ChangeError . ErrorMessage ) ;
}
2013-11-12 18:07:10 +11:00
throw new HttpResponseException ( Request . CreateValidationErrorResponse ( ModelState ) ) ;
}
}
}