protected override void init()
 {
     if (UserId.HasValue)
     {
         User = UserManagementStatics.GetUser(UserId.Value, true);
     }
 }
Пример #2
0
        /// <summary>
        /// Initializes the class. This includes loading application settings from the configuration file. The application name should be scoped within the system.
        /// For non web applications, this method must be called directly from the main executable assembly and not from a supporting library.
        ///
        /// To debug this method, create a folder called C:\AnyoneFullControl and give Everyone full control. A file will appear in that folder explaining how far
        /// it got in init.
        /// </summary>
        /// <param name="appName"></param>
        /// <param name="isClientSideProgram"></param>
        /// <param name="systemLogic"></param>
        /// <param name="mainDataAccessStateGetter">A method that returns the current main data-access state whenever it is requested, including during this
        /// AppTools.Init call. Do not allow multiple threads to use the same state at the same time. If you pass null, the data-access subsystem will not be
        /// available in the application.</param>
        public static void Init(string appName, bool isClientSideProgram, SystemLogic systemLogic, Func <DataAccessState> mainDataAccessStateGetter = null)
        {
            var initializationLog = "Starting init";

            try {
                if (initialized)
                {
                    throw new ApplicationException("This class can only be initialized once.");
                }

                if (systemLogic == null)
                {
                    throw new ApplicationException("The system must have a global logic class and you must pass an instance of it to AppTools.Init.");
                }

                // Initialize ConfigurationStatics, including the general provider, before the exception handling block below because it's reasonable for the exception
                // handling to depend on this.
                ConfigurationStatics.Init(systemLogic.GetType(), appName, isClientSideProgram, ref initializationLog);

                // Setting the initialized flag to true must be done before executing the secondary init block below so that exception handling works.
                initialized        = true;
                initializationLog += Environment.NewLine + "Succeeded in primary init.";
            }
            catch (Exception e) {
                initializationLog += Environment.NewLine + e;
                StandardLibraryMethods.EmergencyLog("Initialization log", initializationLog);
                throw;
            }

            try {
                var asposeLicense = ConfigurationStatics.SystemGeneralProvider.AsposeLicenseName;
                if (asposeLicense.Any())
                {
                    new Aspose.Pdf.License().SetLicense(asposeLicense);
                    new Aspose.Words.License().SetLicense(asposeLicense);
                }

                // This initialization could be performed using reflection. There is no need for AppTools to have a dependency on these classes.
                AppMemoryCache.Init();
                BlobFileOps.Init();
                DataAccessStatics.Init();
                DataAccessState.Init(mainDataAccessStateGetter);
                EncryptionOps.Init();
                HtmlBlockStatics.Init();
                InstallationSupportUtility.ConfigurationLogic.Init1();
                UserManagementStatics.Init();

                systemLogic.InitSystem();
            }
            catch (Exception e) {
                secondaryInitFailed = true;

                // Suppress all exceptions since they would prevent apps from knowing that primary initialization succeeded. EWF apps need to know this in order to
                // automatically restart themselves. Other apps could find this knowledge useful as well.
                try {
                    EmailAndLogError("An exception occurred during application initialization:", e);
                }
                catch {}
            }
        }
Пример #3
0
 protected override void init()
 {
     User = UserManagementStatics.GetUser(EmailAddress);
     if (User == null)
     {
         throw new ApplicationException("emailAddress");
     }
 }
