Skip to content

Commit

Permalink
Added user and sessions. Authentication from scratch
Browse files Browse the repository at this point in the history
  • Loading branch information
lmbacelar committed Apr 14, 2012
1 parent e66c735 commit cc65009
Show file tree
Hide file tree
Showing 34 changed files with 291 additions and 13 deletions.
1 change: 1 addition & 0 deletions Gemfile
Expand Up @@ -3,6 +3,7 @@ source 'https://rubygems.org'
gem 'rails', '3.2.0'
gem 'pg'
gem 'jquery-rails'
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'state_machine'
gem 'simple_form', '~> 2.0.0.rc'

Expand Down
2 changes: 2 additions & 0 deletions Gemfile.lock
Expand Up @@ -30,6 +30,7 @@ GEM
multi_json (~> 1.0)
addressable (2.2.7)
arel (3.0.2)
bcrypt-ruby (3.0.1)
bootstrap-sass (2.0.2)
builder (3.0.0)
capybara (1.1.2)
Expand Down Expand Up @@ -178,6 +179,7 @@ PLATFORMS
ruby

DEPENDENCIES
bcrypt-ruby (~> 3.0.0)
bootstrap-sass (~> 2.0.2)
capybara
coffee-rails (~> 3.2.1)
Expand Down
3 changes: 3 additions & 0 deletions app/assets/javascripts/sessions.js.coffee
@@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
3 changes: 3 additions & 0 deletions app/assets/javascripts/users.js.coffee
@@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
3 changes: 3 additions & 0 deletions app/assets/stylesheets/sessions.css.scss
@@ -0,0 +1,3 @@
// Place all the styles related to the sessions controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
3 changes: 3 additions & 0 deletions app/assets/stylesheets/users.css.scss
@@ -0,0 +1,3 @@
// Place all the styles related to the users controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
9 changes: 9 additions & 0 deletions app/controllers/application_controller.rb
Expand Up @@ -15,4 +15,13 @@ def set_locale
def default_url_options(options = {})
{locale: I18n.locale}
end

def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user

def authorize
redirect_to login_url, alert: t('flash.alert.unauthorized') if current_user.nil?
end
end
9 changes: 6 additions & 3 deletions app/controllers/documents_controller.rb
Expand Up @@ -44,7 +44,8 @@ def create

respond_to do |format|
if @document.save
format.html { redirect_to @document, notice: 'Document was successfully created.' }
format.html { redirect_to @document,
notice: "#{Document.model_name.human} #{ t('flash.notice.create')}" }
format.json { render json: @document, status: :created, location: @document }
else
format.html { render action: "new" }
Expand All @@ -60,7 +61,8 @@ def update

respond_to do |format|
if @document.update_attributes(params[:document])
format.html { redirect_to @document, notice: 'Document was successfully updated.' }
format.html { redirect_to @document,
notice: "#{Document.model_name.human} #{ t('flash.notice.update')}" }
format.json { head :no_content }
else
format.html { render action: "edit" }
Expand All @@ -76,7 +78,8 @@ def destroy
@document.destroy

respond_to do |format|
format.html { redirect_to documents_url }
format.html { redirect_to documents_url,
notice: "#{Document.model_name.human} #{ t('flash.notice.destroy')}" }
format.json { head :no_content }
end
end
Expand Down
20 changes: 20 additions & 0 deletions app/controllers/sessions_controller.rb
@@ -0,0 +1,20 @@
class SessionsController < ApplicationController
def new
end

def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to root_url, notice: t('flash.notice.logged_in')
else
flash.now.alert = t('flash.alert.login_invalid')
render "new"
end
end

def destroy
session[:user_id] = nil
redirect_to root_url, notice: t('flash.notice.logged_out')
end
end
17 changes: 17 additions & 0 deletions app/controllers/users_controller.rb
@@ -0,0 +1,17 @@
class UsersController < ApplicationController

def new
@user = User.new
end

def create
@user = User.new(params[:user])
if @user.save
session[:user_id] = @user.id
redirect_to root_url, notice: t('flash.notice.signup')
else
render 'new'
end
end

