Commit 5b4d821

mokha <mo@mokhan.ca>
2019-01-21 18:50:27
extract external key info class
1 parent a64fcb8
lib/xml/kit/templates/encryption.builder
@@ -2,18 +2,7 @@
 
 xml.EncryptedData xmlns: ::Xml::Kit::Namespaces::XMLENC do
   xml.EncryptionMethod Algorithm: symmetric_algorithm
-  if key_info
-    key_info.call(xml)
-  else
-    xml.KeyInfo xmlns: ::Xml::Kit::Namespaces::XMLDSIG do
-      xml.EncryptedKey xmlns: ::Xml::Kit::Namespaces::XMLENC do
-        xml.EncryptionMethod Algorithm: asymmetric_algorithm
-        xml.CipherData do
-          xml.CipherValue asymmetric_cipher_value
-        end
-      end
-    end
-  end
+  render key_info, xml: xml
   xml.CipherData do
     xml.CipherValue symmetric_cipher_value
   end
lib/xml/kit/templates/external_key_info.builder
@@ -0,0 +1,3 @@
+xml.KeyInfo xmlns: ::Xml::Kit::Namespaces::XMLDSIG do
+  xml.RetrievalMethod xmlns: ::Xml::Kit::Namespaces::XMLDSIG, URI: uri, Type: type
+end
lib/xml/kit/encryption.rb
@@ -23,13 +23,17 @@ module Xml
         @asymmetric_algorithm = asymmetric_algorithm
         asymmetric_cipher = asymmetric(asymmetric_algorithm, public_key)
         @asymmetric_cipher_value = Base64.strict_encode64(asymmetric_cipher.encrypt(symmetric_cipher.key))
-        @key_info = key_info
+        @key_info = key_info || KeyInfo.new(algorithm: asymmetric_algorithm, cipher_value: asymmetric_cipher_value)
       end
 
       def to_xml(xml: ::Builder::XmlMarkup.new)
         ::Xml::Kit::Template.new(self).to_xml(xml: xml)
       end
 
+      def render(model, options)
+        ::Xml::Kit::Template.new(model).to_xml(options)
+      end
+
       private
 
       def symmetric(algorithm)
lib/xml/kit/external_key_info.rb
@@ -0,0 +1,19 @@
+
+# frozen_string_literal: true
+
+module Xml
+  module Kit
+    class ExternalKeyInfo
+      attr_reader :uri, :type
+
+      def initialize(uri:, type: "http://www.w3.org/2001/04/xmlenc#EncryptedKey")
+        @uri = uri
+        @type = type
+      end
+
+      def to_xml(xml: ::Builder::XmlMarkup.new)
+        ::Xml::Kit::Template.new(self).to_xml(xml: xml)
+      end
+    end
+  end
+end
lib/xml/kit.rb
@@ -20,6 +20,7 @@ require 'xml/kit/decryption'
 require 'xml/kit/decryption_error'
 require 'xml/kit/document'
 require 'xml/kit/encryption'
+require 'xml/kit/external_key_info'
 require 'xml/kit/fingerprint'
 require 'xml/kit/id'
 require 'xml/kit/key_info'
spec/fixtures/item-extracted-key.builder
@@ -2,12 +2,7 @@ xml.instruct!
 xml.Item ID: id, xmlns: 'https://www.example.org/item#' do
   signature_for reference_id: id, xml: xml
   xml.Encrypted xmlns: 'https://www.example.org/item#' do
-    key_info = lambda do |xml|
-      xml.KeyInfo xmlns: ::Xml::Kit::Namespaces::XMLDSIG do
-        xml.RetrievalMethod xmlns: ::Xml::Kit::Namespaces::XMLDSIG, URI: "#EK", Type: "http://www.w3.org/2001/04/xmlenc#EncryptedKey"
-      end
-    end
-    encryption_for(xml: xml, key_info: key_info) do |xml|
+    encryption_for(xml: xml, key_info: ::Xml::Kit::ExternalKeyInfo.new(uri: "#EK")) do |xml|
       xml.EncryptMe do
         xml.Secret "secret"
       end
spec/xml/kit/external_key_info_spec.rb
@@ -0,0 +1,15 @@
+RSpec.describe Xml::Kit::ExternalKeyInfo do
+  describe "#to_xml" do
+    subject { described_class.new(uri: uri, type: type) }
+    let(:uri) { "#EK" }
+    let(:type) { "http://www.w3.org/2001/04/xmlenc#EncryptedKey" }
+    let(:result) { Hash.from_xml(subject.to_xml) }
+
+    specify { expect(result['KeyInfo']).to be_present }
+    specify { expect(result["KeyInfo"]["RetrievalMethod"]).to be_present }
+    specify { expect(result["KeyInfo"]["RetrievalMethod"]["xmlns"]).to eql(::Xml::Kit::Namespaces::XMLDSIG) }
+    specify { expect(result["KeyInfo"]["RetrievalMethod"]["URI"]).to eql(uri) }
+    specify { expect(result["KeyInfo"]["RetrievalMethod"]["Type"]).to eql(type) }
+    specify { expect(result["KeyInfo"]["EncryptedKey"]).to be_nil }
+  end
+end