Fixing column value in the model


#1

I’m using a Crypto.encrypt(“string”) to create a record for a column and
Crypto.decrypt(column) when reading and presenting it in the browser. I
do this in the controller. Can I do it in the model instead?


#2

Pål Bergström wrote:

I’m using a Crypto.encrypt(“string”) to create a record for a column and
Crypto.decrypt(column) when reading and presenting it in the browser. I
do this in the controller. Can I do it in the model instead?

Yes. You can create a custom attribute for the unencypted version,
which will exist in memory and not be persisted. You can then use a
Callback to encrypt and set the persisted column before an
insert/update. Look at examples of authentication plugins and blog
posts and you’ll see how it’s done.

Also, don’t forget to filter the parameter in the controller (e.g.
filter_parameter_loggoing :password) so the form posted parameter is not
logged in clear text, assuming you’re accepting if from a form that is.

b


#3

Brian Mr wrote:

Pål Bergström wrote:

I’m using a Crypto.encrypt(“string”) to create a record for a column and
Crypto.decrypt(column) when reading and presenting it in the browser. I
do this in the controller. Can I do it in the model instead?

Yes. You can create a custom attribute for the unencypted version,
which will exist in memory and not be persisted. You can then use a
Callback to encrypt and set the persisted column before an
insert/update. Look at examples of authentication plugins and blog
posts and you’ll see how it’s done.

Also, don’t forget to filter the parameter in the controller (e.g.
filter_parameter_loggoing :password) so the form posted parameter is not
logged in clear text, assuming you’re accepting if from a form that is.

b

I got it working with before_save in the model, encrypting the data
before it goes to the db. Great.

But what about before show or listing records? How can I make a similar
decrypt? Don’t understand what to use.


#4

Brian Mr wrote:

Pål Bergström wrote:

Simply add a public method to the model that returns the unendrypted
version. The method will not map to an actual column in the db, but to
the controller it will appear just like any other colum.

e.g.

def myattribute
Crypto.decrypt(column)
end

I don’t understand all the way. Probably a stupid question but could you
be more specific with what you mean with"myattribute"? Is that the
column name or?


#5

Pål Bergström wrote:

Brian Mr wrote:

Pål Bergström wrote:

I’m using a Crypto.encrypt(“string”) to create a record for a column and
Crypto.decrypt(column) when reading and presenting it in the browser. I
do this in the controller. Can I do it in the model instead?

Yes. You can create a custom attribute for the unencypted version,
which will exist in memory and not be persisted. You can then use a
Callback to encrypt and set the persisted column before an
insert/update. Look at examples of authentication plugins and blog
posts and you’ll see how it’s done.

Also, don’t forget to filter the parameter in the controller (e.g.
filter_parameter_loggoing :password) so the form posted parameter is not
logged in clear text, assuming you’re accepting if from a form that is.

b

I got it working with before_save in the model, encrypting the data
before it goes to the db. Great.

But what about before show or listing records? How can I make a similar
decrypt? Don’t understand what to use.

Simply add a public method to the model that returns the unendrypted
version. The method will not map to an actual column in the db, but to
the controller it will appear just like any other colum.

e.g.

def myattribute
Crypto.decrypt(column)
end


#6

Pål Bergström wrote:

Brian Mr wrote:

Pål Bergström wrote:

Simply add a public method to the model that returns the unendrypted
version. The method will not map to an actual column in the db, but to
the controller it will appear just like any other colum.

e.g.

def myattribute
Crypto.decrypt(column)
end

I don’t understand all the way. Probably a stupid question but could you
be more specific with what you mean with"myattribute"? Is that the
column name or?

It’s not a column, it’s just a method. ActiveRecord is just a Ruby
Class, so you can add your own methods. e.g. To use the method in a
controller:

x = myrecord.find…
y = myrecord.myattribute

y now holds the unencypted value.


#7

Pål Bergström wrote:

Brian Mr wrote:

Pål Bergström wrote:

y = myrecord.myattribute

y now holds the unencypted value.

Got it working with this in the model:

before_save :crypt_data
after_save :decrypt_data
after_find :decrypt_data
define_method(:after_find) { }

Works perfect.

Just one more thing. How do I deal with search? I have a solution but
perhaps I’m not doing it right.

I have a custom decrypt on the data before the find using %string% and
LIKE, but it must be full words as the columns holds the encrypted data.
Anyway around this?

Sorry, don’t have an answer for that. If nobody else replies, you might
want to post a new question for that. Glad the got the rest working!

b


#8

Brian Mr wrote:

Pål Bergström wrote:

y = myrecord.myattribute

y now holds the unencypted value.

Got it working with this in the model:

before_save :crypt_data
after_save :decrypt_data
after_find :decrypt_data
define_method(:after_find) { }

Works perfect.

Just one more thing. How do I deal with search? I have a solution but
perhaps I’m not doing it right.

I have a custom decrypt on the data before the find using %string% and
LIKE, but it must be full words as the columns holds the encrypted data.
Anyway around this?