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 ...@@ -9,7 +9,8 @@ import Reactix as R
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Components.Nodes.Corpus.Chart.Types (Reload, Path, Props, MetricsProps, ReloadPath) 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.Sessions (Session)
import Gargantext.Utils.CacheAPI as GUC import Gargantext.Utils.CacheAPI as GUC
......
...@@ -14,6 +14,7 @@ import Effect.Exception (error) ...@@ -14,6 +14,7 @@ import Effect.Exception (error)
import Gargantext.Components.LoadingSpinner (loadingSpinner) import Gargantext.Components.LoadingSpinner (loadingSpinner)
import Gargantext.Ends (class ToUrl, toUrl) import Gargantext.Ends (class ToUrl, toUrl)
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Utils.Crypto (Hash)
import Gargantext.Utils as GU import Gargantext.Utils as GU
import Gargantext.Utils.CacheAPI as GUC import Gargantext.Utils.CacheAPI as GUC
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
...@@ -51,13 +52,10 @@ useLoaderEffect path state@(state' /\ setState) loader = do ...@@ -51,13 +52,10 @@ useLoaderEffect path state@(state' /\ setState) loader = do
liftEffect $ setState $ const $ Just l liftEffect $ setState $ const $ Just l
type Hash = String newtype HashedResponse a =
HashedResponse { hash :: Hash
, value :: a
newtype HashedResponse a = HashedResponse { }
hash :: Hash
, value :: a
}
instance decodeHashedResponse :: DecodeJson a => DecodeJson (HashedResponse a) where instance decodeHashedResponse :: DecodeJson a => DecodeJson (HashedResponse a) where
decodeJson json = do decodeJson json = do
...@@ -156,8 +154,8 @@ useCachedLoaderEffect { cacheEndpoint, keyFunc, loadRealData, path, state: state ...@@ -156,8 +154,8 @@ useCachedLoaderEffect { cacheEndpoint, keyFunc, loadRealData, path, state: state
decode j = GU.mapLeft (\err -> "Error decoding serialised sessions:" <> show err) (decodeJson j) decode j = GU.mapLeft (\err -> "Error decoding serialised sessions:" <> show err) (decodeJson j)
type LoaderWithCacheAPIProps path res ret = ( type LoaderWithCacheAPIProps path res ret =
cacheEndpoint :: path -> Aff Hash ( cacheEndpoint :: path -> Aff Hash
, handleResponse :: HashedResponse res -> ret , handleResponse :: HashedResponse res -> ret
, mkRequest :: path -> GUC.Request , mkRequest :: path -> GUC.Request
, path :: path , path :: path
...@@ -177,16 +175,17 @@ useLoaderWithCacheAPI { cacheEndpoint, handleResponse, mkRequest, path, renderer ...@@ -177,16 +175,17 @@ useLoaderWithCacheAPI { cacheEndpoint, handleResponse, mkRequest, path, renderer
, state } , state }
pure $ maybe (loadingSpinner {}) renderer (fst state) pure $ maybe (loadingSpinner {}) renderer (fst state)
type LoaderWithCacheAPIEffectProps path res ret = ( type LoaderWithCacheAPIEffectProps path res ret =
cacheEndpoint :: path -> Aff Hash ( cacheEndpoint :: path -> Aff Hash
, handleResponse :: HashedResponse res -> ret , handleResponse :: HashedResponse res -> ret
, mkRequest :: path -> GUC.Request , mkRequest :: path -> GUC.Request
, path :: path , path :: path
, state :: R.State (Maybe ret) , state :: R.State (Maybe ret)
) )
useCachedAPILoaderEffect :: forall path res ret. Eq path => Show path => DecodeJson res => useCachedAPILoaderEffect :: forall path res ret
Record (LoaderWithCacheAPIEffectProps path res ret) . Eq path => Show path => DecodeJson res
=> Record (LoaderWithCacheAPIEffectProps path res ret)
-> R.Hooks Unit -> R.Hooks Unit
useCachedAPILoaderEffect { cacheEndpoint useCachedAPILoaderEffect { cacheEndpoint
, handleResponse , handleResponse
......
module Gargantext.Utils.Crypto where module Gargantext.Utils.Crypto where
import Data.Set (Set)
import Data.Set as Set
import Data.Array as Array
import Gargantext.Prelude import Gargantext.Prelude
import Crypto.Simple as Crypto import Crypto.Simple as Crypto
hash :: forall a. Crypto.Hashable a => a -> String -- | TODO use newtype to disambiguate Set String and Set Hash
hash = Crypto.toString <<< Crypto.hash Crypto.SHA256 -- 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) ...@@ -8,7 +8,7 @@ import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow) import Data.Generic.Rep.Show (genericShow)
import Gargantext.Utils as GU import Gargantext.Utils as GU
import Gargantext.Utils.Argonaut (genericEnumDecodeJson, genericEnumEncodeJson, genericSumDecodeJson, genericSumEncodeJson) 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 Gargantext.Utils.Math as GUM
import Test.Spec (Spec, describe, it) import Test.Spec (Spec, describe, it)
import Test.Spec.Assertions (shouldEqual) import Test.Spec.Assertions (shouldEqual)
...@@ -63,11 +63,6 @@ spec = ...@@ -63,11 +63,6 @@ spec =
GU.zeroPad 3 1000 `shouldEqual` "1000" GU.zeroPad 3 1000 `shouldEqual` "1000"
it "log10 10" do it "log10 10" do
GUM.log10 10.0 `shouldEqual` 1.0 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 it "genericSumDecodeJson works" do
let result1 = Argonaut.decodeJson =<< Argonaut.jsonParser """{"Boat":{"hi":1}}""" let result1 = Argonaut.decodeJson =<< Argonaut.jsonParser """{"Boat":{"hi":1}}"""
...@@ -114,3 +109,28 @@ spec = ...@@ -114,3 +109,28 @@ spec =
let result2' = Argonaut.decodeJson result2 let result2' = Argonaut.decodeJson result2
Argonaut.stringify result2 `shouldEqual` "\"Member2\"" Argonaut.stringify result2 `shouldEqual` "\"Member2\""
result2' `shouldEqual` Right input2 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