zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

commit 01772175bd27acf673b69a979f06f93807199731
parent f2ee459e7e2fd344fbb284eead4ee0275c00ccc4
Author: srfsh <dev@srf.sh>
Date:   Mon, 20 Jun 2022 17:55:03 +0300

restroom: change the crypto module with restroom-interacting code

Diffstat:
M.iex.exs | 3++-
Dsrc/zencode/keygen.zen | 28----------------------------
Dsrc/zencode/passgen_pbkdf2.zen | 5-----
Dsrc/zencode/passverify_pbkdf2.zen | 7-------
Dsrc/zenflows/crypto/pass.ex | 303-------------------------------------------------------------------------------
Asrc/zenflows/restroom.ex | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/zenflows/vf/economic_event/domain.ex | 29++++++++++++++---------------
Msrc/zenflows/vf/person.ex | 4++--
Dtest/crypto/pass.test.exs | 79-------------------------------------------------------------------------------
Mtest/help/factory.ex | 5++---
Atest/restroom.test.exs | 13+++++++++++++
Mtest/vf/person/domain.test.exs | 8++++----
12 files changed, 115 insertions(+), 447 deletions(-)

diff --git a/.iex.exs b/.iex.exs @@ -4,6 +4,7 @@ end alias Zenflows.DB alias Zenflows.DB.Repo -alias Zenflows.VF alias Zenflows.GQL alias Zenflows.GQL.Schema +alias Zenflows.Restroom +alias Zenflows.VF diff --git a/src/zencode/keygen.zen b/src/zencode/keygen.zen @@ -1,28 +0,0 @@ -Scenario ecdh : 'keygen' -Scenario ethereum: 'keygen' -Scenario schnorr: 'keygen' -Scenario reflow: 'keygen' - -Given nothing -When I create the ecdh key -When I create the reflow key -When I create the schnorr key -When I create the ethereum key -When I create the bitcoin key - -When I create the 'base64 dictionary' named 'pubkeys' -When I create the ecdh public key -and I move 'ecdh public key' in 'pubkeys' -When I create the reflow public key -and I move 'reflow public key' in 'pubkeys' -When I create the schnorr public key -and I move 'schnorr public key' in 'pubkeys' - -When I create the ethereum address -When I create the bitcoin address - -Then print the 'keyring' -and print the 'pubkeys' -and print the 'ethereum address' -and print the 'bitcoin address' - diff --git a/src/zencode/passgen_pbkdf2.zen b/src/zencode/passgen_pbkdf2.zen @@ -1,5 +0,0 @@ -Given I have a 'hex' named 'salt' -and I have a 'string' named 'password' -When I create the key derivation of 'password' with password 'salt' -Then print the 'key derivation' as 'base64' - diff --git a/src/zencode/passverify_pbkdf2.zen b/src/zencode/passverify_pbkdf2.zen @@ -1,7 +0,0 @@ -Given I have a 'hex' named 'salt' -and I have a 'base64' named 'hash' -and I have a 'string' named 'password' -When I create the key derivation of 'password' with password 'salt' -and I verify 'key_derivation' is equal to 'hash' -Then print the string '1' -# when false zenroom returns error diff --git a/src/zenflows/crypto/pass.ex b/src/zenflows/crypto/pass.ex @@ -1,303 +0,0 @@ -defmodule Zenflows.Crypto.Pass do -@moduledoc """ -Functionality for passphrase hashing. - -The `hash/1` function here is designed to output a custom-formatted -binary so that it allows future expansion. Meaning that the outputted -binary will contain information about what type of algorith is used -(the first octet), what parameters are used for that particular function -(following couple octets). - -The format looks like this (`+` used for concatenation): - -* output = type + params + hash -* type = one octet, representing what algorithm is used as unsiged integer -* params = if type is `@type_pbdkf2`, it will be as: iteration-count + salt-length + salt-binary - -The `params` for `@type_pbkdf2` will be (all values are inclusive): -* iteration-count = an unsigned integer within the range - `@iter_2_min..@iter_4_max`, encoded with `iter_encode/1` -* salt-length = an unsinged integer within the range - `@salt_min..@salt_max`, encoded as an octet with `salt_encode/1` -* salt-binary = it is the `salt-length`-octet long, cryptographically - secure random binary, generated with `gen_salt/1` - -This allows future expansion, backwards-compability, and changing -the parameter values (increasing/decreasing, for example) without -effecting the old schemas. - -How paraters are encoded and decoded is descriped in their doc strings. -""" - -import Bitwise -import Plug.Crypto, only: [secure_compare: 2] - -# @type_invalid 0 -@type_pbdkf2 1 -# @type_argon2id 2 -# and so on (in the future maybe)... - -# Min and max salt size values in octects for pbdkf2 hashing. -@salt_min 16 -@salt_max 255 - -# Iteration counts' min and max ranges. Each number (such as 2 in -# `@iter_2_min`) represents the number (unsigned integer) will be encoded -# in that that much octets. -# -# `@iter_1` is special though, it represents the test-only value 1, -# which is used for speeding up tests. Otherwise, the absolute production -# minimum is `@iter_2_min`. -@iter_1 0b1000_0001 -@iter_2_min 0b0000_0100_0000_0000 -@iter_2_max 0b0011_1111_1111_1111 -@iter_3_min 0b0000_0000_0100_0000_0000_0000 -@iter_3_max 0b0111_1111_1111_1111_1111_1111 -@iter_4_min 0b0000_0000_1000_0000_0000_0000_0000_0000 -@iter_4_max 0b0011_1111_1111_1111_1111_1111_1111_1111 - -@doc """ -Hashes a passphrase in plaintext string format. Outputs a -custom-formatted binary, thus should be stored in the database as-is -and used only with `match?/2` to securely compare generated hashes. -""" -@spec hash(String.t()) :: binary() -def hash(pass) do - conf = conf() - iter_cnt = Keyword.fetch!(conf, :iter) - salt_len = Keyword.fetch!(conf, :slen) - dkey_len = Keyword.fetch!(conf, :klen) - - # As `byte_size/1` is constant-time, I don't think we'll need to - # keep `salt_len`'s state in `encode/4` and just use: - # `byte_size(salt)`. - salt = gen_salt(salt_len) - hash = hash_pbdkf2(pass, salt, iter_cnt, dkey_len) - encode(:pbdkf2, hash, salt, iter_cnt) -end - -@doc """ -Generate the hash of the given string `pass` and securly compare it -against the custom-formatted binary hash `hash`. - -The information of how to hash the string `pass` will be read from the -custom-formatted binary hash `hash`. -""" -@spec match?(String.t(), binary()) :: boolean() -def match?(pass, hash) do - case decode(hash) do - {:pbdkf2, iter, salt, hash} -> do_match?(:pbdkf2, iter, salt, hash, pass) - end -end - -@spec do_match?(:pbdkf2, non_neg_integer(), binary(), binary(), String.t()) :: boolean() -defp do_match?(:pbdkf2, iter, salt, hash, pass) do - h = hash_pbdkf2(pass, salt, iter, byte_size(hash)) - secure_compare(h, hash) -end - -@spec hash_pbdkf2(binary(), binary(), pos_integer(), pos_integer()) :: binary() -defp hash_pbdkf2(pass, salt, iter, klen) do - opts = [iterations: iter, length: klen, digest: :sha512] - Plug.Crypto.KeyGenerator.generate(pass, salt, opts) -end - -@doc """ -Generates a cryptographically-secure random binary of the given length -in octets. - -The given length must be within the range `@salt_min..@salt_max`, or 0 -for testing purposes. -""" -@spec gen_salt(non_neg_integer()) :: binary() -def gen_salt(0) do - <<>> -end - -def gen_salt(len) when len >= @salt_min or len <= @salt_max do - :crypto.strong_rand_bytes(len) -end - -# Encode the given hashing algorithm and its parameters into a -# custom-formatted binary. Can be used with `decode/1` to read the -# encoded informations back. -@spec encode(:pbdkf2, binary(), binary(), non_neg_integer()) :: binary() -defp encode(:pbdkf2, hash, salt, iter_cnt) do - type = @type_pbdkf2 - iter = iter_encode(iter_cnt) - salt_len = salt_encode(byte_size(salt)) - IO.iodata_to_binary([type, iter, salt_len, salt, hash]) -end - -# Decode the given custom-formatted hash binary and strip the information -# from their boundries. It is designed to read the output of `encode()` -# functions (currently there's only `encode/4`). -@spec decode(binary()) :: {:pbdkf2, non_neg_integer(), binary(), binary()} -defp decode(<<@type_pbdkf2, rest::binary>>) do - {iter, rest} = iter_decode(rest) - {salt_len, rest} = salt_decode(rest) - <<salt::binary-size(salt_len), hash::binary>> = rest - {:pbdkf2, iter, salt, hash} -end - -# Encodes the length (unsigned integer) of a salt binary. Use it like -# this: `salt_iodata = salt_encode(byte_size(my_salt_binary))`. -# -# It'll encode it as iodata so the `encode/4` function can use it -# efficiently. -# -# The given length must be within the `@salt_min..@salt_max` range, -# or 0 for testing purposes. -@doc false -@spec salt_encode(non_neg_integer()) :: iodata() -def salt_encode(0) do - [0] -end - -def salt_encode(v) when v >= @salt_min and v <= @salt_max do - [v] -end - -# Decodes the binary from `salt_encode/1`. It returns the decoded length -# (unsigned integer) and the rest of the binary in a tuple. The returned -# salt length can be used to read the actual salt binary from the returned -# rest binary like this: -# -# ``` -# {salt_len, rest} = salt_decode(bin) -# <<salt_bin::binary-size(salt_len), rest>> = rest -# ``` -# -# It decodes vaulues within the range `@salt_min..@salt_max`, and 0 for -# testing purposes. -@doc false -@spec salt_decode(binary()) :: {non_neg_integer(), binary()} -def salt_decode(<<0, rest::binary>>) do - {0, rest} -end - -def salt_decode(<<x, rest::binary>>) when x >= @salt_min do - {x, rest} -end - -# Encodes the iteration count (unsigned integer). Use it like this: -# `iter_iodata = iter_encode(iter_count)`. -# -# It'll encode it as iodata so the `encode/4` function can use it -# efficiently. -# -# The given length must be within the range `@iter_2_min..@iter_4_max`, -# or 1 for testing purposes. -# -# It is going to encode the lengths: -# -# * just 1 as just one octet -# * the range `@iter_2_min..@iter_2_max` as two octets -# * the range `@iter_3_min..@iter_3_max` as three octets -# * the range `@iter_4_min..@iter_4_max` as four octets -# -# How it works: -# -# We use the first bit of the first octet to determine where the given -# binary ends. -# -# If the first bit is 0, it is a 3-octet long binary and the following -# 23 bits in big-endian order gives you the decoded integer. Such as: -# 0XXXXXXX XXXXXXXX XXXXXXXX. -# -# If the first bit is 1, the following bit will determine whether it is -# 2-octets long or 4-octet long. (The following two paragraphs talk -# about that.) -# -# If the first two bits is 10, it will be 2-octet long. The following -# 14 bits in big-endian order gives you the decoded integer. Such as: -# 10XXXXXX XXXXXXXX. -# -# If the first tow bits is 11, it will be 4-octet long. The following -# 30 bits in big-endian order gives you the decdode integer. Such as: -# 11XXXXXX XXXXXXXX XXXXXXXX XXXXXXXX. -# -# If the first octet is exactly 10000001, it represents the integer 1. -# It is only used for testing purposes (to speed up the tests, to be -# precise). -# -# This schema is designed so that the 3-octet long binary value gets -# the most space for the actual bits, then the 4-octet long binary, then -# the 2-octet binary. This is because the 3-octet binary will be the -# most used one, 2-octet binary will be the least used one. -# -# Just as a quick reference on the ranges of the values (the first bits -# are separated such that they are more apparent): -# -# 1: 0b10000001 -# 2min: 0b10_00010000000000 -# 2max: 0b10_11111111111111 -# 3min: 0b0_00000000100000000000000 -# 3max: 0b0_11111111111111111111111 -# 4min: 0b11_000000100000000000000000000000 -# 4max: 0b11_111111111111111111111111111111 -@doc false -@spec iter_encode(pos_integer()) :: iodata() -def iter_encode(1) do - [@iter_1] -end - -def iter_encode(v) when v >= @iter_2_min and v <= @iter_2_max do - <<bor(bsr(v, 8), 0b1000_0000), v>> -end - -def iter_encode(v) when v >= @iter_3_min and v <= @iter_3_max do - b0 = bsr(v, 16) - b1 = bsr(v, 8) - b2 = v - <<b0, b1, b2>> -end - -def iter_encode(v) when v >= @iter_4_min and v <= @iter_4_max do - b0 = bor(bsr(v, 24), 0b1100_0000) - b1 = bsr(v, 16) - b2 = bsr(v, 8) - b3 = v - <<b0, b1, b2, b3>> -end - -# Decodes the binary from `iter_encode/1`. It returns the decoded -# iteration count (unsigned integer) and the rest of the binary in -# a tuple. -# -# Use it like this: `{iter_cnt, rest} = iter_decode(bin)` -# -# Depending on the first octet, it determines whether if the iteration -# count is 1-, 2-, 3-, or 4-octet long. -# -# The algorithm is explained in `iter_encode/1`. -@doc false -@spec iter_decode(binary()) :: {pos_integer(), binary()} -def iter_decode(<<@iter_1, rest::binary>>) do - {1, rest} -end - -def iter_decode(<<b0, rest::binary>>) when band(b0, 0b1100_0000) == 0b1000_0000 and b0 >= 0b1000_0100 do - <<b1, rest::binary>> = rest - v = bor(b1, bsl(band(b0, 0b0011_1111), 8)) - {v, rest} -end - -def iter_decode(<<b0, rest::binary>>) when band(b0, 0b1000_0000) == 0b0000_0000 do - <<b1, b2, rest::binary>> = rest - v = bor(bor(b2, bsl(b1, 8)), bsl(b0, 16)) - {v, rest} -end - -def iter_decode(<<b0, rest::binary>>) when band(b0, 0b1100_0000) == 0b1100_0000 do - <<b1, b2, b3, rest::binary>> = rest - v = bor(bor(bor(b3, bsl(b2, 8)), bsl(b1, 16)), bsl(band(b0, 0b0011_1111), 24)) - {v, rest} -end - -# Returns the configs of this particular module. -@spec conf() :: Keyword.t() -defp conf() do - Application.fetch_env!(:zenflows, __MODULE__) -end -end diff --git a/src/zenflows/restroom.ex b/src/zenflows/restroom.ex @@ -0,0 +1,78 @@ +defmodule Zenflows.Restroom do +@moduledoc """ +A module to interact with Restroom instances over (for now) HTTP. +""" + +@doc """ +Generate a hash out of a passhprase character string using a constant salt. +""" +@spec passgen(String.t()) :: String.t() +def passgen(pass) do + data = %{salt: salt(), password: pass} + {:ok, %{"key_derivation" => keyder}} = exec("passgen_pbkdf2", data) + keyder +end + +@doc """ +Securely compare a passphrase and a hash, and return `true` if they match, +`false` otherwise. +""" +@spec passverify?(String.t(), String.t()) :: boolean() +def passverify?(pass, hash) do + data = %{salt: salt(), hash: hash, password: pass} + case exec("passverify_pbkdf2", data) do + {:ok, %{"output" => ["1"]}} -> true + _ -> false + end +end + +# Execute a Zencode specified by `name` with JSON data `data`. +@spec exec(String.t(), map()) :: {:ok, map()} | {:error, any()} +defp exec(name, data) do + url = to_charlist("http://#{host()}/api/#{name}") + hdrs = [{'user-agent', useragent()}] + http_opts = [ + {:timeout, 3000}, # 30 seconds + {:connect_timeout, 500}, # 5 seconds + {:autoredirect, false}, + ] + with {:ok, data} <- Jason.encode(%{data: data}), + {:ok, {{_, 200, _}, _, body_charlist}} <- + :httpc.request(:post, {url, hdrs, 'application/json', data}, http_opts, []), + {:ok, map} <- body_charlist |> to_string() |> Jason.decode() do + {:ok, map} + else + {:ok, {{_, stat, _}, _, body_charlist}} -> + {:error, "the http call result in non-200 status code #{stat}: #{to_string(body_charlist)}"} + + other -> other + end +end + + +# Return the useragent to be used by the HTTP client, this module. +@spec useragent() :: charlist() +defp useragent() do + 'zenflows/' ++ Application.spec(:zenflows, :vsn) +end + + +# Return the host string (hostname:port) of the Restroom instance. +@spec host() :: String.t() +defp host() do + conf = conf() + "#{conf[:room_host]}:#{conf[:room_port]}" +end + + +# Return the salt binary that is for passphrase hashing. +defp salt() do + conf() |> Keyword.fetch!(:room_salt) +end + +# Return the application configurations of this module. +@spec conf() :: Keyword.t() +defp conf() do + Application.fetch_env!(:zenflows, __MODULE__) +end +end diff --git a/src/zenflows/vf/economic_event/domain.ex b/src/zenflows/vf/economic_event/domain.ex @@ -90,14 +90,14 @@ defp handle_multi(action_id, evt, res_params) when action_id in ["raise", "produ res = from( r in EconomicResource, where: [id: ^evt.resource_inventoried_as_id], - # cr = container resource - left_join: cr in EconomicResource, on: cr.contained_in_id == r.id, select: merge(map(r, ^fields), %{ contained?: not is_nil(r.contained_in_id), # is it contained in something? - container?: not is_nil(cr) # is it a container, containing something? }) ) |> repo.one!() + res = Map.put(res, :container?, + where(EconomicResource, contained_in_id: ^evt.resource_inventoried_as_id) + |> repo.exists?()) cond do evt.provider_id != res.primary_accountable_id or evt.provider_id != res.custodian_id -> @@ -133,14 +133,14 @@ defp handle_multi(action_id, evt, _) when action_id in ["lower", "consume"] do res = from( r in EconomicResource, where: [id: ^evt.resource_inventoried_as_id], - # cr = container resource - left_join: cr in EconomicResource, on: cr.contained_in_id == r.id, select: merge(map(r, ^fields), %{ contained?: not is_nil(r.contained_in_id), # is it contained in something? - container?: not is_nil(cr) # is it a container, containing something? }) ) |> repo.one!() + res = Map.put(res, :container?, + where(EconomicResource, contained_in_id: ^evt.resource_inventoried_as_id) + |> repo.exists?()) cond do evt.provider_id != res.primary_accountable_id or evt.provider_id != res.custodian_id -> @@ -184,14 +184,14 @@ defp handle_multi("use", evt, _) do res = from( r in EconomicResource, where: [id: ^evt.resource_inventoried_as_id], - # cr = container resource - left_join: cr in EconomicResource, on: cr.contained_in_id == r.id, select: merge(map(r, ^fields), %{ contained?: not is_nil(r.contained_in_id), # is it contained in something? - container?: not is_nil(cr) # is it a container, containing something? }) ) |> repo.one!() + res = Map.put(res, :container?, + where(EconomicResource, contained_in_id: ^evt.resource_inventoried_as_id) + |> repo.exists?()) cond do evt.resource_quantity && (evt.resource_quantity_has_unit_id != res.accounting_quantity_has_unit_id) -> @@ -221,14 +221,13 @@ defp handle_multi("cite", evt, _) do res = from( r in EconomicResource, where: [id: ^evt.resource_inventoried_as_id], - # cr = container resource - left_join: cr in EconomicResource, on: cr.contained_in_id == r.id, select: merge(map(r, [:accounting_quantity_has_unit_id]), %{ contained?: not is_nil(r.contained_in_id), # is it contained in something? - container?: not is_nil(cr) # is it a container, containing something? }) ) |> repo.one!() + res = Map.put(res, :container?, + where(EconomicResource, contained_in_id: ^res.id) |> repo.exists?()) cond do evt.resource_quantity_has_unit_id != res.accounting_quantity_has_unit_id -> @@ -367,15 +366,15 @@ defp handle_multi("accept", evt, _) do ]a res = from( r in EconomicResource, - # cr = container resource - left_join: cr in EconomicResource, on: cr.contained_in_id == r.id, where: [id: ^evt.resource_inventoried_as_id], select: merge(map(r, ^fields), %{ contained?: not is_nil(r.contained_in_id), # is it contained in something? - container?: not is_nil(cr), }) ) |> repo.one!() + res = Map.put(res, :container?, + where(EconomicResource, contained_in_id: ^evt.resource_inventoried_as_id) + |> repo.exists?()) single_ref? = fn -> where(EconomicEvent, [e], diff --git a/src/zenflows/vf/person.ex b/src/zenflows/vf/person.ex @@ -3,7 +3,7 @@ defmodule Zenflows.VF.Person do use Zenflows.DB.Schema -alias Zenflows.Crypto.Pass +alias Zenflows.Restroom alias Zenflows.VF.{SpatialThing, Validate} @type t() :: %__MODULE__{ @@ -80,7 +80,7 @@ end @spec hash_pass(Changeset.t()) :: Changeset.t() defp hash_pass(cset) do if plain = Changeset.get_change(cset, :pass_plain) do - hash = Pass.hash(plain) + hash = Restroom.passgen(plain) Changeset.put_change(cset, :pass, hash) else cset diff --git a/test/crypto/pass.test.exs b/test/crypto/pass.test.exs @@ -1,79 +0,0 @@ -defmodule ZenflowsTest.Crypto.Pass do -use ExUnit.Case, async: true - -import Zenflows.Crypto.Pass - -describe "salt" do - test "encodes and decodes values within the range `16..255` and just 0" do - assert {0, <<>>} = - 0 - |> salt_encode() - |> IO.iodata_to_binary() - |> salt_decode() - - for i <- 16..255 do - assert {^i, <<>>} = - i - |> salt_encode() - |> IO.iodata_to_binary() - |> salt_decode() - end - end - - test "doesn't encode values out of the range `16..255` and just 0" do - for i <- [15, 256] do - assert_raise FunctionClauseError, fn -> - i - |> salt_encode() - |> IO.iodata_to_binary() - |> salt_decode() - end - end - end -end - -describe "itertion count" do - test "encodes and decodes values within the range `1024..1073741823` and just 1" do - # I figured it is fair to just test the lower and upper bounds. - iter_1 = 1 - iter_2_min = 0b0000_0100_0000_0000 - iter_2_max = 0b0011_1111_1111_1111 - iter_3_min = 0b0000_0000_0100_0000_0000_0000 - iter_3_max = 0b0111_1111_1111_1111_1111_1111 - iter_4_min = 0b0000_0000_1000_0000_0000_0000_0000_0000 - iter_4_max = 0b0011_1111_1111_1111_1111_1111_1111_1111 - - for i <- [iter_1, iter_2_min, iter_2_max, iter_3_min, iter_3_max, iter_4_min, iter_4_max] do - assert {^i, <<>>} = - i - |> iter_encode() - |> IO.iodata_to_binary() - |> iter_decode() - end - end - - test "doesn't encode values out of the range `1024..1073741823` and just 1" do - # I figured it is fair to just test the lower and upper bounds. - iter_1 = 1 - iter_2_min = 0b0000_0100_0000_0000 - iter_4_max = 0b0011_1111_1111_1111_1111_1111_1111_1111 - - for i <- [iter_1 - 1, iter_1 + 1, iter_2_min - 1, iter_4_max + 1] do - assert_raise FunctionClauseError, fn -> - i - |> iter_encode() - |> IO.iodata_to_binary() - |> iter_decode() - end - end - end -end - -test "hash/1 and match?/2 works together correctly" do - pass = "hunter2" - h = hash(pass) - # When imported, `Zenflows.Crypto.Pass.match?/2` conflict with - # `Kernel.match?/2`. - assert Zenflows.Crypto.Pass.match?(pass, h) -end -end diff --git a/test/help/factory.ex b/test/help/factory.ex @@ -3,9 +3,8 @@ defmodule ZenflowsTest.Help.Factory do Defines shortcuts for DB testing. """ -alias Zenflows.Crypto.Pass alias Zenflows.DB.Repo -alias Zenflows.VF +alias Zenflows.{Restroom, VF} defdelegate id(), to: Zenflows.DB.ID, as: :gen @@ -220,7 +219,7 @@ def build(:person) do primary_location: build(:spatial_thing), user: uniq("some user"), email: uniq("some email"), - pass: Pass.hash(pass_plain()), + pass: Restroom.passgen(pass_plain()), } end diff --git a/test/restroom.test.exs b/test/restroom.test.exs @@ -0,0 +1,13 @@ +defmodule ZenflowsTest.Restroom do +use ExUnit.Case, async: true + +import Zenflows.Restroom + +test "`passgen/1` and `passverify?/2` works together correctly" do + pass = "hunter2" + notpass = "hunter" + hash = passgen(pass) + assert passverify?(pass, hash) + refute passverify?(notpass, hash) +end +end diff --git a/test/vf/person/domain.test.exs b/test/vf/person/domain.test.exs @@ -2,7 +2,7 @@ defmodule ZenflowsTest.VF.Person.Domain do use ZenflowsTest.Help.EctoCase, async: true alias Ecto.Changeset -alias Zenflows.Crypto.Pass +alias Zenflows.Restroom alias Zenflows.VF.{Person, Person.Domain} setup ctx do @@ -59,7 +59,7 @@ describe "create/1" do assert per.primary_location_id == params.primary_location_id assert per.user == params.user assert per.email == params.email - assert Pass.match?(Factory.pass_plain(), per.pass) + assert Restroom.passverify?(Factory.pass_plain(), per.pass) end test "doesn't create a Person with invalid params" do @@ -77,7 +77,7 @@ describe "update/2" do assert new.primary_location_id == params.primary_location_id assert new.user == params.user assert new.email == old.email - assert Pass.match?(Factory.pass_plain(), new.pass) + assert Restroom.passverify?(Factory.pass_plain(), new.pass) end test "doesn't update a Person with invalid params", %{per: old} do @@ -90,7 +90,7 @@ describe "update/2" do assert new.primary_location_id == old.primary_location_id assert new.user == old.user assert new.email == old.email - assert Pass.match?(Factory.pass_plain(), new.pass) + assert Restroom.passverify?(Factory.pass_plain(), new.pass) end end