Пример #4
0
        private PostBackAction getSendNewPasswordAction()
        {
            var userLocal = UserManagementStatics.GetUser(emailAddress.Value);

            if (userLocal == null)
            {
                throw new DataModificationException(getUnregisteredEmailMessage());
            }
            return(new PostBackAction(ConfirmPasswordReset.GetInfo(userLocal.Email, info.ReturnUrl)));
        }
        protected override PageContent getContent()
        {
            var content = new UiPageContent(omitContentBox: true);

            if (UserManagementStatics.IdentityProviders.OfType <SamlIdentityProvider>().Any())
            {
                var certificate = UserManagementStatics.GetCertificate();
                content.Add(
                    new Section(
                        "Identity providers",
                        FormItemList.CreateStack(
                            items:
                            (certificate.Any()
                                                                          ? "Certificate valid until {0}.".FormatWith(
                                 new X509Certificate2(Convert.FromBase64String(certificate), UserManagementStatics.CertificatePassword).NotAfter
                                 .ToDayMonthYearString(
                                     false))
                             .ToComponents()
                                                                          : "No certificate.".ToComponents()).Concat(" ".ToComponents())
                            .Append(
                                new EwfButton(
                                    new StandardButtonStyle("Regenerate", buttonSize: ButtonSize.ShrinkWrap),
                                    behavior: new ConfirmationButtonBehavior(
                                        "Are you sure?".ToComponents(),
                                        postBack: PostBack.CreateFull(
                                            "certificate",
                                            modificationMethod: () => UserManagementStatics.UpdateCertificate(generateCertificate(DateTimeOffset.UtcNow))))))
                            .Materialize()
                            .ToFormItem(label: "System self-signed certificate".ToComponents())
                            .Concat(
                                AuthenticationStatics.SamlIdentityProviders.Any()
                                                                                ? new EwfHyperlink(EnterpriseWebFramework.UserManagement.SamlResources.Metadata.GetInfo(), new StandardHyperlinkStyle(""))
                                .ToFormItem(label: "Application SAML metadata".ToComponents())
                                .ToCollection()
                                                                                : Enumerable.Empty <FormItem>())
                            .Materialize())
                        .ToCollection(),
                        style: SectionStyle.Box));
            }
            content.Add(
                new Section(
                    "System users",
                    EwfTable.Create(
                        tableActions: new HyperlinkSetup(new SystemUser(Es, null), "Create User").ToCollection(),
                        headItems: EwfTableItem.Create("Email".ToCell().Append("Role".ToCell()).Materialize()).ToCollection())
                    .AddData(
                        UserManagementStatics.SystemProvider.GetUsers(),
                        user => EwfTableItem.Create(
                            user.Email.ToCell().Append(user.Role.Name.ToCell()).Materialize(),
                            setup: EwfTableItemSetup.Create(activationBehavior: ElementActivationBehavior.CreateHyperlink(new SystemUser(Es, user.UserId)))))
                    .ToCollection(),
                    style: SectionStyle.Box));
            return(content);
        }
Пример #6
0
            protected override void init()
            {
                if (!UserManagementStatics.UserManagementEnabled)
                {
                    throw new ApplicationException("User management not enabled");
                }

                if (User.Any() && User != "anonymous" && (UserObject = UserManagementStatics.GetUser(User)) == null)
                {
                    throw new ApplicationException("user");
                }
            }
