Tony Schneider

  • Archive
  • RSS

Nested Routing w/ a parameterized scope

The Rails router is awesome. But every once in a while I come across something I want to do and it’s not immediately obvious. In this particular case I wanted to have a simple nested resource with a scope.

i.e

/foos/:foo_id/:scope/bars/:id

Sounds easy enough, right?

Well, here was my first attempt:

resources :foos do
  member do
    scope ":scope" do
      resources :bars
    end
  end
end

But, to my surprise this generates the following:

/foos/:id/:scope/bars/:id

Oops! That’s no good. In your controller, you’ll only get one of those :id parameters. In fact, I think it might be a bug. Hopefully if I have a few cycles I can try and get a fix in. At the very least a test exposing the observed behavior to see if this is intended.

Anyway, as a work around, I was able to do the following after digging through the source.

resources :foos do
  resources :bars, path: ":scope/children"
end

I wasn’t aware of the path option to resources, and I certainly didn’t know you could make the path parameterized. I hope to improve the docs on this a bit after work.

***note: In production, it’s probably a good idea to add a custom constraint to limit the allowed parameterized scopes - Especially if you’re using that parameter as… I don’t know… a scope.

    • #ruby
    • #rails
    • #routing
    • #scope
    • #resources
  • 6 months ago
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+

Don’t forget! or vs ||

See this happening way too much. Just remember, watch out when assigning…

irb: foo = false || true
===> true

irb: foo
===> true

irb: foo = false or true
===> true

irb: foo
===> false
    • #ruby
  • 6 months ago
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+

Rails HTTP status to symbol mapping

    • #rails
    • #http
    • #ruby
  • 1 year ago
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+

Securing Your API Using Rack Middleware & OAuth 1.0

Forgot to post a link to this. I wrote an article for the EdgeCase Library!

    • #edgecase
    • #ruby
    • #rack
    • #OAuth 1.0
  • 1 year ago
  • 1
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+

UTF-8 Good, Windows-1252 Bad

So I’m using sidekiq, with sidekiq-scheduler at work in production to handle background tasks. Well, the other night around 10pm, just as I was settling down to watch the last episode of Mad Men, all hell broke lose.

After digging through the logs to find out what happened, all I could find was this

