public async Task <IActionResult> PostAsync([FromRoute] Guid organizationuuid, [FromBody] MapHiveUser user, string applicationContext = null, [FromQuery] EmailAccount ea = null) { //only owners or admins should be allowed to perform this action var callerId = Cartomatic.Utils.Identity.GetUserGuid(); if (!(UserIsOrgOwner(callerId) || UserIsOrgAdmin(callerId))) { return(NotAllowed()); } //this is an org user, so needs to be flagged as such! user.IsOrgUser = true; user.ParentOrganizationId = organizationuuid; try { //initial email template customization var replacementData = new Dictionary <string, object> { { "UserName", $"{user.GetFullUserName()} ({user.Email})" }, { "Email", user.Email }, { "RedirectUrl", this.GetRequestSource(HttpContext)?.Split('#')[0] } }; var(emailAccount, emailTemplate) = await GetEmailStuffAsync("user_created", applicationContext); //use custom email account if provided if (ea != null && ea.SeemsComplete()) { emailAccount = ea; } //note: //org users and org roles are created against mh meta db! //This is where some env core objects are kept var createdUser = await MapHiveUser.CreateUserAccountAsync(GetDefaultDbContext(), user, EmailSender, emailAccount, emailTemplate?.Prepare(replacementData)); if (createdUser != null) { //user has been created, so now need to add it to the org with an appropriate role await this.OrganizationContext.AddOrganizationUserAsync(GetDefaultDbContext(), createdUser.User); //at this stage user should have had a member role assigned //mkae sure to assign the one that has been asked for if (user.OrganizationRole.HasValue && user.OrganizationRole != Organization.OrganizationRole.Member) { await this.OrganizationContext.ChangeOrganizationUserRoleAsync(GetDefaultDbContext(), user); } return(Ok(createdUser.User)); } return(NotFound()); } catch (Exception ex) { return(this.HandleException(ex)); } }
public async Task <IActionResult> PassResetRequestAsync([FromBody] PassResetRequestInput input, [FromRoute] string app = null, [FromQuery] EmailAccount ea = null) { //Note: basically this is a pass reset request, so NO need to inform a potential attacker about exceptions - always return ok! if (input == null) { return(BadRequest()); } try { var requestPassResetOutput = await Auth.RequestPassResetAsync(input.Email); var(emailAccount, emailTemplate) = await GetEmailStuffAsync("pass_reset_request", app); //use custom email account if provided if (ea != null && ea.SeemsComplete()) { emailAccount = ea; } //basically need to send an email the verification key has expired and send a new one var user = await GetDefaultDbContext().Users.FirstOrDefaultAsync(u => u.Email == input.Email); //since got here and email off mbr, user should not be null, but just in a case... if (user == null) { //return BadRequest(); return(Ok()); } //prepare the email template tokens var tokens = new Dictionary <string, object> { { "UserName", $"{user.GetFullUserName()} ({user.Email})" }, { "Email", user.Email }, { "RedirectUrl", this.GetRequestSource(HttpContext).Split('#')[0] }, { "VerificationKey", requestPassResetOutput.VerificationKey } }; //prepare and send the email EmailSender.Send(emailAccount, emailTemplate.Prepare(tokens), user.Email); return(Ok()); } catch //(Exception ex) { //return HandleException(ex); return(Ok()); } }
public async Task <IActionResult> ResendActivationLinkAsync([FromRoute] Guid uuid, [FromRoute] string app = null, [FromQuery] EmailAccount ea = null) { try { var dbCtx = GetDefaultDbContext(); //grab a user first var u = await new MapHiveUser().ReadAsync(dbCtx, uuid); if (u == null) { return(BadRequest("Unknown user.")); } //and make sure there is point in resending a link if (u.IsAccountVerified) { return(BadRequest("User has already activated his account.")); } //get the request lang without re-setting a cookie. will be used to get a proper email template later var(emailAccount, emailTemplate) = await GetEmailStuffAsync("user_created", app); //use custom email account if provided if (ea != null && ea.SeemsComplete()) { emailAccount = ea; } var initialEmailData = new Dictionary <string, object> { { "UserName", $"{u.GetFullUserName()} ({u.Email})" }, { "Email", u.Email }, { "RedirectUrl", (GetRequestSource(HttpContext) ?? string.Empty).Split('#')[0] } }; await u.ResendActivationLinkAsync( dbCtx, EmailSender, emailAccount, emailTemplate.Prepare(initialEmailData) ); return(Ok()); } catch (Exception ex) { return(this.HandleException(ex)); } }
public async Task <IActionResult> ActivateAccountAsync([FromBody] AccountActivationInput activationInput, [FromRoute] string app = null, [FromQuery] EmailAccount ea = null) { try { //work out user id from token var activationOutput = await Auth.ActivateAccountAsync(activationInput.VerificationKey); //aspnet identity has not found a user, so bad, bad, bad request it was if (activationOutput.UnknownUser) { return(BadRequest()); } //basically need to send an email the verification key has expired and send a new one var user = await GetDefaultDbContext().Users.FirstOrDefaultAsync(u => u.Uuid == Auth.ExtractIdFromMergedToken(activationInput.VerificationKey)); //since got an email off mbr, user should not be null, but just in a case... if (user == null) { return(BadRequest()); } //need to resend email with new verification key, as the previous one was stale if (activationOutput.VerificationKeyStale) { var(emailAccount, emailTemplate) = await GetEmailStuffAsync("activate_account_stale", app); //use custom email account if provided if (ea != null && ea.SeemsComplete()) { emailAccount = ea; } //prepare the email template tokens var tokens = new Dictionary <string, object> { { "UserName", $"{user.GetFullUserName()} ({user.Email})" }, { "Email", user.Email }, { "RedirectUrl", this.GetRequestSource(HttpContext).Split('#')[0] }, { "VerificationKey", activationOutput.VerificationKey }, { "InitialPassword", "" } }; //prepare and send the email EmailSender.Send(emailAccount, emailTemplate.Prepare(tokens), user.Email); } //going to save, so need to impersonate Cartomatic.Utils.Identity.ImpersonateGhostUser(); //mark user rec as activated if (activationOutput.Success) { user.IsAccountVerified = true; Cartomatic.Utils.Identity.ImpersonateUserViaHttpContext(user.Uuid); //nee to impersonate, as otherwise dbctx will fail to save changes! await user.UpdateAsync(GetDefaultDbContext()); } //wipe out some potentially sensitive data activationOutput.Email = null; activationOutput.VerificationKey = null; return(Ok(activationOutput)); } catch (Exception ex) { return(HandleException(ex)); } }