Запретить "attr_encrypted" & "blind_index" создавать зашифрованные поля, когда исходное значение - пустые строки - PullRequest
0 голосов
/ 08 ноября 2018

Я использую attr_encrypted & blind_index Gems для безопасного сохранения и поиска конфиденциальных данных.

Gemfile:

gem "attr_encrypted", "~> 3.0.0"  
gem "blind_index"

Модель

attr_encrypted :email, :key => [ENV["DB_ENCRYPTED_KEY"]].pack("H*")
blind_index :email, :key => [ENV["BLIND_INDEX_KEY"]].pack("H*")

validates :email, :uniqueness => true, :allow_blank => true

Миграция

add_column :users, :encrypted_email, :string
add_column :users, :encrypted_email_iv, :string
add_column :users, :encrypted_email_bidx, :string

add_index :users, :encrypted_email_bidx, :unique => true

Все работает нормально, за исключением того, что, когда я пытаюсь добавить пользователя, где электронная почта пуста (пустая строка), он все равно создает поля encrypted_email_iv и encrypted_email_bidx, и, соответственно, вызывает исключение postgres 'PG :: UniqueViolation', когда Я пытаюсь создать другого пользователя с пустым адресом электронной почты. Вот подробная ошибка:

PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_customers_on_encrypted_email_bidx" DETAIL: Key (encrypted_email_bidx)=(DuFZwCHck+O9kivr2J64r5Q9MJrGoP5P1U0ikIgyj7c= ) already exists.

Когда я пытаюсь сделать это с консоли rails, я получаю ту же ошибку, однако она отлично работает, если адрес электронной почты nil, а не пустая строка.

То есть User.create(name: 'aaa', telephone: '1234-5678') не будет создавать зашифрованные поля Пока User.create(name: 'aaa', telephone: '1234-5678', email: '') подойдет !!

1 Ответ

0 голосов
/ 08 ноября 2018

Оба драгоценных камня выдают только NULL для nil значений, их можно исправить в контроллере:

params[:user][:email] = nil if params[:user][:email].empty?
@user = User.new(user_params)
...

или заставьте вашу модель преобразовать пустые строки в nil s, переопределив setter:

attr_encrypted :email, ...
...
old_setter = instance_method(:email=)
define_method(:email=) do |val|
  val = nil if val.blank?
  old_setter.bind(self).call(val)
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...