Пример #1
0
        public void Role_Change_Takes_Effect_Immediately()
        {
            // create the test user
            Create_Edit_User(TestData.ServiceAdminUsername, true);
            var testUser = new LinqMetaData().User.FirstOrDefault(x => x.FirstName == TestValues["FirstName"]);

            Assert.IsNotNull(testUser);

            // remove the restriction on the user account, this is faster than going through the registration process
            testUser.Username = "******";
            testUser.UserAccountRestrictions.DeleteMulti();
            testUser.Save();

            // check the menu
            var menuController = Mock <MenuController>();

            menuController.RouteData.DataTokens.Add("ParentActionViewContext", MockObjects.MockExtensions.Mock <ControllerContext>());
            menuController.HttpContext.User = new RolePrincipal(new GenericIdentity("TestUser1"));
            menuController.Invoke("ListMenu");
            var originalMenu = menuController.Response.Output.ToString();

            // change the role
            var controller = Mock();

            controller.HttpContext.User = new RolePrincipal(new GenericIdentity(TestData.ServiceAdminUsername));
            var request = controller.Mock(x => x.ControllerContext.HttpContext.Request);

            request.Setup(x => x.HttpMethod).Returns("POST");

            // set the userId
            controller.RouteData.Values.Add("userId", testUser.UserId);

            // set the role to something else
            TestValues["Role"] = OrganizationUtils.GetAllowedRoles(testUser.OrganizationId)
                                 .First(x => !testUser.Roles.Any(y => y.RoleId == x.RoleId)).RoleId.ToString(CultureInfo.InvariantCulture);
            request.SetupGet(x => x.Form).Returns(() => TestValues);
            controller.Invoke("Edit");
            testUser = new LinqMetaData().User.FirstOrDefault(x => x.FirstName == TestValues["FirstName"]);
            Assert.IsNotNull(testUser);

            // make sure the role has changed
            Assert.AreEqual(testUser.Roles.First().RoleId.ToString(CultureInfo.InvariantCulture), TestValues["Role"]);

            // make sure menu items have changed
            menuController = Mock <MenuController>();
            menuController.RouteData.DataTokens.Add("ParentActionViewContext", MockObjects.MockExtensions.Mock <ControllerContext>());
            menuController.HttpContext.User = new RolePrincipal(new GenericIdentity("TestUser1"));
            menuController.Invoke("ListMenu");
            var newMenu = menuController.Response.Output.ToString();

            Assert.AreNotEqual(originalMenu, newMenu);
        }
Пример #2
0
 /// <summary>
 /// Gets a list of roles that are available to users within the specified organization,
 ///   mostly just filters out making an organization the ServiceHost, which only one is allowed and that is EPIC Central
 /// </summary>
 /// <param name="organizationId"></param>
 /// <returns></returns>
 public JsonResult GetRoles(int?organizationId)
 {
     return(Json(OrganizationUtils.GetAllowedRoles(organizationId).ToDictionary(r => r.RoleId.ToString(CultureInfo.InvariantCulture), x => x.Name), JsonRequestBehavior.AllowGet));
 }