end
2 changes: 2 additions & 0 deletions app/helpers/sessions_helper.rb
@@ -0,0 +1,2 @@
module SessionsHelper
end
2 changes: 2 additions & 0 deletions app/helpers/users_helper.rb
@@ -0,0 +1,2 @@
module UsersHelper
end
6 changes: 6 additions & 0 deletions app/models/category.rb
Expand Up @@ -6,4 +6,10 @@ class Category < ActiveRecord::Base

# Associations
has_many :documents, dependent: :destroy

# # # # # Public Methods
# # # # # Instance Methods
def to_s
name
end
end
6 changes: 6 additions & 0 deletions app/models/document.rb
Expand Up @@ -7,4 +7,10 @@ class Document < ActiveRecord::Base
# Associations
belongs_to :category
has_many :versions, dependent: :destroy

# # # # # Public Methods
# # # # # Instance Methods
def to_s
name
end
end
5 changes: 5 additions & 0 deletions app/models/state_change.rb
Expand Up @@ -7,4 +7,9 @@ class StateChange < ActiveRecord::Base
# # # # # Associations
belongs_to :version

# # # # # Public Methods
# # # # # Instance Methods
def to_s
"Set as #{state} by #{user} on #{updated_at}"
end
end
7 changes: 7 additions & 0 deletions app/models/user.rb
@@ -0,0 +1,7 @@
class User < ActiveRecord::Base
has_secure_password

attr_accessible :email, :password, :password_confirmation
validates_presence_of :email, :password
validates_uniqueness_of :email
end
1 change: 1 addition & 0 deletions app/views/documents/_form.html.haml
Expand Up @@ -5,6 +5,7 @@
= f.input :name, input_html: { class: 'span3' }
= f.input :title, input_html: { class: 'span5' }
= f.input :subtitle, input_html: { class: 'span5' }
= f.association :category, input_html: { class: 'span3' }
= f.input :description, input_html: { class: 'span5', rows: '5' }

.form-actions
Expand Down
2 changes: 2 additions & 0 deletions app/views/documents/show.html.haml
Expand Up @@ -4,6 +4,8 @@
%h2= @document.title
%h3= @document.subtitle
%dl
%dt Category
%dd= @document.category.to_s
%dt Description
%dd= @document.description

Expand Down
9 changes: 9 additions & 0 deletions app/views/layouts/_i18n_nav.html.haml
@@ -0,0 +1,9 @@
- if I18n.available_locales.count > 1
%li.dropdown
%a.dropdown-toggle{ href: '#', 'data-toggle' => 'dropdown' }
= "#{I18n.locale.upcase} "
%b.caret
%ul.dropdown-menu
- I18n.available_locales.each do |loc|
- unless loc == I18n.locale
%li= link_to loc.upcase, locale: loc
18 changes: 18 additions & 0 deletions app/views/layouts/_user_nav.html.haml
@@ -0,0 +1,18 @@
- if current_user
%li.dropdown
%a.dropdown-toggle{ href: '#', 'data-toggle' => 'dropdown' }
= "#{ t('session.logged_in_as') } #{ current_user.email }"
%b.caret
%ul.dropdown-menu
%li= link_to "#{ t('actions.edit') } #{ User.model_name.human }", current_user
%li.divider
%li= link_to t('actions.logout'), logout_path
- else
%li.dropdown
%a.dropdown-toggle{ href: '#', 'data-toggle' => 'dropdown' }
= "#{ t('session.logged_out') } "
%b.caret
%ul.dropdown-menu
%li= link_to t('actions.login'), login_path
%li.divider
%li= link_to t('actions.signup'), signup_path
12 changes: 3 additions & 9 deletions app/views/layouts/application.html.haml
Expand Up @@ -22,15 +22,9 @@
%ul.nav
%li= link_to t('.documents_link'), documents_path
%ul.nav.pull-right
- if I18n.available_locales.count > 1
%li.dropdown
%a.dropdown-toggle{ href: '#', 'data-toggle' => 'dropdown' }
= "#{I18n.locale.upcase} "
%b.caret
%ul.dropdown-menu
- I18n.available_locales.each do |loc|
- unless loc == I18n.locale
%li= link_to loc.upcase, locale: loc
= render 'layouts/user_nav'
%li.divider-vertical
= render 'layouts/i18n_nav'

.container
- flash.each do |name, msg|
Expand Down
17 changes: 17 additions & 0 deletions app/views/sessions/new.html.haml
@@ -0,0 +1,17 @@

