public HttpResponseMessage PostLoginUser(UserModel model)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
            {
                using (var dbContext = new AcadBlogContext())
                {
                    this.ValidateUsername(model.Username);
                    this.ValidateAuthCode(model.AuthCode);

                    var usernameAsLowercase = model.Username.ToLower();
                    var existingUser = dbContext.Users.FirstOrDefault(
                        u => u.Username == usernameAsLowercase &&
                        u.AuthCode == model.AuthCode);

                    if (existingUser == null)
                    {
                        throw new InvalidOperationException(
                            "Username or password is invalid.");
                    }

                    if (existingUser.SessionKey == null)
                    {
                        existingUser.SessionKey = this.GenerateSessionKey(existingUser.Id);
                        dbContext.SaveChanges();
                    }

                    var loggedModel = new LoggedUserModel()
                    {
                        Displayname = existingUser.Displayname,
                        SessionKey = existingUser.SessionKey
                    };

                    var response = this.Request.CreateResponse(HttpStatusCode.OK,
                        loggedModel);

                    return response;
                };
            });

            return responseMsg;
        }
        public HttpResponseMessage PostRegisterUser(UserModel model)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
            {
                using (var dbContext = new AcadBlogContext())
                {
                    this.ValidateUsername(model.Username);
                    this.ValidateNickname(model.Displayname);
                    this.ValidateAuthCode(model.AuthCode);

                    var usernameAsLowercase = model.Username.ToLower();
                    var nicknameAsLowercase = model.Displayname.ToLower();

                    var existingUser = dbContext.Users.FirstOrDefault(
                        u => u.Username == usernameAsLowercase ||
                            u.Displayname == nicknameAsLowercase);

                    if (existingUser != null)
                    {
                        throw new InvalidOperationException(
                            "User with the same displayname or username already exists.");
                    }

                    var newUser = new User()
                    {
                        Username = usernameAsLowercase,
                        Displayname = model.Displayname,
                        AuthCode = model.AuthCode,
                    };

                    dbContext.Users.Add(newUser);
                    dbContext.SaveChanges();

                    newUser.SessionKey = this.GenerateSessionKey(newUser.Id);
                    dbContext.SaveChanges();

                    var loggedModel = new LoggedUserModel()
                    {
                        Displayname = model.Displayname,
                        SessionKey = newUser.SessionKey
                    };

                    var response = this.Request.CreateResponse(HttpStatusCode.Created,
                        loggedModel);

                    return response;
                };
            });

            return responseMsg;
        }
        public HttpResponseMessage PutLogoutUser(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
            {
                using (var dbContext = new AcadBlogContext())
                {
                    this.ValidateSessionKey(sessionKey);

                    var user = dbContext.Users.FirstOrDefault(
                        u => u.SessionKey == sessionKey);

                    if (user == null)
                    {
                        throw new InvalidOperationException("Incorrect session key.");
                    }

                    user.SessionKey = null;
                    dbContext.SaveChanges();

                    var response = this.Request.CreateResponse(HttpStatusCode.OK);

                    return response;
                }
            });

            return responseMsg;
        }
        private ICollection<Tag> FindOrCreateTagsByTitle(AcadBlogContext context,
            ICollection<string> tags)
        {
            List<Tag> tagsToReturn = new List<Tag>();
            foreach (var tag in tags)
            {
                var existingTag = context.Tags.FirstOrDefault(t => t.Title == tag);
                if (existingTag != null)
                {
                    tagsToReturn.Add(existingTag);
                }
                else
                {
                    var newTag = new Tag()
                    {
                        Title = tag
                    };

                    tagsToReturn.Add(newTag);
                    context.Tags.Add(newTag);
                    context.SaveChanges();
                }
            }

            return tagsToReturn;
        }
        public HttpResponseMessage PutCommentOnAPost(
            int postId, CommentPostModel model,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
            {
                this.ValidateCommentPostModel(model);

                using (var dbContext = new AcadBlogContext())
                {
                    var user = this.ValidateAndGetUserBySessionKey(dbContext, sessionKey);
                    var post = this.ValidateAndGetPostById(dbContext, postId);

                    var newComment = new Comment()
                    {
                        Content = model.Text,
                        DateCreated = DateTime.Now,
                        User = user,
                        Post = post
                    };

                    dbContext.Comments.Add(newComment);
                    dbContext.SaveChanges();

                    var response = this.Request.CreateResponse(HttpStatusCode.OK);

                    return response;
                }
            });

            return responseMsg;
        }
        public HttpResponseMessage PostCreatePost(PostCreateRequestModel model,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
            {
                this.ValidatePostCreateModel(model);

                using (var dbContext = new AcadBlogContext())
                {
                    var user = this.ValidateAndGetUserBySessionKey(dbContext, sessionKey);

                    Post newPost = new Post
                    {
                        Title = model.Title,
                        Content = model.Text,
                        Tags = this.FindOrCreateTagsByTitle(dbContext, model.Tags),
                        PostDate = DateTime.Now,
                        User = user,
                    };

                    dbContext.Posts.Add(newPost);
                    dbContext.SaveChanges();

                    var responseModel = new PostCreateResponseModel()
                    {
                        Id = newPost.Id,
                        Title = model.Title,
                    };

                    var response = this.Request.CreateResponse(HttpStatusCode.Created,
                        responseModel);

                    return response;
                }
            });

            return responseMsg;
        }