简体   繁体   中英

Access controller properties within Ember Data Transform

I like to access a controller property within Ember Data Transform. Is there anyway how to do that?

Perhaps a few words to my use case. I like to create a custom attribute 'encryptedStrings' and use DS.Transform to encrypt / decrypt the string with a given key by using Stanford Javascript Crypto Library. The key should by part a query param in the uri.

get method is defined in DS.Transform but I did not get further. Here the relevant parts of the code:

App.EncryptedStringTransform = DS.Transform.extend({
    deserialize: function(serialized) {
       var key = this.get('pollController.encryptionKey');
       return Ember.isNone(serialized) ? null : String( sjcl.decrypt( key , serialized) );
    },
    serialize: function(deserialized) {
       var key = this.get('pollController.encryptionKey');
       return Ember.isNone(deserialized) ? null : String( sjcl.encrypt( key , deserialized) );
    }
});

App.PollController = Ember.ObjectController.extend({
    queryParams: ['encryptionKey'],
    encryptionKey: 'default'
});

Instead of

this.get('pollController.encryptionKey');

I also tried this ones:

console.log( this.get('controller.encryptionKey') );
console.log( this.get('controllers.poll.encryptionKey') );
console.log( this.get('controllers.pollController.encryptionKey') );

Interesting! I wonder whether it's a good idea to have the encryption key be so exposed to be in the URL. But, assuming this is what you want to do, instead of transforming the data as part of the serializer, I think what I would do is set the key as a property on the model (from the route where the queryParam is exposed). Then, have the unencrypted values be computed properties on the model that are derived based on the key and the encrypted values, which would just be regular DS.attr() . Computed properties can be both getters and setters so if a new value is set on the unencrypted property, then you can just set the reencrypted value.

Update:

Here's an example of how you can write the computed property in a reusable way:

Ember.computed.encrypted = function(encryptedField, keyField) {
  return Ember.computed(encryptedField, keyField, function(key, decryptedValue) {
    var encryptKey = this.get(keyField), encryptedValue;
    //setter
    if (arguments.length == 2) {
      encryptedValue = Ember.isNone(decryptedValue) ? null : String( sjcl.encrypt( encryptKey , decryptedValue) );
      this.set(encryptedField, encryptedValue);
    }
    encryptedValue = this.get(encryptedField);
    return Ember.isNone(encryptedValue) ? null : String( sjcl.decrypt( encryptKey , encryptedValue) );
  });
};

Then, you can write your model like this:

App.SensitiveData = DS.Model.extend({
  encryptKey:      DS.attr('string'),
  encryptedField1: DS.attr('string'),
  encryptedField2: DS.attr('string'),
  decryptedField1: Ember.computed.encrypted('encryptedField1','encryptKey'),
  decryptedField2: Ember.computed.encrypted('encryptedField2','encryptKey')
});

Update 2:

You can set the encryption key on your model via the Route, like this:

App.SensitiveDataRoute = Ember.Route.extend({
  model: function(params) {
    return this.store.find('sensitive-data', params.sensitive_data_id).then(function(sensitiveData) {
      sensitiveData.set('encryptKey', params.encryption_key);
      return sensitiveData;
    });
  }
});

Or, assuming the data isn't exposed via the route, but only through the controller, you can add an observer to the controller and set the value through the observer, like this (note, it's possible that this isn't even necessary and since the controller proxies to the model, as long as the attribute in the model matches the query param name specified in the controller, you don't even need to do the observer logic, I'd need to play around with it to say for sure):

App.SensitiveDataController = Ember.ObjectController.extend({
  queryParams: ['encryptionKey'],
  encryptionKey: null,

  updateEncryptKey: function() {
    this.set('encryptKey', this.get('encryptionKey'))
  }.observes('encryptionKey')
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM