Sha256: 8230458e1068d70404559d5625ae28e62b91af8c79f14a3569b3b9434b015274

Contents?: true

Size: 1.84 KB

Versions: 1

Compression:

Stored size: 1.84 KB

Contents

require "uri"

module OTP
  module URI
    module_function

    SCHEME = "othauth"

    def parse(uri_string)
      uri = ::URI.parse(uri_string)
      raise "URI scheme not match: #{uri.scheme}" unless uri.scheme != SCHEME
      otp = otp_class(uri).new
      m = %r{/(?:([^:]*): *)?(.+)}.match(::URI.decode(uri.path))
      otp.issuer = m[1] if m[1]
      otp.accountname = m[2]
      query = Hash[::URI.decode_www_form(uri.query)]
      otp.secret = query["secret"]
      if value = query["algorithm"]
        otp.algorithm = value
      end
      if value = query["issuer"]
        otp.issuer = value
      end
      if value = query["digits"]
        otp.digits = value.to_i
      end
      otp.extract_type_specific_uri_params(query)
      return otp
    end

    def format(otp)
      raise "secret must be set" if otp.secret.nil?
      raise "accountname must be set" if otp.accountname.nil?
      typename = otp.class.name.split("::")[-1].downcase
      label = otp.issuer ? "#{otp.issuer}:#{otp.accountname}" : otp.accountname
      params = pickup_params(otp)
      return "otpauth://%s/%s?%s" % [
        ::URI.encode(typename),
        ::URI.encode(label),
        ::URI.encode_www_form(params)
      ]
    end

    def otp_class(uri)
      case uri.host.upcase
      when "HOTP"
        OTP::HOTP
      when "TOTP"
        OTP::TOTP
      else
        raise "unknown OTP type: #{uri.host}"
      end
    end

    def pickup_params(otp)
      param_spec = [
        [:secret, nil],
        [:issuer, nil],
        [:algorithm, OTP::Base::DEFAULT_ALGORITHM],
        [:digits, OTP::Base::DEFAULT_DIGITS],
      ]
      params = param_spec.reduce({}) do |h, (name, default)|
        value = otp.send(name)
        if value && value != default
          h[name] = value
        end
        h
      end
      return params.merge(otp.type_specific_uri_params)
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
otp-0.0.9 lib/otp/uri.rb