Esempio n. 1
0
        public ActionResult UserSpecificNavigation()
        {
            using (var db = ApplicationDbContext.Create())
            {
                var thisUser = db.Users.Where(x => x.UserName == User.Identity.Name)
                               .Include(x => x.Organizations)
                               .FirstOrDefault();

                var  org        = OrganizationHelper.GetOrganizationByHost(Request, db);
                bool isOrgAdmin = false;

                if (org != null)
                {
                    isOrgAdmin = OrganizationHelper.DoesUserHaveRight(db, User, org.Id, Right.CanEditOrganization);
                }

                var model = new UserInfoModel()
                {
                    IsOrgAdmin          = isOrgAdmin,
                    IsSiteAdministrator = thisUser.IsAdministrator,
                    Organization        = org
                };

                return(PartialView("_UserSpecificNavigation", model));
            }
        }
Esempio n. 2
0
        public ActionResult Login(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;

            using (var db = ApplicationDbContext.Create())
            {
                var model = new LoginViewModel();

                var settings = SettingsHelper.GetSiteSettings(db);
                model.CanCreateOrganization = settings.IsAnonymousOrganizationRegistrationAllowed;

                // Get the organization associated with the hostname.
                var org = OrganizationHelper.GetOrganizationByHost(Request, db);
                if (org == null)
                {
                    model.CanRegisterForOrganization = false;
                }
                else
                {
                    model.CanRegisterForOrganization = org.IsAnonymousRegistrationAllowed;
                    model.ImageUrl         = org.ImageUrl;
                    model.OrganizationName = org.Name;
                    model.LoginPageText    = org.LoginPageText;
                }

                return(View(model));
            }
        }
Esempio n. 3
0
        public ActionResult Create()
        {
            using (var db = ApplicationDbContext.Create())
            {
                var thisUser = db.Users.Single(x => x.UserName == User.Identity.Name);

                var org = OrganizationHelper.GetOrganizationByHost(Request, db);

                bool isOrgAdmin = false;

                if (org != null)
                {
                    isOrgAdmin = OrganizationHelper.DoesUserHaveRight(db, User, org.Id, Right.CanAssignRights);
                }

                if (thisUser == null ||
                    (!thisUser.IsAdministrator &&
                     !isOrgAdmin))
                {
                    throw new HttpException(403, "Only administrators can create new users.");
                }

                var model = new RegisterViewModel();

                return(View(model));
            }
        }
Esempio n. 4
0
        public ActionResult Index()
        {
            using (var db = ApplicationDbContext.Create())
            {
                var thisUser = db.Users.Where(x => x.UserName == User.Identity.Name)
                               .Include(x => x.Organizations)
                               .FirstOrDefault();

                var org = OrganizationHelper.GetOrganizationByHost(Request, db);
                List <ApplicationUser> users = null;

                if (org != null)
                {
                    bool isOrgAdmin = OrganizationHelper.DoesUserHaveRight(db, User, org.Id, Right.CanAssignRights);

                    // Site administrators can see all users of the current organization.
                    if (thisUser.IsAdministrator)
                    {
                        users = db.Organizations
                                .Where(x => x.Id == org.Id)
                                .Include(x => x.ApplicationUsers)
                                .Include("ApplicationUsers.Organizations")
                                .FirstOrDefault()
                                ?.ApplicationUsers
                                ?.ToList();
                    }
                    else if (isOrgAdmin)
                    {
                        // Organization administrators can see that organization's users.
                        users = db.Organizations
                                .Where(x => x.Id == org.Id)
                                .Include(x => x.ApplicationUsers)
                                .Include("ApplicationUsers.Organizations")
                                .FirstOrDefault()
                                ?.ApplicationUsers
                                ?.ToList();
                    }
                    else
                    {
                        // Regular users should just see their own page.
                        return(RedirectToAction("Details", new { id = thisUser.UserName }));
                    }
                }
                else
                {
                    // When not on an organization-specific site, show all users.
                    users = db.Users
                            .Include(x => x.Organizations)
                            .OrderBy(x => x.Email)
                            .ToList();
                }

                var model = new UsersViewModel(users);
                return(View(model));
            }
        }
