示例#1
0
        /// <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);
            }
        }
示例#2
0
        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());
            }
        }
示例#3
0
        /// <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();
                }
            }
        }
示例#4
0
        /// <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)));
            }
        }
示例#5
0
        /// <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);
        }
示例#6
0
        // 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
                }));
            }
        }
示例#7
0
        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());
            }
        }
示例#8
0
        // 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
                });
            }
        }
示例#9
0
 public void Init()
 {
     using (var ctx = new Models.Ao3TrackEntities())
     {
     }
 }
示例#10
0
        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));
            }
        }