Hiding a model function

I'm still developing my user model, and I've reached a quandary.

I want to keep anyone from being able to do "user.password = 'bob'", but don't want to break any built in AR magic.

I'm not entirely sure I even know how to do that... and beyond that, I'm not sure if I do figure out how to do that, how I'm going to actually set the password (I intend to write a change_password function, but if I take away the ability to do user.password = 'blah', then I almost certainly can't do self.password = 'blah' either)...

Try attr_protected railsapi.org - railsapi Resources and Information.

-r

In your model class:

def password=(password) end

That will silently ignore the call to password=. You can have it raise an error if you want.

"I want to keep anyone from being able to do "user.password = 'bob'", but don't want to break any built in AR magic."

the question is, who do you need to stop from doing this and why? who is 'anyone'?

Make the method private:

def change_password(pass)   self.password = pass end

private def password=(password)   do some stuff   self.save end

then you can only call the password= method from within the model and then use model.change_password(password) to make the password change.

M<><

Alan and Ben beat me to it :slight_smile:

that was the reason i asked why you wanted to 'hide' the method.

another method is to just override the method itself

def password=(password)   self.password_salt = "some random salt value" # used to validate password at login   self.password_hash = encrypted_pw end

i would argue 'what does it HURT?'.

Curious. What kind of environment are you developing in that you can’t trust other developers to know what’s up and to not try something stupid? It’s not like the regular user can do anything to the model as such.

Jason

Luke Ivers wrote:

Chris Hall wrote:

Alan and Ben beat me to it :slight_smile:

that was the reason i asked why you wanted to 'hide' the method.

another method is to just override the method itself

def password=(password)   self.password_salt = "some random salt value" # used to validate password at login   self.password_hash = encrypted_pw end

Okay, this has prompted me to ask another question: in all of these, it generates a new salt every time it generates a new password... is there a particular reason for this? I understand it would be slightly more secure... but it seems to me the added security of changing the salt every time the password changes is basically neglible... if someone has cracked the original salt, they've probably already hijacked the account and changed the password themselves.

Don't do that. The salt is there for a reason - it makes creating comprehensive lookup tables that much harder. If you hardcode the salt, you make it that much easier for someone to generate a lookup table that covers _all_ of your passwords. You don't "crack the salt" - the salt adds complexity to the password.

Salt (cryptography) - Wikipedia explains it well.

protected "encrypted_password="

will take care of what you need. Since symbols and strings are relatively the same, this will work fine.

Unfortunately ruby doesn't really give you absolute power over making sure your developers don't go and blow their brains out. You can make it really hard for them not to blow their brains out, but eventually one of them will decide to say, well... why don't I just do...

#TODO: Not hardcode this password user.instance_eval("@attributes['password'] = \"changeme\") user.save!

Now I can save the password without that silly evaluation going on. In such case, I really recommend that you fire your developer. Or roll back his code, isn't that what revisions were made for?