Esempio n. 5
0
        public ActionResult Permissions(UserDetailsModel model)
        {
            using (var db = ApplicationDbContext.Create())
            {
                // Only allow Admins to edit.
                var thisUser = db.Users.Where(x => x.UserName == User.Identity.Name)
                               .Include(x => x.Organizations)
                               .FirstOrDefault();

                var org = OrganizationHelper.GetOrganizationByHost(Request, db);
                if (org == null)
                {
                    return(RedirectToAction("Index"));
                }

                bool isOrgAdmin = OrganizationHelper.DoesUserHaveRight(db, User, org.Id, Right.CanAssignRights);

                if (!thisUser.IsAdministrator &&
                    !isOrgAdmin)
                {
                    throw new HttpException(403, "Only administrators can edit users permissions.");
                }

                var user = db.Users.Where(x => x.UserName == model.UserName)
                           .Include(x => x.Permissions)
                           .FirstOrDefault();

                if (user == null)
                {
                    throw new HttpException(404, "NotFound");
                }

                // Add or remove site administrator status.
                if (thisUser.IsAdministrator)
                {
                    user.IsAdministrator = model.IsSiteAdministrator;
                }

                // Add or remove permissions.
                SetPermission(user, org, Right.CanAssignRights, model.CanAssignRights);
                SetPermission(user, org, Right.CanViewAllCatalogRecords, model.CanViewAllCatalogRecords);
                SetPermission(user, org, Right.CanAssignCurator, model.CanAssignCurator);
                SetPermission(user, org, Right.CanEditOrganization, model.CanEditOrganization);
                SetPermission(user, org, Right.CanApprove, model.CanApprove);

                db.SaveChanges();

                return(RedirectToAction("Index"));
            }
        }
Esempio n. 6
0
        public async Task <ActionResult> Create(RegisterViewModel model)
        {
            using (var db = ApplicationDbContext.Create())
            {
                var thisUser = db.Users.Single(x => x.UserName == User.Identity.Name);

                var org = OrganizationHelper.GetOrganizationByHost(Request, db);

                bool isOrgAdmin = false;

                if (org != null)
                {
                    isOrgAdmin = OrganizationHelper.DoesUserHaveRight(db, User, org.Id, Right.CanAssignRights);
                }

                if (thisUser == null ||
                    (!thisUser.IsAdministrator && !isOrgAdmin))
                {
                    throw new HttpException(403, "Forbidden");
                }

                if (ModelState.IsValid)
                {
                    // If they specified an existing organization for the user, add the user to that.
                    if (org == null)
                    {
                        org = db.Organizations.FirstOrDefault();
                    }

                    var userManager = HttpContext.GetOwinContext().GetUserManager <ApplicationUserManager>();

                    var user = await CreateUser(model.Email, model.Password, model.FirstName, model.LastName,
                                                false,
                                                org,
                                                userManager,
                                                ModelState,
                                                db);

                    if (user != null)
                    {
                        return(RedirectToAction("Index"));
                    }
                }

                return(View(model));
            }
        }
Esempio n. 7
0
        public async Task <ActionResult> ForgotPassword(ForgotPasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = await UserManager.FindByNameAsync(model.Email);

                // TODO For now, don't require emails to be validated.
                //if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
                if (user == null)
                {
                    ModelState.AddModelError("", "The user either does not exist or is not confirmed.");
                    return(View());
                }

                // Send an email with this link
                string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);

                var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                // await UserManager.SendEmailAsync(
                //user.Id,
                //"Reset Password",
                //"Please reset your password by clicking <a href=\"" + callbackUrl + "\">here</a>");
                using (var db = ApplicationDbContext.Create())
                {
                    var org = OrganizationHelper.GetOrganizationByHost(Request, db);
                    if (org != null)
                    {
                        NotificationService.SendActionEmail(
                            user.Email, string.Format("{0} {1}", user.FirstName, user.LastName),
                            org.ReplyToAddress, org.Name,
                            "Reset password",
                            "Hello,",
                            "We heard you need a password reset. Click the link below and you will be redirected to a secure site from which you can set a new password.",
                            "Reset Password", callbackUrl,
                            "Thank you.",
                            Request.Url.Scheme + "://" + Request.Url.Host + "/User/EmailPreferences/" + user.UserName,
                            db);
                    }
                }

                return(RedirectToAction("ForgotPasswordConfirmation", "Account"));
            }

            // If we got this far, something failed, redisplay form
            return(View(model));
        }
