Top Banner
SOME INTERESTING THINGS YOU CAN DO WITH RENDER Being a Brief Treatise on Matters of Eciency & Security Alex Koppel - Railsberry
13

Railsberry Lightning Talk: Playing with Render

Nov 29, 2014

Download

Technology

Alex Koppel

Railsberry Lightning Talk: Playing with Render

Slides from the lightning talk I gave at Railsberry* on how you can wrap Rails' render function to expose universal options and and additional security to an API. It's an appetizer: I'll be talking in more detail about API uniformity and control at the Barcelona Ruby Conference in September 2012.

Best part of the talk: afterward, Yehuda Katz (yes, that @wycats) came by to tell me he had the same initial reaction [wrapping render = bad idea], but that no, the approach is quite fine. The signature is stable and ActionController::Metal does it too. Score.

* one of the sweetest Rails conferences I've been to, incidentally.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Railsberry Lightning Talk: Playing with Render

SOME INTERESTING THINGS YOU CAN DO WITH RENDER

Being a Brief Treatise on Matters of Efficiency & Security

Alex Koppel - Railsberry

Page 2: Railsberry Lightning Talk: Playing with Render

BACKGROUND/GOALS

 Wunderkit: an API-driven app  Give clients control over the data returned  Provide secured output  Universal implementation

Page 3: Railsberry Lightning Talk: Playing with Render

THE RENDER METHOD

 Stable signature (2.3-4.0beta)   For our purposes

 Arguments => options hash  This hash is provided to renderers

  to_json, to_xml, ActiveModel::Serializers, etc.  Controller action

  Complete access to user state

Page 4: Railsberry Lightning Talk: Playing with Render

DEF RENDER # /actionpack/lib/abstract_controller/rendering.rb (3.2)

def render(*args, &block) options = _normalize_render(*args, &block) self.response_body = render_to_body(options) end

Page 5: Railsberry Lightning Talk: Playing with Render

EXAMPLE: DATASET SIZE

 Problem: different devices want different amounts of data   Web: full record at first encounter   iOS: only what’s needed

 Ideal solution   Serialization solution handles dataset contents

 Model#as_json, serializer, etc.

  API exposes universal options

Page 6: Railsberry Lightning Talk: Playing with Render

MAKE IT SO

def render(*args, &block) # ensure we have an options hash options = args.find {|a| a.is_a?(Hash)} args << (options = {}) unless options

# set the dataset option options[:dataset] = params[:dataset] || "full"

# proceed super end

Page 7: Railsberry Lightning Talk: Playing with Render

EXAMPLE: CURRENT USER INFO

 Example: current user info  Problem: some info should only be shown to

the current user   Billing status, location info   ActiveModel::Serializers provides this automatically

 Ideal solution   Serializer/model knows what (if any) sensitive data

they contain   Controllers filter that data transparently

Page 8: Railsberry Lightning Talk: Playing with Render

ENGAGE

def render(*args, &block) # ensure we have an options hash options = args.find {|a| a.is_a?(Hash)} args << (options = {}) unless options

# store the current user options[:user] = current_user

# proceed super end

Page 9: Railsberry Lightning Talk: Playing with Render

SECURITY

 Can we use a similar approach?   Prevent unauthorized data access?

 Sure! But…

Page 10: Railsberry Lightning Talk: Playing with Render

ACTIVATE SHIELDS

def render(*args, &block) # ...

if data = options[:json] # remove any items that the user shouldn't see secure_content!(data) end

# ... super end

Page 11: Railsberry Lightning Talk: Playing with Render

GENERAL DOWNSIDES

 Patching render somehow feels wrong   Is it?

 Other libraries may handle options hash badly   Occasionally seen options defaulted to nil

 Low risk of the render signature changing

Page 12: Railsberry Lightning Talk: Playing with Render

SECURITY DOWNSIDES

 Huge risk of accidental overhead   Structure carefully to only use data in memory

 Not bulletproof   Handling non-Array data types gets tricky   Misses data as_json’d in the controller   Inflexible (though probably for the best)

Page 13: Railsberry Lightning Talk: Playing with Render

THANKS!

@arsduo I work for @6wunderkinder

I’ll talk about this at @baruco2012 too