Class: Ksef::Auth::Challenge

Inherits:
Data
  • Object
show all
Defined in:
lib/ksef/auth/challenge.rb,
lib/ksef/auth/challenge.rb

Overview

Reopened rather than using a Data.define block, matching FA3::Invoice: a constant inside that block would be defined on Object, not on the class.

Constant Summary collapse

LIFETIME =

Ten minutes from issue (§4).

600
FORMAT =

Length 36, \d{8}-CR-[A-F0-9]{10}-[A-F0-9]{10}-[A-F0-9]{2} (§4.1). Lives here rather than on the request documents because it describes a challenge, and both authentication methods consume the same one — the XAdES document and the KSeF-token JSON body would otherwise each carry their own copy.

/\A\d{8}-CR-[A-F0-9]{10}-[A-F0-9]{10}-[A-F0-9]{2}\z/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#challenge ⇒ Object (readonly)

Returns the value of attribute challenge

Returns:

  • (Object) —

    the current value of challenge



10
11
12
# File 'lib/ksef/auth/challenge.rb', line 10

def challenge
  @challenge
end

#client_ip ⇒ Object (readonly)

Returns the value of attribute client_ip

Returns:

  • (Object) —

    the current value of client_ip



10
11
12
# File 'lib/ksef/auth/challenge.rb', line 10

def client_ip
  @client_ip
end

#timestamp ⇒ Object (readonly)

Returns the value of attribute timestamp

Returns:

  • (Object) —

    the current value of timestamp



10
11
12
# File 'lib/ksef/auth/challenge.rb', line 10

def timestamp
  @timestamp
end

#timestamp_ms ⇒ Object (readonly)

Returns the value of attribute timestamp_ms

Returns:

  • (Object) —

    the current value of timestamp_ms



10
11
12
# File 'lib/ksef/auth/challenge.rb', line 10

def timestamp_ms
  @timestamp_ms
end

Class Method Details

.from(payload) ⇒ Object



38
39
40
41
42
43
44
45
# File 'lib/ksef/auth/challenge.rb', line 38

def self.from(payload)
  new(
    challenge: payload["challenge"],
    timestamp: Ksef::Auth.time(payload["timestamp"]),
    timestamp_ms: payload["timestampMs"],
    client_ip: payload["clientIp"]
  )
end

.validate_format!(value) ⇒ Object

Checked before a request is spent on the challenge, since a malformed or copy-pasted one is the cheapest failure to catch locally.

Parameters:

  • value (String)

Raises:



29
30
31
32
33
34
35
36
# File 'lib/ksef/auth/challenge.rb', line 29

def self.validate_format!(value)
  return value if value.is_a?(String) && FORMAT.match?(value)

  raise ValidationError,
        "Challenge #{value.inspect} is malformed. Expected 36 characters as " \
        "YYYYMMDD-CR-XXXXXXXXXX-XXXXXXXXXX-XX with uppercase hex, exactly as returned by " \
        "POST /auth/challenge."
end

Instance Method Details

#expired?(now = Time.now) ⇒ Boolean

Returns:

  • (Boolean)


49
# File 'lib/ksef/auth/challenge.rb', line 49

def expired?(now = Time.now) = !expires_at.nil? && expires_at <= now

#expires_at ⇒ Object

Worth checking before spending a signature on a challenge that has already lapsed.



48
# File 'lib/ksef/auth/challenge.rb', line 48

def expires_at = timestamp && (timestamp + LIFETIME)

#to_s ⇒ Object



50
# File 'lib/ksef/auth/challenge.rb', line 50

def to_s = challenge.to_s