Esempio n. 8
0
        public ActionResult Register()
        {
            using (var db = ApplicationDbContext.Create())
            {
                var model = new RegisterViewModel();

                var org = OrganizationHelper.GetOrganizationByHost(Request, db);
                if (org == null ||
                    !org.IsAnonymousRegistrationAllowed)
                {
                    throw new HttpException(403, "Forbidden");
                }

                InitializeRegisterModel(model, org);

                return(View(model));
            }
        }
Esempio n. 9
0
        public async Task <ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                using (var db = ApplicationDbContext.Create())
                {
                    var org = OrganizationHelper.GetOrganizationByHost(Request, db);

                    var user = await UserManager.FindAsync(model.Email, model.Password);

                    // Only allow users to log in if they are members of the organization.
                    // Also allow logins if this is not an org-specific site, and the user
                    // is a site administrator.
                    bool isUserInOrg = false;
                    if (user != null)
                    {
                        if (org == null && user.IsAdministrator)
                        {
                            isUserInOrg = true;
                        }
                        else if (org != null)
                        {
                            isUserInOrg = user.Organizations.Any(x => x.Id == org.Id);
                        }
                    }

                    if (user != null && isUserInOrg)
                    {
                        await SignInAsync(user, model.RememberMe);

                        return(RedirectToLocal(returnUrl));
                    }
                    else
                    {
                        ModelState.AddModelError("", "Invalid username or password.");
                    }
                }
            }

            // If we got this far, something failed, redisplay form
            return(View(model));
        }
Esempio n. 10
0
        public ActionResult Edit(UserDetailsModel model)
        {
            using (var db = ApplicationDbContext.Create())
            {
                // Only allow Admins or the actual user to edit.
                var thisUser = db.Users.Where(x => x.UserName == User.Identity.Name)
                               .Include(x => x.Organizations)
                               .FirstOrDefault();

                var org = OrganizationHelper.GetOrganizationByHost(Request, db);

                bool isOrgAdmin = false;
                if (org != null)
                {
                    isOrgAdmin = OrganizationHelper.DoesUserHaveRight(db, User, org.Id, Right.CanAssignRights);
                }

                if (!thisUser.IsAdministrator &&
                    !isOrgAdmin &&
                    thisUser.UserName != model.UserName)
                {
                    throw new HttpException(403, "Only administrators can edit users");
                }

                if (!ModelState.IsValid)
                {
                    return(RedirectToAction("Edit", new { id = thisUser.UserName }));
                }

                var user = db.Users.Where(x => x.UserName == model.UserName).FirstOrDefault();
                if (user == null)
                {
                    throw new HttpException(404, "Not Found");
                }

                Mapper.Map(model, user);

                db.SaveChanges();

                return(RedirectToAction("Index"));
            }
        }