2012-05-07T01:59:10Z 24340 TID-fmbc0 ERROR: Manager#assign died
2012-05-07T01:59:10Z 24340 TID-fmbc0 ERROR: "\xC3" on US-ASCII
2012-05-07T01:59:10Z 24340 TID-fmbc0 ERROR: /home/web_apps/dream/shared/bundle/ruby/1.9.1/gems/json-1.6.6/lib/json/common.rb:148:in `encode'

None of the stack trace bubbled up to my app, so I knew I had no chance at rescuing from an exception. That left me with one thing to do, try and figure out what the heck caused this. Fortunately, I was able to lean on a few more seasoned colleagues of mine for advice.

After some discussion, we landed on our app being sent a windows-1252 encoded character, and trying to parse it as UTF-8.

So, to combat such things, we came up with this:

# This method exists because it has been shown that we cannot
# trust data coming from facebook
#
def clean_fb_str(str)
  ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
  if str == ic.iconv(str)
    # valid UTF-8 string should match its iconv version
    str
  else
    # UTF-8 conversion changed string, force windows-1252 into utf-8
    windows_ic = Iconv.new('UTF-8//IGNORE//TRANSLIT', 'WINDOWS-1252')
    windows_ic.iconv(str)
  end
end

Seems to do the job, as we haven’t yet had a reoccurrence of the issue.

NOTE: After deploying this on ruby-1.9.3, I’ve noticed we are getting deprecation warnings. I suppose we should be using String#encode instead.

    • #utf-8
    • #windows-1252
    • #iconv
    • #ruby
    • #sidekiq
  • 1 year ago
  • 1
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+

Ruby Standard Library: Shellwords

It wasn’t too long ago I was working on a command line application. Luckily, ruby makes parsing the command line pretty trivial with the OptionParser. OptionParser works great if you want to specify command line arguments with flags. However, sometimes you want to accept options in a more declarative style.

The Shellwords library, also found in the standard library, may come in handy for this.

This module manipulates strings according to the word parsing rules of the UNIX Bourne shell.


require "shellwords"

Shellwords.split("todo new 'Get the milk'") 
# => ["todo", "new", "Get the milk"]

Maybe I’m the only one, but I was not aware this existed. Sure, it may not be the most difficult thing to implement yourself. But, having not researched the word parsing rules of the UNIX Bourne shell, I’m willing to guess there are plenty of edgecases I would miss.

Yay Ruby Standard Library!

    • #ruby
    • #shellwords
    • #stdlib
  • 1 year ago
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+

OAuth, OAuth2 and Ruby

Recently, some colleagues and I have been working on a client project that involves several different internal web services. Along with the usual user authentication, we needed a way to authenticate and verify API requests across these services.

Let’s start with user authentication. Enter OAuth2…

OAuth2

If you aren’t familiar with the OAuth2 protocol, I’m sure you’ve at least used it as a client. You click the “login-using-some-3rd-party”, get redirected, enter your credentials, get redirected back. Badda boom, badda bing, done - you’re authenticated. This works great for that three-legged exchange of resource owned credentials discussed at length in section 4.1 in the RFC. There are a ton of resources for this. Especially in the ruby/rails space. Some excellent ones to check out are the following:

  • devise_oauth2_providable (github)
  • omniauth (github)

The devise_oauth2_providable is a rails engine that makes creating a standard OAuth2 provider insanely easy. At the time of this post, it is actively maintained. In fact, when we came across a bug during development, it wasn’t more than an hour later and someone had provided a fix, pulled it in, and cut a new version.

Omniauth is a wonderful little gem that provides an excellent abstraction for any type of client authentication. It has templates that provide a simple DSL for the most popular authentication schemes.

This workflow is excellent when you have a service that wishes to authenticate using a third party (like Facebook or Google). However, since the we owned both the OAuth2 provider and the OAuth2 client, it seems pretty silly to redirect to our Authentication server, enter credentials, and redirect back our client app. Fortunately, the OAuth2 specifies a protocol for this use case as well in Section 4.3 of the RFC.

As a fan of the omniauth abstraction, I looked into the OAuth2 abstract strategy for easily defining OAuth2 client strategies. Unfortunately it is designed for use with the Authorization code grant type. To solve this, a co-worker and I made a similar omniauth abstract strategy for providing the functionality defined in section 4.3 (should be open source shortly). Having used devise_oauth2_providable for the OAuth2 provider, it just worked.

Now, for the final piece of the puzzle, authenticating API requests. Again, OAuth2 has a flow for this use case. It’s specified in the Client Credentials grant type in section 4.4. However, we noticed a problem. The OAuth2 specification had been edited a week prior. And on top of that, section 4.4 relies only on Basic Auth. I’m sure this has its use cases, but after some research there appears to be a lot of discussion on whether or not this is a sufficient solution.

We certainly wanted something more secure than Basic Auth. Enter OAuth 1.0…

OAuth 1.0

OAuth 1.0 solves the same problems that OAuth 2 aims to solve, but in a different (arguably more secure) way. It also supports workflows analogous to sections 4.1, 4.3, and 4.4 of OAuth2. So, given the current state of the OAuth2 RFC, if you need the functionality described in the client credentials grant type of OAuth2, and basic auth doesn’t provide enough security, you’re probably better off using OAuth 1.0.

If you’re using Ruby, you might be tempted to use the oauth gem. I would highly recommend not doing this given the state of the gem. The github network graph seems to imply a pretty heavily divergent state. Having found at least one bug, and a serious lack of tests and documentation, I hope you’ll learn from my mistake and look elsewhere.

Fortunately, there are some pretty amazing options that I wish I would have found earlier. Here’s a quick recap:

  • simple_oauth (github) - It is just that. It signs and verifies OAuth requests. This gem has tests, documentation, and is well maintained.
  • faraday_middleware (github) - This is a bit of Rack middleware that works alongside the excellent Faraday gem. It comes with a couple middlewares for tampering with outgoing requests, two of which include OAuth and OAuth2.

So, if you’re integrating the oauth or oauth2 protocols into one of your services, hopefully you’ll find this bit of first hand experience useful.

Other useful/helper links:

  • http://hueniverse.com/2010/09/oauth-2-0-without-signatures-is-bad-for-the-web/
  • http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-00
    • #OAuth 1.0
    • #OAuth 2.0
    • #OAuth
    • #Rails
    • #Ruby
    • #oauth-ruby
    • #simple_oauth
    • #faraday
    • #faraday_middleware
  • 1 year ago
  • 1
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+

ActiveRecord & ActiveRecord::Observer Callbacks

    • #ruby
    • #rails
    • #rails 3.1
  • 1 year ago
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+

Around Aliasing

I’m making my way through Paolo Perrotta’s Metaprogramming Ruby book and I stumbled upon this nugget of Ruby meta-magic..

class Fixnum
  alias :new_plus :+
  
  def +(num)
    old_plus(old_plus(1))
  end
end

1 + 1 => 3

At first glance this may appear to be merely a technique to show off the flexibility of Ruby, but as it turns out, it is quite useful in day-to-day programming. This technique is known as an “Around Alias” and can be seen in many popular Ruby libraries. One in particular being Rails, which uses this technique in the mind numbingly cool #alias_method_chain method. Go check out Rails source if you’d like to read up on #alias_method_chain.

Here’s an immediately useful and simple application of Around Aliasing adapted from an example given in the text:

alias :safe_method_that_calls_api :method_that_calls_api

def method_that_calls_api
  start_time = Time.now
  result = safe_method_that_calls_api
  time_taken = Time.now - start_time
    
  if time_taken > 2
    puts "method_that_calls_api() took #{time_taken} seconds."
  end
  result
rescue
  puts "method_that_calls_api() failed."
  []
end
    • #metaprogramming
    • #ruby
    • #around alias
    • #rails
  • 1 year ago
  • 3
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+

About

Avatar Hello there,

I'm a recent graduate of The Ohio State University. While attending OSU, I studied Computer Science & Engineering and minored in Studio Art.

I'm currently a software developer working for Neo. I'm an avid music listener, movie watcher, concert goer, and traveler.

You've stumbled upon a bag of my favorite links, thoughts, lessons, and opinions. I hope you enjoy.

Pages

  • Year End Lists

Me, Elsewhere

  • tonywok on Forrst
  • @tonywok on Twitter
  • tsnydermtg on Last.fm
  • My Skype Info
  • tonywok on github

Twitter

loading tweets…

  • RSS
  • Random
  • Archive
  • Mobile
Effector Theme by Pixel Union