5

Chcę przetestować model, który wykorzystuje attr_encrypted zaszyfrować tajemnicy w bazieJak używać urządzeń z attr_encrypted

class Thing 
    attr_encrypted :secret, encode: true 
end 

Ale kiedy zdefiniować tajemnicę w uchwycie zakodowany znak nowej linii zostanie uciekł na zewnątrz.

one: 
    encrypted_secret: '<%= Thing.encrypt_secret(SecureRandom.uuid) %>' 

Czyli:

'axZFZEknxUSYdUlPhwLBbj8CwSeCW5at2INA98EcCcY7MVFdmXvk7Sb4DZhC\nm6qD\n' 

są przechowywane w bazie danych jako:

'axZFZEknxUSYdUlPhwLBbj8CwSeCW5at2INA98EcCcY7MVFdmXvk7Sb4DZhC 
m6qD' 

Problem z tym jest to, że wtedy nie powiedzie:

thing = things(:one) 
assert_equal thing, Thing.find_by_secret(thing.secret) 

Thing. find_by_secret (thing.secret) zwraca nil becau se wynikowa kwerenda SQL próbuje dopasować dwie wersje zaszyfrowanego tajnego klucza i nie uda się dopasować.

Próbowałem:

one: 
    encrypted_secret: 'axZFZEknxUSYdUlPhwLBbj8CwSeCW5at2INA98EcCcY7MVFdmXvk7Sb4DZhC\nm6qD\n' 

ale uzyskać ten sam rezultat.

Jak skonfigurować swoje urządzenia do pracy z attr_encrypted?

Odpowiedz

0

Rozwiązaniem, które działa, jest zamiana wszystkich "\ n" na "\\ n" i użycie podwójnych cudzysłowów. Działa to:

one: 
    encryped_secret: "<%= Thing.encrypt_secret(SecureRandom.uuid).gsub(/\n/, '\\\\n') %>" 

Czy istnieje lepszy sposób na zrobienie tego?

0

Zmierzyłem się z podobną sytuacją pod Rails4 + attr_encrypted + fixture + Minitest environment, a tutaj moje obejście jest.

Podsumowując, miałem następujące kroki:

  1. zapisu zwykłego (= niezaszyfrowane) urządzenie tekstową z określonym rozszerzeniem pliku (w moim przypadku jest to * .yml.noenc).
  2. wpisz rake-task, aby przekonwertować z pustego urządzenia (.yml.noenc) na zaszyfrowane urządzenie ( .yml).

Proszę pozwolić mi wyjaśnić szczegóły poniżej.

Na przykład, „Message” model posiada dwa atrybuty „Nazwa” i „ciało”, które muszą być szyfrowane, co następuje:

class Message < ActiveRecord::Base 
    attr_encrypted :name, key: ... 
    attr_encrypted :body, key: ... 
    ... 
end 
  1. testowego zapisu/przynależności/messages.yml.noenc jako wynika z tego, który ma prostą nazwę i treść:
msg1: 
    name: Hello 
    body: Hello, I am here... 
msg2: 
    name: How are you 
    body: Good morning, ... 
  1. napisz następującą prowizję-zadanie (np. lib/tasks/encrypt_fixture.rake) do konwersji messages.yml.noenc do wiadomości.yml:
require 'active_record/fixtures' 

src_yml = 'test/fixtures/messages.yml.noenc' 
dest_yml = 'test/fixtures/messages.yml' 

task 'test' => dest_yml 

namespace :[MY_APP] do 
    desc "generate encrypted fixture" 
    file dest_yml => src_yml do |t| 
    require Rails.root + 'config/environment' 

    encrypted_hash = {} 
    for k, v in YAML.load(ERB.new(File.read(Rails.root + src_yml)).result) do 
     msg = Message.new(v.merge([ANY ADDITIONAL ATTRS])) 
     encrypted_hash[k] = { 
     'encrypted_name' => msg.encrypted_name, 
     'encrypted_name_iv' => msg.encrypted_name_iv, 
     'encrypted_body' => msg.encrypted_body, 
     'encrypted_body_iv' => msg.encrypted_body_iv, 
     [ANY ADDITIONAL KEY_N_VALUE] 
     } 
    end 

    File.open(Rails.root + t.name, 'w') do |f| 
     f.write(<<EOH) 
    #---------------------------------------------------------------------- 
    # DO NOT MODIFY THIS FILE!! 
    # 
    # This file is generated from #{src_yml} by: 
    # 
    # (edit #{src_yml}) 
    # $ rake [MY_APP]:generate_fixture, or 
    # $ rake 
    #---------------------------------------------------------------------- 
EOH 
     f.write(encrypted_hash.to_yaml) 
    end 
    end 
end 

Należy zastąpić [MY_APP], [WSZELKICH DODATKOWYCH attrs] i [] Wszelkie dodatkowe KEY_N_VALUE do wartości rzeczywistych.

Następnie "rake" lub "test rake" sprawdza zależność między plikami messages.yml.noenc i messages.yml, i generuje messages.yml w razie potrzeby przed "testem rake".