Esempio n. 11
0
        public ActionResult Records()
        {
            var logger = LogManager.GetLogger("Curation");

            logger.Debug("Entering Records()");

            logger.Debug("Creating XML root");
            var root = new XElement("publishedCatalogRecords");

            logger.Debug("Opening DB context");
            using (var db = ApplicationDbContext.Create())
            {
                var org = OrganizationHelper.GetOrganizationByHost(Request, db);
                if (org == null)
                {
                    return(RedirectToAction("Index", "Dashboard"));
                }

                // Get all published records.
                logger.Debug("Getting published records");
                var publishedRecords = db.CatalogRecords
                                       .Where(x => x.Organization.Id == org.Id)
                                       .Where(x => x.Status == CatalogRecordStatus.Published)
                                       .Include(x => x.Authors)
                                       .Include(x => x.Files);

                int i = 1;
                foreach (var record in publishedRecords)
                {
                    logger.Debug($"Writing record {i++}");

                    // Create an element for this record.
                    var recordElement = new XElement("Record");
                    root.Add(recordElement);

                    // Add all the properties to the XML.
                    recordElement.Add(new XElement("Guid", record.Id));
                    recordElement.Add(new XElement("Title", record.Title));
                    recordElement.Add(new XElement("Author", record.AuthorsText));

                    if (!string.IsNullOrWhiteSpace(record.Owner?.FullName))
                    {
                        recordElement.Add(new XElement("Owner", record.Owner.FullName));
                    }
                    else
                    {
                        recordElement.Add(new XElement("Owner", record.OwnerText));
                    }

                    recordElement.Add(new XElement("Description", record.Description));
                    recordElement.Add(new XElement("StudyID", record.Number));
                    recordElement.Add(new XElement("StudyIDLower", record.Number?.ToLower()));
                    recordElement.Add(new XElement("RelatedPublication", record.RelatedPublications));
                    recordElement.Add(new XElement("RelatedProject", record.RelatedProjects));
                    recordElement.Add(new XElement("RelatedDatabase", record.RelatedDatabase));
                    recordElement.Add(new XElement("keywords", record.Keywords));
                    recordElement.Add(new XElement("CreateDate", record.CreatedDate));
                    recordElement.Add(new XElement("ResearchDesign", record.ResearchDesign));

                    CatalogRecordMethodsViewModel.GetConcatenatedDataProperties(record, out string dataType, out string dataSource, out string dataSourceInformation);
                    recordElement.Add(new XElement("DataType", dataType));
                    recordElement.Add(new XElement("DataSource", dataSource));
                    recordElement.Add(new XElement("DataSourceInformation", dataSourceInformation));

                    // Show information from the catalog record independently.
                    recordElement.Add(new XElement("CatalogRecordDataType", record.DataType));
                    recordElement.Add(new XElement("CatalogRecordDataSource", record.DataSource));
                    recordElement.Add(new XElement("CatalogRecordDataSourceInformation", record.DataSourceInformation));

                    if (!string.IsNullOrWhiteSpace(record.PersistentId))
                    {
                        string pid = record.PersistentId;
                        if (!pid.StartsWith("http"))
                        {
                            pid = "http://hdl.handle.net/" + pid;
                        }

                        recordElement.Add(new XElement("PersistentId", pid));
                    }
                    else
                    {
                        recordElement.Add(new XElement("PersistentId", string.Empty));
                    }

                    bool hasFieldDates = false;
                    if (!string.IsNullOrWhiteSpace(record.FieldDates))
                    {
                        var fieldDatesModel = JsonConvert.DeserializeObject <DateModel>(record.FieldDates);
                        if (fieldDatesModel != null)
                        {
                            hasFieldDates = true;

                            if (fieldDatesModel.isRange)
                            {
                                recordElement.Add(new XElement("FieldDates", $"{fieldDatesModel.date} - {fieldDatesModel.endDate}"));
                            }
                            else
                            {
                                recordElement.Add(new XElement("FieldDates", fieldDatesModel.date));
                            }
                        }
                    }
                    if (!hasFieldDates)
                    {
                        recordElement.Add(new XElement("FieldDates", string.Empty));
                    }

                    recordElement.Add(new XElement("Location", record.Location));
                    recordElement.Add(new XElement("LocationDetails", record.LocationDetails));
                    recordElement.Add(new XElement("UnitOfObservation", record.UnitOfObservation));
                    recordElement.Add(new XElement("SampleSize", record.SampleSize));
                    recordElement.Add(new XElement("InclusionExclusionCriteria", record.InclusionExclusionCriteria));
                    recordElement.Add(new XElement("RandomizedProcedure", record.RandomizationProcedure));
                    recordElement.Add(new XElement("Treatment", record.Treatment));
                    recordElement.Add(new XElement("TreatmentAdministration", record.TreatmentAdministration));
                    recordElement.Add(new XElement("OutcomeMeasures", record.OutcomeMeasures));
                    recordElement.Add(new XElement("ArchiveDate", record.ArchiveDate));
                    var fileElement = new XElement("FileElement");

                    int f = 1;
                    foreach (var file in record.Files)
                    {
                        logger.Debug($"Writing file {f++}");

                        if (string.IsNullOrWhiteSpace(file.Number))
                        {
                            continue;
                        }

                        var fileinfo = new XElement("File");
                        fileinfo.Add(new XElement("id", file.Id));
                        fileinfo.Add(new XElement("FileSize", file.Size));

                        string fileUrl = file.PersistentLink;
                        if (!string.IsNullOrWhiteSpace(fileUrl))
                        {
                            if (!fileUrl.StartsWith("http"))
                            {
                                fileUrl = "http://hdl.handle.net/" + fileUrl;
                            }
                            fileinfo.Add(new XElement("FileUrl", fileUrl));
                        }
                        else
                        {
                            fileinfo.Add(new XElement("FileUrl", string.Empty));
                        }

                        fileinfo.Add(new XElement("FileNumber", file.Number));
                        fileinfo.Add(new XElement("FileDescription", file.Title));
                        fileinfo.Add(new XElement("FileFormat", file.FormatName));
                        fileinfo.Add(new XElement("PublicFile", file.IsPublicAccess ? "1" : "0"));
                        fileinfo.Add(new XElement("CatalogRecordId", record.Number));
                        fileElement.Add(fileinfo);
                    }

                    recordElement.Add(fileElement);
                }
            }

            // Write the XML to the web response.
            logger.Debug("Writing XML");

            XDocument document = new XDocument(root);
            string    xmlStr   = document.Root.ToString();

            return(Content(xmlStr, "text/xml"));

            logger.Debug("Leaving Records()");
        }
