From a6c326f09209767678a52fc0b1a59c3b78197bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dav=C3=AD=C3=B0=20L=C3=BA=C3=B0v=C3=ADksson?= Date: Thu, 12 Mar 2009 19:40:50 +0000 Subject: [PATCH] Added user functionallty --- .gitignore | 1 - app/controllers/users_controller.rb | 85 ++++++++++++++++++++++++ app/helpers/users_helper.rb | 2 + app/models/user.rb | 50 ++++++++++++++ app/views/layouts/users.html.erb | 17 +++++ app/views/users/edit.html.erb | 28 ++++++++ app/views/users/index.html.erb | 22 ++++++ app/views/users/new.html.erb | 27 ++++++++ app/views/users/show.html.erb | 23 +++++++ config/database.yml | 20 ++++++ config/routes.rb | 2 + db/schema.rb | 23 +++++++ public/stylesheets/scaffold.css | 54 +++++++++++++++ test/fixtures/users.yml | 13 ++++ test/functional/users_controller_test.rb | 45 +++++++++++++ test/unit/user_test.rb | 8 +++ 16 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 app/controllers/users_controller.rb create mode 100644 app/helpers/users_helper.rb create mode 100644 app/models/user.rb create mode 100644 app/views/layouts/users.html.erb create mode 100644 app/views/users/edit.html.erb create mode 100644 app/views/users/index.html.erb create mode 100644 app/views/users/new.html.erb create mode 100644 app/views/users/show.html.erb create mode 100644 config/database.yml create mode 100644 db/schema.rb create mode 100644 public/stylesheets/scaffold.css create mode 100644 test/fixtures/users.yml create mode 100644 test/functional/users_controller_test.rb create mode 100644 test/unit/user_test.rb diff --git a/.gitignore b/.gitignore index 5931f32..8bde86a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ .DS_Store log/*.log tmp/**/* -config/database.yml db/*.sqlite3 encodings.xml misc.xml diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..2cae2b4 --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,85 @@ +class UsersController < ApplicationController + # GET /users + # GET /users.xml + def index + @users = User.find(:all, :order => :name) + + respond_to do |format| + format.html # index.html.erb + format.xml { render :xml => @users } + end + end + + # GET /users/1 + # GET /users/1.xml + def show + @user = User.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.xml { render :xml => @user } + end + end + + # GET /users/new + # GET /users/new.xml + def new + @user = User.new + + respond_to do |format| + format.html # new.html.erb + format.xml { render :xml => @user } + end + end + + # GET /users/1/edit + def edit + @user = User.find(params[:id]) + end + + # POST /users + # POST /users.xml + def create + @user = User.new(params[:user]) + + respond_to do |format| + if @user.save + flash[:notice] = "User #{@user.name} was successfully created." + format.html { redirect_to(:action=>'index') } + format.xml { render :xml => @user, :status => :created, :location => @user } + else + format.html { render :action => "new" } + format.xml { render :xml => @user.errors, :status => :unprocessable_entity } + end + end + end + + # PUT /users/1 + # PUT /users/1.xml + def update + @user = User.find(params[:id]) + + respond_to do |format| + if @user.update_attributes(params[:user]) + flash[:notice] = "User #{@user.name} was successfully updated." + format.html { redirect_to(:action =>'index') } + format.xml { head :ok } + else + format.html { render :action => "edit" } + format.xml { render :xml => @user.errors, :status => :unprocessable_entity } + end + end + end + + # DELETE /users/1 + # DELETE /users/1.xml + def destroy + @user = User.find(params[:id]) + @user.destroy + + respond_to do |format| + format.html { redirect_to(users_url) } + format.xml { head :ok } + end + end +end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 0000000..2310a24 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,2 @@ +module UsersHelper +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..73378e7 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,50 @@ +require 'digest/sha2' + +class User < ActiveRecord::Base + + validates_presence_of :name + validates_uniqueness_of :name + attr_accessor :password_confirmation + validates_confirmation_of :password + validate :password_non_blank + validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i + + def self.authenticate(name, password) + user = self.find_by_name(name) + if user + expected_password = encrypted_password(password, user.salt) + if user.hashed_password != expected_password + user = nil + end + end + user + end + + def password + @password + end + + def password=(pwd) + @password = pwd + return if pwd.blank? + create_new_salt + self.hashed_password = User.encrypted_password(self.password, self.salt) + end + + + def password_non_blank + errors.add(:password, "Missing password") if hashed_password.blank? + end + + private + + def self.encrypted_password(password, salt) + string_to_hash = password + "kisi" + salt + Digest::SHA256.hexdigest(string_to_hash) + end + + def create_new_salt + self.salt = self.object_id.to_s + rand.to_s + end + +end diff --git a/app/views/layouts/users.html.erb b/app/views/layouts/users.html.erb new file mode 100644 index 0000000..23757aa --- /dev/null +++ b/app/views/layouts/users.html.erb @@ -0,0 +1,17 @@ + + + + + + Users: <%= controller.action_name %> + <%= stylesheet_link_tag 'scaffold' %> + + + +

<%= flash[:notice] %>

+ +<%= yield %> + + + diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb new file mode 100644 index 0000000..8565f61 --- /dev/null +++ b/app/views/users/edit.html.erb @@ -0,0 +1,28 @@ +

Editing user

+ +<% form_for(@user) do |f| %> + <%= f.error_messages %> + +

+ <%= f.label :name %>
+ <%= f.text_field :name %> +

+

+ <%= f.label :email %>
+ <%= f.text_field :email %> +

+

+ <%= f.label :hashed_password %>
+ <%= f.text_field :hashed_password %> +

+

+ <%= f.label :salt %>
+ <%= f.text_field :salt %> +

+

+ <%= f.submit "Update" %> +

+<% end %> + +<%= link_to 'Show', @user %> | +<%= link_to 'Back', users_path %> diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb new file mode 100644 index 0000000..b5e0cf2 --- /dev/null +++ b/app/views/users/index.html.erb @@ -0,0 +1,22 @@ +

Listing users

+ + + + + + + +<% for user in @users %> + + + + + + + +<% end %> +
NameEmail
<%=h user.name %><%=h user.email %><%= link_to 'Show', user %><%= link_to 'Edit', edit_user_path(user) %><%= link_to 'Destroy', user, :confirm => 'Are you sure?', :method => :delete %>
+ +
+ +<%= link_to 'New user', new_user_path %> diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb new file mode 100644 index 0000000..59f85ef --- /dev/null +++ b/app/views/users/new.html.erb @@ -0,0 +1,27 @@ +

New user

+ +<% form_for(@user) do |f| %> + <%= f.error_messages %> + +

+ <%= f.label :name %>
+ <%= f.text_field :name %> +

+

+ <%= f.label :email %>
+ <%= f.text_field :email %> +

+

+ <%= f.label :password %>
+ <%= f.text_field :password %> +

+

+ <%= f.label :user_password_confirmation %>
+ <%= f.text_field :password_confirmation %> +

+

+ <%= f.submit "Create" %> +

+<% end %> + +<%= link_to 'Back', users_path %> diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb new file mode 100644 index 0000000..0c4aa5d --- /dev/null +++ b/app/views/users/show.html.erb @@ -0,0 +1,23 @@ +

+ Name: + <%=h @user.name %> +

+ +

+ Email: + <%=h @user.email %> +

+ +

+ Hashed password: + <%=h @user.hashed_password %> +

+ +

+ Salt: + <%=h @user.salt %> +

+ + +<%= link_to 'Edit', edit_user_path(@user) %> | +<%= link_to 'Back', users_path %> diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 0000000..94b279f --- /dev/null +++ b/config/database.yml @@ -0,0 +1,20 @@ +# SQLite version 3.x +# gem install sqlite3-ruby (not necessary on OS X Leopard) +development: + adapter: sqlite3 + database: db/development.sqlite3 + timeout: 5000 + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + adapter: sqlite3 + database: db/test.sqlite3 + timeout: 5000 + +# Need to change pefore deploying to prod +production: + adapter: sqlite3 + database: db/production.sqlite3 + timeout: 5000 diff --git a/config/routes.rb b/config/routes.rb index 4f3d9d2..a876289 100755 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,6 @@ ActionController::Routing::Routes.draw do |map| + map.resources :users + # The priority is based upon order of creation: first created -> highest priority. # Sample of regular route: diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000..4bd4720 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,23 @@ +# This file is auto-generated from the current state of the database. Instead of editing this file, +# please use the migrations feature of Active Record to incrementally modify your database, and +# then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your database schema. If you need +# to create the application database on another system, you should be using db:schema:load, not running +# all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended to check this file into your version control system. + +ActiveRecord::Schema.define(:version => 20090312174058) do + + create_table "users", :force => true do |t| + t.string "name", :limit => 128, :null => false + t.string "email", :limit => 128, :null => false + t.string "hashed_password", :limit => 64 + t.string "salt" + t.datetime "created_at" + t.datetime "updated_at" + end + +end diff --git a/public/stylesheets/scaffold.css b/public/stylesheets/scaffold.css new file mode 100644 index 0000000..093c209 --- /dev/null +++ b/public/stylesheets/scaffold.css @@ -0,0 +1,54 @@ +body { background-color: #fff; color: #333; } + +body, p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; +} + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; +} + +a { color: #000; } +a:visited { color: #666; } +a:hover { color: #fff; background-color:#000; } + +.fieldWithErrors { + padding: 2px; + background-color: red; + display: table; +} + +#errorExplanation { + width: 400px; + border: 2px solid red; + padding: 7px; + padding-bottom: 12px; + margin-bottom: 20px; + background-color: #f0f0f0; +} + +#errorExplanation h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + background-color: #c00; + color: #fff; +} + +#errorExplanation p { + color: #333; + margin-bottom: 0; + padding: 5px; +} + +#errorExplanation ul li { + font-size: 12px; + list-style: square; +} + diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..127cec9 --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,13 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html + +one: + name: MyString + email: MyString + hashed_password: MyString + salt: MyString + +two: + name: MyString + email: MyString + hashed_password: MyString + salt: MyString diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb new file mode 100644 index 0000000..c4a4804 --- /dev/null +++ b/test/functional/users_controller_test.rb @@ -0,0 +1,45 @@ +require 'test_helper' + +class UsersControllerTest < ActionController::TestCase + test "should get index" do + get :index + assert_response :success + assert_not_nil assigns(:users) + end + + test "should get new" do + get :new + assert_response :success + end + + test "should create user" do + assert_difference('User.count') do + post :create, :user => { } + end + + assert_redirected_to user_path(assigns(:user)) + end + + test "should show user" do + get :show, :id => users(:one).id + assert_response :success + end + + test "should get edit" do + get :edit, :id => users(:one).id + assert_response :success + end + + test "should update user" do + put :update, :id => users(:one).id, :user => { } + assert_redirected_to user_path(assigns(:user)) + end + + test "should destroy user" do + assert_difference('User.count', -1) do + delete :destroy, :id => users(:one).id + end + + assert_redirected_to users_path + end +end diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb new file mode 100644 index 0000000..a64d2d3 --- /dev/null +++ b/test/unit/user_test.rb @@ -0,0 +1,8 @@ +require 'test_helper' + +class UserTest < ActiveSupport::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end