Commit 5cff20a1 authored by Alexandre Delanoë's avatar Alexandre Delanoë

[Crypto] hash for list ok but needs more types

parent 9b25a3dd
......@@ -9,7 +9,8 @@ import Reactix as R
import Gargantext.Prelude
import Gargantext.Components.Nodes.Corpus.Chart.Types (Reload, Path, Props, MetricsProps, ReloadPath)
import Gargantext.Hooks.Loader (Hash, HashedResponse, useLoader, useLoaderWithCache, useLoaderWithCacheAPI)
import Gargantext.Hooks.Loader (HashedResponse, useLoader, useLoaderWithCache, useLoaderWithCacheAPI)
import Gargantext.Utils.Crypto (Hash)
import Gargantext.Sessions (Session)
import Gargantext.Utils.CacheAPI as GUC
......
......@@ -14,6 +14,7 @@ import Effect.Exception (error)
import Gargantext.Components.LoadingSpinner (loadingSpinner)
import Gargantext.Ends (class ToUrl, toUrl)
import Gargantext.Prelude
import Gargantext.Utils.Crypto (Hash)
import Gargantext.Utils as GU
import Gargantext.Utils.CacheAPI as GUC
import Gargantext.Utils.Reactix as R2
......@@ -51,11 +52,8 @@ useLoaderEffect path state@(state' /\ setState) loader = do
liftEffect $ setState $ const $ Just l
type Hash = String
newtype HashedResponse a = HashedResponse {
hash :: Hash
newtype HashedResponse a =
HashedResponse { hash :: Hash
, value :: a
}
......@@ -156,8 +154,8 @@ useCachedLoaderEffect { cacheEndpoint, keyFunc, loadRealData, path, state: state
decode j = GU.mapLeft (\err -> "Error decoding serialised sessions:" <> show err) (decodeJson j)
type LoaderWithCacheAPIProps path res ret = (
cacheEndpoint :: path -> Aff Hash
type LoaderWithCacheAPIProps path res ret =
( cacheEndpoint :: path -> Aff Hash
, handleResponse :: HashedResponse res -> ret
, mkRequest :: path -> GUC.Request
, path :: path
......@@ -177,16 +175,17 @@ useLoaderWithCacheAPI { cacheEndpoint, handleResponse, mkRequest, path, renderer
, state }
pure $ maybe (loadingSpinner {}) renderer (fst state)
type LoaderWithCacheAPIEffectProps path res ret = (
cacheEndpoint :: path -> Aff Hash
type LoaderWithCacheAPIEffectProps path res ret =
( cacheEndpoint :: path -> Aff Hash
, handleResponse :: HashedResponse res -> ret
, mkRequest :: path -> GUC.Request
, path :: path
, state :: R.State (Maybe ret)
)
useCachedAPILoaderEffect :: forall path res ret. Eq path => Show path => DecodeJson res =>
Record (LoaderWithCacheAPIEffectProps path res ret)
useCachedAPILoaderEffect :: forall path res ret
. Eq path => Show path => DecodeJson res
=> Record (LoaderWithCacheAPIEffectProps path res ret)
-> R.Hooks Unit
useCachedAPILoaderEffect { cacheEndpoint
, handleResponse
......
module Gargantext.Utils.Crypto where
import Data.Set (Set)
import Data.Set as Set
import Data.Array as Array
import Gargantext.Prelude
import Crypto.Simple as Crypto
hash :: forall a. Crypto.Hashable a => a -> String
hash = Crypto.toString <<< Crypto.hash Crypto.SHA256
-- | TODO use newtype to disambiguate Set String and Set Hash
-- Set String needs Set.map hash
-- Set Hash does not need Set.map hash (just concat)
type Hash = String
hash' :: forall a. Crypto.Hashable a => a -> String
hash' = Crypto.toString <<< Crypto.hash Crypto.SHA256
class IsHashable a where
hash :: a -> Hash
instance isHashableString :: IsHashable String
where
hash = hash'
instance isHashableArray :: (Crypto.Hashable a, IsHashable a) => IsHashable (Array a)
where
hash = hash <<< Set.fromFoldable <<< map hash
instance isHashableSet :: IsHashable (Set String) where
hash = hash <<< concat <<< toArray
where
toArray :: forall a. Set a -> Array a
toArray = Set.toUnfoldable
concat :: Array Hash -> String
concat = Array.foldl (<>) ""
......@@ -8,7 +8,7 @@ import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Gargantext.Utils as GU
import Gargantext.Utils.Argonaut (genericEnumDecodeJson, genericEnumEncodeJson, genericSumDecodeJson, genericSumEncodeJson)
import Gargantext.Utils.Crypto as GUC
import Gargantext.Utils.Crypto as Crypto
import Gargantext.Utils.Math as GUM
import Test.Spec (Spec, describe, it)
import Test.Spec.Assertions (shouldEqual)
......@@ -63,11 +63,6 @@ spec =
GU.zeroPad 3 1000 `shouldEqual` "1000"
it "log10 10" do
GUM.log10 10.0 `shouldEqual` 1.0
it "Hash works with backend" do
let text = "To hash with backend"
let hashed = "8a69a94d164279af2b7d1443ce08da6184b3d7e815406076e148159c284b53c3"
-- ^ hash from backend with text above
GUC.hash text `shouldEqual` hashed
it "genericSumDecodeJson works" do
let result1 = Argonaut.decodeJson =<< Argonaut.jsonParser """{"Boat":{"hi":1}}"""
......@@ -114,3 +109,28 @@ spec =
let result2' = Argonaut.decodeJson result2
Argonaut.stringify result2 `shouldEqual` "\"Member2\""
result2' `shouldEqual` Right input2
------------------------------------------------------------------------
-- | Crypto Hash tests
it "Hash String with backend works" do
let text = "To hash with backend"
let hashed = "8a69a94d164279af2b7d1443ce08da6184b3d7e815406076e148159c284b53c3"
-- ^ hash from backend with text above
Crypto.hash text `shouldEqual` hashed
it "Hash List with backend works" do
let list = ["a","b"]
let hashed = "ab19ec537f09499b26f0f62eed7aefad46ab9f498e06a7328ce8e8ef90da6d86"
-- ^ hash from backend with text above
Crypto.hash list `shouldEqual` hashed
------------------------------------------------------------------------
-- | TODO property based tests
it "Hash works with any order of list" do
let hash1 = Crypto.hash ["a","b"]
let hash2 = Crypto.hash ["b","a"]
hash1 `shouldEqual` hash2
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