Esempio n. 12
0
        public ActionResult Index()
        {
            using (var db = ApplicationDbContext.Create())
            {
                var model = new DashboardViewModel();

                var thisUser = db.Users.Where(x => x.UserName == User.Identity.Name)
                               .Include(x => x.Organizations)
                               .FirstOrDefault();

                var org = OrganizationHelper.GetOrganizationByHost(Request, db);
                if (org == null)
                {
                    model.IsOrganizationAmbiguous = true;
                    model.Organizations           = db.Organizations.ToList();
                }
                else
                {
                    model.IsAdmin = OrganizationHelper.DoesUserHaveRight(db, User, org.Id, Right.CanViewAllCatalogRecords);

                    // Restrict queries to files and users to which the current user shared an organization.
                    // Maybe it would be nicer to do per-organization dashboards, or to allow filtering
                    // of this information dynamically.
                    IEnumerable <CatalogRecord>   userRecords = null;
                    IEnumerable <ManagedFile>     userFiles   = null;
                    IEnumerable <ApplicationUser> userUsers   = null;


                    if (model.IsAdmin)
                    {
                        userRecords = db.CatalogRecords.Where(x => x.Organization.Id == org.Id);

                        userFiles = db.Files.Where(x => x.CatalogRecord.Organization.Id == org.Id);
                        userUsers = db.Users
                                    .Where(u => u.Organizations.Any(o => o.Id == org.Id));
                    }
                    else
                    {
                        userRecords = db.CatalogRecords.Where(x => x.Organization.Id == org.Id &&
                                                              x.CreatedBy.UserName == thisUser.UserName ||
                                                              x.Owner.UserName == thisUser.UserName ||
                                                              x.Curators.Any(u => u.UserName == thisUser.UserName) ||
                                                              x.Authors.Any(u => u.UserName == thisUser.UserName));

                        userFiles = db.Files.Where(x => x.CatalogRecord.Organization.Id == org.Id &&
                                                   x.CatalogRecord.CreatedBy.UserName == thisUser.UserName ||
                                                   x.CatalogRecord.Owner.UserName == thisUser.UserName ||
                                                   x.CatalogRecord.Curators.Any(u => u.UserName == thisUser.UserName) ||
                                                   x.CatalogRecord.Authors.Any(u => u.UserName == thisUser.UserName));
                    }


                    // CatalogRecords
                    model.NewCatalogRecordCount = userRecords
                                                  .Where(x => x.Status == CatalogRecordStatus.New)
                                                  .Count();

                    model.ProcessingCatalogRecordCount = userRecords
                                                         .Where(x => x.Status == CatalogRecordStatus.Processing ||
                                                                x.Status == CatalogRecordStatus.PublicationRequested ||
                                                                x.Status == CatalogRecordStatus.PublicationApproved)
                                                         .Count();

                    model.PublishedCatalogRecordCount = userRecords
                                                        .Where(x => x.Status == CatalogRecordStatus.Published)
                                                        .Count();

                    // Files
                    model.FileCount = userFiles.Where(x => x.Status == FileStatus.Accepted).Count();
                    model.FileSize  = userFiles.Where(x => x.Status == FileStatus.Accepted).Select(x => x.Size).DefaultIfEmpty(0).Sum();

                    // Users
                    if (model.IsAdmin)
                    {
                        model.UserCount = userUsers.Count();
                    }
                }

                return(View(model));
            }
        }
