~arestifo/crystal-webauthn

60f9470f2c3eedc4d476fa5a1d4d0779f19a5b58 — Alberto Restifo 3 years ago 40bbca2
Initialize public credentials structure
A spec/webauthn/public_key_credential/creation_options_spec.cr => spec/webauthn/public_key_credential/creation_options_spec.cr +13 -0
@@ 0,0 1,13 @@
require "../../spec_helper"

describe WebAuthn::PublicKeyCredential::CreationOptions do
  describe "#to_json" do
    it "encodes to json" do
      user = WebAuthn::PublicKeyCredential::User.new(id: "something", name: "the user", display_name: "User 1")
      rp = WebAuthn::PublicKeyCredential::RPEntity.new(id: "something", name: "rep")
      creation_options = WebAuthn::PublicKeyCredential::CreationOptions.new(rp: rp, user: user)

      creation_options.to_json.should be_a(String)
    end
  end
end

A spec/webauthn/public_key_credential/user_spec.cr => spec/webauthn/public_key_credential/user_spec.cr +25 -0
@@ 0,0 1,25 @@
require "../../spec_helper"

describe WebAuthn::PublicKeyCredential::User do
  describe "#to_json" do
    it "encodes to json" do
      user = WebAuthn::PublicKeyCredential::User.new(id: "something",
        name: "the user",
        display_name: "User 1")

      user.to_json.should be_a(String)
    end
  end

  describe "#from_json" do
    it "decodes a JSON payload" do
      user_json = %({"name":"the user","id":"c29tZXRoaW5n","displayName":"User 1"})

      user = WebAuthn::PublicKeyCredential::User.from_json(user_json)

      user.id.should eq("something")
      user.name.should eq("the user")
      user.display_name.should eq("User 1")
    end
  end
end

M spec/webauthn_spec.cr => spec/webauthn_spec.cr +9 -4
@@ 1,9 1,14 @@
require "./spec_helper"

describe Webauthn do
  # TODO: Write tests
describe WebAuthn do
  describe "#generate_user_id" do
    it "generates a spec-compliant user ID" do
      user_id = WebAuthn.generate_user_id

  it "works" do
    false.should eq(true)
      user_id.should be_a(String)

      # As specified, the generate user id should not contain equals
      user_id.should_not end_with("=")
    end
  end
end

M src/webauthn.cr => src/webauthn.cr +15 -3
@@ 1,6 1,18 @@
# TODO: Write documentation for `Webauthn`
module Webauthn
require "io"
require "json"
require "random"

require "./webauthn/**"

# TODO: Write documentation for `WebAuthn`
module WebAuthn
  VERSION = "0.1.0"

  # TODO: Put your code here
  # Generates a [WebAuthn User Handle][1] that follows the WebAuthn spec
  # recommendations.
  #
  # [1]: https://www.w3.org/TR/webauthn-2/#user-handle
  def self.generate_user_id : String
    Random::Secure.urlsafe_base64(64, false)
  end
end

A src/webauthn/base64.cr => src/webauthn/base64.cr +10 -0
@@ 0,0 1,10 @@
class WebAuthn::Base64
  def self.from_json(pull : JSON::PullParser)
    string = pull.read_string
    ::Base64.decode_string(string)
  end

  def self.to_json(value : String, json : JSON::Builder)
    ::Base64.urlsafe_encode(value, false).to_json(json)
  end
end

A src/webauthn/credential.cr => src/webauthn/credential.cr +4 -0
@@ 0,0 1,4 @@
module WebAuthn::Credential
  def self.options_for_create
  end
end

A src/webauthn/public_key_credential/creation_options.cr => src/webauthn/public_key_credential/creation_options.cr +9 -0
@@ 0,0 1,9 @@
class WebAuthn::PublicKeyCredential::CreationOptions
  include JSON::Serializable

  getter rp : WebAuthn::PublicKeyCredential::RPEntity
  getter user : WebAuthn::PublicKeyCredential::User

  def initialize(@rp, @user)
  end
end

A src/webauthn/public_key_credential/entity.cr => src/webauthn/public_key_credential/entity.cr +6 -0
@@ 0,0 1,6 @@
class WebAuthn::PublicKeyCredential::Entity
  include JSON::Serializable

  @[JSON::Field(key: "name")]
  getter name : String
end

A src/webauthn/public_key_credential/options.cr => src/webauthn/public_key_credential/options.cr +10 -0
@@ 0,0 1,10 @@
abstract class Options
  CHALLENGE_LENGTH = 32

  abstract def to_json : String
  abstract def to_json(io : IO)

  def challenge : String
    @challenge ||= Random::Secure.urlsafe_base64(CHALLENGE_LENGTH, false)
  end
end

A src/webauthn/public_key_credential/relying_party.cr => src/webauthn/public_key_credential/relying_party.cr +2 -0
@@ 0,0 1,2 @@
class WebAuthn::PublicKeyCredential::RelyingParty
end

A src/webauthn/public_key_credential/rp_entity.cr => src/webauthn/public_key_credential/rp_entity.cr +8 -0
@@ 0,0 1,8 @@
class WebAuthn::PublicKeyCredential::RPEntity < WebAuthn::PublicKeyCredential::Entity
  include JSON::Serializable

  getter id : String

  def initialize(@name, @id)
  end
end

A src/webauthn/public_key_credential/user.cr => src/webauthn/public_key_credential/user.cr +12 -0
@@ 0,0 1,12 @@
class WebAuthn::PublicKeyCredential::User < WebAuthn::PublicKeyCredential::Entity
  include JSON::Serializable

  @[JSON::Field(key: "id", converter: WebAuthn::Base64)]
  getter id : String

  @[JSON::Field(key: "displayName")]
  getter display_name : String

  def initialize(@id, @name, @display_name)
  end
end