I have added the acts_as_authenticated plugin to code, and have gotten VERY BASIC...
author<jlsharps@mit.edu> <>
Tue, 31 Jul 2007 20:03:10 +0000 (16:03 -0400)
committer<jlsharps@mit.edu> <>
Tue, 31 Jul 2007 20:03:10 +0000 (16:03 -0400)
README
app/controllers/quickvote_controller.rb
app/controllers/site_controller.rb
app/helpers/application_helper.rb
app/models/user.rb
app/views/layouts/hc.rhtml
app/views/site/_basic_login.rhtml
db/create.sql

diff --git a/README b/README
index 1c1f548df2d7561fbb5010520560c8d27e84ccbf..341ef6d10113abd1522342fc74d46924d7f3df0f 100644 (file)
--- a/README
+++ b/README
@@ -3,3 +3,23 @@ Contributors to Selectricity Include:
  * Benjamin Mako Hill <mako@atdot.cc>
  * John Dong          <jdong@ubuntu.com>
  * Justin Sharps      <jlsharps@mit.edu>
  * Benjamin Mako Hill <mako@atdot.cc>
  * John Dong          <jdong@ubuntu.com>
  * Justin Sharps      <jlsharps@mit.edu>
+
+07/31/07
+jlsharps: I've added a user authentication system known as
+"acts_as_authenticated" to the code. The plugin is the the vendor/plugins 
+directory. The two most noticeable changes are the AccountController and a 
+redone User model. I've left the UserController in place for now, but the 
+AccountController works in a different manner, so am switching over to that 
+gradually. I saved the 5 lines or so in the old User model, overwrote 
+it with the authenticated generator and then recopied the old stuff back in: 
+has_many :elections and the name() method. The generator also creates its own 
+migration file, but since we are using a create.sql file I adopted the 
+migration file into a new users table in the create.sql file. I have yet to 
+delete the old table because I haven't fully combed through the code yet and 
+determined how many of the old attributes (such as first_name, last_name) may 
+need to be retained. 
+http://technoweenie.stikipad.com/plugins/show/Acts+as+Authenticated is the 
+best site for documentation regarding acts_as_authenticaed. Also, currently
+it only stores the user_id in the session, but i just found a guide to help 
+me make it store the entire user object, so I'll do that while my battery 
+charges.
\ No newline at end of file
index 5e29a10caa2e2d529761666f8e2c0864bbf6f59c..10815b3c590ac19af542240d3cf8ec6d420cb9e9 100644 (file)
@@ -66,7 +66,7 @@ class QuickvoteController < ApplicationController
        @voter = nil
       end
 
        @voter = nil
       end
 
-      # if the voter does not exist or as has been destroyed, lets
+      # if the voter does not exist or has has been destroyed, lets
       # create a new one
       unless @voter
         # create a new voter and populate it
       # create a new one
       unless @voter
         # create a new voter and populate it
index d5eab862c5326434d9bc6979be4cc85b2caa7eba..3307d88a27e0e31c0c9e9fa99ce1efafb6fdb595 100644 (file)
@@ -1,6 +1,6 @@
 class SiteController < ApplicationController
   layout 'hc'
 class SiteController < ApplicationController
   layout 'hc'
-  model :user, :election
+  model :user, :election, :account
 
   def index
     @quickvotes = QuickVote.find_all(["quickvote = 1"]).sort {|a,b| b.enddate <=> a.enddate}[0..1]
 
   def index
     @quickvotes = QuickVote.find_all(["quickvote = 1"]).sort {|a,b| b.enddate <=> a.enddate}[0..1]
index f1aff78dbf2c9b58f4ce3d56a040db35a95f6682..4752f008facadb66fb89eec6e9753adc10134817 100755 (executable)
@@ -1,4 +1,4 @@
 # Methods added to this helper will be available to all templates in the application.
 module ApplicationHelper
 # Methods added to this helper will be available to all templates in the application.
 module ApplicationHelper
-  include LoginEngine
 end
 end
index 17f58a1b16c9947843a806390486ca1d19c434f7..64fd71c544af5ff93c858f871b763ded4842b644 100755 (executable)
@@ -1,8 +1,70 @@
+require 'digest/sha1'
 class User < ActiveRecord::Base
   has_many :elections
 
 class User < ActiveRecord::Base
   has_many :elections
 