Пример #7
0
        protected override void loadData()
        {
            BasicPage.Instance.Body.Attributes["class"] = CssElementCreator.SelectUserPageBodyCssClass;

            ph.AddControlsReturnThis(new PageName());

            if (AppTools.IsLiveInstallation)
            {
                ph.AddControlsReturnThis(
                    new Paragraph(
                        new Strong("Warning:"),
                        " Do not impersonate a user without permission. Your actions will be attributed to the user you are impersonating, not to you.".GetLiteralControl()));
            }

            var pb = PostBack.CreateFull(
                actionGetter: () => new PostBackAction(new ExternalResourceInfo(info.ReturnUrl.Any() ? info.ReturnUrl : NetTools.HomeUrl)));

            DataValue <User> user = new DataValue <User>();

            ph.AddControlsReturnThis(
                FormItem.Create(
                    "User's email address (leave blank for anonymous)",
                    new EwfTextBox(""),
                    validationGetter: control => new EwfValidation(
                        (pbv, validator) => {
                var errorHandler = new ValidationErrorHandler("user");
                var emailAddress = validator.GetEmailAddress(errorHandler, control.GetPostBackValue(pbv), true);
                if (errorHandler.LastResult != ErrorCondition.NoError)
                {
                    return;
                }
                if (!emailAddress.Any())
                {
                    user.Value = null;
                    return;
                }
                user.Value = UserManagementStatics.GetUser(emailAddress);
                if (user.Value == null)
                {
                    validator.NoteErrorAndAddMessage("The email address you entered does not match a user.");
                }
            },
                        pb)).ToControl(),
                new Paragraph(
                    new PostBackButton(
                        pb,
                        new ButtonActionControlStyle(
                            AppRequestState.Instance.ImpersonatorExists ? "Change User" : "Begin Impersonation",
                            buttonSize: ButtonActionControlStyle.ButtonSize.Large))));

            pb.AddModificationMethod(() => UserImpersonationStatics.BeginImpersonation(user.Value));
        }
        protected override void loadData()
        {
            var table = new DynamicTable(new EwfTableColumn("Email", Unit.Percentage(50)), new EwfTableColumn("Role", Unit.Percentage(50)));

            table.AddActionLink(new ActionButtonSetup("Create User", new EwfLink(new EditUser.Info(es.info, null))));
            foreach (var user in UserManagementStatics.GetUsers())
            {
                table.AddTextRow(new RowSetup {
                    ClickScript = ClickScript.CreateRedirectScript(new EditUser.Info(es.info, user.UserId))
                }, user.Email, user.Role.Name);
            }
            ph.AddControlsReturnThis(table);
        }
 protected override void loadData()
 {
     ph.AddControlsReturnThis(
         EwfTable
         .Create(
             tableActions: new HyperlinkSetup(new EditUser.Info(es.info, null), "Create User").ToCollection(),
             headItems: EwfTableItem.Create("Email".ToCell().Append("Role".ToCell()).Materialize()).ToCollection())
         .AddData(
             UserManagementStatics.GetUsers(),
             user => EwfTableItem.Create(
                 user.Email.ToCell().Append(user.Role.Name.ToCell()).Materialize(),
                 setup: EwfTableItemSetup.Create(
                     activationBehavior: ElementActivationBehavior.CreateRedirectScript(new EditUser.Info(es.info, user.UserId)))))
         .ToCollection()
         .GetControls());
 }
        /// <summary>
        /// Call this during LoadData.
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="vl"></param>
        /// <param name="availableRoles">Pass a restricted list of <see cref="Role"/>s the user may select. Otherwise, Roles available
        /// in the System Provider are used.</param>
        /// <param name="validationPredicate">If the function returns true, validation continues.</param>
        public void LoadData(int?userId, ValidationList vl, List <Role> availableRoles = null, Func <bool> validationPredicate = null)
        {
            availableRoles = (availableRoles != null ? availableRoles.OrderBy(r => r.Name) : UserManagementStatics.SystemProvider.GetRoles()).ToList();

            user = userId.HasValue ? UserManagementStatics.GetUser(userId.Value, true) : null;
            if (includePasswordControls() && user != null)
            {
                facUser = FormsAuthStatics.GetUser(user.UserId, true);
            }

            Func <bool> validationShouldRun = () => validationPredicate == null || validationPredicate();

            var b = FormItemBlock.CreateFormItemTable(heading: "Security Information");

            b.AddFormItems(
                FormItem.Create(
                    "Email address",
                    new EwfTextBox(user != null ? user.Email : ""),
                    validationGetter: control => new Validation(
                        (pbv, validator) => {
                if (validationShouldRun())
                {
                    Email = validator.GetEmailAddress(new ValidationErrorHandler("email address"), control.GetPostBackValue(pbv), false);
                }
            },
                        vl)));

            if (includePasswordControls())
            {
                var group = new RadioButtonGroup(false);

                var keepPassword = FormItem.Create(
                    "",
                    group.CreateInlineRadioButton(true, label: userId.HasValue ? "Keep the current password" : "Do not create a password"),
                    validationGetter: control => new Validation(
                        (pbv, validator) => {
                    if (!validationShouldRun() || !control.IsCheckedInPostBack(pbv))
                    {
                        return;
                    }
                    if (user != null)
                    {
                        Salt               = facUser.Salt;
                        SaltedPassword     = facUser.SaltedPassword;
                        MustChangePassword = facUser.MustChangePassword;
                    }
                    else
                    {
                        genPassword(false);
                    }
                },
                        vl));

                var generatePassword = FormItem.Create(
                    "",
                    group.CreateInlineRadioButton(false, label: "Generate a " + (userId.HasValue ? "new, " : "") + "random password and email it to the user"),
                    validationGetter: control => new Validation(
                        (pbv, validator) => {
                    if (validationShouldRun() && control.IsCheckedInPostBack(pbv))
                    {
                        genPassword(true);
                    }
                },
                        vl));

                var newPassword      = new DataValue <string>();
                var confirmPassword  = new DataValue <string>();
                var newPasswordTable = EwfTable.Create(style: EwfTableStyle.StandardExceptLayout);
                newPasswordTable.AddItem(
                    new EwfTableItem(
                        "Password",
                        FormItem.Create(
                            "",
                            new EwfTextBox("", masksCharacters: true, disableBrowserAutoComplete: true)
                {
                    Width = Unit.Pixel(200)
                },
                            validationGetter: control => new Validation((pbv, v) => newPassword.Value = control.GetPostBackValue(pbv), vl)).ToControl()));
                newPasswordTable.AddItem(
                    new EwfTableItem(
                        "Password again",
                        FormItem.Create(
                            "",
                            new EwfTextBox("", masksCharacters: true, disableBrowserAutoComplete: true)
                {
                    Width = Unit.Pixel(200)
                },
                            validationGetter: control => new Validation((pbv, v) => confirmPassword.Value = control.GetPostBackValue(pbv), vl)).ToControl()));

                var providePasswordRadio = group.CreateBlockRadioButton(false, label: "Provide a " + (userId.HasValue ? "new " : "") + "password");
                providePasswordRadio.NestedControls.Add(newPasswordTable);
                var providePassword = FormItem.Create(
                    "",
                    providePasswordRadio,
                    validationGetter: control => new Validation(
                        (pbv, validator) => {
                    if (!validationShouldRun() || !control.IsCheckedInPostBack(pbv))
                    {
                        return;
                    }
                    FormsAuthStatics.ValidatePassword(validator, newPassword, confirmPassword);
                    var p              = new Password(newPassword.Value);
                    Salt               = p.Salt;
                    SaltedPassword     = p.ComputeSaltedHash();
                    MustChangePassword = false;
                },
                        vl));

                b.AddFormItems(
                    FormItem.Create("Password", ControlStack.CreateWithControls(true, keepPassword.ToControl(), generatePassword.ToControl(), providePassword.ToControl())));
            }

            b.AddFormItems(
                FormItem.Create(
                    "Role",
                    SelectList.CreateDropDown(
                        from i in availableRoles select SelectListItem.Create(i.RoleId as int?, i.Name),
                        user != null ? user.Role.RoleId as int? : null),
                    validationGetter: control => new Validation(
                        (pbv, validator) => {
                if (validationShouldRun())
                {
                    RoleId = control.ValidateAndGetSelectedItemIdInPostBack(pbv, validator) ?? default(int);
                }
            },
                        vl)));

            Controls.Add(b);
        }
