예제 #1
0
        public async Task <ActionResult> Setup(SetupApiViewModel model)
        {
            if (!IsDefaultShell())
            {
                return(this.ChallengeOrForbid("Api"));
            }

            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageTenants))
            {
                return(this.ChallengeOrForbid("Api"));
            }

            if (!String.IsNullOrEmpty(model.UserName) && model.UserName.Any(c => !_identityOptions.User.AllowedUserNameCharacters.Contains(c)))
            {
                ModelState.AddModelError(nameof(model.UserName), S["User name '{0}' is invalid, can only contain letters or digits.", model.UserName]);
            }

            // Only add additional error if attribute validation has passed.
            if (!String.IsNullOrEmpty(model.Email) && !_emailAddressValidator.Validate(model.Email))
            {
                ModelState.AddModelError(nameof(model.Email), S["The email is invalid."]);
            }

            if (!ModelState.IsValid)
            {
                return(BadRequest());
            }

            if (!_shellHost.TryGetSettings(model.Name, out var shellSettings))
            {
                ModelState.AddModelError(nameof(SetupApiViewModel.Name), S["Tenant not found: '{0}'", model.Name]);
            }

            if (shellSettings.State == TenantState.Running)
            {
                return(StatusCode(201));
            }

            if (shellSettings.State != TenantState.Uninitialized)
            {
                return(BadRequest(S["The tenant can't be setup."]));
            }

            var databaseProvider = shellSettings["DatabaseProvider"];

            if (String.IsNullOrEmpty(databaseProvider))
            {
                databaseProvider = model.DatabaseProvider;
            }

            var selectedProvider = _databaseProviders.FirstOrDefault(x => String.Equals(x.Value, databaseProvider, StringComparison.OrdinalIgnoreCase));

            if (selectedProvider == null)
            {
                return(BadRequest(S["The database provider is not defined."]));
            }

            var tablePrefix = shellSettings["TablePrefix"];

            if (String.IsNullOrEmpty(tablePrefix))
            {
                tablePrefix = model.TablePrefix;
            }

            var connectionString = shellSettings["connectionString"];

            if (String.IsNullOrEmpty(connectionString))
            {
                connectionString = model.ConnectionString;
            }

            if (selectedProvider.HasConnectionString && String.IsNullOrEmpty(connectionString))
            {
                return(BadRequest(S["The connection string is required for this database provider."]));
            }

            var recipeName = shellSettings["RecipeName"];

            if (String.IsNullOrEmpty(recipeName))
            {
                recipeName = model.RecipeName;
            }

            RecipeDescriptor recipeDescriptor = null;

            if (String.IsNullOrEmpty(recipeName))
            {
                if (model.Recipe == null)
                {
                    return(BadRequest(S["Either 'Recipe' or 'RecipeName' is required."]));
                }

                var tempFilename = Path.GetTempFileName();

                using (var fs = System.IO.File.Create(tempFilename))
                {
                    await model.Recipe.CopyToAsync(fs);
                }

                var fileProvider = new PhysicalFileProvider(Path.GetDirectoryName(tempFilename));

                recipeDescriptor = new RecipeDescriptor
                {
                    FileProvider   = fileProvider,
                    BasePath       = "",
                    RecipeFileInfo = fileProvider.GetFileInfo(Path.GetFileName(tempFilename))
                };
            }
            else
            {
                var setupRecipes = await _setupService.GetSetupRecipesAsync();

                recipeDescriptor = setupRecipes.FirstOrDefault(x => String.Equals(x.Name, recipeName, StringComparison.OrdinalIgnoreCase));

                if (recipeDescriptor == null)
                {
                    return(BadRequest(S["Recipe '{0}' not found.", recipeName]));
                }
            }

            var setupContext = new SetupContext
            {
                ShellSettings   = shellSettings,
                EnabledFeatures = null, // default list,
                Errors          = new Dictionary <string, string>(),
                Recipe          = recipeDescriptor,
                Properties      = new Dictionary <string, object>
                {
                    { SetupConstants.SiteName, model.SiteName },
                    { SetupConstants.AdminUsername, model.UserName },
                    { SetupConstants.AdminEmail, model.Email },
                    { SetupConstants.AdminPassword, model.Password },
                    { SetupConstants.SiteTimeZone, model.SiteTimeZone },
                    { SetupConstants.DatabaseProvider, selectedProvider.Value },
                    { SetupConstants.DatabaseConnectionString, connectionString },
                    { SetupConstants.DatabaseTablePrefix, tablePrefix },
                }
            };

            var executionId = await _setupService.SetupAsync(setupContext);

            // Check if a component in the Setup failed
            if (setupContext.Errors.Any())
            {
                foreach (var error in setupContext.Errors)
                {
                    ModelState.AddModelError(error.Key, error.Value);
                }

                return(StatusCode(500, ModelState));
            }

            return(Ok(executionId));
        }
        public async Task <ActionResult> Setup(SetupApiViewModel model)
        {
            if (!IsDefaultShell())
            {
                return(Unauthorized());
            }

            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageTenants))
            {
                return(Unauthorized());
            }

            if (!ModelState.IsValid)
            {
                return(BadRequest());
            }

            if (!_shellHost.TryGetSettings(model.Name, out var shellSettings))
            {
                ModelState.AddModelError(nameof(SetupApiViewModel.Name), S["Tenant not found: '{0}'", model.Name]);
            }

            if (shellSettings.State == TenantState.Running)
            {
                return(StatusCode(201));
            }

            if (shellSettings.State != TenantState.Uninitialized)
            {
                return(BadRequest(S["The tenant can't be setup."]));
            }

            var selectedProvider = _databaseProviders.FirstOrDefault(x => String.Equals(x.Value, model.DatabaseProvider, StringComparison.OrdinalIgnoreCase));

            if (selectedProvider == null)
            {
                return(BadRequest(S["The database provider is not defined."]));
            }

            var tablePrefix = shellSettings.TablePrefix;

            if (String.IsNullOrEmpty(tablePrefix))
            {
                tablePrefix = model.TablePrefix;
            }

            var connectionString = shellSettings.ConnectionString;

            if (String.IsNullOrEmpty(connectionString))
            {
                connectionString = model.ConnectionString;
            }

            if (selectedProvider.HasConnectionString && String.IsNullOrEmpty(connectionString))
            {
                return(BadRequest(S["The connection string is required for this database provider."]));
            }

            var recipeName = shellSettings.RecipeName;

            if (String.IsNullOrEmpty(recipeName))
            {
                recipeName = model.RecipeName;
            }

            RecipeDescriptor recipeDescriptor = null;

            if (String.IsNullOrEmpty(recipeName))
            {
                if (model.Recipe == null)
                {
                    return(BadRequest(S["Either 'Recipe' or 'RecipeName' is required."]));
                }

                var tempFilename = Path.GetTempFileName();

                using (var fs = System.IO.File.Create(tempFilename))
                {
                    await model.Recipe.CopyToAsync(fs);
                }

                var fileProvider = new PhysicalFileProvider(Path.GetDirectoryName(tempFilename));

                recipeDescriptor = new RecipeDescriptor
                {
                    FileProvider   = fileProvider,
                    BasePath       = "",
                    RecipeFileInfo = fileProvider.GetFileInfo(Path.GetFileName(tempFilename))
                };
            }
            else
            {
                var setupRecipes = await _setupService.GetSetupRecipesAsync();

                recipeDescriptor = setupRecipes.FirstOrDefault(x => String.Equals(x.Name, recipeName, StringComparison.OrdinalIgnoreCase));

                if (recipeDescriptor == null)
                {
                    return(BadRequest(S["Recipe '{0}' not found.", recipeName]));
                }
            }

            var setupContext = new SetupContext
            {
                ShellSettings            = shellSettings,
                SiteName                 = model.SiteName,
                EnabledFeatures          = null, // default list,
                AdminUsername            = model.UserName,
                AdminEmail               = model.Email,
                AdminPassword            = model.Password,
                Errors                   = new Dictionary <string, string>(),
                Recipe                   = recipeDescriptor,
                SiteTimeZone             = model.SiteTimeZone,
                DatabaseProvider         = selectedProvider.Name,
                DatabaseConnectionString = connectionString,
                DatabaseTablePrefix      = tablePrefix
            };

            var executionId = await _setupService.SetupAsync(setupContext);

            // Check if a component in the Setup failed
            if (setupContext.Errors.Any())
            {
                foreach (var error in setupContext.Errors)
                {
                    ModelState.AddModelError(error.Key, error.Value);
                }

                return(StatusCode(500, ModelState));
            }

            return(Ok(executionId));
        }