= form_tag sessions_path, class: 'simple_form form-horizontal' do
%fieldset
%legend= t 'actions.login'
.control-group.email.required
.control-label.email.required
= label_tag :email
.controls
= text_field_tag :email, params[:email]
.control-group.password.required
.control-label.password.required
= label_tag :password
.controls
= password_field_tag :password
.form-actions
= submit_tag t('actions.login'), class: 'btn btn-primary'
= link_to t('actions.cancel'), documents_path, class: 'btn'
10 changes: 10 additions & 0 deletions app/views/users/new.html.haml
@@ -0,0 +1,10 @@
= simple_form_for @user, html: {class: 'form-horizontal'} do |f|
%fieldset
%legend= "#{t("actions.#{controller.action_name.downcase}")} #{User.model_name.human}"
= f.input :email
= f.input :password
= f.input :password_confirmation

.form-actions
= f.button :submit, class: 'btn-primary'
= link_to t('actions.cancel'), documents_path, class: 'btn'
26 changes: 26 additions & 0 deletions config/locales/en.yml
Expand Up @@ -20,16 +20,42 @@ en:
confirm: 'Are you sure?'
cancel: 'Cancel'
back: 'Back'
signup: 'Sign Up'
login: 'Login'
logout: 'Logout'

session:
logged_in: 'Logged In'
logged_in_as: 'Logged In as'
logged_out: 'Logged Out'

flash:
notice:
signup: 'Thank you for signing up!'
create: 'was successfully created.'
update: 'was successfully updated.'
destroy: 'was successfully destroyed.'
logged_in: 'Logged In!'
logged_out: 'Logged Out!'
alert:
login_invalid: 'Email or password is invalid!'
unauthorized: 'Not authorized!'

activerecord:
models:
document: 'Document'
user: 'User'
attributes:
document:
name: 'Name'
title: 'Title'
subtitle: 'Subtitle'
description: 'Description'
user:
email: 'Email'
name: 'Name'
password: 'Password'
password_confirmation: 'Password confirmation'

date:
abbr_day_names:
Expand Down
26 changes: 26 additions & 0 deletions config/locales/pt.yml
Expand Up @@ -20,16 +20,42 @@ pt:
confirm: 'Tem a certeza?'
cancel: 'Cancelar'
back: 'Voltar'
signup: 'Registar'
login: 'Iniciar sessão'
logout: 'Terminar sessão'

session:
logged_in: 'Sessão iniciada'
logged_in_as: 'Sessão iniciada como'
logged_out: 'Sessão terminada'

flash:
notice:
signup: 'Obrigado pelo seu registo!'
create: 'foi criado com sucesso.'
update: 'foi actualizado com sucesso.'
destroy: 'foi destruído com sucesso.'
logged_in: 'Sessão iniciada com sucesso!'
logged_out: 'Sessão terminada com sucesso!'
alert:
login_invalid: 'Email e/ou password inválidos!'
unauthorized: 'Não autorizado!'

activerecord:
models:
document: 'Documento'
user: 'Utilizador'
attributes:
document:
name: 'Nome'
title: 'Título'
subtitle: 'Subtítulo'
description: 'Descrição'
user:
email: 'Email'
name: 'Nome'
password: 'Password'
password_confirmation: 'Confirme password'

date:
abbr_day_names:
Expand Down
7 changes: 7 additions & 0 deletions config/routes.rb
@@ -1,5 +1,12 @@
Athena::Application.routes.draw do

scope ':locale' do
get 'signup', to: 'users#new', as: 'signup'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'

resources :sessions
resources :users
resources :documents
root to: 'documents#index'
end
Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20120413231751_create_users.rb
@@ -0,0 +1,11 @@
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :email
t.string :name
t.string :password_digest

t.timestamps
end
end
end
10 changes: 9 additions & 1 deletion db/schema.rb
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20120412002518) do
ActiveRecord::Schema.define(:version => 20120413231751) do

create_table "categories", :force => true do |t|
t.string "name"
Expand Down Expand Up @@ -40,6 +40,14 @@
t.datetime "updated_at", :null => false
end

create_table "users", :force => true do |t|
t.string "email"
t.string "name"
t.string "password_digest"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end

create_table "versions", :force => true do |t|
t.integer "number"
t.string "state"
Expand Down

0 comments on commit cc65009

Please sign in to comment.