Пример #3
0
        public void Service_Administrator_Can_Assign_Any_Role()
        {
            // create a test user
            Create_Edit_User(TestData.ServiceAdminUsername, true);

            var user     = TestData.ServiceAdminUser;
            var testUser = new LinqMetaData().User.FirstOrDefault(x => x.FirstName == TestValues["FirstName"]);
            var profile  = new UserSettingEntity(user.UserId, "SupportUser")
            {
                UserId = user.UserId, Name = "SupportUser"
            };

            Assert.IsFalse(profile.IsNew);
            Assert.IsNotNull(testUser);
            Thread.Sleep(5000); // wait for exchange to deliver the e-mail

            // check the inbox for the e-mail
            var imap     = SupportController.EnsureConnection(user);
            var msgCount = imap.SelectMailbox("INBOX").NumMsg;

            Assert.IsTrue(msgCount > 0);

            var msgs =
                imap.Search(SearchCondition.Deleted().Not()).Select(
                    x =>
                    imap.GetMessage(x, true, true,
                                    new[] { "date", "subject", "from", "content-type", "to", "cc", "message-id" }));
            var message =
                msgs.Where(x => x.Subject.Contains(ControllerRes.Account.Email_SubjectUserRegistration)).
                OrderByDescending(x => x.Date).FirstOrDefault();

            Assert.IsNotNull(message);

            message = imap.GetMessage(message.Uid, false, false);
            // make sure the link matches the current test user in the database
            var match = Regex.Match(message.Body, "RegistrationKey=([a-zA-Z0-9]*)");

            Assert.IsTrue(match.Success);

            // register the test user
            var controller = Mock <AccountController>();
            var request    = controller.Mock(x => x.ControllerContext.HttpContext.Request);

            request.Setup(x => x.HttpMethod).Returns("POST");

            // mock global forms authentication
            var mockformsAuthenticationService = new Mock <Global.FormsAuthenticationService>();

            mockformsAuthenticationService.Setup(
                service => service.SetAuthCookie(It.IsAny <string>(), It.IsAny <bool>())).Callback <string, bool>(
                (s, b) => new RolePrincipal(new GenericIdentity(s)));
            mockformsAuthenticationService.Setup(x => x.SignOut()).Callback(() => { });
            Global.FormsAuthentication = mockformsAuthenticationService.Object;

            // submit test values
            request.SetupGet(x => x.Form).Returns(() => new NameValueCollection
            {
                { "UserName", TestValues["FirstName"] },
                { "Email", profile.Value + '@' + SupportController.DOMAIN },
                { "Password", "Th1s|sAV4lidPa$$w0rd" },
                { "ConfirmPassword", "Th1s|sAV4lidPa$$w0rd" },
                { "Pin", "1234" },
                { "OriginalEmail", profile.Value + '@' + SupportController.DOMAIN },
                { "RegistrationKey", match.Groups[1].Value }
            });
            controller.Invoke("Register");
            testUser = new LinqMetaData().User.FirstOrDefault(x => x.Username == TestValues["FirstName"]);
            Assert.IsNotNull(testUser);

            // change the role
            var userController = Mock();

            userController.HttpContext.User = new RolePrincipal(new GenericIdentity(TestData.ServiceAdminUsername));
            request = userController.Mock(x => x.ControllerContext.HttpContext.Request);
            request.Setup(x => x.HttpMethod).Returns("POST");

            // set the userId
            userController.RouteData.Values.Add("userId", testUser.UserId);
            TestValues["Role"] = OrganizationUtils.GetAllowedRoles(testUser.OrganizationId)
                                 .First(x => !testUser.Roles.Any(y => y.RoleId == x.RoleId)).RoleId.ToString(CultureInfo.InvariantCulture);
            request.SetupGet(x => x.Form).Returns(() => TestValues);
            userController.Invoke("Edit");
            testUser = new LinqMetaData().User.FirstOrDefault(x => x.FirstName == TestValues["FirstName"]);
            Assert.IsNotNull(testUser);
            Assert.AreEqual(TestValues["Role"], testUser.Roles.Single().RoleId.ToString(CultureInfo.InvariantCulture));
        }