Esempio n. 13
0
        public async Task <ActionResult> Register(RegisterViewModel model)
        {
            using (var db = ApplicationDbContext.Create())
            {
                var org = OrganizationHelper.GetOrganizationByHost(Request, db);
                if (org == null ||
                    !org.IsAnonymousRegistrationAllowed)
                {
                    throw new HttpException(403, "Forbidden");
                }

                if (!model.IsTermsOfServiceAgreed)
                {
                    model.SkippedTermsOfService = true;
                    InitializeRegisterModel(model, org);
                    return(View(model));
                }

                if (ModelState.IsValid)
                {
                    var user = new ApplicationUser();
                    user.UserName  = model.Email;
                    user.Email     = model.Email;
                    user.FirstName = model.FirstName;
                    user.LastName  = model.LastName;

                    IdentityResult result = await UserManager.CreateAsync(user, model.Password);

                    if (result.Succeeded)
                    {
                        await SignInAsync(user, isPersistent : false);

                        db.Users.Attach(user);
                        org.ApplicationUsers.Add(user);

                        db.SaveChanges();


                        // Notify permission assigners of the new user.
                        var usersToNotify = OrganizationHelper.GetUsersWithRight(db, org.Id, Right.CanAssignRights)
                                            .ToList();
                        foreach (var notifyUser in usersToNotify)
                        {
                            try
                            {
                                NotificationService.SendActionEmail(
                                    notifyUser.Email, notifyUser.FullName,
                                    org.ReplyToAddress, org.Name,
                                    "[New User] " + model.Email,
                                    string.Format("{0} {1} has created a new account with user name {2}.", model.FirstName, model.LastName, model.Email),
                                    "Please assign any appropriate rights to the new user.",
                                    "Assign Rights ",
                                    Request.Url.Scheme + "://" + Request.Url.Host + "/User/Permissions/" + model.Email,
                                    org.NotificationEmailClosing,
                                    Request.Url.Scheme + "://" + Request.Url.Host + "/User/EmailPreferences/" + notifyUser.UserName,
                                    db);
                            }
                            catch (Exception ex)
                            {
                                Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
                            }
                        }

                        // Send an email with this link
                        string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);

                        var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);

                        NotificationService.SendActionEmail(
                            user.Email, string.Format("{0} {1}", model.FirstName, model.LastName),
                            org.ReplyToAddress, org.Name,
                            "Confirm your account",
                            "Welcome to " + org.Name + ".",
                            "We are ready to activate your account. All we need to do is make sure this is your email address.",
                            "Verify Address", callbackUrl,
                            "If you didn't create an account, just delete this email.",
                            Request.Url.Scheme + "://" + Request.Url.Host + "/User/EmailPreferences/" + user.UserName,
                            db);

                        return(RedirectToAction("Index", "Home"));
                    }
                    else
                    {
                        AddErrors(result);
                    }
                }
            }

            // If we got this far, something failed, redisplay form
            return(View(model));
        }