Пример #11
0
        protected override void loadData()
        {
            if (info.User.Any())
            {
                if (!pageViewDataModificationsExecuted)
                {
                    throw new ApplicationException("Page-view data modifications did not execute.");
                }

                ph.AddControlsReturnThis(new Paragraph("Please wait.".ToComponents()).ToCollection().GetControls());
                StandardLibrarySessionState.Instance.SetInstantClientSideNavigation(new ExternalResourceInfo(info.ReturnUrl).GetUrl());
                return;
            }

            BasicPage.Instance.Body.Attributes["class"] = CssElementCreator.SelectUserPageBodyCssClass;

            ph.AddControlsReturnThis(new PageName().ToCollection().GetControls());

            if (ConfigurationStatics.IsLiveInstallation)
            {
                ph.AddControlsReturnThis(
                    new Paragraph(
                        new ImportantContent("Warning:".ToComponents()).ToCollection()
                        .Concat(
                            " Do not impersonate a user without permission. Your actions will be attributed to the user you are impersonating, not to you."
                            .ToComponents())
                        .Materialize()).ToCollection()
                    .GetControls());
            }

            var user = new DataValue <User>();
            var pb   = PostBack.CreateFull(
                firstModificationMethod: () => UserImpersonationStatics.BeginImpersonation(user.Value),
                actionGetter: () => new PostBackAction(new ExternalResourceInfo(info.ReturnUrl.Any() ? info.ReturnUrl : NetTools.HomeUrl)));

            FormState.ExecuteWithDataModificationsAndDefaultAction(
                pb.ToCollection(),
                () => {
                ph.AddControlsReturnThis(
                    new EmailAddressControl(
                        "",
                        true,
                        validationMethod: (postBackValue, validator) => {
                    if (!postBackValue.Any())
                    {
                        user.Value = null;
                        return;
                    }
                    user.Value = UserManagementStatics.GetUser(postBackValue);
                    if (user.Value == null)
                    {
                        validator.NoteErrorAndAddMessage("The email address you entered does not match a user.");
                    }
                }).ToFormItem(label: "User's email address (leave blank for anonymous)".ToComponents())
                    .ToComponentCollection()
                    .Append(
                        new Paragraph(
                            new EwfButton(
                                new StandardButtonStyle(
                                    AppRequestState.Instance.ImpersonatorExists ? "Change User" : "Begin Impersonation",
                                    buttonSize: ButtonSize.Large))
                            .ToCollection()))
                    .GetControls());
            });
        }
