/// <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"); }
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); }