Пример #4
0
        public ActionResult Add(int organizationId, AddUserModel model)
        {
            var organization = new OrganizationEntity(organizationId);

            if (organization.IsNew)
            {
                throw new HttpException(404, SharedRes.Error.NotFound_Organization);
            }

            var restrictionKey = EpicMembershipProvider.CreateSalt(16);

            if (ModelState.IsValid)
            {
                if (!Permissions.UserHasPermission("Edit", organization))
                {
                    throw new HttpException(401, SharedRes.Error.Unauthorized_OrganizationEdit);
                }

                // Validate submitted role.
                if (!model.Role.HasValue || !(OrganizationUtils.GetAllowedRoles(organizationId).Any(r => r.RoleId == model.Role)))
                {
                    throw new HttpException(417, ControllerRes.Account.Invalid_RoleSpecified);
                }

                // Locations are only valid for non-admin users.
                bool isAdmin = RoleUtils.IsRoleForAdmin(model.Role.Value);
                if (!isAdmin)
                {
                    // Validate submitted locations are locations of the organization.
                    if (model.Locations.Except(new LinqMetaData().Location.Where(l => l.OrganizationId == organizationId).Select(l => l.LocationId).ToList()).Any())
                    {
                        throw new HttpException(404, SharedRes.Error.NotFound_Location);
                    }
                }

                Transaction transaction = new Transaction(IsolationLevel.ReadCommitted, "user add");

                try
                {
                    UserEntity user = new UserEntity
                    {
                        OrganizationId = organizationId,
                        FirstName      = model.FirstName,
                        LastName       = model.LastName,
                        EmailAddress   = model.EmailAddress,
                        Username       = string.Empty,
                        Password       = string.Empty
                    };
                    transaction.Add(user);

                    // If role is non-admin, set up locations.
                    if (!isAdmin)
                    {
                        foreach (var loc in model.Locations)
                        {
                            var assignedLocation = user.UserAssignedLocations.AddNew();
                            assignedLocation.LocationId = loc;
                        }
                    }

                    var userRole = user.Roles.AddNew();
                    userRole.RoleId = model.Role.Value;

                    var accountRestriction = new AccountRestrictionEntity
                    {
                        AccountRestrictionType = AccountRestrictionType.NewUser,
                        RestrictionKey         = restrictionKey,
                        EmailAddress           = model.EmailAddress,
                        Parameters             = string.IsNullOrWhiteSpace(model.Pin) ? string.Empty : model.Pin,
                        CreatedBy = Membership.GetUser().GetUserId().Id,
                        IPAddress = Request.ServerVariables["REMOTE_ADDR"]
                    };
                    transaction.Add(accountRestriction);
                    accountRestriction.Save();

                    var userRestriction = user.UserAccountRestrictions.AddNew();
                    userRestriction.AccountRestrictionId = accountRestriction.AccountRestrictionId;

                    // Save recursively ... so assigned locations, role and restriction are saved, too.
                    user.Save(true);

                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new HttpException(500, SharedRes.Error.Error_DatabaseUnknown);
                }
                finally
                {
                    transaction.Dispose();
                }

                // Send email for registration validation.
                SendRegistrationEmail(model, restrictionKey);

                // Add user complete. Modal dialog will close, so no response except "success".
                return(new EmptyResult());
            }

            Response.StatusCode             = 417;
            Response.TrySkipIisCustomErrors = true;

            return(PartialView(model));
        }