+  # Virtual attribute for the unencrypted password
+  attr_accessor :password
+
+  validates_presence_of     :login, :email
+  validates_presence_of     :password,                   :if => :password_required?
+  validates_presence_of     :password_confirmation,      :if => :password_required?
+  validates_length_of       :password, :within => 4..40, :if => :password_required?
+  validates_confirmation_of :password,                   :if => :password_required?
+  validates_length_of       :login,    :within => 3..40
+  validates_length_of       :email,    :within => 3..100
+  validates_uniqueness_of   :login, :email, :case_sensitive => false
+  before_save :encrypt_password
+
   def name
   def name
-    [ firstname, lastname].join(" ")
+     [ firstname, lastname].join(" ")
+  end
+
+  # Authenticates a user by their login name and unencrypted password.  Returns the user or nil.
+  def self.authenticate(login, password)
+    u = find_by_login(login) # need to get the salt
+    u && u.authenticated?(password) ? u : nil
+  end
+
+  # Encrypts some data with the salt.
+  def self.encrypt(password, salt)
+    Digest::SHA1.hexdigest("--#{salt}--#{password}--")
+  end
+
+  # Encrypts the password with the user salt
+  def encrypt(password)
+    self.class.encrypt(password, salt)
   end
   end
-end
 
 
+  def authenticated?(password)
+    crypted_password == encrypt(password)
+  end
+
+  def remember_token?
+    remember_token_expires_at && Time.now.utc < remember_token_expires_at 
+  end
+
+  # These create and unset the fields required for remembering users between browser closes
+  def remember_me
+    self.remember_token_expires_at = 2.weeks.from_now.utc
+    self.remember_token            = encrypt("#{email}--#{remember_token_expires_at}")
+    save(false)
+  end
+
+  def forget_me
+    self.remember_token_expires_at = nil
+    self.remember_token            = nil
+    save(false)
+  end
+
+  protected
+    # before filter 
+    def encrypt_password
+      return if password.blank?
+      self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
+      self.crypted_password = encrypt(password)
+    end
+    
+    def password_required?
+      crypted_password.blank? || !password.blank?
+    end
+end
index 860992a4dbd25a495ac247035a25aa807b7a4a40..2408083e6bc14df624225056a8f92d1e3110987f 100755 (executable)
 
            <div id="links">
              <% if session[:user] %>
 
            <div id="links">
              <% if session[:user] %>
-               Welcome <strong><%= session[:user].login.capitalize %></strong>
+<% breakpoint%>
+               Welcome <strong><%= User.find(session[:user]).login.capitalize %></strong>
              <% else %>
              <% else %>
-               <%= link_to("Login",:controller => "user", :action => "login")
-                %>/<%= link_to("Sign up", :controller => "user", :action => "signup")%>
+               <%= link_to("Login", :controller => "account", :action => "login")
+                %>/<%= link_to("Sign up", :controller => "account", :action => "signup")%>
              <% end %> |
          
              <% if session[:user] %>
              <% end %> |
          
              <% if session[:user] %>
-               <%= link_to("Logout", :controller => "user", :action => "logout") %>  |
+               <%= link_to("Logout", :controller => "account", :action => "logout") %>  |
              <% end %>
              
             <%= link_to("Help/About", :controller => "site", :action => "about") %>
              <% end %>
              
             <%= link_to("Help/About", :controller => "site", :action => "about") %>
index d3043dbfd96abf30b4de7cff49d76ee0ccd6b41b..f02d362819f23e478b82705f434d99ab89ea0ded 100755 (executable)
@@ -1,15 +1,19 @@
 <% -%>
 <% -%>
 <%= start_form_tag :controller => 'user', :action => 'login'  %>
<% form_tag :controller => 'account', :action => 'login'  do %>
     <table>
     <table>
