public HttpResponseMessage DeleteComment(int id,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))]string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new BookstoreContext();

                var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
                if (user == null)
                {
                    throw new UnauthorizedAccessException("Invalid username or password");
                }

                var commentEntity = context.Comments.Include("User").SingleOrDefault(u => u.Id == id);
                if (commentEntity == null)
                {
                    throw new ServerErrorException("User does not exist.");
                }

                if (commentEntity.User.Id != user.Id)
                {
                    throw new ServerErrorException("You do not have permissions to delete other users' comments.");
                }

                context.Comments.Remove(commentEntity);
                context.SaveChanges();

                return Request.CreateResponse(HttpStatusCode.OK);
            });

            return responseMsg;
        }
        public HttpResponseMessage DeleteUser(int id,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))]string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new BookstoreContext();

                var adminUser = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
                if (adminUser == null)
                {
                    throw new UnauthorizedAccessException("Invalid username or password");
                }

                if (adminUser.IsAdmin != true)
                {
                    throw new UnauthorizedAccessException("You dont have permissions to access this resourse!");
                }

                var userEntity = context.Users.SingleOrDefault(u => u.Id == id);
                if (userEntity == null)
                {
                    throw new ServerErrorException("User does not exist.");
                }

                userEntity.IsActive = false;
                context.SaveChanges();

                return Request.CreateResponse(HttpStatusCode.OK);
            });

            return responseMsg;
        }
        public HttpResponseMessage CreateBook([FromBody]BookShortModel book,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new BookstoreContext();

                var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
                if (user == null)
                {
                    throw new InvalidOperationException("Invalid username or password");
                }

                var bookToAdd = new Book();
                bookToAdd.Title = book.Title;
                if (book.PublishDate != null)
                {
                    bookToAdd.PublishDate = book.PublishDate;
                }

                bookToAdd.CoverUrl = book.CoverUrl;

                context.Books.Add(bookToAdd);
                context.SaveChanges();
                return Request.CreateResponse(HttpStatusCode.Created);
            });

            return responseMsg;
        }
 public static void Main()
 {
     Database.SetInitializer(new MigrateDatabaseToLatestVersion<BookstoreContext, Configuration>());
     using (BookstoreContext context = new BookstoreContext())
     {
         var user = new User();
         user.Username = "******";
         user.AuthCode = "0123456789012345678901234567890123456789";
         context.Users.Add(user);
         context.SaveChanges();
     }
 }
        public HttpResponseMessage DeleteBook(int id,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))]string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                BookstoreContext context = new BookstoreContext();
                var bookEntity = context.Books.SingleOrDefault(u => u.Id == id);
                if (bookEntity == null)
                {
                    throw new ServerErrorException("User does not exist.");
                }

                context.Books.Remove(bookEntity);
                context.SaveChanges();

                return Request.CreateResponse(HttpStatusCode.OK);
            });

            return responseMsg;
        }
        public HttpResponseMessage UpdateUser([FromBody] UserFullModel userModel,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))]string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
               {
               var context = new BookstoreContext();

               var adminUser = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
               if (adminUser == null)
               {
                   throw new UnauthorizedAccessException("Invalid username or password");
               }

               if (adminUser.IsAdmin != true)
               {
                   throw new UnauthorizedAccessException("You dont have permissions to access this resourse!");
               }

               var userEntity = context.Users.SingleOrDefault(u => u.Id == userModel.Id);
               if (userModel.Username != null)
               {
                   userEntity.Username = userModel.Username;
               }

               if (userModel.IsActive != null)
               {
                   userEntity.IsActive = userModel.IsActive.Value;
               }

               if (userModel.IsAdmin != null)
               {
                   userEntity.IsAdmin = userModel.IsAdmin.Value;
               }

               context.SaveChanges();

               return Request.CreateResponse(HttpStatusCode.OK);
               });

            return responseMsg;
        }
        public HttpResponseMessage RegisterUser([FromBody]UserUnloggedModel userModel)
        {
            var responseMessage = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new BookstoreContext();
                using (context)
                {
                    if (userModel == null)
                    {
                        throw new ServerErrorException("User credentials not passed correctly",
                            "invalid_credentials");
                    }

                    this.ValidateUsername(userModel.Username);
                    this.ValidateAuthCode(userModel.AuthCode);

                    var lowerCaseUsername = userModel.Username.ToLower();

                    var existingUser = context.Users.SingleOrDefault(u => u.Username == lowerCaseUsername);

                    if (existingUser != null)
                    {
                        throw new ServerErrorException("User with that username or nickname already exists.", "user_exists");
                    }

                    var newUser = new User();
                    newUser.Username = lowerCaseUsername;
                    newUser.AuthCode = userModel.AuthCode;
                    newUser.IsActive = true;
                    context.Users.Add(newUser);
                    context.SaveChanges();

                    var sessionKey = this.GenerateSessionKey(newUser.Id);
                    newUser.SessionKey = sessionKey;
                    context.SaveChanges();

                    var userReturnModel = new UserLoggedModel();
                    userReturnModel.SessionKey = newUser.SessionKey;
                    userReturnModel.DisplayName = newUser.Username;

                    return Request.CreateResponse(HttpStatusCode.Created, userReturnModel);
                }
            });

            return responseMessage;
        }
        public HttpResponseMessage LogoutUser([
            ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMessage = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new BookstoreContext();
                using (context)
                {
                    this.ValidateSessionKey(context, sessionKey);
                    var existingUser = context.Users.SingleOrDefault(u => u.SessionKey == sessionKey);

                    /* If you want the comparison to be case-sensitive, please uncomment.
                    if (existingUser == null /*|| existingUser.SessionKey != sessionKey)
                    {
                        throw new ServerErrorException("Invalid session key", "inv_session_key");
                    }*/

                    existingUser.SessionKey = null;
                    context.SaveChanges();

                    return Request.CreateResponse(HttpStatusCode.OK);
                }
            });

            return responseMessage;
        }
        public HttpResponseMessage LoginUser([FromBody]UserUnloggedModel userModel)
        {
            var responseMessage = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new BookstoreContext();
                using (context)
                {
                    if (userModel == null)
                    {
                        throw new ServerErrorException("User credentials not passed correctly", "invalid_credentials");
                    }

                    this.ValidateUsername(userModel.Username);
                    this.ValidateAuthCode(userModel.AuthCode);

                    var lowerCaseUsername = userModel.Username.ToLower();

                    var existingUser = context.Users.SingleOrDefault(u => u.Username == lowerCaseUsername &&
                        u.AuthCode == userModel.AuthCode);

                    if (existingUser == null)
                    {
                        throw new ServerErrorException("User with that username or password does not exist.", "user_does_not_exist");
                    }

                    if (existingUser.IsActive == false)
                    {
                        throw new ServerErrorException("User is not active.", "user_is_not_active");
                    }

                    if (existingUser.SessionKey == null)
                    {
                        var sessionKey = this.GenerateSessionKey(existingUser.Id);
                        existingUser.SessionKey = sessionKey;
                        context.SaveChanges();
                    }

                    var userReturnModel = new UserLoggedModel();
                    userReturnModel.SessionKey = existingUser.SessionKey;
                    userReturnModel.DisplayName = existingUser.Username;

                    return Request.CreateResponse(HttpStatusCode.Created, userReturnModel);
                }
            });

            return responseMessage;
        }
        public HttpResponseMessage PostComment([FromBody]CommentPostModel comment,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new BookstoreContext();

                var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
                if (user == null)
                {
                    throw new InvalidOperationException("Invalid username or password");
                }

                var book = context.Books.SingleOrDefault(b => b.Id == comment.BookId);
                if (book == null)
                {
                    throw new ServerErrorException("Book to comment does not exist.");
                }

                var commentToAdd = new Comment();
                commentToAdd.Text = comment.Text;
                commentToAdd.User = user;
                commentToAdd.Book = book;
                context.Comments.Add(commentToAdd);
                context.SaveChanges();
                return Request.CreateResponse(HttpStatusCode.Created);
            });

            return responseMsg;
        }
        public HttpResponseMessage UpdateBook([FromBody] BookShortModel bookModel,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))]string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                BookstoreContext context = new BookstoreContext();
                var bookEntity = context.Books.SingleOrDefault(u => u.Id == bookModel.Id);
                if (bookModel.Title != null)
                {
                    bookEntity.Title = bookModel.Title;
                }

                if (bookModel.PublishDate != null)
                {
                    bookEntity.PublishDate = bookModel.PublishDate;
                }

                if (bookModel.CoverUrl != null)
                {
                    bookEntity.CoverUrl = bookModel.CoverUrl;
                }

                context.SaveChanges();

                return Request.CreateResponse(HttpStatusCode.OK);
            });

            return responseMsg;
        }