Esempio n. 14
0
        public ActionResult Details(string id)
        {
            if (id == null)
            {
                throw new HttpException(400, "Bad Request");
            }

            using (var db = ApplicationDbContext.Create())
            {
                var user = db.Users
                           .Where(x => x.UserName == id)
                           .Include(x => x.Organizations)
                           .Include(x => x.AuthorFor)
                           .Include(x => x.CuratorFor)
                           .Include(x => x.ApproverFor)
                           .FirstOrDefault();
                if (user == null)
                {
                    throw new HttpException(404, "Not Found");
                }

                // Information about the requesting user.
                var thisUser = db.Users.Where(x => x.UserName == User.Identity.Name)
                               .Include(x => x.Organizations)
                               .FirstOrDefault();


                var model = new UserDetailsModel();
                model.User = user;

                // Get information about each organization the user belongs to.
                foreach (var o in user.Organizations)
                {
                    var orgModel = new UserInOrganizationModel();
                    orgModel.OrganizationId   = o.Id;
                    orgModel.OrganizationName = o.Name;
                    model.Organizations.Add(orgModel);

                    // TODO better to do this in one query above.
                    var permissions = db.Permissions
                                      .Where(x => x.User.Id == user.Id && x.Organization.Id == o.Id);

                    foreach (var permission in permissions)
                    {
                        switch (permission.Right)
                        {
                        case Right.CanAssignRights:
                            orgModel.CanAssignRights = true;
                            break;

                        case Right.CanViewAllCatalogRecords:
                            orgModel.CanViewAllCatalogRecords = true;
                            break;

                        case Right.CanAssignCurator:
                            orgModel.CanAssignCurators = true;
                            break;

                        default:
                            break;
                        }
                    }
                }

                // Get history information for the user.
                var events = db.Events
                             .Where(x => x.User.UserName == id)
                             .OrderByDescending(x => x.Timestamp)
                             .Include(x => x.RelatedCatalogRecord)
                             .Include(x => x.RelatedManagedFiles);

                foreach (var userEvent in events)
                {
                    var eventModel = HistoryEventModel.FromEvent(userEvent, user);
                    model.Events.Add(eventModel);
                }

                // Ideas for more events to add
                // TODO Show when this user was created?
                // TODO Show when this user creates other users?
                // TODO Show when records, files, and anything else is edited?

                // Can the requesting user edit the user?
                var org = OrganizationHelper.GetOrganizationByHost(Request, db);
                if (org == null)
                {
                    model.IsOrganizationAmbiguous = true;
                }

                bool isOrgAdmin = false;
                if (org != null)
                {
                    isOrgAdmin = OrganizationHelper.DoesUserHaveRight(db, User, org.Id, Right.CanAssignRights);
                }

                model.CanEditUser = thisUser.IsAdministrator ||
                                    isOrgAdmin ||
                                    thisUser.UserName == id;

                // Permissions
                model.CanEditPermissions             = thisUser.IsAdministrator || isOrgAdmin;
                model.IsEditingUserSiteAdministrator = thisUser.IsAdministrator;

                if (org != null)
                {
                    model.OrganizationName = org.Name;
                }
                else
                {
                    model.OrganizationName = string.Join(", ", user.Organizations.Select(x => x.Name));
                }

                model.IsSiteAdministrator = user.IsAdministrator;

                if (org != null)
                {
                    var orgPermissions = user.Permissions.Where(x => x.Organization.Id == org.Id);
                    model.CanAssignRights          = orgPermissions.Any(x => x.Right == Right.CanAssignRights);
                    model.CanViewAllCatalogRecords = orgPermissions.Any(x => x.Right == Right.CanViewAllCatalogRecords);
                    model.CanAssignCurator         = orgPermissions.Any(x => x.Right == Right.CanAssignCurator);
                    model.CanEditOrganization      = orgPermissions.Any(x => x.Right == Right.CanEditOrganization);
                    model.CanApprove = orgPermissions.Any(x => x.Right == Right.CanApprove);
                }

                // Map information from the user object to the view model.
                model.UserName           = user.UserName;
                model.FirstName          = user.FirstName;
                model.LastName           = user.LastName;
                model.Affiliation        = user.Affiliation;
                model.ContactInformation = user.ContactInformation;
                model.Orcid       = user.Orcid;
                model.Email       = user.Email;
                model.PhoneNumber = user.PhoneNumber;


                return(View(model));
            }
        }