{-| Module : Main.hs Description : Gargantext DB obfuscation Copyright : (c) CNRS, 2017-Present License : AGPL + CECILL v3 Maintainer : team@gargantext.org Stability : experimental Portability : POSIX See issue https://gitlab.iscpif.fr/gargantext/haskell-gargantext/issues/282 This script obfuscates the DB. We don't use gargantext.ini on purpose, so that we don't accidentally break a running DB. The procedure is that you clone the DB and provide the cloned DB location to this script. Copy the DB with this SQL statement: CREATE DATABASE "gargantext_copy" WITH TEMPLATE "gargandbV5" OWNER gargantua; https://stackoverflow.com/questions/876522/creating-a-copy-of-a-database-in-postgresql -} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE Strict #-} module CLI.ObfuscateDB ( obfuscateDB , obfuscateDBCmd ) where import Data.Text qualified as T import Database.PostgreSQL.Simple qualified as PSQL import Database.PostgreSQL.Simple.SqlQQ (sql) import Gargantext.Core (toDBid) import Gargantext.Database.Admin.Config () import Gargantext.Database.Admin.Types.Node (NodeType(..)) import Gargantext.Prelude import Gargantext.Prelude.Database (runPGSExecute, runPGSQuery) import CLI.Types import Options.Applicative obfuscateDBCmd :: HasCallStack => Mod CommandFields CLI obfuscateDBCmd = command "obfuscate-db" (info (helper <*> fmap CLISub obfuscateDB_p) (progDesc "Obfuscate a cloned Gargantext DB.")) obfuscateDB_p :: Parser CLICmd obfuscateDB_p = fmap CCMD_obfuscate_db $ ObfuscateDBArgs <$> ( strOption ( long "db-host" <> metavar "db-host" <> help "Location of the DB server" <> value "localhost" <> showDefault ) ) <*> ( option auto ( long "db-port" <> metavar "db-port" <> value 5432 ) ) <*> ( strOption ( long "db-name" <> metavar "db-name" <> value "gargantext_copy" ) ) <*> ( strOption ( long "db-user" <> metavar "db-user" <> value "gargantua" ) ) <*> ( strOption ( long "db-password" <> metavar "db-password" <> value "" )) obfuscateDB :: ObfuscateDBArgs -> IO () obfuscateDB opts = do putText $ show opts let ci = PSQL.ConnectInfo { connectHost = T.unpack $ dbHost opts , connectPort = fromIntegral $ dbPort opts , connectUser = T.unpack $ dbUser opts , connectPassword = T.unpack $ dbPassword opts , connectDatabase = T.unpack $ dbName opts } putText $ show ci c <- PSQL.connect ci obfuscateNotes c obfuscateNotes :: PSQL.Connection -> IO () obfuscateNotes c = do let nt = toDBid Notes _ <- runPGSExecute c [sql|UPDATE nodes SET name = concat('notes-', id) WHERE typename = ?;|] (PSQL.Only nt) nsNew <- runPGSQuery c [sql|SELECT id, name FROM nodes WHERE typename = ?|] (PSQL.Only nt) :: IO [(Int, Text)] putText $ show nsNew _ <- runPGSExecute c [sql|UPDATE nodes SET hyperdata = jsonb_set(hyperdata, '{frame_id}', '"xxx"', false) WHERE typename = ?;|] (PSQL.Only nt) frameIdsNew <- runPGSQuery c [sql|SELECT id, hyperdata ->> 'frame_id' FROM nodes WHERE typename = ?;|] (PSQL.Only nt) :: IO [(Int, Text)] putText $ show frameIdsNew pure ()