<commit_before>module Handler.ProjectBlog where

import Import

import Handler.Comment
import Handler.Discussion
import Handler.Utils
import Model.Blog
import Model.Comment
import Model.Comment.ActionPermissions
import Model.Comment.HandlerInfo
import Model.Comment.Mods
import Model.Comment.Sql
import Model.Markdown
import Model.User
import View.Comment
import View.Project
import View.User

import Widgets.Preview
import Widgets.Time

import           Data.Default
import qualified Data.Text      as T
import           Data.Tree      (Forest, Tree)
import qualified Data.Tree      as Tree

import           Text.Cassius   (cassiusFile)


-- | Sanity check for Project Comment pages. Redirects if the comment was rethreaded.
-- 404's if the comment doesn't exist. 403 if permission denied.
checkComment :: Text -> Text -> CommentId -> Handler (Maybe (Entity User), Entity Project, Comment)
checkComment project_handle post_name comment_id = do
    muser <- maybeAuth
    (project, comment) <- checkComment' (entityKey <$> muser) project_handle post_name comment_id
    return (muser, project, comment)

-- | Like checkComment, but authentication is required.
checkCommentRequireAuth :: Text -> Text -> CommentId -> Handler (Entity User, Entity Project, Comment)
checkCommentRequireAuth project_handle post_name comment_id = do
    user@(Entity user_id _) <- requireAuth
    (project, comment) <- checkComment' (Just user_id) project_handle post_name comment_id
    return (user, project, comment)

-- | Abstract checkComment and checkCommentRequireAuth. You shouldn't use this function directly.
checkComment' :: Maybe UserId -> Text -> Text -> CommentId -> Handler (Entity Project, Comment)
checkComment' muser_id project_handle post_name comment_id = do
    redirectIfRethreaded comment_id

    (project, blog_post, ecomment) <- runYDB $ do
        liftIO $ appendFile "log" $ unwords [ "getting project with handle", show project_handle ] ++ "\n"
        project@(Entity project_id _)   <- getBy404 $ UniqueProjectHandle project_handle

        liftIO $ appendFile "log" $ unwords [ "getting post for project", show project_id, "with handle", show post_name ] ++ "\n"
        Entity _ blog_post              <- getBy404 $ UniqueBlogPost project_id post_name

        let has_permission = exprCommentProjectPermissionFilter muser_id (val project_id)

        ecomment <- fetchCommentDB comment_id has_permission
        return (project, blog_post, ecomment)

    case ecomment of
        Left CommentNotFound         -> do
            liftIO $ appendFile "log" "comment not found"
            notFound

        Left CommentPermissionDenied -> permissionDenied "You don't have permission to view this comment."
        Right comment                ->
            if commentDiscussion comment /= blogPostDiscussion blog_post
                then do
                    liftIO $ appendFile "log" $ unwords
                        [ "comment discussion"
                        , show $ commentDiscussion comment
                        , "does not match blog post discussion"
                        , show $ blogPostDiscussion blog_post
                        ]

                    notFound

                else return (project, comment)


checkBlogPostCommentActionPermission
        :: (CommentActionPermissions -> Bool)
        -> Entity User
        -> Text
        -> Entity Comment
        -> Handler ()
checkBlogPostCommentActionPermission
        can_perform_action
        user
        project_handle
        comment@(Entity comment_id _) = do

    action_permissions <-
        lookupErr "checkBlogPostCommentActionPermission: comment id not found in map" comment_id
            <$> makeProjectCommentActionPermissionsMap (Just user) project_handle def [comment]

    unless (can_perform_action action_permissions) $ permissionDenied "You don't have permission to perform this action."

makeBlogPostCommentForestWidget
        :: Maybe (Entity User)
        -> ProjectId
        -> Text
        -> Text<commit_msg>Stripping some debugging, committed accidentally<commit_after>module Handler.ProjectBlog where

import Import

import Handler.Comment
import Handler.Discussion
import Handler.Utils
import Model.Blog
import Model.Comment
import Model.Comment.ActionPermissions
import Model.Comment.HandlerInfo
import Model.Comment.Mods
import Model.Comment.Sql
import Model.Markdown
import Model.User
import View.Comment
import View.Project
import View.User

import Widgets.Preview
import Widgets.Time

import           Data.Default
import qualified Data.Text      as T
import           Data.Tree      (Forest, Tree)
import qualified Data.Tree      as Tree

import           Text.Cassius   (cassiusFile)


-- | Sanity check for Project Comment pages. Redirects if the comment was rethreaded.
-- 404's if the comment doesn't exist. 403 if permission denied.
checkComment :: Text -> Text -> CommentId -> Handler (Maybe (Entity User), Entity Project, Comment)
checkComment project_handle post_name comment_id = do
    muser <- maybeAuth
    (project, comment) <- checkComment' (entityKey <$> muser) project_handle post_name comment_id
    return (muser, project, comment)

-- | Like checkComment, but authentication is required.
checkCommentRequireAuth :: Text -> Text -> CommentId -> Handler (Entity User, Entity Project, Comment)
checkCommentRequireAuth project_handle post_name comment_id = do
    user@(Entity user_id _) <- requireAuth
    (project, comment) <- checkComment' (Just user_id) project_handle post_name comment_id
    return (user, project, comment)

-- | Abstract checkComment and checkCommentRequireAuth. You shouldn't use this function directly.
checkComment' :: Maybe UserId -> Text -> Text -> CommentId -> Handler (Entity Project, Comment)
checkComment' muser_id project_handle post_name comment_id = do
    redirectIfRethreaded comment_id

    (project, blog_post, ecomment) <- runYDB $ do
        project@(Entity project_id _)   <- getBy404 $ UniqueProjectHandle project_handle
        Entity _ blog_post              <- getBy404 $ UniqueBlogPost project_id post_name

        let has_permission = exprCommentProjectPermissionFilter muser_id (val project_id)

        ecomment <- fetchCommentDB comment_id has_permission
        return (project, blog_post, ecomment)

    case ecomment of
        Left CommentNotFound         -> notFound
        Left CommentPermissionDenied -> permissionDenied "You don't have permission to view this comment."
        Right comment                ->
            if commentDiscussion comment /= blogPostDiscussion blog_post
                then notFound
                else return (project, comment)


checkBlogPostCommentActionPermission
        :: (CommentActionPermissions -> Bool)
        -> Entity User
        -> Text
        -> Entity Comment
        -> Handler ()
checkBlogPostCommentActionPermission
        can_perform_action
        user
        project_handle
        comment@(Entity comment_id _) = do

    action_permissions <-
        lookupErr "checkBlogPostCommentActionPermission: comment id not found in map" comment_id
            <$> makeProjectCommentActionPermissionsMap (Just user) project_handle def [comment]

    unless (can_perform_action action_permissions) $ permissionDenied "You don't have permission to perform this action."

makeBlogPostCommentForestWidget
        :: Maybe (Entity User)
        -> ProjectId
        -> Text
        -> Text
{'fraction_non_alphanumeric': 0.06706087891412445, 'fraction_numerical': 0.0032253729337454644, 'mean_word_length': 2.977552111170497, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1319957', 'n_tokens_mistral': 1941, 'n_tokens_neox': 1820, 'n_words': 621}