Skip to content

Instantly share code, notes, and snippets.

@pirj
Created July 4, 2012 08:30
Show Gist options
  • Save pirj/3046095 to your computer and use it in GitHub Desktop.
Save pirj/3046095 to your computer and use it in GitHub Desktop.
Padrino authentication
migration 1, :create_accounts do
up do
create_table :accounts do
column :id, Integer, :serial => true
column :name, String
column :surname, String
column :email, String
column :crypted_password, String, :length => 64
column :role, String
end
end
down do
drop_table :accounts
end
end
require 'bcrypt'
class Account
include DataMapper::Resource
include DataMapper::Validate
attr_accessor :password, :password_confirmation
# Properties
property :id, Serial
property :name, String
property :surname, String
property :email, String, :length => 100
# BCrypt gives you a 60 character string
property :crypted_password, String, :length => 60
property :role, String
property :deleted_at, ParanoidDateTime
timestamps :at
# Validations
validates_presence_of :email, :role
# validates_presence_of :password, :if => :password_required
# validates_presence_of :password_confirmation, :if => :password_required
# validates_length_of :password, :min => 4, :max => 40, :if => :password_required
# validates_confirmation_of :password, :if => :password_required
validates_length_of :email, :min => 3, :max => 100
validates_uniqueness_of :email, :case_sensitive => false
validates_format_of :email, :with => :email_address
validates_format_of :role, :with => /[A-Za-z]/
# Callbacks
# before :save, :encrypt_password
##
# This method is for authentication purpose
#
def self.authenticate(email, password)
account = first(:conditions => { :email => email }) if email.present?
account && account.has_password?(password) ? account : nil
end
##
# This method is used by AuthenticationHelper
#
def self.find_by_id(id)
get(id) rescue nil
end
def has_password?(password)
::BCrypt::Password.new(crypted_password) == password
end
private
def password_required
crypted_password.blank? || password.present?
end
def encrypt_password
self.crypted_password = ::BCrypt::Password.create(password) if password.present?
end
end
App.controllers :accounts do
get :index do
authorize! :index, Account
accounts = Account.all
render 'accounts/index', :locals => {:accounts => accounts}
end
get :view, :with => :id do
authorize! :view, Account
account = Account.get params[:id]
render 'accounts/view', :locals => {:account => account}
end
get :new do
authorize! :new, Account
account = Account.new
render 'accounts/new', :locals => {:account => account}
end
post :create do
authorize! :create, Account
account = Account.new(params[:account])
if account.save
flash[:notice] = pt :user_created
redirect url(:accounts, :index)
else
render 'accounts/new', :locals => {:account => account}
end
end
get :edit, :with => :id do
account = Account.get(params[:id])
authorize! :edit, account
render 'accounts/edit', :locals => {:account => account}
end
post :update, :with => :id do
account = Account.get(params[:id])
authorize! :update, account
if account.update(params[:account])
flash[:notice] = pt :user_updated
redirect url(:accounts, :index)
else
render 'accounts/edit', :locals => {:account => account}
end
end
get :destroy, :with => :id do
authorize! :destroy, Account
account = Account.get(params[:id])
if account != current_account && account.destroy
flash[:notice] = pt :destroyed
else
flash[:error] = pt :cannot_destroy
end
redirect url(:accounts, :index)
end
end
!!! Strict
%html{:lang => "en", :xmlns => "http://www.w3.org/1999/xhtml"}
%head
%meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}
%title=pt(:login_box)
=stylesheet_link_tag :base, "themes/blue/style"
%body
#container
#box
#block-login.block
%h2=pt(:login_box)
.content.login
.flash=[:error, :warning, :notice].map { |type| flash_tag(type, :class => "message #{type}") }.join
-form_tag(url(:sessions, :create), :class => 'form login') do
.group.wat-cf
.left
%label.label.right=mat(:account, :email)
.right=text_field_tag :email, :value => params[:email], :class => :text_field
.group.wat-cf
.left
%label.label.right=mat(:account, :password)
.right=password_field_tag :password, :value => params[:password], :class => :text_field
.group.navform.wat-cf
.right=submit_tag(pt(:sign_in), :class => :button)
App.controllers :sessions do
get :new do
render "/sessions/new", nil, :layout => false
end
post :create do
if account = Account.authenticate(params[:email], params[:password])
set_current_account(account)
redirect url(:base, :index)
elsif Padrino.env == :development && params[:bypass]
account = Account.first
set_current_account(account)
redirect url(:base, :index)
else
flash[:warning] = pt :wrong_login
redirect url(:sessions, :new)
end
end
get :destroy do
set_current_account(nil)
redirect url(:base, :index)
end
end
@pirj
Copy link
Author

pirj commented Dec 28, 2013

@dustMason That's right, it's described how to use CanCan with Padrino in the previous gist: https://gist.github.com/pirj/1088021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment