Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HOTP algorithm #106

Merged
merged 11 commits into from
Jul 15, 2022
Merged

Add HOTP algorithm #106

merged 11 commits into from
Jul 15, 2022

Conversation

DavidGregory084
Copy link
Member

@DavidGregory084 DavidGregory084 commented Jun 17, 2022

I couldn't resist adding this since it's very easy if HMAC is already there 😛

@DavidGregory084
Copy link
Member Author

I have a PR for TOTP cooking as well, but I'm still figuring out how to test it as it's implemented using F.monotonic. I've seen TestControl but I don't really get how to set a fixed time with it, or what the initial time will be (I guess 0?).
I found in previous projects that I simply used IO(clock.instant()) with some java.time.Clock in my implementation code, then Clock.fixed for testing (see e.g. this squuid thing in https://github.com/hmrc/transit-movements-guarantee-balance/blob/main/app/models/values/BalanceId.scala#L59= and its tests in https://github.com/hmrc/transit-movements-guarantee-balance/blob/main/test/models/values/BalanceIdSpec.scala#L43=) so I've managed to avoid understanding TestControl so far 😆.

@armanbilge
Copy link
Member

Yes, the initial time will be 0. If you want to advance it just do an IO.sleep at the beginning 😂

Then you can do TestControl.executeEmbed(...) to run your IO efficiently.

@DavidGregory084
Copy link
Member Author

Does that mean that you cannot test with SyncIO since TestControl expects an IO program?

@armanbilge
Copy link
Member

Note you can always upgrade a SyncIO to an IO, there is a method for that (to I think). In any case IO is fine.

Comment on lines 52 to 53
require(digits >= 6, s"digits must be at least 6, was $digits")
require(digits < 10, s"digits must be less than 10, was $digits")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's wrap this in F.catchNonFatal so that errors suspend properly into F.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, why do we need Sync here? Would Functor be enough? In which case you can leave the require as-is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's a design question here whether we need an Hotp capability trait actually since it's not hiding bigger constraints. We could implement these as methods on an object, that take Functor and Hmac constraints. I'd need to look to other Typelevel libs for inspiration on the right way to do this :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there possibly be effectful equivalents of require, assume and assert in cats-effect Sync? It's the lowest part of the Typelevel hierarchy that has knowledge that E is Throwable and can raiseError I think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that's interesting :) We have ApplicativeThrow#catchNonFatal and there may be similar methods in there.

@DavidGregory084
Copy link
Member Author

DavidGregory084 commented Jun 20, 2022

Hmm I don't really know what to do with this test failure. I don't get the same failure locally and there is no actual output from the failed test in the log. I have not been testing with the Chrome JSEnv locally and that seems to be the one that is failing in these test runs but I know very little about Scala.js.

 bobcats.HmacSuite:
  + SHA1 RFC2022 test case 1 with IO0.02s
  + SHA1 RFC2022 test case 2 with IO0.00s
  + SHA1 RFC2022 test case 3 with IO0.00s
  + SHA1 RFC2022 test case 4 with IO0.01s
  + SHA1 RFC2022 test case 5 with IO0.00s
  + SHA1 RFC2022 test case 6 with IO0.00s
  + SHA1 RFC2022 test case 7 with IO0.01s
  + SHA1 with IO0.01s
  + SHA256 with IO0.01s
  + SHA512 with IO0.00s
  + generate key for SHA1 with IO0.00s
  + generate key for SHA[error] Error: Total 22, Failed 0, Errors 1, Passed 21
[error] Error during tests:
[error] 	bobcats.bobcats.HotpSuite
[error] (coreJS / Test / test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 8 s, completed Jun 20, 2022 11:35:01 AM
256 with IO0.01s
  + generate key for SHA512 with IO0.00s
Error: Process completed with exit code 1.

@DavidGregory084

This comment was marked as resolved.

@DavidGregory084
Copy link
Member Author

DavidGregory084 commented Jun 20, 2022

Oh, in my case it's just that I haven't used chromedriver for ages so it's out of date, never mind - I get the same thing as the CI server, "tests unsuccessful" but with no output related to those tests:

[error] Error: Total 8, Failed 0, Errors 3, Passed 5
[error] Error during tests:
[error]         bobcats.HashSuite
[error]         bobcats.HmacSuite
[error]         bobcats.bobcats.HotpSuite
[error] (coreJS / Test / test) sbt.TestsFailedException: Tests unsuccessful

@armanbilge
Copy link
Member

armanbilge commented Jun 20, 2022

Yup, sorry, you are stumbling into scalameta/munit#492.

Anyway, did you mention you are running the tests with SyncIO? Browsers don't support synchronous crypto, only async, so SyncIO will crash.

However, Node.js supports sync and async crypto via different APIs. This is why I was running the tests with both SyncIO and IO depending on the runtime. But I no longer think this was a good idea (see #79); we should just require Async and be done with it.

@DavidGregory084
Copy link
Member Author

@armanbilge I think the tests on this PR were failing for the same reason as #108

@armanbilge
Copy link
Member

@armanbilge I think the tests on this PR were failing for the same reason as #108

You mean because of the old Node.js? I thought the tests were failing in the browser.

Copy link
Member

@armanbilge armanbilge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice addition, thank you!

core/shared/src/test/scala/bobcats/HotpSuite.scala Outdated Show resolved Hide resolved
Copy link
Member

@armanbilge armanbilge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic! 😃

@armanbilge armanbilge merged commit 8d03685 into typelevel:main Jul 15, 2022
@DavidGregory084 DavidGregory084 deleted the hotp branch July 15, 2022 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants