Giter VIP home page Giter VIP logo

Comments (8)

skalee avatar skalee commented on June 29, 2024 1

Okay, so I thought about it a bit, and I got two ideas:

First of all, how it works now:

  1. The masker return value is simply passed to the SQL UPDATE command. Model attribute writers are not involved.
  2. By default, name of the column to be updated is derived from the attribute name, but it can be overwritten with column_name option.

We can easily enhance it in a following way:

  1. An array of column names can be passed as column_names option. If so, the masker's return value is expected to be an array as well, and its subsequent elements are update values for corresponding columns.

Example:

Here we're setting some agreed password for every user so that developers can log in as anyone they want. Password digest and salt are stored in separate columns.

class User
  attr_masker :password, column_names: ["password_digest", "password_salt"], masker: proc do
    new_password = "verysecret"
    salt = generate_random_salt()
    digest = encrypt_password(new_password, salt)
    [digest, salt]
  end
end

The masker's return value will be used in update operation like this one:

User.update(user.id, {password_digest: masker_retval[0], password_hash: masker_retval[1]})

However I am also thinking about a more radical change:

  1. The masker's return value is assigned to model's attribute via respective attribute writer method.
  2. The attribute writer may have arbitrary side effects. In particular, it may alter more than one database fields (see example below).
  3. However only changes made to fields specified in column_names option are saved. All other changes are discarded. The column_names option defaults to one-element array containing the attribute name.

Example:

class User
  attr_masker :password, masker: proc { "verysecret" }, column_names: ["password_hash", "password_salt"]

  def password=(new_password)
    self.password_salt = salt = generate_random_salt()
    self.password_hash = encrypt_password(new_password, salt)
  end
end

Consequences of this approach are as follows:

  1. It must be user's responsibility to ensure that the attribute writer is safe to use. For example, it could perform a database update (and that will happen before other attributes get reverted!), or some junk could be uploaded to S3, overwriting production pictures. On the other hand, :if, and :unless filters may also call model methods, so maybe it's not that bad. (But typically they will rely on getter methods and are far less likely to break anything).
  2. Since we're working on models, it should be possible to validate them before saving.

from attr_masker.

skalee avatar skalee commented on June 29, 2024

@ribose-jeffreylau Your input here is very welcome. I'd really like to know the usage example for the column_name option before I make any radical changes.

from attr_masker.

ribose-jeffreylau avatar ribose-jeffreylau commented on June 29, 2024

@skalee
For our current use case, it is actually very similar to the one you just posted above.
We use attr_encrypted alongside attr_masker. Using attr_encrypted means there would be some columns that are renamed to encrypted_old_column_name instead of just old_column_name.
In our test environment, we also want to be able to mask the column old_column_name. This is where :column_name comes into play.
Your proposed solution looks like it could handle this situation well.

from attr_masker.

ronaldtse avatar ronaldtse commented on June 29, 2024

Thanks @ribose-jeffreylau for the clarification, @skalee let's proceed, thanks!

from attr_masker.

ronaldtse avatar ronaldtse commented on June 29, 2024

@skalee I agree that the solution to #51 is this. The attribute writer can support "super" so that all necessary attribute writer modifiers are applied prior to masking.

I thought the tricky part is how to ensure attr_masker is in the attribute-writers chain, but that said all overrides to the attribute writer would technically have to call super so it won't be an issue.

Let's go ahead, thanks!

from attr_masker.

skalee avatar skalee commented on June 29, 2024

As for now, attr_masker does not use attribute writers at all.

from attr_masker.

ronaldtse avatar ronaldtse commented on June 29, 2024

Got it, let's do it. 👍

from attr_masker.

skalee avatar skalee commented on June 29, 2024

The column_name option has been introduced in #53.

from attr_masker.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.