public async Task <ActionResult <UserActionIdentityResult> > RegisterUser([FromBody] OrganizationUserRegistration registration)
        {
            UserActionIdentityResult result;

            TryValidateModel(registration);

            if (ModelState.IsValid)
            {
                //Allow to register new users only within own organization
                var authorizationResult = await _authorizationService.AuthorizeAsync(User, new Organization { Id = registration.OrganizationId }, CanEditOrganizationResourceAuthorizeRequirement.PolicyName);

                if (!authorizationResult.Succeeded)
                {
                    return(Unauthorized());
                }

                var contact = registration.ToContact();
                contact.OrganizationId = registration.OrganizationId;

                var user = registration.User;
                user.Contact = contact;
                user.StoreId = WorkContext.CurrentStore.Id;

                var creatingResult = await _userManager.CreateAsync(user, registration.Password);

                result = UserActionIdentityResult.Instance(creatingResult);
                if (result.Succeeded)
                {
                    user = await _userManager.FindByNameAsync(user.UserName);

                    await _publisher.Publish(new UserRegisteredEvent(WorkContext, user, registration));

                    result.MemberId = user.Id;
                }
            }
            else
            {
                result = UserActionIdentityResult
                         .Failed(ModelState.Values.SelectMany(x => x.Errors)
                                 .Select(x => new IdentityError {
                    Description = x.ErrorMessage
                })
                                 .ToArray());
            }
            return(result);
        }
        public async Task <ActionResult <UserActionIdentityResult> > DeleteUser([FromRoute] string userId)
        {
            //TODO: Authorization check
            var result = UserActionIdentityResult.Success;
            var user   = await _userManager.FindByIdAsync(userId);

            if (user != null)
            {
                var authorizationResult = await _authorizationService.AuthorizeAsync(User, user?.Contact?.Organization, CanEditOrganizationResourceAuthorizeRequirement.PolicyName);

                if (!authorizationResult.Succeeded)
                {
                    return(Unauthorized());
                }

                result = UserActionIdentityResult.Instance(await _userManager.DeleteAsync(user));
                if (result.Succeeded)
                {
                    await _publisher.Publish(new UserDeletedEvent(WorkContext, user));
                }
            }
            return(result);
        }
        public async Task <ActionResult <UserActionIdentityResult> > CreateUserInvitation([FromBody] UsersInvitation invitation)
        {
            var result = UserActionIdentityResult.Success;

            TryValidateModel(invitation);

            if (ModelState.IsValid)
            {
                var organizationId = WorkContext.CurrentUser?.Contact?.Organization?.Id;
                //If it is organization invitation need to check authorization for this action
                if (!string.IsNullOrEmpty(organizationId))
                {
                    var authorizationResult = await _authorizationService.AuthorizeAsync(User, null, SecurityConstants.Permissions.CanInviteUsers);

                    if (!authorizationResult.Succeeded)
                    {
                        return(Unauthorized());
                    }
                }

                foreach (var email in invitation.Emails)
                {
                    var user = await _userManager.FindByEmailAsync(email);

                    if (user == null)
                    {
                        user = new User
                        {
                            UserName = email,
                            StoreId  = WorkContext.CurrentStore.Id,
                            Email    = email,
                        };

                        var roles = invitation.Roles?.Select(x => new Role {
                            Id = x, Name = x
                        }).ToList();
                        //Add default role for organization member invitation
                        if (roles.IsNullOrEmpty() && !string.IsNullOrEmpty(organizationId))
                        {
                            roles = new[] { SecurityConstants.Roles.OrganizationEmployee }.ToList();
                        }
                        user.Roles = roles;
                        result     = UserActionIdentityResult.Instance(await _userManager.CreateAsync(user));
                    }

                    if (result.Succeeded)
                    {
                        user = await _userManager.FindByNameAsync(user.UserName);

                        var token = await _userManager.GeneratePasswordResetTokenAsync(user);

                        var callbackUrl        = Url.Action("ConfirmInvitation", "Account", new { OrganizationId = organizationId, user.Email, Token = token }, Request.Scheme, host: WorkContext.CurrentStore.Host);
                        var inviteNotification = new RegistrationInvitationNotification(WorkContext.CurrentStore.Id, WorkContext.CurrentLanguage)
                        {
                            InviteUrl = callbackUrl,
                            Sender    = WorkContext.CurrentStore.Email,
                            Recipient = user.Email,
                            Message   = invitation.Message,
                        };
                        var sendingResult = await _platformNotificationApi.SendNotificationByRequestAsync(inviteNotification.ToNotificationDto());

                        if (sendingResult.IsSuccess != true)
                        {
                            var errors = result.Errors.Concat(new IdentityError[] { new IdentityError()
                                                                                    {
                                                                                        Description = sendingResult.ErrorMessage
                                                                                    } }).ToArray();
                            result = UserActionIdentityResult.Failed(errors);
                        }
                    }
                }
            }
            else
            {
                result = UserActionIdentityResult.Failed(ModelState.Values.SelectMany(x => x.Errors).Select(x => new IdentityError {
                    Description = x.ErrorMessage
                }).ToArray());
            }
            return(result);
        }
        public async Task <ActionResult <UserActionIdentityResult> > RegisterOrganization([FromBody] OrganizationRegistration orgRegistration)
        {
            UserActionIdentityResult result;

            TryValidateModel(orgRegistration);

            if (ModelState.IsValid)
            {
                var user = await _userManager.FindByEmailAsync(orgRegistration.Email);

                if (user != null)
                {
                    var error = new IdentityError
                    {
                        Description = $"Email '{orgRegistration.Email}' is already taken."
                    };

                    return(UserActionIdentityResult.Failed(error));
                }

                user = await _userManager.FindByNameAsync(orgRegistration.UserName);

                if (user != null)
                {
                    var error = new IdentityError
                    {
                        Description = $"User name '{orgRegistration.UserName}' is already taken."
                    };

                    return(UserActionIdentityResult.Failed(error));
                }

                var contact = orgRegistration.ToContact();

                if (!string.IsNullOrEmpty(orgRegistration.OrganizationName))
                {
                    var organization = orgRegistration.ToOrganization();
                    organization = await _memberService.CreateOrganizationAsync(organization);

                    contact.OrganizationId = organization.Id;
                }

                user         = orgRegistration.ToUser();
                user.Contact = contact;
                user.StoreId = WorkContext.CurrentStore.Id;
                user.Roles   = new[]
                {
                    SecurityConstants.Roles.OrganizationMaintainer
                };

                var creatingResult = await _userManager.CreateAsync(user, orgRegistration.Password);

                result = UserActionIdentityResult.Instance(creatingResult);
                if (result.Succeeded)
                {
                    user = await _userManager.FindByNameAsync(user.UserName);

                    await _publisher.Publish(new UserRegisteredEvent(WorkContext, user, orgRegistration));

                    await _signInManager.SignInAsync(user, isPersistent : true);

                    await _publisher.Publish(new UserLoginEvent(WorkContext, user));

                    result.MemberId = user.Id;
                }
            }
            else
            {
                result = UserActionIdentityResult
                         .Failed(ModelState.Values.SelectMany(x => x.Errors)
                                 .Select(x => new IdentityError {
                    Description = x.ErrorMessage
                })
                                 .ToArray());
            }

            return(result);
        }