require 'openssl'
require 'digest/md5'
require 'jwt'

module Nexmo
  class Signature
    def initialize(secret)
      @secret = secret
    end

    # Check webhook request signature.
    #
    # @example
    #   client = Nexmo::Client.new(signature_secret: 'secret')
    #
    #   if client.signature.check(request.GET)
    #     # valid signature
    #   else
    #     # invalid signature
    #   end
    #
    # @param [Hash] params
    #
    # @see https://developer.nexmo.com/concepts/guides/signing-messages
    #
    def check(params, signature_method: 'md5hash')
      params = params.dup

      signature = params.delete('sig')

      ::JWT::SecurityUtils.secure_compare(signature, digest(params, signature_method))
    end

    private

    def digest(params, signature_method)
      digest_string = params.sort.map { |k, v| "&#{k}=#{v.tr('&=', '_')}" }.join

      if ['md5', 'sha1', 'sha256', 'sha512'].include? signature_method
        OpenSSL::HMAC.hexdigest(signature_method, @secret, digest_string).upcase
      elsif signature_method == 'md5hash'
        Digest::MD5.hexdigest("#{digest_string}#{@secret}")
      else
        raise "Unknown signature algorithm: #{signature_method}. Expected: md5hash, md5, sha1, sha256, or sha512."
      end
    end
  end
end

# frozen_string_literal: true
require 'openssl'
require 'digest/md5'
require 'jwt'

module Nexmo
  class Signature
    def initialize(secret)
      @secret = secret
    end

    # Check webhook request signature.
    #
    # @example
    #   client = Nexmo::Client.new(signature_secret: 'secret')
    #
    #   if client.signature.check(request.GET)
    #     # valid signature
    #   else
    #     # invalid signature
    #   end
    #
    # @param [Hash] params
    #
    # @see https://developer.nexmo.com/concepts/guides/signing-messages
    #
    def check(params, signature_method: 'md5hash')
      params = params.dup

      signature = params.delete('sig')

      ::JWT::SecurityUtils.secure_compare(signature, digest(params, signature_method))
    end

    private

    def digest(params, signature_method)
      digest_string = params.sort.map { |k, v| "&#{k}=#{v.tr('&=', '_')}" }.join

      case signature_method
      when 'md5', 'sha1', 'sha256', 'sha512'
        OpenSSL::HMAC.hexdigest(signature_method, @secret, digest_string).upcase
      when 'md5hash'
        Digest::MD5.hexdigest("#{digest_string}#{@secret}")
      else
        raise "Unknown signature algorithm: #{signature_method}. Expected: md5hash, md5, sha1, sha256, or sha512."
      end
    end
  end
end

Use case statement instead of if/elsif
Use case statement instead of if/elsif
