From 3d4946489ccf770d9b98cf3d17b677032731cb57 Mon Sep 17 00:00:00 2001
From: Alfredo Di Napoli <alfredo.dinapoli@gmail.com>
Date: Mon, 18 Nov 2024 13:04:48 +0100
Subject: [PATCH] Extract publish_node in its own function

This function extracts the Node.Update logic for `publish_node` into a
separate function, so that we can use it in a `POST` request, i.e. a new
endpoint for publishing nodes.
---
 .../Database/Query/Table/Node/Update.hs       | 79 +++++++++++--------
 1 file changed, 44 insertions(+), 35 deletions(-)

diff --git a/src/Gargantext/Database/Query/Table/Node/Update.hs b/src/Gargantext/Database/Query/Table/Node/Update.hs
index 2dedf065..8eb68479 100644
--- a/src/Gargantext/Database/Query/Table/Node/Update.hs
+++ b/src/Gargantext/Database/Query/Table/Node/Update.hs
@@ -10,7 +10,10 @@ Portability : POSIX
 
 -}
 
-module Gargantext.Database.Query.Table.Node.Update (Update(..), update)
+module Gargantext.Database.Query.Table.Node.Update (
+    Update(..)
+  , update
+  )
   where
 
 import Database.PostgreSQL.Simple ( Only(Only) )
@@ -45,58 +48,41 @@ unOnly (Only a) = a
 
 -- | Prefer this, because it notifies parents of the node change
 update :: HasNodeError err => UserId -> Update -> Cmd err [Int]
-update _loggedInUserId u@(Rename nId _name) = do
-  ret <- update' u
+update _loggedInUserId (Rename nId newName) = do
+  ret <- rename_db_update nId newName
   mpId <- getParentId nId
   case mpId of
     Nothing -> pure ()
     Just pId -> CE.ce_notify $ CE.UpdateTreeFirstLevel pId
   return ret
-update loggedInUserId u@(Move sourceId targetId) = do
+update loggedInUserId (Move sourceId targetId) = do
   mbParentId <- getParentId sourceId
 
   -- if the source and the target are the same, this is identity.
   case sourceId == targetId of
     True  -> pure [ _NodeId sourceId ]
     False -> do
-      -- Check if the source and the target are read only (i.e. published) and
-      -- act accordingly.
-      sourceNode <- getNode sourceId
-      targetNode <- getNode targetId
-
       isSourceRO <- isNodeReadOnly sourceId
       isTargetRO <- isNodeReadOnly targetId
 
+      -- Check if the source and the target are read only (i.e. published) and
+      -- act accordingly.
       ids <- case (isSourceRO, isTargetRO) of
         (False, False)
           -> -- both are not read-only, normal move
-             update' u
+             move_db_update sourceId targetId
         (False, True)
-          -> -- the target is read only
-             -- First of all, we need to understand if the target node
-             -- is a public folder, as we don't allow (at the moment)
-             -- publishing into sub (public) directories.
-             do case fromDBid $ _node_typename targetNode of
-                 NodeFolderPublic
-                   -> do
-                   check_publish_source_type_allowed (SourceId sourceId) (TargetId targetId) (fromDBid $ _node_typename sourceNode)
-                   -- See issue #400, by default we publish in a \"strict\"
-                   -- way by disallowing further edits on the original node,
-                   -- including edits from the owner itself!
-                   publishNode NPP_publish_no_edits_allowed (SourceId sourceId) (TargetId targetId)
-                   pure [ _NodeId $ sourceId]
-                 _ -> nodeError (NodeIsReadOnly targetId "Target is read only, but not a public folder.")
+          -> publish_node (SourceId sourceId) (TargetId targetId) NPP_publish_no_edits_allowed
         (True, False)
           -> -- the source is read only. If we are the owner we allow unpublishing.
              -- FIXME(adn) is this check enough?
-             do
-               case _node_user_id sourceNode == loggedInUserId of
-                 True -> do
-                   userPublicFolderNode <- getUserRootPublicNode loggedInUserId
-                   unpublishNode (SourceId $ sourceId) (TargetId $ _node_id userPublicFolderNode)
-                   -- Now we can perform the move
-                   update' u
-                 False -> nodeError (NodeIsReadOnly targetId "logged user is not allowed to move/unpublish a read-only node")
+             do sourceNode <- getNode sourceId
+                case _node_user_id sourceNode == loggedInUserId of
+                  True -> do
+                    userPublicFolderNode <- getUserRootPublicNode loggedInUserId
+                    unpublishNode (SourceId $ sourceId) (TargetId $ _node_id userPublicFolderNode)
+                    pure [ _NodeId $ sourceId]
+                  False -> nodeError (NodeIsReadOnly targetId "logged user is not allowed to move/unpublish a read-only node")
         (True, True)
           -> -- this case is not allowed.
             nodeError (NodeIsReadOnly targetId "Both the source and the target are read-only.")
@@ -106,6 +92,27 @@ update loggedInUserId u@(Move sourceId targetId) = do
 
       pure ids
 
+publish_node :: HasNodeError err => SourceId -> TargetId -> NodePublishPolicy -> Cmd err [Int]
+publish_node (SourceId sourceId) (TargetId targetId) policy = do
+  sourceNode <- getNode sourceId
+  targetNode <- getNode targetId
+
+  -- the target is read only
+  -- First of all, we need to understand if the target node
+  -- is a public folder, as we don't allow (at the moment)
+  -- publishing into sub (public) directories.
+  case fromDBid $ _node_typename targetNode of
+   NodeFolderPublic
+     -> do
+     check_publish_source_type_allowed (SourceId sourceId) (TargetId targetId) (fromDBid $ _node_typename sourceNode)
+     -- See issue #400, by default we publish in a \"strict\"
+     -- way by disallowing further edits on the original node,
+     -- including edits from the owner itself!
+     publishNode policy (SourceId sourceId) (TargetId targetId)
+     pure [ _NodeId $ sourceId]
+   _ -> nodeError (NodeIsReadOnly targetId "Target is read only, but not a public folder.")
+
+
 -- Issue #400, for now we support only publishing corpus nodes
 check_publish_source_type_allowed :: HasNodeError err => SourceId -> TargetId -> NodeType -> Cmd err ()
 check_publish_source_type_allowed (SourceId nId) (TargetId tId) = \case
@@ -114,6 +121,8 @@ check_publish_source_type_allowed (SourceId nId) (TargetId tId) = \case
   _            -> nodeError (MoveError nId tId "At the moment only corpus nodes can be published.")
 
 -- TODO-ACCESS
-update' :: Update -> DBCmd err [Int]
-update' (Rename nId name) = map unOnly <$> runPGSQuery "UPDATE nodes SET name=? where id=? returning id" (DT.take 255 name, nId)
-update' (Move nId pId)    = map unOnly <$> runPGSQuery "UPDATE nodes SET parent_id= ? where id=? returning id" (pId, nId)
+rename_db_update :: NodeId -> Name -> DBCmd err [Int]
+rename_db_update nId name = map unOnly <$> runPGSQuery "UPDATE nodes SET name=? where id=? returning id" (DT.take 255 name, nId)
+
+move_db_update :: NodeId -> NodeId -> DBCmd err [Int]
+move_db_update nId pId = map unOnly <$> runPGSQuery "UPDATE nodes SET parent_id= ? where id=? returning id" (pId, nId)
-- 
2.21.0