-      <%= form_input :text_field, "Login ID", "login", :size => 30 %>
-      <%= form_input :password_field, "Password", "password", :size => 30 %>
+         <label for="login">Login</label>
+      <%= text_field "Login", "login", :size => 30 %><br />
+      <label for="password">Password</label>
+      <%= password_field "Password", "password", :size => 30 %><br />
     </table>
 
     <div class="button-bar">
       <p><%= submit_tag 'Login' %></p>
     </table>
 
     <div class="button-bar">
       <p><%= submit_tag 'Login' %></p>
-<!--      <p><%= link_to 'Register for an account', :controller =>
-'user', :action => 'signup' %></p> -->
-      <p><%= link_to 'Lost or forgot your password?', :controller => 'user', :action => 'forgot_password' %></p>
+<% end %>
+     <p><%= link_to 'Register for an account', :controller =>
+'account', :action => 'signup' %></p>
+
+      <p><%= link_to 'Lost or forgot your password?', :controller => 'account', :action => 'forgot_password' %></p>
 
       <p>Unfortunately, Selectricity is currently being tested and new
       accounts for full votes (i.e., non-<em>QuickVotes</em>) can not
 
       <p>Unfortunately, Selectricity is currently being tested and new
       accounts for full votes (i.e., non-<em>QuickVotes</em>) can not
@@ -19,4 +23,4 @@
       href="http://mako.cc/contact.html">Benjamin Mako Hill</a>.</p>
 
     </div>
       href="http://mako.cc/contact.html">Benjamin Mako Hill</a>.</p>
 
     </div>
-  <%= end_form_tag %>
+
index e0c264fabaf50b755d0b0bac4400e0b7f33b23e1..cee33a330ccf8cc2485066eee2fe9a12dbcb21f8 100755 (executable)
@@ -86,24 +86,41 @@ create table rankings (
 
 # CREATE users TABLE
 #####################################
 
 # CREATE users TABLE
 #####################################
-DROP TABLE IF EXISTS `users`;
-CREATE TABLE `users` (
-  `id` int(11) NOT NULL auto_increment,
-  `login` varchar(80) NOT NULL default '',
-  `salted_password` varchar(40) NOT NULL default '',
-  `email` varchar(60) NOT NULL default '',
-  `firstname` varchar(40) default NULL,
-  `lastname` varchar(40) default NULL,
-  `salt` varchar(40) NOT NULL default '',
-  `verified` int(11) default '0',
-  `role` varchar(40) default NULL,
-  `security_token` varchar(40) default NULL,
-  `token_expiry` datetime default NULL,
-  `created_at` datetime default NULL,
-  `updated_at` datetime default NULL,
-  `logged_in_at` datetime default NULL,
-  `deleted` int(11) default '0',
-  `delete_after` datetime default NULL,
-  PRIMARY KEY  (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+#DROP TABLE IF EXISTS `users`;
+#CREATE TABLE `users` (
+#  `id` int(11) NOT NULL auto_increment,
+#  `login` varchar(80) NOT NULL default '',
+#  `salted_password` varchar(40) NOT NULL default '',
+#  `email` varchar(60) NOT NULL default '',
+#  `firstname` varchar(40) default NULL,
+#  `lastname` varchar(40) default NULL,
+#  `salt` varchar(40) NOT NULL default '',
+#  `verified` int(11) default '0',
+#  `role` varchar(40) default NULL,
+#  `security_token` varchar(40) default NULL,
+#  `token_expiry` datetime default NULL,
+#  `created_at` datetime default NULL,
+#  `updated_at` datetime default NULL,
+#  `logged_in_at` datetime default NULL,
+#  `deleted` int(11) default '0',
+#  `delete_after` datetime default NULL,
+#  PRIMARY KEY  (`id`)
+#) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 
+#Following is the new users table that goes with acts_as_authenticated
+#Is simpler for now, saving the old table while in transition between 
+#the two for ideas on what attributes may be helpful/necessary
+drop table if exists users;
+create table users (
+       id                        int         not null auto_increment,
+       login                     text,
+       ip                        text not null,
+       email                     text,
+       crypted_password          varchar(40),
+       salt                      varchar(40),
+       created_at                datetime,
+       updated_at                datetime,
+       remember_token            text,
+       remember_token_expires_at datetime,
+       primary key(id)
+);
\ No newline at end of file

Benjamin Mako Hill || Want to submit a patch?