Пример #5
0
        public ActionResult Edit(int userId, EditUserModel model)
        {
            var user = new UserEntity(userId);

            if (user.IsNew)
            {
                throw new HttpException(404, SharedRes.Error.NotFound_User);
            }

            if (!RoleUtils.IsUserServiceAdmin() && !RoleUtils.IsUserOrgAdmin())
            {
                throw new HttpException(401, SharedRes.Error.Unauthorized_UserEdit);
            }

            if (RoleUtils.IsUserOrgAdmin() && user.OrganizationId != Membership.GetUser().GetUserId().OrganizationId)
            {
                throw new HttpException(401, SharedRes.Error.Unauthorized_OrganizationEdit);
            }

            if (ModelState.IsValid)
            {
                // Validate submitted role.
                if (!model.Role.HasValue || !(OrganizationUtils.GetAllowedRoles(model.OrganizationId).Any(r => r.RoleId == model.Role)))
                {
                    throw new HttpException(417, ControllerRes.Account.Invalid_RoleSpecified);
                }

                // Locations are only valid for non-admin users.
                bool isAdmin = RoleUtils.IsRoleForAdmin(model.Role.Value);
                if (!isAdmin)
                {
                    // Validate submitted locations are locations of the organization.
                    if (model.Locations.Except(new LinqMetaData().Location.Where(l => l.OrganizationId == model.OrganizationId).Select(l => l.LocationId).ToList()).Any())
                    {
                        throw new HttpException(404, SharedRes.Error.NotFound_Location);
                    }
                }

                // Set flag to indicate whether or not it's a pending registration.
                // Not using the posted back value in the model for security reasons.
                bool isPendingRegistration = user.UserAccountRestrictions.Count > 0 && user.UserAccountRestrictions[0].AccountRestriction.AccountRestrictionType == AccountRestrictionType.NewUser;

                // If not pending registration and username changed, validate username is unique.
                // Also, set flag to indicate if it's the current user changing own username.
                bool isCurrentUsernameChange = false;
                if (!isPendingRegistration && user.Username != model.UserName)
                {
                    if (UserUtils.IsUsernameUsed(model.UserName))
                    {
                        throw new HttpException(417, ControllerRes.Account.Invalid_DuplicateUsername);
                    }

                    isCurrentUsernameChange = Membership.GetUser().GetUserId().Id == userId;
                }

                // Set flag to indicate whether or not the email address in a registration
                // has changed.
                bool isRegistrationChange = isPendingRegistration && user.EmailAddress != model.EmailAddress;

                Transaction transaction = new Transaction(IsolationLevel.ReadCommitted, "user add");

                try
                {
                    transaction.Add(user);

                    // Username is empty in pending registrations and can't be changed.
                    // And current user username change isn't a simple change; don't do here.
                    if (!isPendingRegistration && !isCurrentUsernameChange)
                    {
                        user.Username = model.UserName;
                    }

                    user.EmailAddress = model.EmailAddress;
                    user.FirstName    = model.FirstName;
                    user.LastName     = model.LastName;

                    if (RoleUtils.IsUserServiceAdmin())
                    {
                        user.IsActive = model.IsActive;
                    }

                    // Did role change?
                    if (user.Roles.Count == 0 || user.Roles[0].RoleId != model.Role.Value)
                    {
                        user.Roles.DeleteMulti();
                        var userRole = user.Roles.AddNew();
                        userRole.RoleId = model.Role.Value;
                    }

                    int[] newLocations = new int[0];
                    int[] oldLocations;

                    if (!isAdmin)
                    {
                        // User is not an admin. So find the set of locations user has been added to,
                        // and the set of location user has been removed from.
                        newLocations = model.Locations.Except(user.UserAssignedLocations.Select(l => l.LocationId)).ToArray();
                        oldLocations = user.UserAssignedLocations.Select(l => l.LocationId).Except(model.Locations).ToArray();
                    }
                    else
                    {
                        // User is admin. So user will be removed from all locations (admins aren't
                        // assigned to locations).
                        oldLocations = user.UserAssignedLocations.Select(l => l.LocationId).ToArray();
                    }

                    if (oldLocations.Length > 0)
                    {
                        user.UserAssignedLocations.DeleteMulti(UserAssignedLocationFields.UserId == user.UserId & UserAssignedLocationFields.LocationId == oldLocations);
                    }

                    if (newLocations.Length > 0)
                    {
                        foreach (var loc in newLocations)
                        {
                            var assignedLocation = user.UserAssignedLocations.AddNew();
                            assignedLocation.LocationId = loc;
                        }
                    }

                    // If the registration email has changed, update the email address in the account
                    // restriction.
                    if (isRegistrationChange)
                    {
                        user.UserAccountRestrictions[0].AccountRestriction.EmailAddress = model.EmailAddress;
                    }

                    // Is current user changing own username?
                    if (isCurrentUsernameChange)
                    {
                        // Changing the current user's username requres special handling because the
                        // forms-auth cookies must be updated with the new username. The delegate will
                        // be invoked to save the new username updating the datbase. In this case, it
                        // needs to be done within the transaction created here.
                        //
                        // Have already validated the username as unique. So the only reason for this
                        // to fail is with some exception thrown, which will be handled in the "catch".
                        Membership.GetUser().ChangeUsername(model.UserName,
                                                            delegate(string username)
                        {
                            user.Username = username;
                            user.Save(true);
                            // ReSharper disable AccessToDisposedClosure
                            transaction.Commit();
                            // ReSharper restore AccessToDisposedClosure
                        });
                    }
                    else
                    {
                        user.Save(true);
                        transaction.Commit();
                    }
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new HttpException(500, SharedRes.Error.Error_DatabaseUnknown);
                }
                finally
                {
                    transaction.Dispose();
                }

                // If registration email has changed, need to re-send the registration email.
                if (isRegistrationChange)
                {
                    SendRegistrationEmail(model, user.UserAccountRestrictions[0].AccountRestriction.RestrictionKey);
                }
            }

            return((Request.IsAjaxRequest() || ControllerContext.IsChildAction)
                                           ? (ActionResult) new EmptyResult()
                                           : View(GetEditModel(userId)));
        }
        protected void Create_Edit_User(string username, bool dontDelete = false)
        {
            var user = new LinqMetaData().User.Single(x => x.Username == username);

            // get the location for the input username
            var organization = new LinqMetaData().Organization.First(x => x.Users.Any(y => y.Username == username));

            // make sure the user inbox is accessible
            var profile = new UserSettingEntity(user.UserId, "SupportUser")
            {
                UserId = user.UserId, Name = "SupportUser"
            };

            Assert.IsFalse(profile.IsNew);

            // set up a new user account with the email address set to the same as the passed in user
            var controller = Mock();

            controller.HttpContext.User = new RolePrincipal(new GenericIdentity(username));
            var request = controller.Mock(x => x.ControllerContext.HttpContext.Request);

            request.Setup(x => x.HttpMethod).Returns("POST");

            // fill in the missing user values
            TestValues["OrganizationId"] = organization.OrganizationId.ToString(CultureInfo.InvariantCulture);
            TestValues["Role"]           = OrganizationUtils.GetAllowedRoles(organization.OrganizationId)
                                           .First().RoleId.ToString(CultureInfo.InvariantCulture);
            // set the e-mail address equal to the passed in user support center e-mail
            TestValues["EmailAddress"] = profile.Value + '@' + SupportController.DOMAIN;

            // submit test values
            request.SetupGet(x => x.Form).Returns(() => TestValues);
            controller.Invoke("Add");
            var testUser = new LinqMetaData().User.FirstOrDefault(x => x.FirstName == TestValues["FirstName"]);

            Assert.IsNotNull(testUser);

            // try to edit the user
            controller = Mock();
            controller.HttpContext.User = new RolePrincipal(new GenericIdentity(username));
            request = controller.Mock(x => x.ControllerContext.HttpContext.Request);
            request.Setup(x => x.HttpMethod).Returns("POST");

            // set the userId
            controller.RouteData.Values.Add("userId", testUser.UserId);

            // username cannot be changed because registration is still pending at this point
            // just edit the first name
            TestValues["FirstName"] = "UserTest1";
            TestValues["IsActive"]  = "true";
            TestValues["UserName"]  = "******";
            request.SetupGet(x => x.Form).Returns(() => TestValues);
            controller.Invoke("Edit");
            testUser = new LinqMetaData().User.FirstOrDefault(x => x.FirstName == TestValues["FirstName"]);
            Assert.IsNotNull(testUser);

            // don't delete for further testing by the caller, which is responsible for cleanup
            if (!dontDelete)
            {
                var ars = testUser.UserAccountRestrictions.Select(y => y.AccountRestriction).ToList();
                testUser.UserAccountRestrictions.DeleteMulti();
                ars.ForEach(y => y.Delete());
                // finally delete the test user
                testUser.Delete();
            }
        }