Adding column encryption #225
Replies: 6 comments 4 replies
-
You can override any part of Rodauth, even parts without configuration methods, using plugin :rodauth do
auth_class_eval do
private def account_ds(id=account_id)
# ...
end
end
end |
Beta Was this translation helpful? Give feedback.
-
Ah yes, this is a much better and easier solution. It is even listed in the readme file, but I didn't realize this can be used to overwrite existing methods. This opens up a lot of new options, for starters changing the |
Beta Was this translation helpful? Give feedback.
-
First of all, thanks to @jeremyevans for writing Rodauth. We've just started using it and it looks great. We're trying to also encrypt the email column. Did you ever get this to work? Using your clues here, we think we need to:
But now RodauthRails is crashing when we try to read the account as a Rails model. We will ask Janko who wrote RodauthRails about that part. But I'm wondering if we are trying to override things at the wrong level. Does it sound like changing |
Beta Was this translation helpful? Give feedback.
-
Thanks so much for your fast reply. You've really built a nice and composable system here. We have a new idea: Instead of overriding Rodauth's
My hunch is it will disrupt the inner workings of Rodauth less, and thus be more reliable. Which would you suspect would be the easier route?
|
Beta Was this translation helpful? Give feedback.
-
This is what I came up with for encrypting emails using Active Record encryption mentioned in janko/rodauth-rails#196 (though it can be generalized to any encryption): save_account do
original_email = account[login_column]
account[login_column] = encrypt(original_email)
super()
account[login_column] = original_email
end
account_from_login { |login| super(encrypt(login)) }
verify_login_change_old_login { decrypt(super()) }
# if you want emails to be encrypted in account_login_change_keys table as well:
verify_login_change_key_insert_hash { |login| super(encrypt(login)) }
get_verify_login_change_login_and_key do |id|
login, key = super(id)
[decrypt(login), key]
end
auth_class_eval do
private
def account_table_ds
super.with_row_proc(-> (data) { with_decrypted(data, login_column) })
end
def _update_login(login)
result = super(encrypt(login))
account[login_column] = login
result
end
def with_decrypted(hash, key)
hash.merge(key => decrypt(hash[key]))
end
def encrypt(string)
encrypted_type.serialize(string)
end
def decrypt(string)
encrypted_type.deserialize(string)
end
def encrypted_type
Account.attribute_types[login_column.to_s]
end
end There are places where Rodauth separates out writing from setting value in memory well, such as This isn't bulletproof, as any code that calls |
Beta Was this translation helpful? Give feedback.
-
It's working! We also had to adjust how Account.instantiate worked so that
|
Beta Was this translation helpful? Give feedback.
-
I'm using roda, sequel and rodauth to create a single-signon application. After a lot of tinkering, reading the docs and source code it all seems to work smoothly.
Currently I'm trying to add column-encryption to the email field of the accounts model. So I changed the migration a bit (postgres version) removing the check constraint on email and adding a unique index:
left(email, 48)
.Next added a model
Account < Sequel::Model
and set up column encryption. After that I found some methods needed overriding to work with the model, so far: email_to, account_from_login, account_from_session, new_account, save_account, verify_login_change, otp_provisioning_name.To make other features like ChangeLogin work some more overrides can be used. An easier solution would be to override method
account_ds
from feature 'Base', so it returnsAccount.where(id: id)
. This method can not be overridden the same way as the other methods since it is not in list 'auth_private_methods'. After changing account_ds implementation in the source of my local rodauth gem all features work like a charm. To make such a change permanent a fork of Rodauth would be needed: not my favorite solution.So I am wondering if this is the right approach for adding column-encryption? Am I missing something that would make it a lot simpler to add this feature?
Beta Was this translation helpful? Give feedback.
All reactions