The following code is not working correctly. It is supposed to be associating an ip address of a user with a post's content, which in an online scenareo you know can be two different ip addresses. It is therefore showing exactly what was done with an account in the event of a password cracking scenareo. It is supposed to display what the hacker did while you were out. It is just a sample program, and if you could troubleshoot my linq that would be great. What it is doing now is not correctly taking into account the date and time of the next entry in the list.

/*Author: XXX
    Purpose: To create a program that tracks the posts of disperate parties logging into an application in order to determine culpability. 
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DualPersonalitiesCulpability {

    class Program {

        static void Main(string[] args) {
            List<Post> posts = new List<Post>();

            User user = new User("Joe Schmoe");

            DateTime dateOccurred = DateTime.Now - TimeSpan.FromDays(-4);
            user.AddLoginEvent("192.168.1.1", DateTime.Now - TimeSpan.FromDays(-1));
            Post post = new Post(user, "Something Good... ", dateOccurred.AddMinutes(15));
            posts.Add(post);

            dateOccurred = DateTime.Now - TimeSpan.FromDays(-3);
            user.AddLoginEvent("192.168.1.2", dateOccurred);
            post = new Post(user, "Something Bad... ", dateOccurred.AddMinutes(15));
            posts.Add(post);

            //dateOccurred = DateTime.Now - TimeSpan.FromDays(-2);
            //user.AddLoginEvent("192.168.1.1", dateOccurred);
            //post = new Post(user, "Something Good... ", dateOccurred.AddMinutes(15));
            //posts.Add(post);

            //dateOccurred = DateTime.Now - TimeSpan.FromDays(-1);
            //user.AddLoginEvent("192.168.1.2", dateOccurred);
            //post = new Post(user, "Something Bad... ", dateOccurred.AddMinutes(15));
            //posts.Add(post);

            //var ipAndDate = user.LoginEvents.Select(usr => new { IpAddress = usr.IpAddress, DateOccurred = usr.DateOccurred, Usr = usr });

            posts = posts.OrderByDescending(p => p.DateOccurred).ToList();

            var query = user.LoginEvents.Join(posts, x => x.User, y => y.User, (x, y) => new { Login = x, Post = y })
                .Where(obj => obj.Post.DateOccurred > obj.Login.DateOccurred)
                .Join(user.LoginEvents, x => x.Login.User, y => y.User, (x, y) => new { Post = x.Post, Login = x.Login, LoginY = y })
                //.Where(obj => obj.Post.DateOccurred < obj.LoginY.DateOccurred)
                .Select(obj => new { IpAddress = obj.Login.IpAddress, Content = obj.Post.Content, DateOccurred = obj.Post.DateOccurred, NextLogin = obj.LoginY });

            //loop over query
            foreach (var entry in query) {
                Console.WriteLine(String.Format("{0}-{1}->{2}->{3}", entry.IpAddress, entry.DateOccurred, entry.Content, entry.NextLogin.ToString()));
            }//end loop

            Console.Write("Press any key to continue... ");
            Console.ReadKey();
        }//end method

    }//end class

    /// <summary>
    /// A message from one user to another. 
    /// </summary>
    public class Post {

        /// <summary>
        /// Unique database identifier for the post table. 
        /// </summary>
        public int PostId {
            get; set;
        }

        /// <summary>
        /// The content of the message. 
        /// </summary>
        public String Content {
            get; set;
        }

        /// <summary>
        /// User profile responsible for post. 
        /// </summary>
        public User User {
            get; set;
        }

        /// <summary>
        /// The date and time this post occurred. 
        /// </summary>
        public DateTime DateOccurred {
            get; set;
        }

        public Post(User user, String content, DateTime dateOccurred) {
            this.Content = content;
            this.User = user;
            this.DateOccurred = dateOccurred;
        }//end method

        /// <summary>
        /// Display a string representation of the object. 
        /// </summary>
        /// <returns></returns>
        public override string ToString() {
            return String.Format("POST: {0} {1}", this.User.ToString(), this.DateOccurred);
        }//end method

    }//end class

    /// <summary>
    /// Represents a user login. 
    /// </summary>
    public class User {

        /// <summary>
        /// Unique database identifier for the User table. 
        /// </summary>
        public int UserId {
            get; set;
        }

        /// <summary>
        /// Name of the user. 
        /// </summary>
        public String Name {
            get; set;
        }

        public User(String name) {
            this.Name = name;

            //sanity check
            if (LoginEvents == null)
                LoginEvents = new List<LoginEvent>();
        }//end method

        /// <summary>
        /// Represents a history of the user logging onto the system. 
        /// </summary>
        public IList<LoginEvent> LoginEvents {
            get; set;
        }

        /// <summary>
        /// Create a login event for this user. 
        /// </summary>
        /// <param name="evt"></param>
        private void AddLoginEvent(LoginEvent evt) {
            this.LoginEvents.Add(evt);
        }//end method

        /// <summary>
        /// Create a login event for this user. 
        /// </summary>
        /// <param name="evt"></param>
        public void AddLoginEvent(String ipAddress, DateTime dateOccurred) {
            LoginEvent evt = new LoginEvent(this, ipAddress, dateOccurred);
            AddLoginEvent(evt);
        }//end method

        /// <summary>
        /// Displays a string represenation of the object. 
        /// </summary>
        /// <returns></returns>
        public override string ToString() {
            return String.Format("{0}", this.Name);
        }//end method

    }//end class

    /// <summary>
    /// Represents the user logging into the system. 
    /// </summary>
    public class LoginEvent {

        /// <summary>
        /// Unique database identifier for the LoginEvent table. 
        /// </summary>
        public int LoginEventId {
            get; set;
        }

        /// <summary>
        /// The ip address of the user logging onto the system. 
        /// </summary>
        public String IpAddress {
            get; set;
        }

        /// <summary>
        /// The date the user logged onto the system. 
        /// </summary>
        public DateTime DateOccurred {
            get; set;
        }

        /// <summary>
        /// The user logging onto the system. 
        /// </summary>
        public User User {
            get; set;
        }

        public LoginEvent(User user, String ipAddress) {
            this.User = user;
            this.IpAddress = ipAddress;
            this.DateOccurred = DateTime.Now;
        }//end method

        public LoginEvent(User user, String ipAddress, DateTime dateOccurred) {
            this.User = user;
            this.IpAddress = ipAddress;
            this.DateOccurred = dateOccurred;
        }//end method

        /// <summary>
        /// Displays a string representation of the object. 
        /// </summary>
        /// <returns></returns>
        public override string ToString() {
            return String.Format("{0} -> {1}", User.ToString(), this.DateOccurred);
        }//end method

    }//end class

}//end namespace

Recommended Answers

All 7 Replies

Please supply more detail than "code is not working correctly." Since you are, from what I can see using Visual Studio you can set break points to examine variables and more to narrow it down.

The problem appears to be the linq. What it will have to be able to do is sort of interleave the LoginEvents which I am trying to join to twice. Essentially the where clause needs to have a greater than component, and a less than component.

            var query = user.LoginEvents.Join(posts, x => x.User, y => y.User, (x, y) => new { Login = x, Post = y })
                .Where(obj => obj.Post.DateOccurred > obj.Login.DateOccurred)
                .Join(user.LoginEvents, x => x.Login.User, y => y.User, (x, y) => new { Post = x.Post, Login = x.Login, LoginY = y })
                //.Where(obj => obj.Post.DateOccurred < obj.LoginY.DateOccurred)
                .Select(obj => new { IpAddress = obj.Login.IpAddress, Content = obj.Post.Content, DateOccurred = obj.Post.DateOccurred, NextLogin = obj.LoginY });

Here is a translation to query syntax. From what I have been learning from online sources the three 'from' statements should be cartesioning all the entries, post, logA, and logB. This is useful, but the problem is actually the where statement. The second statement in the where statement is not working correctly. I don't know exactly how to express this.

            var query = from pst in posts
                        from logA in user.LoginEvents
                        from logB in user.LoginEvents
                        where pst.DateOccurred > logA.DateOccurred && pst.DateOccurred < logB.DateOccurred
                        select new { Post = pst, LogA = logA, LogB = logB};

Actually this is linq to objects. It is completely runnable on your own system. It makes no database calls yet.

I am not on my dev machine. Also, you can break on that statement to see what it is doing.

What if some variable is not what you assumed it to be? You have an excellent dev system yet I find many ignore it and ask for the code.

The following is not exactly what I wanted, it uses looping instead of queries. I do not know a query technique that gets me around the problem with the where statement growing for every login expressed. I also noticed that some of the variables at the top of the program were not what they should have been, it was the date times of the first or second grouping of code.

List<Post> posts = new List<Post>();

            User user = new User("Joe Schmoe");

            DateTime dateOccurred = DateTime.Now - TimeSpan.FromDays(-4);
            user.AddLoginEvent("192.168.1.1", dateOccurred);
            Post post = new Post(user, "Something Good... ", dateOccurred.AddMinutes(15));
            posts.Add(post);

            dateOccurred = DateTime.Now - TimeSpan.FromDays(-3);
            user.AddLoginEvent("192.168.1.2", dateOccurred);
            post = new Post(user, "Something Bad... ", dateOccurred.AddMinutes(15));
            posts.Add(post);

            dateOccurred = DateTime.Now - TimeSpan.FromDays(-2);
            user.AddLoginEvent("192.168.1.1", dateOccurred);
            post = new Post(user, "Something Good... ", dateOccurred.AddMinutes(15));
            posts.Add(post);

            dateOccurred = DateTime.Now - TimeSpan.FromDays(-1);
            user.AddLoginEvent("192.168.1.2", dateOccurred);
            post = new Post(user, "Something Bad... ", dateOccurred.AddMinutes(15));
            posts.Add(post);

            posts = posts.OrderByDescending(p => p.DateOccurred).ToList();

            //var query = user.LoginEvents.Join(posts, x => x.User, y => y.User, (x, y) => new { Login = x, Post = y })
            //    .Where(obj => obj.Login.DateOccurred < obj.Post.DateOccurred)
            //    .Join(user.LoginEvents, x => x.Login.User, y => y.User, (x, y) => new { Post = x.Post, Login = x.Login, LoginY = y })
            //    .Where(obj => obj.LoginY.DateOccurred < obj.Post.DateOccurred);
            ////.Select(obj => new { IpAddress = obj.Login.IpAddress, Content = obj.Post.Content, DateOccurred = obj.Post.DateOccurred });
            ////.Select(obj => new { IpAddress = obj.Login.IpAddress, Content = obj.Post.Content, DateOccurred = obj.Post.DateOccurred, NextLogin = obj.LoginY });

            //var query = from pst in posts
            //            from logA in user.LoginEvents
            //            from logB in user.LoginEvents
            //            where pst.DateOccurred > logA.DateOccurred && pst.DateOccurred < logB.DateOccurred
            //            select new { Post = pst, LogA = logA, LogB = logB };

            //inputs 'posts' and 'user.LoginEvents'
            List<Tuple<Post, LoginEvent>> list = new List<Tuple<Post, LoginEvent>>();
            foreach (var pst in posts) {
                for (int i = 0; i < user.LoginEvents.Count; i++) {
                    LoginEvent current = null;
                    LoginEvent next = null;

                    try {
                        current = user.LoginEvents[i];
                    }
                    catch (ArgumentException) { }
                    try {
                        next = user.LoginEvents[i + 1];
                    }
                    catch (ArgumentException) { }

                    if (pst.DateOccurred > current.DateOccurred) { 
                        list.Add(new Tuple<Post, LoginEvent>(pst, current));
                        break;
                    }
                }//end loop
            }//end loop

            foreach (var tuple in list) {
                String ipAddress = tuple.Item2.IpAddress;
                Post p = tuple.Item1;
                Console.WriteLine(String.Format("{0} -> {1}", ipAddress, p.Content));
            }//end loop

            ////loop over query
            //foreach (var entry in query) {
            //    //Console.WriteLine(String.Format("{0}\t{1}\t{2}", entry.LogA, entry.Post, entry.LogB));
            //    Console.WriteLine(String.Format("{0} -> {1}", entry.LogA.IpAddress, entry.Post.Content));
            //    //Console.WriteLine(String.Format("{0} -> {1}", entry.Login.ToString(), entry.Post.ToString()));
            //    //Console.WriteLine(String.Format("{0} -> {1} -> {2}", entry.Login.ToString(), entry.Post.ToString(), entry.LoginY.ToString()));
            //    //Console.WriteLine(String.Format("{0}-{1}->{2}", entry.IpAddress, entry.DateOccurred, entry.Content));
            //    //Console.WriteLine(String.Format("{0}-{1}->{2}-> LoginY: {3}", entry.IpAddress, entry.DateOccurred, entry.Content, entry.NextLogin.ToString()));
            //    //Console.WriteLine(String.Format("{0}{1} PostDate: {2}... NextLogin: {3}", entry.IpAddress, entry.Content, entry.DateOccurred.ToShortDateString(), entry.NextLogin.DateOccurred.ToShortDateString()));
            //    //Console.WriteLine(String.Format("{0} --> {1}", entry.DateOccurred, entry.NextLogin.DateOccurred));
            //}//end loop

            Console.Write("Press any key to continue... ");
            Console.ReadKey();
        }//end method
commented: Working code wins over "this would be better if it worked" code. +15
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.