Commit e36cc6ff authored by Alexandre Delanoë's avatar Alexandre Delanoë

[CLEAN] removing Prelude && adding gargantext-prelude dependency

parent 719fd6e7
Pipeline #1606 failed with stage
in 5 minutes and 23 seconds
......@@ -65,10 +65,6 @@ library:
- Gargantext.Database.Admin.Config
- Gargantext.Database.Admin.Types.Hyperdata
- Gargantext.Database.Admin.Types.Node
- Gargantext.Prelude
- Gargantext.Prelude.Crypto.Pass.User
- Gargantext.Prelude.Crypto.Hash
- Gargantext.Prelude.Utils
- Gargantext.Core.Text
- Gargantext.Core.Text.Context
- Gargantext.Core.Text.Corpus.Parsers
......@@ -100,13 +96,13 @@ library:
dependencies:
- HSvm
- KMP
- MissingH
- MonadRandom
- QuickCheck
- SHA
- Unique
- accelerate
- accelerate-utility
- accelerate-arithmetic
- accelerate-utility
- aeson
- aeson-lens
- aeson-pretty
......@@ -124,16 +120,15 @@ library:
- case-insensitive
- cassava
- cereal # (IGraph)
- clock
- conduit
- conduit-extra
- containers
- contravariant
- cryptohash
- crawlerHAL
- crawlerISTEX
- crawlerIsidore
- crawlerPubMed
- cryptohash
- data-time-segment
- deepseq
- directory
......@@ -147,6 +142,7 @@ library:
- formatting
- full-text-search
- fullstop
- gargantext-prelude
- graphviz
- hashable
- haskell-igraph
......@@ -168,7 +164,6 @@ library:
- located-base
- logging-effect
- matrix
- MissingH
- monad-control
- monad-logger
- mtl
......@@ -191,7 +186,6 @@ library:
- quickcheck-instances
- rake
- random
- random-shuffle
- rdf4h
- regex-compat
- resource-pool
......@@ -216,24 +210,11 @@ library:
- servant-xml
- simple-reflect
- singletons # (IGraph)
- template-haskell
- wai-app-static
# for mail
- smtp-mail
- mime-mail
# for password generation
- cprng-aes
- binary
- crypto-random
- password
- split
- stemmer
- string-conversions
- swagger2
- tagsoup
- template-haskell
- temporary
- text-metrics
- time
......@@ -246,6 +227,7 @@ library:
- validity
- vector
- wai
- wai-app-static
- wai-cors
- wai-extra
- warp
......@@ -256,10 +238,6 @@ library:
- yaml
- zip
- zlib
# - kmeans-vector
#- charsetdetect-ae # detect charset
# - utc
# API external connections
executables:
gargantext-server:
......@@ -277,6 +255,7 @@ executables:
- base
- containers
- gargantext
- gargantext-prelude
- vector
- cassava
- ini
......@@ -300,6 +279,7 @@ executables:
- bytestring
- containers
- gargantext
- gargantext-prelude
- vector
- cassava
- ini
......@@ -325,6 +305,7 @@ executables:
- containers
- directory
- gargantext
- gargantext-prelude
- vector
- parallel
- cassava
......@@ -346,6 +327,7 @@ executables:
- -Wmissing-signatures
dependencies:
- gargantext
- gargantext-prelude
- base
- servant-server
......@@ -360,6 +342,7 @@ executables:
- -Wmissing-signatures
dependencies:
- gargantext
- gargantext-prelude
- base
gargantext-upgrade:
......@@ -373,6 +356,7 @@ executables:
- -Wmissing-signatures
dependencies:
- gargantext
- gargantext-prelude
- base
gargantext-admin:
......@@ -386,6 +370,7 @@ executables:
- -Wmissing-signatures
dependencies:
- gargantext
- gargantext-prelude
- base
gargantext-cbor2json:
......@@ -399,6 +384,7 @@ executables:
- -Wmissing-signatures
dependencies:
- gargantext
- gargantext-prelude
- base
- bytestring
- aeson
......@@ -426,6 +412,7 @@ tests:
dependencies:
- base
- gargantext
- gargantext-prelude
- hspec
- QuickCheck
- quickcheck-instances
......
module Gargantext.Prelude.Job where
module Gargantext.API.Job where
import Data.IORef
import Data.Maybe
......
......@@ -117,7 +117,7 @@ import Gargantext.Database.Query.Table.Node.Error (HasNodeError)
import Gargantext.Database.Query.Table.Node.Select
import Gargantext.Database.Schema.Node (node_id, node_parent_id, node_user_id)
import Gargantext.Prelude hiding (log)
import Gargantext.Prelude.Job
import Gargantext.API.Job
import Gargantext.Prelude.Clock (hasTime, getTime)
import Prelude (error)
import Servant hiding (Patch)
......
This diff is collapsed.
{-|
Module : Gargantext.Prelude.Clock
Description : Useful Tools near Prelude of the project
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
-}
module Gargantext.Prelude.Clock
where
import Formatting.Clock (timeSpecs)
import Formatting.Internal (Format(..))
import Gargantext.Prelude
import qualified System.Clock as Clock (getTime, TimeSpec, Clock(..))
---------------------------------------------------------------------------------
getTime :: MonadBase IO m => m Clock.TimeSpec
getTime = liftBase $ Clock.getTime Clock.ProcessCPUTime
hasTime :: Formatting.Internal.Format r (Clock.TimeSpec -> Clock.TimeSpec -> r)
hasTime = timeSpecs
{-|
Module : Gargantext.Prelude.Config
Description : Textmining Collaborative Platform
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
-}
{-# LANGUAGE TemplateHaskell #-}
module Gargantext.Prelude.Config where
import Prelude (read)
import System.IO (FilePath)
import Data.Ini (readIniFile, lookupValue)
import Data.Either.Extra (Either(Left, Right))
import Data.Text as T
import GHC.Generics (Generic)
import Control.Lens (makeLenses)
import Gargantext.Prelude
-- | strip a given character from end of string
stripRight :: Char -> T.Text -> T.Text
stripRight c s = if T.last s == c then stripRight c (T.take (T.length s - 1) s) else s
data GargConfig = GargConfig { _gc_url :: !T.Text
, _gc_url_backend_api :: !T.Text
, _gc_masteruser :: !T.Text
, _gc_secretkey :: !T.Text
, _gc_datafilepath :: !FilePath
, _gc_repofilepath :: !FilePath
, _gc_frame_write_url :: !T.Text
, _gc_frame_calc_url :: !T.Text
, _gc_frame_visio_url :: !T.Text
, _gc_frame_searx_url :: !T.Text
, _gc_frame_istex_url :: !T.Text
, _gc_max_docs_scrapers :: !Integer
}
deriving (Generic, Show)
makeLenses ''GargConfig
readConfig :: FilePath -> IO GargConfig
readConfig fp = do
ini <- readIniFile fp
let ini'' = case ini of
Left e -> panic (T.pack $ "gargantext.ini not found" <> show e)
Right ini' -> ini'
let val x = case (lookupValue (T.pack "gargantext") (T.pack x) ini'') of
Left _ -> panic (T.pack $ "ERROR: add " <> x <> " to your gargantext.ini")
Right p' -> p'
pure $ GargConfig (stripRight '/' $ val "URL")
(stripRight '/' $ val "URL_BACKEND_API")
(val "MASTER_USER")
(val "SECRET_KEY")
(cs $ val "DATA_FILEPATH")
(cs $ val "REPO_FILEPATH")
(stripRight '/' $ val "FRAME_WRITE_URL")
(stripRight '/' $ val "FRAME_CALC_URL")
(stripRight '/' $ val "FRAME_VISIO_URL")
(stripRight '/' $ val "FRAME_SEARX_URL")
(stripRight '/' $ val "FRAME_ISTEX_URL")
(read $ cs $ val "MAX_DOCS_SCRAPERS")
{- UNUSED
defaultConfig :: GargConfig
defaultConfig = GargConfig "https://localhost"
"https://localhost:8008/api/v1.0"
"gargantua"
"secret"
"data"
"repos/"
"https://frame_write.url"
"https://frame_calc.url"
"https://frame_searx.url"
"https://frame_istex.url"
1000
-}
{-|
Module : Gargantext.Prelude.Crypto.Auth
Description :
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
-}
module Gargantext.Prelude.Crypto.Auth ( createPasswordHash
, checkPassword
, module Data.Password.Argon2
)
where
import Control.Monad.IO.Class (MonadIO)
import Data.Text (Text)
import Data.Password.Argon2 hiding (checkPassword)
import qualified Data.Password.Argon2 as A
createPasswordHash :: MonadIO m
=> Text
-> m (PasswordHash Argon2)
createPasswordHash x = hashPassword (mkPassword x)
checkPassword :: Password
-> PasswordHash Argon2
-> PasswordCheck
checkPassword = A.checkPassword
{-
-- Notes to implement Raw Password with argon2 lib
-- (now using password library, which does not use salt anymore)
-- import Crypto.Argon2 as Crypto
-- import Data.ByteString.Base64.URL as URL
-- import Data.Either
-- import Data.ByteString (ByteString)
secret_key :: ByteString
secret_key = "WRV5ymit8s~ge6%08dLR7Q!gBcpb1MY%7e67db2206"
type SecretKey = ByteString
hashNode :: SecretKey -> NodeToHash -> ByteString
hashNode sk (NodeToHash nt ni) = case hashResult of
Left e -> panic (cs $ show e)
Right h -> URL.encode h
where
hashResult = Crypto.hash Crypto.defaultHashOptions
sk
(cs $ show nt <> show ni)
-}
{-|
Module : Gargantext.Prelude.Crypto.Hash
Description : Useful Tools near Prelude of the project
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Gargantext.Prelude.Crypto.Hash
where
import Prelude (String)
import Data.Set (Set)
import Data.Text (Text)
import Gargantext.Prelude
import qualified Data.ByteString.Lazy.Char8 as Char
import qualified Data.Digest.Pure.SHA as SHA (sha256, showDigest)
import qualified Data.Set as Set
import qualified Data.Text as Text
--------------------------------------------------------------------------
-- | Use this datatype to keep traceability of hashes
-- TODO use newtype
type Hash = Text
-- | Class to make hashes
class IsHashable a where
hash :: a -> Hash
-- | Main API to hash text
-- using sha256 for now
instance IsHashable Char.ByteString where
hash = Text.pack
. SHA.showDigest
. SHA.sha256
instance {-# OVERLAPPING #-} IsHashable String where
hash = hash . Char.pack
instance IsHashable Text where
hash = hash . Text.unpack
instance IsHashable (Set Hash) where
hash = hash . foldl (<>) "" . Set.toList
instance {-# OVERLAPPABLE #-} IsHashable a => IsHashable [a] where
hash = hash . Set.fromList . map hash
{-|
Module : Gargantext.Prelude.Crypto.Pass.Machine
Description :
Copyright : (c) CNRS, 2017-Present
License : Public Domain
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
Random Text generator (for machines mainly)
Thanks to
https://zuttobenkyou.wordpress.com/2011/12/23/simple-password-generation-with-haskell/
-}
module Gargantext.Prelude.Crypto.Pass.Machine
where
import Data.List (nub)
-- import System.Environment (getArgs)
-- import System.IO (hSetEcho)
import Control.Monad.State
import Crypto.Random (cprgGenerate)
import Crypto.Random.AESCtr
import Data.Binary (decode)
import Prelude
import qualified Data.ByteString.Lazy as B
import Data.ByteString as S (ByteString, unpack)
import Data.ByteString.Char8 as C8 (pack)
import Data.Char (chr)
strToBS :: String -> S.ByteString
strToBS = C8.pack
bsToStr :: S.ByteString -> String
bsToStr = map (chr . fromEnum) . S.unpack
keysChar, keysNum, keysPunc, keysCharNum, keysAll, keysHex :: String
keysChar = ['a'..'z'] ++ ['A'..'Z']
keysHex = ['a'..'f']
keysNum = ['0'..'9']
keysPunc = "`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/? "
keysCharNum = keysChar ++ keysNum
keysAll = keysChar ++ keysNum ++ keysPunc
giveKey :: String -> Char -> Int -> Char
giveKey keysCustom c n = extractChar $ case c of
'i' -> (keysNum ++ keysHex)
'j' -> keysNum
'k' -> keysChar
'l' -> keysCharNum
';' -> keysPunc
'h' -> (keysCharNum ++ keysCustom)
'\n' -> ['\n']
_ -> keysAll
where
extractChar xs = xs!!mod n (length xs)
showRandomKey :: Int -> String -> StateT AESRNG IO ()
showRandomKey len keysCustom = handleKey =<< liftIO getChar
where
handleKey key = case key of
'\n' -> liftIO (putChar '\n') >> showRandomKey len keysCustom
'q' -> (liftIO $ putStrLn "\nBye!") >> return ()
_ -> mapM_ f [0..len] >> (liftIO $ putStrLn []) >> showRandomKey len keysCustom
where
f _ = liftIO
. putChar
. giveKey keysCustom key
. (\n -> mod n (length (keysAll ++ keysCustom) - 1))
=<< aesRandomInt
aesRandomInt :: StateT AESRNG IO Int
aesRandomInt = do
aesState <- get
-- aesState <- liftIO makeSystem
-- let aesState = 128
let (bs, aesState') = cprgGenerate 64 aesState
put aesState'
return (decode $ B.fromChunks [bs])
printPass :: Int -> IO ()
printPass len = do
let as = ["alphanumeric","punctuation"]
let as' = filter (\c -> elem c keysAll) . nub $ unwords as
aesState <- makeSystem -- gather entropy from the system to use as the initial seed
_ <- runStateT (showRandomKey len as') aesState -- enter loop
return ()
gargPassMachine :: IO (Int, AESRNG)
gargPassMachine = do
aesState <- makeSystem -- gather entropy from the system to use as the initial seed
pass <- runStateT aesRandomInt aesState -- enter loop
pure pass
{-
main :: IO ()
main = do
hSetBuffering stdin NoBuffering -- disable buffering from STDIN
hSetBuffering stdout NoBuffering -- disable buffering from STDOUT
hSetEcho stdin False -- disable terminal echo
as <- getArgs
let as' = filter (\c -> elem c keysAll) . nub $ unwords as
mapM_ putStrLn
[ []
, "poke: 'q' quit"
, " 'j' number"
, " 'k' letter"
, " 'l' alphanumeric"
, " ';' punctuation"
, " 'h' alphanumeric" ++ (if null as' then [] else " + " ++ as')
, " 'i' hexadecimal"
, " 'ENTER' newline"
, " else any"
, []
]
aesState <- makeSystem -- gather entropy from the system to use as the initial seed
_ <- runStateT (showRandomKey as') aesState -- enter loop
return ()
-}
{-|
Module : Gargantext.Prelude.Crypto.Pass.User
Description :
Copyright : (c) CNRS, 2017-Present
License : Public Domain
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
1) quick password generator for first invitations
2) Easy password manager for User (easy to memorize) (needs list of words)
-}
module Gargantext.Prelude.Crypto.Pass.User
where
-- 1) Quick password generator imports
import Data.Text (Text)
import Data.String (String)
import Control.Monad
import Control.Monad.Random
import qualified Data.List as List
-- 2) Easy password manager imports
import Gargantext.Prelude
import Gargantext.Prelude.Utils (shuffle)
-- 1) Quick password generator
-- Inspired by Rosetta code
-- https://www.rosettacode.org/wiki/Password_generator#Haskell
gargPass :: MonadRandom m => m Text
gargPass = cs <$> gargPass' chars 33
where
chars = zipWith (List.\\) charSets visualySimilar
charSets = [ ['a'..'z']
, ['A'..'Z']
, ['0'..'9']
, "!\"#$%&'()*+,-./:;<=>?@[]^_{|}~"
]
visualySimilar = ["l","IOSZ","012","!|.,'\""]
gargPass' :: MonadRandom m => [String] -> Int -> m String
gargPass' charSets n = do
parts <- getPartition n
chars <- zipWithM replicateM parts (uniform <$> charSets)
shuffle' (List.concat chars)
where
getPartition n' = adjust <$> replicateM (k-1) (getRandomR (1, n' `div` k))
k = length charSets
adjust p = (n - sum p) : p
shuffle' :: (Eq a, MonadRandom m) => [a] -> m [a]
shuffle' [] = pure []
shuffle' lst = do
x <- uniform lst
xs <- shuffle (List.delete x lst)
return (x : xs)
-- | 2) Easy password manager
-- TODO add this as parameter to gargantext.ini
gargPassUserEasy :: (Num a, Enum a, Integral a) => a -> [b] -> IO [b]
gargPassUserEasy n = gargPassUserEasy' (100 * fromIntegral n) n
gargPassUserEasy' :: (Num a, Enum a) => Int -> a -> [b] -> IO [b]
gargPassUserEasy' threshold size wlist
| length wlist > threshold = generatePassword size wlist
| otherwise = panic "List to short"
generatePassword :: (Num a, Enum a) => a -> [b] -> IO [b]
generatePassword size wlist = shuffle wlist
>>= \wlist' -> mapM (\_ -> getRandomElement wlist') [1..size]
getRandomIndex :: Foldable t => t a -> IO Int
getRandomIndex list = randomRIO (0, (length list - 1))
getRandomElement :: [b] -> IO b
getRandomElement list = do
index <- (getRandomIndex list)
pure (list List.!! index)
{-|
Module : Gargantext.Prelude.Crypto.Share
Description :
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
# Random work/research (WIP)
Goal: share secretly a sequence of random actions (either [Bool] or
[Ordering] for instances here) but without sharing secrets.
Motivation: useful to share clustering algorithm reproduction using BAC
(Ballades Aléatoires Courtes).
Question: how to certify the author of such (random) actions ? Solution
later ;)
-}
------------------------------------------------------------------------
{-# OPTIONS_GHC -fno-warn-orphans #-}
------------------------------------------------------------------------
module Gargantext.Prelude.Crypto.Share
where
import Data.Maybe
import System.Random
import Prelude (fromEnum, toEnum)
import Gargantext.Core.Types (Ordering)
import Gargantext.Prelude
------------------------------------------------------------------------
-- | Main Types
newtype Seed = Seed Int
type Private = Seed
type Public = Seed
------------------------------------------------------------------------
instance Random Ordering where
randomR (a, b) g =
case randomR (fromEnum a, fromEnum b) g of
(x, g') -> (toEnum x, g')
random g = randomR (minBound, maxBound) g
randomOrdering :: Maybe Seed -> Int -> IO [Ordering]
randomOrdering = randomWith
randomBool :: Maybe Seed -> Int -> IO [Bool]
randomBool= randomWith
------------------------------------------------------------------
randomWith :: Random a => Maybe Seed -> Int -> IO [a]
randomWith seed n = do
g <- case seed of
Nothing -> newStdGen
Just (Seed s) -> pure $ mkStdGen s
pure $ take n $ (randoms g)
genWith :: Private -> Public -> Int -> IO [Bool]
genWith privateSeed publicSeed n = do
xs <- randomBool (Just privateSeed) n
ys <- randomBool (Just publicSeed ) n
pure $ zipWith xor xs ys
{-
- TODO WIP
searchSeeds :: Int -> IO [Int]
searchSeeds xs = mapM (\n -> randomWith (Just n) l) [1..]
where
l = length xs
shareSeed = undefined
certifySeed = undefined
-}
{-|
Module : Gargantext.Prelude.Utils
Description : Useful Tools near Prelude of the project
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
Nice optimization of the Fibonacci function.
Source:
Gabriel Gonzales, Blazing fast Fibonacci numbers using Monoids, 2020-04,
http://www.haskellforall.com/2020/04/blazing-fast-fibonacci-numbers-using.html
(This post illustrates a nifty application of Haskell’s standard library to solve a numeric problem.)
TODO: quikcheck
-}
module Gargantext.Prelude.Fibonacci where
import Protolude
import qualified Data.Monoid as Monoid
import qualified Data.Semigroup as Semigroup
-------------------------------------------------------------
fib' :: Integer -> Integer
fib' 0 = 0
fib' 1 = 1
fib' n = fib (n-1) + fib (n-2)
-------------------------------------------------------------
data Matrix2x2 = Matrix
{ x00 :: Integer, x01 :: Integer
, x10 :: Integer, x11 :: Integer
}
instance Monoid.Monoid Matrix2x2 where
mempty =
Matrix
{ x00 = 1, x01 = 0
, x10 = 0, x11 = 1
}
instance Semigroup.Semigroup Matrix2x2 where
Matrix l00 l01 l10 l11 <> Matrix r00 r01 r10 r11 =
Matrix
{ x00 = l00 * r00 + l01 * r10, x01 = l00 * r01 + l01 * r11
, x10 = l10 * r00 + l11 * r10, x11 = l10 * r01 + l11 * r11
}
fib :: Integer -> Integer
fib n = x01 (Semigroup.mtimesDefault n matrix)
where
matrix =
Matrix
{ x00 = 0, x01 = 1
, x10 = 1, x11 = 1
}
{-|
Module : Gargantext.Core.Mail
Description :
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
-}
{-# LANGUAGE OverloadedStrings #-}
module Gargantext.Prelude.Mail
(gargMail, GargMail(..))
where
-- import Data.Text.Internal.Lazy (Text)
import Data.Text (Text)
import Data.Maybe
import Network.Mail.SMTP hiding (htmlPart)
import Gargantext.Prelude
import Network.Mail.Mime (plainPart)
type Email = Text
type Name = Text
data GargMail = GargMail { gm_to :: Email
, gm_name :: Maybe Name
, gm_subject :: Text
, gm_body :: Text
}
-- | TODO add parameters to gargantext.ini
gargMail :: GargMail -> IO ()
gargMail (GargMail to' name subject body) = sendMail "localhost" mail
where
mail = simpleMail from to cc bcc subject [plainPart $ cs body]
from = Address (Just "GargTeam") "contact@gargantext.org"
to = [Address name to']
cc = []
bcc = []
{-|
Module : Gargantext.Prelude.Utils
Description : Useful Tools near Prelude of the project
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
TODO_1: qualitative tests (human)
TODO_2: quantitative tests (coded)
-}
module Gargantext.Prelude.Utils
where
import Control.Monad.Random.Class (MonadRandom)
import qualified System.Random.Shuffle as SRS
------------------------------------------------------------------------
-- | Misc Utils
shuffle :: MonadRandom m => [a] -> m [a]
shuffle ns = SRS.shuffleM ns
--------------------------------------------------------------------------
-- TODO gargDB instance for NodeType
{-
data NodeToHash = NodeToHash { nodeType :: NodeType
, nodeId :: NodeId
}
-}
......@@ -23,7 +23,8 @@ nix:
allow-newer: true
extra-deps:
- git: https://gitlab.iscpif.fr/gargantext/haskell-gargantext-prelude.git
commit: 9dc45d72a52ece3bde5a104653a76ffb7a13a31e
# Data Mining Libs
- git: https://github.com/delanoe/data-time-segment.git
commit: 10a416b9f6c443866b36479c3441ebb3bcdeb7ef
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment