RailsCasts Pro episodes are now free!

Learn more or hide this

Michael de Silva's Profile

GitHub User: bsodmike

Site: http://www.bsodmike.com

Comments by Michael de Silva

Avatar

That works great - does this also have built in support for Helper tests?

Avatar

I'm fifth-ing that! tokens and OAuth 2 please.

Avatar

I just refactored my helper as the previous code was a 'quick and dirty' test of my approach.

ruby
module ApplicationHelper
  def markdown(text, *renderer)      
    case renderer[0]
    when :authored
      rndr = HTMLwithAlbino.new(:hard_wrap => true, :gh_blockcode => true, 
          :filter_html => false, :safe_links_only => true)
    when :featured
      rndr = HTMLwithAlbino.new(:hard_wrap => true, :gh_blockcode => true, 
          :filter_html => true, :safe_links_only => true)
    else
      rndr = HTMLwithAlbino.new(:hard_wrap => true, :gh_blockcode => true, 
          :filter_html => true, :no_images => true, :no_styles => true,
          :safe_links_only => true)
    end
    redcarpet = Redcarpet::Markdown.new(rndr, :space_after_headers => true,
      :fenced_code_blocks => true, :autolink => true, :no_intra_emphasis => true,
      :strikethrough => true, :superscripts => true)
    redcarpet.render(text).html_safe
  end
end

If no valid renderer is specified (as the first method argument) it will assume unsafe content and do the utmost to strip and filter HTML etc.

Avatar

Here's my solution for upgrading to Redcarpet 2

ruby
module ApplicationHelper
  def markdown(text)
    rndr = HTMLwithAlbino.new(:hard_wrap => true, :gh_blockcode => true, 
        :filter_html => false, :safe_links_only => true)
    
    redcarpet = Redcarpet::Markdown.new(rndr, :space_after_headers => true,
      :fenced_code_blocks => true, :autolink => true, :no_intra_emphasis => true,
      :strikethrough => true, :superscripts => true)
    
    redcarpet.render(text).html_safe
  end

  def markdown_unsafe(text)
    rndr = HTMLwithAlbino.new(:hard_wrap => true, :gh_blockcode => true, 
        :filter_html => true, :no_images => true, :no_styles => true,
        :safe_links_only => true)
    
    redcarpet = Redcarpet::Markdown.new(rndr, :space_after_headers => true,
      :fenced_code_blocks => true, :autolink => true, :no_intra_emphasis => true,
      :strikethrough => true, :superscripts => true)
    
    redcarpet.render(text).html_safe
  end
  
end

# create a custom renderer that allows highlighting of code blocks
class HTMLwithAlbino < Redcarpet::Render::HTML      
  def block_code(code, language)
    Albino.colorize(code, language)
  end
end

I'm calling markdown_unsafe for publicly created comments, hence, it filters out as much as possible; still doing Albino.colorize() instead of Albino.safe_colorize() as I haven't upgraded it yet.

Avatar

Consider the previous screencast by Ryan where he does a TDD based overview of adding in the remember me and forgot password into the first 'auth from scratch' application. I would imagine a similar approach here would work fine.

As for sending out emails etc, these can be done in the sessions#create action but do not sign the user in. Instead, you'd generate a confirmation token (which is emailed) and setup another general controller expecting someone to visit it with that token as a parameter - inside the action, you can handle the auth process and even automate the user login and enable whatever attributes on the user in question to indicate they've confirmed their email address.

Avatar

I was getting 401: Unauthorized errors for twitter so decided to give Facebook a try. This caused

json
{ "error": { "message": "Missing client_id parameter.", "type": "OAuthException" } }

The solution was to remove the ENV[ ] from the initialiser for both twitter and facebook and it seems to be working fine.

Avatar

That's the whole point, and that's done by the omniauth gem itself. Once you authenticate against twitter, the 'callback' URL is visited which is handled within the Rails app - note the custom route to handle it in routes.rb

Avatar

I had to set :cli => '--drb' as well as bootstrap cuke's env.rb. Working fine now =)

Avatar

Added Cucumber and ran spork cucumber --bootstrap to ensure it bootstrapped env.rb, features are now running twice. In fact, launching guard loads the rails environment twice as well?

bash
Starting Spork for RSpec & Cucumber 
Spork server for RSpec & Cucumber successfully started
Guard::RSpec is running, with RSpec 2!
Running all features
Using RSpec
Using Cucumber
Preloading Rails environment
Preloading Rails environment
Disabling profiles...
Loading Spork.prefork block...
Loading Spork.prefork block...
Avatar

Hi Noam - liking your work mate, keep it up. I see you merged my pull-request =)

Avatar

Very true Rupert - and yes, I guess most of us think of Devise as "old faithful". I also agree on your points regarding the smaller API.

In time, I think it should come into its own. Till then, I'll be sticking with auth from scratch vs. Devise for production apps - I'll definitely be hacking around with Sorcery though =)

Avatar

That's the whole point though - devise isn't all that flexible when you want to get it to do things 'your way' - personally I ended up having to override most of Devise's own controllers. It all depends on what you really want out of your authentication system in the end, so YMMV of course.

@Ryan - thanks for another fantastic cast, will be sure to try it out tonight!

Avatar

Hi Joe, I'm getting

undefined method `user' for nil:NilClass

This seems to be an issue with request.env['warden'].user - any ideas?

Avatar

A slight improvement:

ruby
Resque::Server.use(Rack::Auth::Basic) do |user, password|
  if ['admin'].include? user do
    [SALTED_HASH] == BCrypt::Engine.hash_secret(password, [SALT])
  end
end

Since it's a mounted sinatra app, I guess inheriting from AdminController won't be possible?

Avatar

Here's how I hardened the login via resque_auth.rb. You'll need the bcrypt-ruby gem installed.

  • Fire up IRB or PRY
  • require 'bcrypt'
  • Generate a salt: salt = BCrypt::Engine.generate_salt
  • puts salt // make sure you copy this somewhere.
  • Now, salted_hash = BCrypt::Engine.hash_secret("YOUR PASSWORD GOES HERE", salt)
  • make sure you save the longer output!

Update resque_auth.rb as follows:

ruby
Resque::Server.use(Rack::Auth::Basic) do |user, password|
  
  [SALTED_HASH] == BCrypt::Engine.hash_secret(password, [SALT])
  
end

Make sure you replace the above respectively. Voila!

Avatar

I'm getting /auth/failure?message=invalid_response although, when I inspect request.env['omniauth.auth'] I can see that it has received the auth info correctly?

It seems this very issue was discussed on Github - I've even upgraded to ruby-1.9.2 and am running Rails 3.0.9.

Sadly, no luck!

Avatar

In the cases where a server-side validation rule would not work on the client (i.e. conditional callbacks like :if, :unless) then do not attempt client side validations. Fall back to the server side validation.

At least this sheds some time on the conditional callback :unless. Any thoughts as to why :message => ... isn't supported?

Avatar

I take it you tried the following ?

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)), :validate => true do |f| %>

Avatar

Hi Brian,

I'm trying to get the demoed callbacks to work. Do I need to update <%= javascript_include_tag :defaults, 'rails.validations', 'rails.validations.callbacks' %> to specify the .callbacks JS file as well?

I've updated my jquery-rails with the --ui tag yet, I'm getting 'easing' related errors in the jquery JS itself based on the example callback code.

Thanks!
Mike.

Avatar

Interestingly, :unless => ... overrides the is: validation. I'm forced to go with validates_length_of :badge_id, :is => 12

The issue is it defaults to displaying

is the wrong length (should be 12 characters)

instead of digits. Hmm!

Avatar

Hello Ryan, really cool cast as always :)

I've got a field thats validated as validates_length_of :badge_id, :is => 12, :message => "ID must be 12 digits", :unless => Proc.new{|r| r.badge_id == '0'} which is causing the following error - this only goes away if I remove the :message => "..." from the above validation:

I18n::InvalidPluralizationData in Registrants#new

translation data {:record_invalid=>"Validation failed: %{errors}", :taken=>"has already been taken"} can not be used with :count => ID must be 12 digits

This column is a string and is also validated as validates_numericality_of :badge_id, :only_integer => true

Thanks!,
Mike