Exemplo n.º 1
0
        /// <summary>
        /// Create a new organization or update an existing one.
        /// This method will never be called if the organization.Id is null (for example, if the attribute
        /// has not been requested from RM Unify).
        /// If your app stores information about an organization, it should use organization.Id as a key to create a
        /// new organization record or update an existing one.
        /// </summary>
        /// <param name="org">Organization profile</param>
        /// <param name="source">Source of update (sign on or provisioning)</param>
        public override void CreateOrUpdateOrganization(RmUnifyOrganization org, Source source)
        {
            using (var context = new Context())
            {
                School school = (from s in context.Schools
                                 where s.RmUnifyId == org.Id
                                 select s).SingleOrDefault();
                if (school == null)
                {
                    school = new School()
                    {
                        RmUnifyId = org.Id
                    };
                    context.Schools.Add(school);
                }
                school.Name = org.Name;
                school.DfeCode = org.Code;
                school.PostCode = "N/A";
                school.IsRmUnifySchool = true;
                context.SaveChanges();

                // Cache school for next method
                _school = school;
            }
        }
        public ActionResult Create(School school)
        {
            try
            {
                using (var context = new Context())
                {
                    context.Schools.Add(school);
                    context.SaveChanges();

                    var account = new Account()
                    {
                        LoginName = "school" + school.Id.ToString() + "admin",
                        Password = "******",
                        SchoolId = school.Id,
                        Role = (int) Role.Admin,
                        DisplayName = school.Name + " admin"
                    };
                    context.Accounts.Add(account);
                    context.SaveChanges();

                    TempData["message"] = "New admin account: " + account.LoginName + " " + account.Password;
                }

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
        public ActionResult Create(AccountViewModel model)
        {
            if (ModelState.IsValid)
            {
                using (var context = new Context())
                {
                    Account oldAccount = (from a in context.Accounts
                                          where a.LoginName == model.LoginName
                                          select a).SingleOrDefault();
                    if (oldAccount != null)
                    {
                        ModelState.AddModelError("LoginName", "Login name already in use");
                    }
                    else
                    {
                        Account account = new Account()
                        {
                            LoginName = model.LoginName,
                            Password = model.Password,
                            DisplayName = model.DisplayName,
                            RoleEnum = model.RoleEnum,
                            SchoolId = School.Current.Id
                        };
                        context.Accounts.Add(account);
                        context.SaveChanges();

                        return RedirectToAction("Index");
                    }
                }
            }

            model.CanEditDisplayName = model.CanEditLoginName = model.CanEditRole = model.CanEditPassword = true;
            return View(model);
        }
        /// <summary>
        /// Create a new organization or update an existing one.
        /// This method will never be called if the organization.Id is null (for example, if the attribute
        /// has not been requested from RM Unify).
        /// If your app stores information about an organization, it should use organization.Id as a key to create a
        /// new organization record or update an existing one.
        /// </summary>
        /// <param name="organization">Organization profile</param>
        /// <param name="source">Source of update (sign on or provisioning)</param>
        public override void CreateOrUpdateUser(RmUnifyUser rmUser, Source source)
        {
            /// This override supports giving each user a login name that is suitable for display
            if (_school == null)
            {
                throw new Exception("CreateOrUpdateUser() called before CreateOrUpdateOrganization()");
            }

            using (var context = new Context())
            {
                Account account = (from a in context.Accounts
                                   where a.RmUnifyId == rmUser.Id
                                   select a).SingleOrDefault();
                if (account == null)
                {
                    account = new Account()
                    {
                        RmUnifyId = rmUser.Id,
                        SchoolId = _school.Id,
                        Password = Guid.NewGuid().ToString() // use random unguessable password
                    };
                    context.Accounts.Add(account);
                }
                else
                {
                    if (account.SchoolId != _school.Id)
                    {
                        // If you use rmUnifyUser.PersonId, you will need to support a user moving between schools
                        // If you use rmUnifyUser.Id, a user moving between schools will be assigned a new Id
                        throw new Exception("School moves not supported");
                    }
                }

                account.LoginName = DeDupeLoginName(rmUser.UnifyUserName, rmUser.Id);
                account.DisplayName = rmUser.DisplayName;
                account.RoleEnum = GetRole(rmUser);
                account.DeletedDate = null;  // if previously deleted, restore
                if (source == Source.SingleSignOn)
                {
                    account.LastLogin = DateTime.Now;
                }
                context.SaveChanges();

                // Cache account for next method
                _account = account;
            }

            // Purge any old users from the system
            // In this example, we've chosen to implement this in the login process
            // If this is likely to be long running, we might want to implement it as a background task
            PurgeUsers();
        }
        public ActionResult Index()
        {
            using (var context = new Context())
            {
                ViewBag.SchoolName = Account.Current.School.Name;
                var posts = (from p in context.Posts.Include("Account")
                             where p.Account.SchoolId == School.Current.Id
                             orderby p.Created descending
                             select p).Take(10).ToList();

                return View(posts);
            }
        }
 /// <summary>
 /// Check that a pre-existing organization that has been linked to RM Unify is licenced in your app.
 /// Only necessary if your app supports SSO Connectors (http://dev.rmunify.com/reference/supporting-sso-connector-licensing.aspx).
 /// In this case, the organization has purchased your app outside RM Unify and wishes to connect RM Unify to this
 /// licence. They get an "app establishment key" from you and enter it into RM Unify. This key is passed in to this
 /// method for you to verify the licence.
 /// Called before UpdateLinkedOrganization() if the organization has an SSO Connector to your app.
 /// </summary>
 /// <param name="appEstablishmentKey">App establishment key (as provided by you to the organization)</param>
 /// <param name="organization">Organization profile</param>
 /// <param name="source">Source of update (sign on or provisioning)</param>
 /// <returns>True if organization licensed, false otherwise</returns>
 public override bool IsOrganizationLicensed(string appEstablishmentKey, RmUnifyOrganization organization, Source source)
 {
     using (var context = new Context())
     {
         var school = (from s in context.Schools
                         where s.RmUnifyId == appEstablishmentKey
                         select s).SingleOrDefault();
         if (school == null)
         {
             throw new RmUnifySsoException(RmUnifySsoException.ERRORCODES_INVALIDAPPESTABLISHMENTKEY, "No school with app establishment key: " + appEstablishmentKey);
         }
         return school.Licenced;
     }
 }
        public ActionResult Create(Post post)
        {
            if (ModelState.IsValid)
            {
                using (var context = new Context())
                {
                    post.Created = DateTime.Now;
                    post.AccountId = Account.Current.Id;
                    context.Posts.Add(post);
                    context.SaveChanges();
                }

                return RedirectToAction("Index");
            }

            return View(post);
        }
        public ActionResult Delete(int id)
        {
            using (var context = new Context())
            {
                Account account = (from a in context.Accounts
                                   where a.Id == id && a.SchoolId == School.Current.Id
                                     && a.DeletedDate == null
                                   select a).SingleOrDefault();

                // account not found or not in school
                if (account == null)
                {
                    return this.HttpNotFound();
                }

                return View(new AccountViewModel(account));
            }
        }
        public ActionResult Index(AccountViewModel model)
        {
            if (ModelState.IsValid)
            {
                if (CanEditDisplayName())
                {
                    using (var context = new Context())
                    {
                        Account account = (from a in context.Accounts
                                           where a.Id == Account.Current.Id
                                           select a).FirstOrDefault();
                        account.DisplayName = model.DisplayName;
                        context.SaveChanges();
                    }
                }

                return RedirectToAction("Index", "Blog");
            }

            return Index();
        }
        public ActionResult AppEstablishmentKey()
        {
            RmUnifyAppEstablishmentKeyViewModel m = new RmUnifyAppEstablishmentKeyViewModel();
            m.AppEstablishmentKey = School.Current.RmUnifyId;

            if (string.IsNullOrEmpty(m.AppEstablishmentKey))
            {
                using (var context = new Context())
                {
                    School school = (from s in context.Schools
                                     where s.Id == School.Current.Id
                                     select s).SingleOrDefault();
                    school.RmUnifyId = Guid.NewGuid().ToString();
                    context.SaveChanges();
                    m.AppEstablishmentKey = school.RmUnifyId;
                }

            }

            return View(m);
        }
        public ActionResult AppEstablishmentKey(RmUnifyAppEstablishmentKeyViewModel m)
        {
            Regex displayNameRegex = new Regex(@"^\s*(Mr.?|Mrs.?|Ms.?|Dr.?|Madame|Monsieur|Prof.?|Professor|Sir)?\s*(\S*)\s*(.+)\s*$");

            // Get a CSV of all users in the school
            using (var context = new Context())
            {
                var accounts = (from a in context.Accounts
                                where a.SchoolId == School.Current.Id && a.DeletedDate == null
                                select a);

                Response.ContentType = "text/csv";
                Response.AddHeader("Content-Disposition", "attachment;filename=appusers.csv");
                Response.Write("FirstName,LastName,UserId\r\n");
                foreach (var account in accounts)
                {
                    Match match = displayNameRegex.Match(account.DisplayName);
                    if (match.Success)
                    {
                        Response.Write(EscapeCsvField(match.Groups[2].Value));
                        Response.Write(",");
                        Response.Write(EscapeCsvField(match.Groups[3].Value));
                        Response.Write(",");
                    }
                    else
                    {
                        Response.Write(",");
                        Response.Write(EscapeCsvField(account.DisplayName));
                        Response.Write(",");
                    }
                    Response.Write(EscapeCsvField(account.LoginName));
                    Response.Write("\r\n");
                }
                Response.End();
            }

            return this.Content("Should never see this");
        }
        public ActionResult Password(PasswordChangeViewModel model)
        {
            if (ModelState.IsValid)
            {
                if (Account.Current.Password != model.OldPassword)
                {
                    ModelState.AddModelError("OldPassword", "Incorrect old password");
                    return View(model);
                }
                using (var context = new Context())
                {
                    Account account = (from a in context.Accounts
                                       where a.Id == Account.Current.Id
                                       select a).FirstOrDefault();
                    account.Password = model.NewPassword;
                    context.SaveChanges();
                }

                return RedirectToAction("Index", "Blog");
            }

            return View(model);
        }
        public ActionResult Delete(int id, School school)
        {
            if (id != 0)
            {
                using (var context = new Context())
                {
                    var accounts = (from a in context.Accounts
                                    where a.SchoolId == id
                                    select a);
                    foreach (var account in accounts)
                    {
                        context.Accounts.Remove(account);
                    }

                    var posts = (from p in context.Posts
                                 where p.Account.SchoolId == id
                                 select p);
                    foreach (var post in posts)
                    {
                        context.Posts.Remove(post);
                    }

                    var sch = (from s in context.Schools
                               where s.Id == id
                               select s).FirstOrDefault();
                    if (sch != null)
                    {
                        context.Schools.Remove(sch);
                    }

                    context.SaveChanges();
                }
            }

            return RedirectToAction("Index");
        }
Exemplo n.º 14
0
        protected void PurgeUsers()
        {
            using (var context = new Context())
            {
                // Purge users who were deleted more than a year ago
                // Don't purge users who have authored blog posts (because that will break attribution on the blog post)
                DateTime minDeleted = DateTime.Now.AddMonths(-12);
                var toPurge = from a in context.Accounts
                              where a.School.IsRmUnifySchool == true && a.DeletedDate != null && a.DeletedDate < minDeleted
                                && !(from p in context.Posts select p.AccountId).Contains(a.Id)
                              select a;
                foreach (var account in toPurge)
                {
                    context.Accounts.Remove(account);
                }

                // Soft delete users who last logged in more than 3 months ago
                DateTime minLastLogin = DateTime.Now.AddMonths(-3);
                var toDelete = from a in context.Accounts
                               where a.School.IsRmUnifySchool == true && a.DeletedDate == null && a.LastLogin != null && a.LastLogin < minLastLogin
                               select a;
                foreach (var account in toDelete)
                {
                    account.DeletedDate = DateTime.Now;
                }

                context.SaveChanges();
            }
        }
 private School GetSchool(int id)
 {
     using (var context = new Context())
     {
         var school = (from s in context.Schools
                       where s.Id == id
                       select s).FirstOrDefault();
         return school;
     }
 }
 public ActionResult Index()
 {
     if (TempData["message"] != null)
     {
         ViewBag.Message = TempData["message"] as string;
     }
     using (var context = new Context())
     {
         var schools = (from s in context.Schools
                        where s.Id != 1
                        select s).ToList();
         return View(schools);
     }
 }
        public ActionResult Edit(int id, School school)
        {
            using (var context = new Context())
            {
                var sch = (from s in context.Schools
                              where s.Id == id
                              select s).FirstOrDefault();
                if (sch == null)
                {
                    return new HttpNotFoundResult();
                }

                sch.Name = school.Name;
                sch.PostCode = school.PostCode;
                sch.DfeCode = school.DfeCode;
                sch.Licenced = school.Licenced;
                context.SaveChanges();
            }

            return RedirectToAction("Index");
        }
        /// <summary>
        /// Make sure that the login name supplied for an RM Unify user is unique
        /// This is only necessary if we are using RM Unify login names - which we only need to do if our
        /// app displays a login name.  Otherwise, we can simply store the rmUnifyUser.Id property in
        /// place of a login name.
        /// </summary>
        /// <param name="loginName">Login name</param>
        /// <param name="rmUnifyId">RM Unify User ID</param>
        /// <returns>New username</returns>
        private static string DeDupeLoginName(string loginName, string rmUnifyId)
        {
            using (var context = new Context())
            {
                // Should always return 0 or 1 matches, but we'll cope with the case of already having a username clash
                var matchingAccounts = (from a in context.Accounts
                                        where a.LoginName == loginName
                                        select a).ToList();

                // Are there any accounts which were not created by RM Unify with a matching login name?
                foreach (var account in matchingAccounts)
                {
                    // Note that we need to test RmUnifyId == null, not School.IsRmUnifySchool = false.
                    // This is because School.IsRmUnifySchool = true will include accounts which have been linked to RM Unify
                    // (where login name does matter - see RmUnifyWithAccountLinking.cs); accounts with RmUnifyId != null
                    // were *created* by RM Unify - in this case login name is not important.
                    if (account.RmUnifyId == null)
                    {
                        // If there are non-RM Unify accounts, we'll need to find a different login name for this account
                        return DeDupeLoginName(IncrementLoginName(loginName), rmUnifyId);
                    }
                }

                // Rename any existing RM Unify accounts that match loginName
                // We rename the matching accounts rather than the current one as we assume that the matching accounts are defunct
                foreach (var account in matchingAccounts)
                {
                    if (account.RmUnifyId != null && account.RmUnifyId != rmUnifyId)
                    {
                        account.LoginName = DeDupeLoginName(IncrementLoginName(account.LoginName), account.RmUnifyId);
                    }
                }

                context.SaveChanges();
            }

            return loginName;
        }
 public ActionResult Index()
 {
     using (var context = new Context())
     {
         var accountViewModels = (from a in context.Accounts
                                  where a.SchoolId == School.Current.Id && a.DeletedDate == null
                                  orderby a.DisplayName
                                  select a).ToList().Select(model => new AccountViewModel(model));
         return View(accountViewModels);
     }
 }
        public ActionResult Delete(int id, string btnSubmit)
        {
            // RMUNIFY
            if (School.Current.IsRmUnifySchool)
            {
                throw new Exception("Can't delete users in RM Unify schools");
            }
            // END RMUNIFY

            // can't delete myself
            if (id == Account.Current.Id)
            {
                return new HttpUnauthorizedResult();
            }

            using (var context = new Context())
            {
                Account account = (from a in context.Accounts
                                   where a.Id == id && a.SchoolId == School.Current.Id
                                     && a.DeletedDate == null
                                   select a).SingleOrDefault();

                // account not found or not in school
                if (account == null)
                {
                    return this.HttpNotFound();
                }

                account.DeletedDate = DateTime.Now;
                context.SaveChanges();
            }
            return RedirectToAction("Index");
        }
        public ActionResult Edit(int id)
        {
            using (var context = new Context())
            {
                Account account = (from a in context.Accounts
                                   where a.Id == id && a.SchoolId == School.Current.Id
                                     && a.DeletedDate == null
                                   select a).SingleOrDefault();

                // account not found or not in school
                if (account == null)
                {
                    return this.HttpNotFound();
                }

                var model = new AccountViewModel(account);

                model.CanEditDisplayName = true;
                model.CanEditLoginName = model.CanEditRole = (id != Account.Current.Id);
                return View(model);
            }
        }
        public ActionResult Login(LoginViewModel model, string returnUrl)
        {
            if (!User.Identity.IsAuthenticated)
            {
                using (var context = new Context())
                {
                    Account account = (from a in context.Accounts.Include("School")
                                       where a.LoginName == model.LoginName
                                         && a.DeletedDate == null
                                       select a).SingleOrDefault();

                    if (account == null || account.Password != model.Password)
                    {
                        ModelState.AddModelError("LoginName", "Invalid username or password");
                    }

                    // RMUNIFY
                    if (ModelState.IsValid && account.School.IsRmUnifySchool)
                    {
                        ModelState.AddModelError("LoginName", "RM Unify sign in required");
                        ViewBag.ValidationSummary = "Your school now signs in with RM Unify; please click on the \"Sign in with RM Unify\" button";
                    }
                    // END RMUNIFY

                    if (ModelState.IsValid && account.School.Licenced == false)
                    {
                        ModelState.AddModelError("LoginName", "");
                        ViewBag.ValidationSummary = "Your school licence for School Blog has expired; please contact School Blog support to renew";
                    }

                    if (!ModelState.IsValid)
                    {
                        return View(model);
                    }

                    account.LastLogin = DateTime.Now;
                    context.SaveChanges();

                    FormsAuthentication.SetAuthCookie(account.LoginName, false);
                }
            }

            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            return RedirectToAction("Index", "Blog");
        }
        /// <summary>
        /// Update properties of a pre-existing organization that has been linked to RM Unify.
        /// Only necessary if your app supports SSO Connectors (http://dev.rmunify.com/reference/supporting-sso-connector-licensing.aspx)
        /// or the RM Unify user account matching process (http://dev.rmunify.com/reference/supporting-user-account-matching/the-rm-unify-process.aspx).
        /// In this case, the organization has obtained your app outside RM Unify and wishes to connect RM Unify to their
        /// existing establishment in your app. They get an "app establishment key" from you and enter it into RM Unify.
        /// This key is passed in to this method for you to identify the establishment and update it.
        /// Called instead of CreateOrUpdateOrganization() if the organization has an SSO Connector to your app
        /// or has linked the organization as part of the RM Unify user account matching process.
        /// </summary>
        /// <param name="appEstablishmentKey">App establishment key (as provided by you to the organization)</param>
        /// <param name="organization">Organization profile</param>
        /// <param name="source">Source of update (sign on or provisioning)</param>
        public override void UpdateLinkedOrganization(string appEstablishmentKey, RmUnifyOrganization organization, Source source)
        {
            using (var context = new Context())
            {
                var school = (from s in context.Schools
                                where s.RmUnifyId == appEstablishmentKey
                                select s).SingleOrDefault();
                if (school == null)
                {
                    throw new RmUnifySsoException(RmUnifySsoException.ERRORCODES_INVALIDAPPESTABLISHMENTKEY, "No school with app establishment key: " + appEstablishmentKey);
                }

                school.Name = organization.Name;
                school.DfeCode = organization.Code;
                school.IsRmUnifySchool = true;
                context.SaveChanges();

                // Cache school for next method
                _school = school;
            }
        }
        /// <summary>
        /// Update properties of a pre-existing user that has been linked to RM Unify.
        /// Only necessary if your app supports the RM Unify user account matching process
        /// (http://dev.rmunify.com/reference/supporting-user-account-matching/the-rm-unify-process.aspx).
        /// In this case, the organization has provisioned users into your app outside RM Unify and wishes to connect RM Unify
        /// to their existing users. Their "app establishment key" and the existing user id in your app (typically login name)
        /// is passed in to this method so that you can verify that the user is in the establishment and update them.
        /// Called instead of CreateOrUpdateUser() if the current user has been linked to a user in your app as part of the
        /// RM Unify user account matching process.
        /// </summary>
        /// <param name="appUserId">User ID in your app (typically login name)</param>
        /// <param name="appEstablishmentKey">App establishment key (as provided by you to the organization)</param>
        /// <param name="user">User profile</param>
        /// <param name="source">Source of update (sign on or provisioning)</param>
        public override void UpdateLinkedUser(string appUserId, string appEstablishmentKey, RmUnifyUser rmUser, Source source)
        {
            if (_school == null)
            {
                throw new Exception("UpdateLinkedUser() called before UpdateLinkedOrganization()");
            }

            using (var context = new Context())
            {
                var account = (from a in context.Accounts
                                where a.LoginName == appUserId
                                select a).SingleOrDefault();
                if (account == null)
                {
                    throw new RmUnifySsoException(RmUnifySsoException.ERRORCODES_INVALIDAPPUSERID, "No such username: "******"User " + appUserId + " is not in school with establishment key " + appEstablishmentKey);
                }

                account.DisplayName = rmUser.DisplayName;
                account.RoleEnum = GetRole(rmUser);
                account.DeletedDate = null;  // if previously deleted, restore
                if (source == Source.SingleSignOn)
                {
                    account.LastLogin = DateTime.Now;
                }
                context.SaveChanges();

                // Cache account for next method
                _account = account;
            }
        }
        public ActionResult Edit(int id, AccountViewModel model)
        {
            // RMUNIFY
            if (School.Current.IsRmUnifySchool)
            {
                throw new Exception("Can't edit users in RM Unify schools");
            }
            // END RMUNIFY

            model.CanEditDisplayName = true;
            model.CanEditLoginName = model.CanEditRole = (id != Account.Current.Id);

            if (ModelState.IsValid)
            {
                using (var context = new Context())
                {
                    Account oldAccount = (from a in context.Accounts
                                          where a.LoginName == model.LoginName
                                          select a).SingleOrDefault();
                    if (oldAccount != null)
                    {
                        ModelState.AddModelError("LoginName", "Login name already in use");
                    }
                    else
                    {
                        Account account = (from a in context.Accounts
                                           where a.Id == id && a.SchoolId == School.Current.Id
                                             && a.DeletedDate == null
                                           select a).SingleOrDefault();

                        // account not found or not in school
                        if (account == null)
                        {
                            return this.HttpNotFound();
                        }

                        if (model.CanEditLoginName)
                        {
                            account.LoginName = model.LoginName;
                        }
                        if (model.CanEditDisplayName)
                        {
                            account.DisplayName = model.DisplayName;
                        }
                        if (model.CanEditRole)
                        {
                            account.RoleEnum = model.RoleEnum;
                        }
                        context.SaveChanges();
                    }
                }

                return RedirectToAction("Index");
            }

            return View(model);
        }