Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Modèle utilisateur avec mot de passe et page de profil

  • Loading branch information...
commit 996c76346b22647e364f560cffb815d6dc0a513a 1 parent 0dc986b
@lolo32 authored
View
2  Gemfile
@@ -7,6 +7,7 @@ gem 'rails', '3.2.3'
gem 'sqlite3'
+gem 'gravatar_image_tag'
# Gems used only for assets and not required
# in production environments by default.
@@ -47,4 +48,5 @@ group :test do
gem 'webrat'
gem 'spork'
+ gem 'factory_girl_rails', '3.2.0'
end
View
16 Gemfile.lock
@@ -40,22 +40,28 @@ GEM
coffee-script-source (1.3.1)
diff-lcs (1.1.3)
erubis (2.7.0)
- execjs (1.3.0)
+ execjs (1.3.1)
multi_json (~> 1.0)
+ factory_girl (3.2.0)
+ activesupport (>= 3.0.0)
+ factory_girl_rails (3.2.0)
+ factory_girl (~> 3.2.0)
+ railties (>= 3.0.0)
+ gravatar_image_tag (1.1.2)
hike (1.2.1)
i18n (0.6.0)
journey (1.0.3)
jquery-rails (2.0.2)
railties (>= 3.2.0, < 5.0)
thor (~> 0.14)
- json (1.6.6)
+ json (1.7.0)
libv8 (3.3.10.4)
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.18)
- multi_json (1.3.2)
+ multi_json (1.3.4)
nokogiri (1.5.2)
polyglot (0.3.3)
rack (1.4.1)
@@ -102,7 +108,7 @@ GEM
sass (>= 3.1.10)
tilt (~> 1.3)
spork (1.0.0rc2)
- sprockets (2.1.2)
+ sprockets (2.1.3)
hike (~> 1.2)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
@@ -129,6 +135,8 @@ PLATFORMS
DEPENDENCIES
annotate (= 2.4.1.beta1)
coffee-rails (~> 3.2.1)
+ factory_girl_rails (= 3.2.0)
+ gravatar_image_tag
jquery-rails
rails (= 3.2.3)
rspec
View
24 app/assets/stylesheets/custom.css
@@ -114,3 +114,27 @@ footer {
footer nav {
float: none;
}
+
+/* User show page */
+
+table.profile {
+ width: 100%;
+ margin-bottom: 0;
+}
+
+td.main {
+ width: 70%;
+ padding: 1em;
+}
+
+td.sidebar {
+ width: 30%;
+ padding: 1em;
+ vertical-align: top;
+ background: #ffc;
+}
+
+.profile img.gravatar {
+ border: 1px solid #999;
+ margin-bottom: -15px;
+}
View
3  app/controllers/utilisateurs_controller.rb
@@ -4,6 +4,7 @@ def new
end
def show
- @user = Utilisateur.find( params[:id] )
+ @utilisateur = Utilisateur.find( params[:id] )
+ @titre = @utilisateur.nom
end
end
View
9 app/helpers/utilisateurs_helper.rb
@@ -1,2 +1,11 @@
module UtilisateursHelper
+
+ # helper pour afficher plus facilement les gravatars
+ def gravatar_for( user, options = { :size => 50 } )
+ gravatar_image_tag( user.courriel.downcase,
+ :alt => user.nom,
+ :class => 'gravatar',
+ :gravatar => options
+ )
+ end
end
View
63 app/models/utilisateur.rb
@@ -1,23 +1,64 @@
class Utilisateur < ActiveRecord::Base
- attr_accessible :courriel, :nom
+ attr_accessor :mdp
+ attr_accessible :nom, :courriel, :mdp, :mdp_confirmation
courriel_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
- validates :nom, :presence => true,
- :length => { :maximum => 50 }
- validates :courriel, :presence => true,
- :format => { :with => courriel_regex },
- :uniqueness => { :case_sensitive => false }
+ validates :nom, :presence => true,
+ :length => { :maximum => 50 }
+ validates :courriel, :presence => true,
+ :format => { :with => courriel_regex },
+ :uniqueness => { :case_sensitive => false }
+ # Crée automatique l'attribut virtuel 'mdp_confirmation'.
+ validates :mdp, :presence => true,
+ :confirmation => true,
+ :length => { :within => 6..40 }
+
+ # Méthode appelée juste avant de sauvegarder
+ before_save :chiffre_mdp
+
+ # Retourne vrai si le mot de passe correspond
+ # Compare mdp_chiffre avec la version chiffre de mdp_soumis
+ def has_mdp?( mdp_soumis )
+ mdp_chiffre == chiffre( mdp_soumis )
+ end
+
+ def self.authentifie( courriel, mdp_saisis )
+ user = find_by_courriel( courriel )
+ return nil if user.nil?
+ return user if user.has_mdp?( mdp_saisis )
+ end
+
+ private
+
+ def chiffre_mdp
+ self.sel = gen_sel if new_record?
+ self.mdp_chiffre = chiffre( mdp )
+ end
+
+ def chiffre( string )
+ hash_securise( "#{sel}--#{string}" )
+ end
+
+ def gen_sel
+ hash_securise( "#{Time.now.utc}--#{mdp}" )
+ end
+
+ def hash_securise( string )
+ Digest::SHA2.hexdigest( string )
+ end
end
# == Schema Information
#
# Table name: utilisateurs
#
-# id :integer not null, primary key
-# nom :string(255)
-# courriel :string(255)
-# created_at :datetime not null
-# updated_at :datetime not null
+# id :integer not null, primary key
+# nom :string(255)
+# courriel :string(255)
+# created_at :datetime not null
+# updated_at :datetime not null
+# mdp_chiffre :string(255)
+# sel :string(255)
#
View
15 app/views/utilisateurs/show.html.erb
@@ -1 +1,14 @@
-<%= @user.nom %>, <%= @user.courriel %>
+<table class="profile" summary="Information sur le profil">
+ <tr>
+ <td class="main">
+ <h1>
+ <%= gravatar_for @utilisateur %>
+ <%= @utilisateur.nom %>
+ </h1>
+ </td>
+ <td class="sidebar round">
+ <strong>Nom</strong> <%= @utilisateur.nom %><br />
+ <strong>URL</strong> <%= link_to utilisateur_path( @utilisateur), @utilisateur %>
+ </td>
+ </tr>
+</table>
View
18 config/routes.rb
@@ -68,10 +68,16 @@
end
#== Route Map
-# Generated on 25 Apr 2012 12:37
+# Generated on 30 Apr 2012 15:19
#
-# signup /signup(.:format) utilisateurs#new
-# contact /contact(.:format) pages#contact
-# about /about(.:format) pages#about
-# help /help(.:format) pages#help
-# root / pages#home
+# POST /utilisateurs(.:format) utilisateurs#create
+# new_utilisateur GET /utilisateurs/new(.:format) utilisateurs#new
+# edit_utilisateur GET /utilisateurs/:id/edit(.:format) utilisateurs#edit
+# utilisateur GET /utilisateurs/:id(.:format) utilisateurs#show
+# PUT /utilisateurs/:id(.:format) utilisateurs#update
+# DELETE /utilisateurs/:id(.:format) utilisateurs#destroy
+# signup /signup(.:format) utilisateurs#new
+# contact /contact(.:format) pages#contact
+# about /about(.:format) pages#about
+# help /help(.:format) pages#help
+# root / pages#home
View
6 db/migrate/20120426083604_add_courriel_uniqueness_index.rb
@@ -1,9 +1,5 @@
class AddCourrielUniquenessIndex < ActiveRecord::Migration
- def up
+ def change
add_index :utilisateurs, :courriel, :unique => true
end
-
- def down
- remove_index :utilisateurs, :courriel
- end
end
View
5 db/migrate/20120426194446_add_mdp_to_utilisateurs.rb
@@ -0,0 +1,5 @@
+class AddMdpToUtilisateurs < ActiveRecord::Migration
+ def change
+ add_column :utilisateurs, :mdp_chiffre, :string
+ end
+end
View
5 db/migrate/20120427105233_add_sel_to_utilisateurs.rb
@@ -0,0 +1,5 @@
+class AddSelToUtilisateurs < ActiveRecord::Migration
+ def change
+ add_column :utilisateurs, :sel, :string
+ end
+end
View
8 db/schema.rb
@@ -11,13 +11,15 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120426083604) do
+ActiveRecord::Schema.define(:version => 20120427105233) do
create_table "utilisateurs", :force => true do |t|
t.string "nom"
t.string "courriel"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ t.string "mdp_chiffre"
+ t.string "sel"
end
add_index "utilisateurs", ["courriel"], :name => "index_utilisateurs_on_courriel", :unique => true
View
32 spec/controllers/utilisateurs_controller_spec.rb
@@ -4,6 +4,38 @@
describe UtilisateursController do
render_views
+ describe "GET 'show'" do
+ before(:each) do
+ @utilisateur = FactoryGirl.create(:utilisateur)
+ end
+
+ it "devrait réussir" do
+ get :show, :id => @utilisateur
+ response.should be_success
+ end
+
+ it "devrait trouver le bon utilisateur" do
+ get :show, :id => @utilisateur
+ assigns(:utilisateur).should eq(@utilisateur)
+ end
+
+ it 'devrait avoir le bon titre' do
+ get :show, :id => @utilisateur
+ response.should have_selector("title", :content => @utilisateur.nom)
+ end
+
+ it 'devrait inclure le nom de l\'utilisateur' do
+ get :show, :id => @utilisateur
+ response.should have_selector("h1", :content => @utilisateur.nom)
+ end
+
+ it "devrait avoir une image de profil" do
+ get :show, :id => @utilisateur
+ response.should have_selector("h1>img", :class => "gravatar")
+ end
+
+ end
+
describe "GET 'new'" do
it "devrait exister" do
get 'new'
View
10 spec/factories.rb
@@ -0,0 +1,10 @@
+# En utilisant le symbole ':utilisateur', nous faisons que
+# Factory Girl simule un modèle User.
+FactoryGirl.define do
+ factory :utilisateur do
+ nom "Michael Hartl"
+ courriel "mhartl@example.com"
+ mdp "foobar"
+ mdp_confirmation "foobar"
+ end
+end
View
86 spec/models/utilisateur_spec.rb
@@ -3,7 +3,12 @@
describe Utilisateur do
before(:each) do
- @attr = { :nom => "Example User", :courriel => "user@example.com" }
+ @attr = {
+ :nom => "Example User",
+ :courriel => "user@example.com",
+ :mdp => "foobar",
+ :mdp_confirmation => "foobar"
+ }
end
it "devrait créer une nouvelle instance dotée des attributs valides" do
@@ -55,15 +60,84 @@
user_with_duplicate_email = Utilisateur.new(@attr)
user_with_duplicate_email.should_not be_valid
end
+
+ describe "password validations" do
+
+ it "devrait exiger un mot de passe" do
+ Utilisateur.new(@attr.merge(:mdp => "", :mdp_confirmation => "")).
+ should_not be_valid
+ end
+
+ it "devrait exiger une confirmation du mot de passe qui correspond" do
+ Utilisateur.new(@attr.merge(:mdp_confirmation => "invalid")).
+ should_not be_valid
+ end
+
+ it "devrait rejeter les mots de passe (trop) courts" do
+ short = "a" * 5
+ hash = @attr.merge(:mdp => short, :mdp_confirmation => short)
+ Utilisateur.new(hash).should_not be_valid
+ end
+
+ it "devrait rejeter les (trop) longs mots de passe" do
+ long = "a" * 41
+ hash = @attr.merge(:mdp => long, :mdp_confirmation => long)
+ Utilisateur.new(hash).should_not be_valid
+ end
+ end
+
+ describe "password encryption" do
+
+ before(:each) do
+ @utilisateur = Utilisateur.create!(@attr)
+ end
+
+ it "devrait avoir un attribut mot de passe chiffré" do
+ @utilisateur.should respond_to(:mdp_chiffre)
+ end
+
+ it "devrait définir le mot de passe chiffré" do
+ @utilisateur.mdp_chiffre.should_not be_blank
+ end
+
+ it 'doit retourner true si les mots de passe coïncident' do
+ @utilisateur.has_mdp?( @attr[:mdp] ).should be_true
+ end
+
+ it 'doit retourner false si les mots de passe divergent' do
+ @utilisateur.has_mdp?( "invalide" ).should be_false
+ end
+
+ describe "méthode d'authentification" do
+
+ it "devrait retourner nul en cas d'inéquation entre email/mot de passe" do
+ wrong_password_user = Utilisateur.authentifie(@attr[:courriel], "wrongpass")
+ wrong_password_user.should be_nil
+ end
+
+ it "devrait retourner nil quand un email ne correspond à aucun utilisateur" do
+ nonexistent_user = Utilisateur.authentifie("bar@foo.com", @attr[:mdp])
+ nonexistent_user.should be_nil
+ end
+
+ it "devrait retourner l'utilisateur si email/mot de passe correspondent" do
+ matching_user = Utilisateur.authentifie(@attr[:courriel], @attr[:mdp])
+ matching_user.should == @utilisateur
+ end
+ end
+ end
end
+
# == Schema Information
#
# Table name: utilisateurs
#
-# id :integer not null, primary key
-# nom :string(255)
-# courriel :string(255)
-# created_at :datetime not null
-# updated_at :datetime not null
+# id :integer not null, primary key
+# nom :string(255)
+# courriel :string(255)
+# created_at :datetime not null
+# updated_at :datetime not null
+# mdp_chiffre :string(255)
+# sel :string(255)
#
View
2  spec/spec_helper.rb
@@ -13,7 +13,7 @@
# in ./support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
- Rspec.configure do |config|
+ RSpec.configure do |config|
# == Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
Please sign in to comment.
Something went wrong with that request. Please try again.