Sha256: f2b1912c7b870a26c3bed3c5deccc50a8fbcf771f77429ab142a6aa5872e75a0

Contents?: true

Size: 1.83 KB

Versions: 6

Compression:

Stored size: 1.83 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
      if %r{/(?:([^:]*): *)?(.+)} =~ uri.path
        otp.issuer = $1
        otp.accountname = $2
      end
      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

6 entries across 6 versions & 1 rubygems

Version Path
otp-0.0.8 lib/otp/uri.rb
otp-0.0.7 lib/otp/uri.rb
otp-0.0.6 lib/otp/uri.rb
otp-0.0.5 lib/otp/uri.rb
otp-0.0.4 lib/otp/uri.rb
otp-0.0.3 lib/otp/uri.rb