{"id":1479,"date":"2022-08-30T15:16:52","date_gmt":"2022-08-30T15:16:52","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/11\/23\/ember-js-registerboundhelper-creating-an-if-like-helper-that-performs-server-side-authorization-via-json-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:16:52","modified_gmt":"2022-08-30T15:16:52","slug":"ember-js-registerboundhelper-creating-an-if-like-helper-that-performs-server-side-authorization-via-json-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/ember-js-registerboundhelper-creating-an-if-like-helper-that-performs-server-side-authorization-via-json-collection-of-common-programming-errors\/","title":{"rendered":"ember.js registerBoundHelper: creating an if-like helper that performs server-side authorization via json-Collection of common programming errors"},"content":{"rendered":"<p>javascript\/coffeescript\/ember.js\/stackoverflow newbie here!<\/p>\n<p>I&#8217;m trying to create an if-like helper that will display content only when the action on an object is authorized from the server. Basically I want the <code>can?<\/code> method from the rails cancan gem. I want to write the template something like this:<\/p>\n<h1><code>Viewing profile for {{email}}<\/code><\/h1>\n<pre>\n<\/pre>\n<h2><code>Scores<\/code><\/h2>\n<pre>\n{{#each score in scores}}\n    {{score.what}}  \n        {{#can score action=destroy}}\n            Destroyable  \n        {{\/can}}\n        {{#can score action=view}}\n            Viewable  \n        {{\/can}}\n        {{#can score action=edit}}\n            Editable  \n        {{\/can}}\n    \n{{\/each}}\n<\/pre>\n<p><code>The <code>can<\/code> ember.js helper will query the server with a json request that looks something like this:<\/code><\/p>\n<pre><code>\/api\/v1\/authorization.json?action=destroy&amp;cName=Score&amp;id=1\n<\/code><\/pre>\n<p>The server would simply return the HTTP status codes 200 or 401, and ember would magically display or hide the content based on the status code. I have to do the authorization this way because there&#8217;s some role- &amp; object based permissions checks that have to happen on the server, and I don&#8217;t want to duplicate the authorization logic in js.<\/p>\n<p>So far, I&#8217;ve used the out-of-the-box <code>if<\/code> helper as an example to create the following custom bound helper (coffeescript).<\/p>\n<pre><code>Ember.Handlebars.registerBoundHelper 'can', (object, options) -&gt;\n\n    permission = EmberDeviseExample.Authorization.create\n        action: options.hash.action\n        object: object\n\n    permission.authorize()\n\n    options.contexts = [permission]\n\n    Ember.Handlebars.helpers.boundIf.call(permission, \"can\", options)\n<\/code><\/pre>\n<p>Here&#8217;s the User object:<\/p>\n<pre><code>EmberDeviseExample.User = DS.Model.extend\n  email:        DS.attr('string')\n  scores:       DS.hasMany('EmberDeviseExample.Score')\n\nEmberDeviseExample.store.adapter.serializer.map('EmberDeviseExample.User', {scores: {embedded: 'load'}})\n<\/code><\/pre>\n<p>And here&#8217;s the Authorization object:<\/p>\n<pre><code>EmberDeviseExample.Authorization = Ember.Object.extend\n  action: ''\n  object: null\n  response: 401\n  urlBase: ApiUrl.authorization_path\n\n  can : (-&gt; \n      return (this.get('response') == 200)\n  ).property('response')\n\n  authorize: -&gt;\n    # if object is an instance, include the id in the query params\n    # otherwise, just include the class name\n    obj = this.get('object')\n    cName = obj.toString()\n    id = null\n    if Ember.typeOf(obj) == \"instance\"\n      # cname looks something like \"\"\n      # turn it into \"name\"\n      cName = cName.split(':')[0].split('.')[1]\n      id = obj.get('id')\n\n    $.ajax \n       url : \"#{this.get('urlBase')}.json\"\n       context : this\n       type : 'GET'\n       data : \n          action : this.get('action')\n          cName : cName\n          id : id\n\n       complete : (data, textStatus, xhr) -&gt;\n          this.set('response', data.status)\n\n    return this.get('can')\n<\/code><\/pre>\n<p>On the server side, the authorization.json code looks like this (rails 3). I am using the cancan gem to control authorization:<\/p>\n<pre><code>class AuthorizationsController &lt; ApplicationController\n  respond_to :json\n  def show\n    id     = params[:id]\n    cName  = params[:cName]\n    action = params[:action]\n\n    object = cName.capitalize.constantize\n\n    object = object.find(id) unless id.blank?\n\n    authorized = can? action, object\n\n    render status: (authorized ? 200 : 401), json: {}\n  end\nend\n<\/code><\/pre>\n<p>And the routes look like this:<\/p>\n<pre><code>  scope \"\/api\" do\n    scope \"\/v1\" do\n      resource :authorization, only: [:show]\n    end\n  end\n<\/code><\/pre>\n<p>Of course there&#8217;s other code in my app, let me know if you need to see it.<\/p>\n<p>When I remove the <code>#can<\/code> helpers, I see the rendered template. When I add the <code>#can<\/code> helpers back in, I get a javascript error, the message in Chrome is <code>\"Uncaught TypeError: Cannot read property '0' of null\" @ ember.prod.js:2362.<\/code><\/p>\n<p>Does anyone know how to build a helper that accepts an object and action, runs a server-side authorization check, and displays\/hides content based on the server result?<\/p>\n<p id=\"rop\"><small>Originally posted 2013-11-23 09:49:50. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>javascript\/coffeescript\/ember.js\/stackoverflow newbie here! I&#8217;m trying to create an if-like helper that will display content only when the action on an object is authorized from the server. Basically I want the can? method from the rails cancan gem. I want to write the template something like this: Viewing profile for {{email}} Scores {{#each score in scores}} [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1479","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1479","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=1479"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1479\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=1479"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=1479"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=1479"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}