/// <summary> /// GET api/values/5 /// Get single Work Chapter /// </summary> /// <param name="id">Workid</param> /// <returns>[workid]: WorkChapter</returns> public IDictionary <long, WorkChapter> Get(long id) { Int64 timestamp = 0; try { timestamp = Convert.ToInt64(Request.RequestUri.ParseQueryString().Get("after")); } catch { } using (var ctx = new Models.Ao3TrackEntities()) { ctx.Configuration.AutoDetectChangesEnabled = false; var work = (from works in ctx.Works where works.userid == User.id && works.id == id && works.timestamp > timestamp select works).AsEnumerable().FirstOrDefault(); var res = new Dictionary <long, WorkChapter> { }; if (work != null) { res.Add(id, new WorkChapter(work)); } return(res); } }
public ActionResult Reset(string id, FormCollection collection) { try { if (!Guid.TryParseExact(id, "N", out var guid)) { return(View("Error")); } var model = new Models.Passwords.Reset { Password = collection["Password"], Check = collection["Check"] }; if (!TryValidateModel(model)) { return(View(model)); } using (var ctx = new Models.Ao3TrackEntities()) { var pwreset = (from rows in ctx.PWResets where rows.id == guid select rows).Single(); if (pwreset.expires <= DateTime.Now || pwreset.complete) { return(View("LinkExpired")); } var user = (from users in ctx.Users where users.id == pwreset.user select users).Single(); if (!user.hash.SequenceEqual(pwreset.oldhash)) { return(View("LinkExpired")); } user.password = model.Password; pwreset.complete = true; ctx.SaveChanges(); return(View("ChangeDone", user)); } } catch (Exception e) { ModelState.AddModelError("", e.ToString()); return(View()); } }
/// <summary> /// DELETE api/values/5 /// Delete a single workchapter from the data /// </summary> /// <param name="id">Workid</param> /// <remarks>Warning there is no way for clients to detect deletions so this wont work as expected. /// The next time the clients sync the workchapter will be re-added to the database.</remarks> public void Delete(long id) { using (var ctx = new Models.Ao3TrackEntities()) { var table = ctx.Works; var item = (from works in table where works.userid == User.id && works.id == id select works).AsEnumerable().FirstOrDefault(); if (item != null) { table.Remove(item); ctx.SaveChanges(); } } }
/// <summary> /// GET api/values /// Get all of logged in user's work chapters /// </summary> /// <returns>[workid]: WorkChapter</returns> public IDictionary <long, WorkChapter> Get() { Int64 timestamp = 0; try { timestamp = Convert.ToInt64(Request.RequestUri.ParseQueryString().Get("after")); } catch { } using (var ctx = new Models.Ao3TrackEntities()) { ctx.Configuration.AutoDetectChangesEnabled = false; return((from works in ctx.Works where works.userid == User.id && works.timestamp > timestamp select works).AsEnumerable().ToDictionary(works => works.id, works => new WorkChapter(works))); } }
/// <summary> /// POST api/values /// </summary> /// <param name="values">WorkChapterse to add and/or update</param> /// <returns>Existing items if there are conflicts</returns> public IDictionary <long, WorkChapter> Post([FromBody] IDictionary <long, WorkChapter> values) { Dictionary <long, WorkChapter> conflicts = new Dictionary <long, WorkChapter>(); using (var ctx = new Models.Ao3TrackEntities()) { ctx.Configuration.AutoDetectChangesEnabled = true; var table = ctx.Works; foreach (var v in values) { var item = (from works in table where works.userid == User.id && works.id == v.Key select works).AsEnumerable().FirstOrDefault(); if (item != null) { if (item.timestamp < v.Value.timestamp || item.seq < v.Value.seq) { item.chapterid = v.Value.chapterid; item.number = v.Value.number; item.location = v.Value.location; item.timestamp = v.Value.timestamp; item.seq = v.Value.seq; } else { conflicts.Add(v.Key, new WorkChapter(item)); } } else { table.Add(new Work(User.id, v.Key, v.Value.chapterid, v.Value.number, v.Value.location, v.Value.timestamp, v.Value.seq)); } } ctx.SaveChanges(); } return(conflicts); }
// GET: Password/Reset/91234561.....3452345 public ActionResult Reset(string id) { if (!Guid.TryParseExact(id, "N", out var guid)) { return(View("Error")); } using (var ctx = new Models.Ao3TrackEntities()) { var pwreset = (from rows in ctx.PWResets where rows.id == guid select rows).FirstOrDefault(); if (pwreset == null) { return(View("Error")); } if (pwreset.expires <= DateTime.Now || pwreset.complete) { return(View("LinkExpired")); } var user = (from users in ctx.Users where users.id == pwreset.user select users).Single(); if (!user.hash.SequenceEqual(pwreset.oldhash)) { return(View("LinkExpired")); } return(View(new Models.Passwords.Reset { Id = guid })); } }
public ActionResult Forgot(FormCollection collection) { try { var model = new Models.Passwords.Forgot { Username = collection["Username"], Email = collection["Email"] }; if (!TryValidateModel(model)) { return(View(model)); } using (var ctx = new Models.Ao3TrackEntities()) { var user = (from users in ctx.Users where users.username == model.Username select users).FirstOrDefault(); if (user == null) { ModelState.AddModelError("Username", "Unknown Username"); return(View(model)); } if (user.email != model.Email) { ModelState.AddModelError("Email", "Email address does not match database"); return(View(model)); } var pwrequest = new Models.PWReset { id = Guid.NewGuid(), expires = DateTime.Now.AddDays(1), user = user.id, oldhash = user.hash, complete = false }; ctx.PWResets.Add(pwrequest); ctx.SaveChanges(); var uri = new Uri(Request.Url, Url.Action("Reset", new { id = pwrequest.id.ToString("N") })); MailMessage message = new MailMessage(new MailAddress("*****@*****.**", "Archive Track Reader"), new MailAddress(user.email)); message.Subject = "Archive Track Reader Password Reset Request"; var doc = new HtmlAgilityPack.HtmlDocument(); var html = doc.CreateElement("html"); doc.DocumentNode.AppendChild(html); var head = doc.CreateElement("head"); html.AppendChild(head); var title = doc.CreateElement("title"); title.AppendChild(doc.CreateTextNode("Archive Track Reader Password Reset Request")); head.AppendChild(title); var style = doc.CreateElement("style"); style.AppendChild(doc.CreateTextNode(@"body { color: #191919; background: #CCCCCC; } h1, h2, h3, h4, h5, h6, h7, h8, a { color: #A50000; } details p { color: #656565; }")); head.AppendChild(style); var body = doc.CreateElement("body"); html.AppendChild(body); var heading = doc.CreateElement("h1"); heading.AppendChild(doc.CreateTextNode("Archive Track Reader Password Reset Request")); body.AppendChild(heading); var para = doc.CreateElement("p"); para.AppendChild(doc.CreateTextNode("A Password Reset Request was made for the account: " + System.Net.WebUtility.HtmlEncode(user.username))); body.AppendChild(para); para = doc.CreateElement("p"); para.AppendChild(doc.CreateTextNode("Follow this link ")); var link = doc.CreateElement("a"); link.Attributes.Add(doc.CreateAttribute("href", System.Net.WebUtility.HtmlEncode(uri.AbsoluteUri))); link.AppendChild(doc.CreateTextNode(System.Net.WebUtility.HtmlEncode(uri.AbsoluteUri))); para.AppendChild(link); para.AppendChild(doc.CreateTextNode(" to change the account's password.")); body.AppendChild(para); para.AppendChild(doc.CreateTextNode("The link will expire at " + pwrequest.expires.ToString("r") + ".")); para = doc.CreateElement("p"); body.AppendChild(para); var writer = new System.IO.StringWriter(); doc.Save(writer); message.Body = "<!DOCTYPE html>\n" + writer.ToString(); message.IsBodyHtml = true; SmtpClient client = new SmtpClient("127.0.0.1"); client.Send(message); return(View("ForgotDone", user)); } } catch (Exception e) { ModelState.AddModelError("", e.ToString()); return(View()); } }
// POST: api/ReadingList public ReadingList Post([FromBody] ReadingList incoming) { using (var ctx = new Models.Ao3TrackEntities()) { var changes = new Dictionary <string, long>(); var existing = (from i in ctx.ReadingLists where i.userid == User.id select i).ToDictionary(i => i.path); Models.ReadingList ls; if (existing.TryGetValue("", out ls)) { existing.Remove(""); } else { ls = ctx.ReadingLists.Add(new Models.ReadingList { userid = User.id, path = "", timestamp = 0 }); } var latest = ls.timestamp; foreach (var item in existing) { if (item.Value.timestamp > latest) { latest = item.Value.timestamp; } if (!incoming.paths.ContainsKey(item.Key)) { if (item.Value.timestamp >= incoming.last_sync) { // Item was added and needs to be sent to client changes.Add(item.Key, item.Value.timestamp); } else { // Client deleted item since we last sent it ctx.ReadingLists.Remove(item.Value); } } else { incoming.paths.Remove(item.Key); } } foreach (var item in incoming.paths) { if (item.Value > latest) { latest = item.Value; } if (!existing.ContainsKey(item.Key)) { if (item.Value >= ls.timestamp) { // Item is NEW! ctx.ReadingLists.Add(new Models.ReadingList { userid = User.id, path = item.Key, timestamp = item.Value }); } else { // Item was previously deleted and client needs to be notified changes.Add(item.Key, -1); } } } ls.timestamp = latest + 1; ctx.SaveChanges(); return(new ReadingList { last_sync = ls.timestamp, paths = changes }); } }
public void Init() { using (var ctx = new Models.Ao3TrackEntities()) { } }
public object Create([FromBody] NewUser newuser) { using (var ctx = new Models.Ao3TrackEntities()) { var Users = ctx.Users; Dictionary <string, string> errors = new Dictionary <string, string> { }; // Verify username if (string.IsNullOrWhiteSpace(newuser.username)) { errors.Add("username", "username must not be empty"); } else if (newuser.username.Contains("\n")) { errors.Add("username", "username must not contain new line characters"); } else if (newuser.username.Trim() != newuser.username) { errors.Add("username", "username must not start or end with whitespace"); } else if (Users.Where(u => u.username == newuser.username).Count() != 0) { errors.Add("username", "username already exists"); } // Verify password if (string.IsNullOrWhiteSpace(newuser.password)) { errors.Add("password", "password must not be empty"); } else if (newuser.password.Length < MIN_PW_SIZE) { errors.Add("password", PW_SIZE_MSG); } // Verify email address if (string.IsNullOrWhiteSpace(newuser.email)) { newuser.email = null; } else if (!IsValidEmail(newuser.email)) { errors.Add("email", "email is not a valid email address"); } else if (Users.Where(u => u.email == newuser.email).Count() != 0) { errors.Add("email", "email already used"); } // We look good to go if (errors.Count != 0) { return(errors); } Models.User user = new Models.User(newuser.username, newuser.email, "users", newuser.password); Users.Add(user); ctx.SaveChanges(); return(Auth.HashHandler.GetHashString(user.hash)); } }