Пример #12
0
        /// <summary>
        /// Initializes the system. This includes loading application settings from the configuration file. The application name should be scoped within the system.
        /// For non web applications, this method must be called directly from the main executable assembly and not from a supporting library.
        ///
        /// To debug this method, create a folder called C:\AnyoneFullControl and give Everyone full control. A file will appear in that folder explaining how far
        /// it got in init.
        /// </summary>
        /// <param name="globalInitializer">The system's global initializer. Do not pass null.</param>
        /// <param name="appName"></param>
        /// <param name="isClientSideApp"></param>
        /// <param name="assemblyFolderPath">Pass a nonempty string to override the assembly folder path, which is used to locate the installation folder. Use with
        /// caution.</param>
        /// <param name="mainDataAccessStateGetter">A method that returns the current main data-access state whenever it is requested, including during this
        /// InitStatics call. Do not allow multiple threads to use the same state at the same time. If you pass null, the data-access subsystem will not be
        /// available in the application.</param>
        /// <param name="useLongDatabaseTimeouts">Pass true if the application is a background process that can tolerate slow database access.</param>
        public static void InitStatics(
            SystemInitializer globalInitializer, string appName, bool isClientSideApp, string assemblyFolderPath = "",
            Func <DataAccessState> mainDataAccessStateGetter = null, bool useLongDatabaseTimeouts = false)
        {
            var initializationLog = "Starting init";

            try {
                if (initialized)
                {
                    throw new ApplicationException("This class can only be initialized once.");
                }

                if (globalInitializer == null)
                {
                    throw new ApplicationException("The system must have a global initializer.");
                }

                // Initialize these before the exception handling block below because it's reasonable for the exception handling to depend on them.
                ConfigurationStatics.Init(assemblyFolderPath, globalInitializer.GetType(), appName, isClientSideApp, ref initializationLog);
                EmailStatics.Init();
                TelemetryStatics.Init();

                // Setting the initialized flag to true must be done before executing the secondary init block below so that exception handling works.
                initialized        = true;
                initializationLog += Environment.NewLine + "Succeeded in primary init.";
            }
            catch (Exception e) {
                initializationLog += Environment.NewLine + e;
                EwlStatics.EmergencyLog("Initialization log", initializationLog);
                throw;
            }

            try {
                CultureInfo.DefaultThreadCurrentCulture = Cultures.EnglishUnitedStates;

                var asposePdfLicensePath = EwlStatics.CombinePaths(ConfigurationStatics.InstallationConfiguration.AsposeLicenseFolderPath, "Aspose.PDF.lic");
                if (File.Exists(asposePdfLicensePath))
                {
                    new Aspose.Pdf.License().SetLicense(asposePdfLicensePath);
                }
                var asposeWordsLicensePath = EwlStatics.CombinePaths(ConfigurationStatics.InstallationConfiguration.AsposeLicenseFolderPath, "Aspose.Words.lic");
                if (File.Exists(asposeWordsLicensePath))
                {
                    new Aspose.Words.License().SetLicense(asposeWordsLicensePath);
                }

                AppMemoryCache.Init();
                BlobStorageStatics.Init();
                DataAccessStatics.Init();
                DataAccessState.Init(mainDataAccessStateGetter, useLongDatabaseTimeouts);
                EncryptionOps.Init();
                HtmlBlockStatics.Init();
                UserManagementStatics.Init();

                GlobalInitializationOps.globalInitializer = globalInitializer;
                globalInitializer.InitStatics();
            }
            catch (Exception e) {
                secondaryInitFailed = true;

                // Suppress all exceptions since they would prevent apps from knowing that primary initialization succeeded. EWF apps need to know this in order to
                // automatically restart themselves. Other apps could find this knowledge useful as well.
                try {
                    TelemetryStatics.ReportError("An exception occurred during application initialization:", e);
                }
                catch {}
            }
        }
        /// <summary>
        /// Call this during LoadData.
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="availableRoles">Pass a restricted list of <see cref="Role"/>s the user may select. Otherwise, Roles available
        /// in the System Provider are used.</param>
        public void LoadData(int?userId, List <Role> availableRoles = null)
        {
            availableRoles = (availableRoles?.OrderBy(r => r.Name) ?? UserManagementStatics.SystemProvider.GetRoles()).ToList();

            var user    = userId.HasValue ? UserManagementStatics.GetUser(userId.Value, true) : null;
            var facUser = includePasswordControls() && user != null?FormsAuthStatics.GetUser(user.UserId, true) : null;

            var b = FormItemList.CreateStack();

            b.AddFormItems(Email.ToEmailAddressControl(false, value: user != null ? user.Email : "").ToFormItem(label: "Email address".ToComponents()));

            if (includePasswordControls())
            {
                var group = new RadioButtonGroup(false);

                var keepPassword = group.CreateRadioButton(
                    true,
                    label: userId.HasValue ? "Keep the current password".ToComponents() : "Do not create a password".ToComponents(),
                    validationMethod: (postBackValue, validator) => {
                    if (!postBackValue.Value)
                    {
                        return;
                    }
                    if (user != null)
                    {
                        Salt.Value               = facUser.Salt;
                        SaltedPassword.Value     = facUser.SaltedPassword;
                        MustChangePassword.Value = facUser.MustChangePassword;
                    }
                    else
                    {
                        genPassword(false);
                    }
                })
                                   .ToFormItem();

                var generatePassword = group.CreateRadioButton(
                    false,
                    label: "Generate a {0} password and email it to the user".FormatWith(userId.HasValue ? "new, random" : "random").ToComponents(),
                    validationMethod: (postBackValue, validator) => {
                    if (postBackValue.Value)
                    {
                        genPassword(true);
                    }
                })
                                       .ToFormItem();

                var providePasswordSelected = new DataValue <bool>();
                var providePassword         = group.CreateFlowRadioButton(
                    false,
                    label: "Provide a {0}".FormatWith(userId.HasValue ? "new password" : "password").ToComponents(),
                    setup: FlowRadioButtonSetup.Create(
                        nestedContentGetter: () => {
                    return(FormState.ExecuteWithValidationPredicate(
                               () => providePasswordSelected.Value,
                               () => {
                        var password = new DataValue <string>();
                        var list = FormItemList.CreateStack(
                            generalSetup: new FormItemListSetup(classes: new ElementClass("newPassword")),
                            items: password.GetPasswordModificationFormItems());

                        new EwfValidation(
                            validator => {
                            var p = new Password(password.Value);
                            Salt.Value = p.Salt;
                            SaltedPassword.Value = p.ComputeSaltedHash();
                            MustChangePassword.Value = false;
                        });

                        return list.ToCollection();
                    }));
                }),
                    validationMethod: (postBackValue, validator) => providePasswordSelected.Value = postBackValue.Value)
                                              .ToFormItem();

                b.AddFormItems(
                    new StackList(keepPassword.ToListItem().ToCollection().Append(generatePassword.ToListItem()).Append(providePassword.ToListItem())).ToFormItem(
                        label: "Password".ToComponents()));
            }

            b.AddFormItems(
                RoleId.ToDropDown(
                    DropDownSetup.Create(from i in availableRoles select SelectListItem.Create(i.RoleId as int?, i.Name)),
                    value: new SpecifiedValue <int?>(user?.Role.RoleId))
                .ToFormItem(label: "Role".ToComponents()));

            this.AddControlsReturnThis(new Section("Security Information", b.ToCollection()).ToCollection().GetControls());
        }
