public async Task <IActionResult> Register(RegisterViewModel model, string returnUrl = null, bool logon = true)
        {
            if (!CanLoginOrRegister())
            {
                return(RedirectToAction("Register"));
            }

            ViewData["ReturnUrl"]    = returnUrl;
            ViewData["Logon"]        = logon.ToString(CultureInfo.InvariantCulture).ToLowerInvariant();
            ViewData["AllowIsAdmin"] = _Options.AllowAdminRegistration;
            var policies = await _SettingsRepository.GetSettingAsync <PoliciesSettings>() ?? new PoliciesSettings();

            if (policies.LockSubscription && !User.IsInRole(Roles.ServerAdmin))
            {
                return(RedirectToAction(nameof(HomeController.Index), "Home"));
            }
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser {
                    UserName = model.Email, Email = model.Email, RequiresEmailConfirmation = policies.RequiresConfirmedEmail,
                    Created  = DateTimeOffset.UtcNow
                };
                var result = await _userManager.CreateAsync(user, model.Password);

                if (result.Succeeded)
                {
                    var admin = await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin);

                    if (admin.Count == 0 || (model.IsAdmin && _Options.AllowAdminRegistration))
                    {
                        await _RoleManager.CreateAsync(new IdentityRole(Roles.ServerAdmin));

                        await _userManager.AddToRoleAsync(user, Roles.ServerAdmin);

                        var settings = await _SettingsRepository.GetSettingAsync <ThemeSettings>();

                        settings.FirstRun = false;
                        await _SettingsRepository.UpdateSetting <ThemeSettings>(settings);

                        await _SettingsRepository.FirstAdminRegistered(policies, _Options.UpdateUrl != null, _Options.DisableRegistration);

                        RegisteredAdmin = true;
                    }

                    _eventAggregator.Publish(new UserRegisteredEvent()
                    {
                        RequestUri = Request.GetAbsoluteRootUri(),
                        User       = user,
                        Admin      = RegisteredAdmin
                    });
                    RegisteredUserId = user.Id;

                    if (!policies.RequiresConfirmedEmail)
                    {
                        if (logon)
                        {
                            await _signInManager.SignInAsync(user, isPersistent : false);
                        }
                        return(RedirectToLocal(returnUrl));
                    }
                    else
                    {
                        TempData[WellKnownTempData.SuccessMessage] = "Account created, please confirm your email";
                        return(View());
                    }
                }
                AddErrors(result);
            }

            // If we got this far, something failed, redisplay form
            return(View(model));
        }
Esempio n. 2
0
        public async Task <IActionResult> CreateUser(CreateApplicationUserRequest request, CancellationToken cancellationToken = default)
        {
            if (request.Email is null)
            {
                ModelState.AddModelError(nameof(request.Email), "Email is missing");
            }
            if (!string.IsNullOrEmpty(request.Email) && !Validation.EmailValidator.IsEmail(request.Email))
            {
                ModelState.AddModelError(nameof(request.Email), "Invalid email");
            }
            if (request.Password is null)
            {
                ModelState.AddModelError(nameof(request.Password), "Password is missing");
            }
            if (!ModelState.IsValid)
            {
                return(this.CreateValidationError(ModelState));
            }
            if (User.Identity is null)
            {
                throw new JsonHttpException(this.StatusCode(401));
            }
            var anyAdmin = (await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin)).Any();
            var policies = await _settingsRepository.GetSettingAsync <PoliciesSettings>() ?? new PoliciesSettings();

            var isAuth = User.Identity.AuthenticationType == GreenfieldConstants.AuthenticationType;

            // If registration are locked and that an admin exists, don't accept unauthenticated connection
            if (anyAdmin && policies.LockSubscription && !isAuth)
            {
                return(this.CreateAPIError(401, "unauthenticated", "New user creation isn't authorized to users who are not admin"));
            }

            // Even if subscription are unlocked, it is forbidden to create admin unauthenticated
            if (anyAdmin && request.IsAdministrator is true && !isAuth)
            {
                return(this.CreateAPIError(401, "unauthenticated", "New admin creation isn't authorized to users who are not admin"));
            }
            // You are de-facto admin if there is no other admin, else you need to be auth and pass policy requirements
            bool isAdmin = anyAdmin ? (await _authorizationService.AuthorizeAsync(User, null, new PolicyRequirement(Policies.CanModifyServerSettings))).Succeeded &&
                           (await _authorizationService.AuthorizeAsync(User, null, new PolicyRequirement(Policies.Unrestricted))).Succeeded &&
                           isAuth
                                    : true;

            // You need to be admin to create an admin
            if (request.IsAdministrator is true && !isAdmin)
            {
                return(this.CreateAPIPermissionError(Policies.Unrestricted, $"Insufficient API Permissions. Please use an API key with permission: {Policies.Unrestricted} and be an admin."));
            }

            if (!isAdmin && (policies.LockSubscription || (await _settingsRepository.GetPolicies()).DisableNonAdminCreateUserApi))
            {
                // If we are not admin and subscriptions are locked, we need to check the Policies.CanCreateUser.Key permission
                var canCreateUser = (await _authorizationService.AuthorizeAsync(User, null, new PolicyRequirement(Policies.CanCreateUser))).Succeeded;
                if (!isAuth || !canCreateUser)
                {
                    return(this.CreateAPIPermissionError(Policies.CanCreateUser));
                }
            }

            var user = new ApplicationUser
            {
                UserName = request.Email,
                Email    = request.Email,
                RequiresEmailConfirmation = policies.RequiresConfirmedEmail,
                Created = DateTimeOffset.UtcNow,
            };
            var passwordValidation = await this._passwordValidator.ValidateAsync(_userManager, user, request.Password);

            if (!passwordValidation.Succeeded)
            {
                foreach (var error in passwordValidation.Errors)
                {
                    ModelState.AddModelError(nameof(request.Password), error.Description);
                }
                return(this.CreateValidationError(ModelState));
            }
            if (!isAdmin)
            {
                if (!await _throttleService.Throttle(ZoneLimits.Register, this.HttpContext.Connection.RemoteIpAddress, cancellationToken))
                {
                    return(new TooManyRequestsResult(ZoneLimits.Register));
                }
            }
            var identityResult = await _userManager.CreateAsync(user, request.Password);

            if (!identityResult.Succeeded)
            {
                foreach (var error in identityResult.Errors)
                {
                    if (error.Code == "DuplicateUserName")
                    {
                        ModelState.AddModelError(nameof(request.Email), error.Description);
                    }
                    else
                    {
                        ModelState.AddModelError(string.Empty, error.Description);
                    }
                }
                return(this.CreateValidationError(ModelState));
            }

            if (request.IsAdministrator is true)
            {
                if (!anyAdmin)
                {
                    await _roleManager.CreateAsync(new IdentityRole(Roles.ServerAdmin));
                }
                await _userManager.AddToRoleAsync(user, Roles.ServerAdmin);

                if (!anyAdmin)
                {
                    var settings = await _settingsRepository.GetSettingAsync <ThemeSettings>();

                    if (settings != null)
                    {
                        settings.FirstRun = false;
                        await _settingsRepository.UpdateSetting(settings);
                    }

                    await _settingsRepository.FirstAdminRegistered(policies, _options.UpdateUrl != null, _options.DisableRegistration, Logs);
                }
            }
            _eventAggregator.Publish(new UserRegisteredEvent()
            {
                RequestUri = Request.GetAbsoluteRootUri(), User = user, Admin = request.IsAdministrator is true
            });