Пример #14
0
        /// <summary>
        /// Call this during LoadData.
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="availableRoles">Pass a restricted list of <see cref="Role"/>s the user may select. Otherwise, Roles available
        /// in the System Provider are used.</param>
        /// <param name="validationPredicate">If the function returns true, validation continues.</param>
        public void LoadData(int?userId, List <Role> availableRoles = null, Func <bool> validationPredicate = null)
        {
            availableRoles = (availableRoles != null ? availableRoles.OrderBy(r => r.Name) : UserManagementStatics.SystemProvider.GetRoles()).ToList();

            user = userId.HasValue ? UserManagementStatics.GetUser(userId.Value, true) : null;
            if (includePasswordControls() && user != null)
            {
                facUser = FormsAuthStatics.GetUser(user.UserId, true);
            }

            Func <bool> validationShouldRun = () => validationPredicate == null || validationPredicate();

            var b = FormItemBlock.CreateFormItemTable(heading: "Security Information");

            b.AddFormItems(
                FormItem.Create(
                    "Email address",
                    new EwfTextBox(user != null ? user.Email : ""),
                    validationGetter: control => new EwfValidation(
                        (pbv, validator) => {
                if (validationShouldRun())
                {
                    Email = validator.GetEmailAddress(new ValidationErrorHandler("email address"), control.GetPostBackValue(pbv), false);
                }
            })));

            if (includePasswordControls())
            {
                var group = new RadioButtonGroup(false);

                var keepPassword = FormItem.Create(
                    "",
                    group.CreateInlineRadioButton(true, label: userId.HasValue ? "Keep the current password" : "Do not create a password"),
                    validationGetter: control => new EwfValidation(
                        (pbv, validator) => {
                    if (!validationShouldRun() || !control.IsCheckedInPostBack(pbv))
                    {
                        return;
                    }
                    if (user != null)
                    {
                        Salt               = facUser.Salt;
                        SaltedPassword     = facUser.SaltedPassword;
                        MustChangePassword = facUser.MustChangePassword;
                    }
                    else
                    {
                        genPassword(false);
                    }
                }));

                var generatePassword = FormItem.Create(
                    "",
                    group.CreateInlineRadioButton(false, label: "Generate a " + (userId.HasValue ? "new, " : "") + "random password and email it to the user"),
                    validationGetter: control => new EwfValidation(
                        (pbv, validator) => {
                    if (validationShouldRun() && control.IsCheckedInPostBack(pbv))
                    {
                        genPassword(true);
                    }
                }));

                var providePassword = FormState.ExecuteWithValidationPredicate(
                    validationShouldRun,
                    () => {
                    var providePasswordSelected = new DataValue <bool>();
                    return(FormItem.Create(
                               "",
                               group.CreateBlockRadioButton(
                                   false,
                                   (postBackValue, validator) => providePasswordSelected.Value = postBackValue.Value,
                                   label: "Provide a {0}".FormatWith(userId.HasValue ? "new password" : "password"),
                                   nestedControlListGetter: () => {
                        return FormState.ExecuteWithValidationPredicate(
                            () => providePasswordSelected.Value,
                            () => {
                            var password = new DataValue <string>();
                            var newPasswordTable = EwfTable.Create(style: EwfTableStyle.StandardExceptLayout);
                            foreach (var i in password.GetPasswordModificationFormItems(textBoxWidth: Unit.Pixel(200)))
                            {
                                newPasswordTable.AddItem(new EwfTableItem(i.Label, i.ToControl(omitLabel: true)));
                            }

                            new EwfValidation(
                                validator => {
                                var p = new Password(password.Value);
                                Salt = p.Salt;
                                SaltedPassword = p.ComputeSaltedHash();
                                MustChangePassword = false;
                            });

                            return newPasswordTable.ToCollection();
                        });
                    }),
                               validationGetter: control => control.Validation));
                });

                b.AddFormItems(
                    FormItem.Create("Password", ControlStack.CreateWithControls(true, keepPassword.ToControl(), generatePassword.ToControl(), providePassword.ToControl())));
            }

            b.AddFormItems(
                FormItem.Create(
                    "Role",
                    SelectList.CreateDropDown(
                        from i in availableRoles select SelectListItem.Create(i.RoleId as int?, i.Name),
                        user != null ? user.Role.RoleId as int? : null),
                    validationGetter: control => new EwfValidation(
                        (pbv, validator) => {
                if (validationShouldRun())
                {
                    RoleId = control.ValidateAndGetSelectedItemIdInPostBack(pbv, validator) ?? default(int);
                }
            })));

            Controls.Add(b);
        }