removes user_id column from User model to use idiomatic Rails automatic IDs

This commit is contained in:
Joseph Mastey
2017-10-07 09:34:26 -06:00
parent c4f0b91534
commit b6c2259b88
29 changed files with 421 additions and 430 deletions
+3 -3
View File
@@ -46,9 +46,9 @@ class AdminController < ApplicationController
end end
def delete_user def delete_user
user = User.find_by_user_id(params[:admin_id]) user = User.find_by(id: params[:admin_id])
if user && !(current_user.user_id == user.user_id) if user && !(current_user.id == user.id)
# Call destroy here so that all association records w/ user_id are destroyed as well # Call destroy here so that all association records w/ id are destroyed as well
# Example user.retirement records would be destroyed # Example user.retirement records would be destroyed
user.destroy user.destroy
message = true message = true
+2 -2
View File
@@ -17,8 +17,8 @@ class ApplicationController < ActionController::Base
def current_user def current_user
@current_user ||= ( @current_user ||= (
User.find_by_auth_token(cookies[:auth_token].to_s) || User.find_by(auth_token: cookies[:auth_token].to_s) ||
User.find_by_user_id(session[:user_id].to_s) User.find_by(id: session[:user_id].to_s)
) )
end end
+2 -2
View File
@@ -16,7 +16,7 @@ class MessagesController < ApplicationController
if message.destroy if message.destroy
flash[:success] = "Your message has been deleted." flash[:success] = "Your message has been deleted."
redirect_to user_messages_path(user_id: current_user.user_id) redirect_to user_messages_path(user_id: current_user.id)
else else
flash[:error] = "Could not delete message." flash[:error] = "Could not delete message."
end end
@@ -25,7 +25,7 @@ class MessagesController < ApplicationController
def create def create
if Message.create(message_params) if Message.create(message_params)
respond_to do |format| respond_to do |format|
format.html { redirect_to user_messages_path(user_id: current_user.user_id) } format.html { redirect_to user_messages_path(user_id: current_user.id) }
format.json { render json: {msg: "success"} } format.json { render json: {msg: "success"} }
end end
else else
@@ -50,10 +50,10 @@ class PasswordResetsController < ApplicationController
end end
def is_valid?(token) def is_valid?(token)
if token =~ /(?<user_id>\d+)-(?<email_hash>[A-Z0-9]{32})/i if token =~ /(?<user>\d+)-(?<email_hash>[A-Z0-9]{32})/i
# Fetch the user by their id, and hash their email address # Fetch the user by their id, and hash their email address
@user = User.find_by_id($~[:user_id]) @user = User.find_by(id: $~[:user])
email = Digest::MD5.hexdigest(@user.email) email = Digest::MD5.hexdigest(@user.email)
# Compare and validate our hashes # Compare and validate our hashes
+3 -2
View File
@@ -9,9 +9,10 @@ class PayController < ApplicationController
pay = Pay.new( pay = Pay.new(
bank_account_num: params[:bank_account_num], bank_account_num: params[:bank_account_num],
bank_routing_num: params[:bank_routing_num], bank_routing_num: params[:bank_routing_num],
percent_of_deposit: params[:dd_percent] percent_of_deposit: params[:dd_percent],
user_id: current_user.id
) )
pay.user_id = current_user.user_id
msg = true if pay.save! msg = true if pay.save!
respond_to do |format| respond_to do |format|
format.json {render json: {msg: msg } } format.json {render json: {msg: msg } }
+1 -1
View File
@@ -7,7 +7,7 @@ class ScheduleController < ApplicationController
if params[:schedule][:event_type] == "pto" if params[:schedule][:event_type] == "pto"
sched = Schedule.new(schedule_params) sched = Schedule.new(schedule_params)
sched.date_begin, sched.date_end = format_schedule_date(params[:date_range1]) sched.date_begin, sched.date_end = format_schedule_date(params[:date_range1])
sched.user_id = current_user.user_id sched.user_id = current_user.id
a = sched.date_end a = sched.date_end
if sched.save if sched.save
message = true message = true
+2 -2
View File
@@ -19,9 +19,9 @@ class SessionsController < ApplicationController
if user if user
if params[:remember_me] if params[:remember_me]
cookies.permanent[:auth_token] = user.auth_token if User.where(user_id: user.user_id).exists? cookies.permanent[:auth_token] = user.auth_token
else else
session[:user_id] = user.user_id if User.where(user_id: user.user_id).exists? session[:user_id] = user.id
end end
redirect_to path redirect_to path
else else
+5 -6
View File
@@ -10,7 +10,7 @@ class UsersController < ApplicationController
def create def create
user = User.new(user_params) user = User.new(user_params)
if user.save if user.save
session[:user_id] = user.user_id session[:user_id] = user.id
redirect_to home_dashboard_index_path redirect_to home_dashboard_index_path
else else
@user = user @user = user
@@ -26,22 +26,21 @@ class UsersController < ApplicationController
def update def update
message = false message = false
user = User.where("user_id = '#{params[:user][:user_id]}'")[0] user = User.where("id = '#{params[:user][:id]}'")[0]
if user if user
user.skip_user_id_assign = true
user.update_attributes(user_params_without_password) user.update_attributes(user_params_without_password)
if params[:user][:password].present? && (params[:user][:password] == params[:user][:password_confirmation]) if params[:user][:password].present? && (params[:user][:password] == params[:user][:password_confirmation])
user.password = params[:user][:password] user.password = params[:user][:password]
end end
message = true if user.save! message = true if user.save!
respond_to do |format| respond_to do |format|
format.html { redirect_to user_account_settings_path(user_id: current_user.user_id) } format.html { redirect_to user_account_settings_path(user_id: current_user.id) }
format.json { render json: {msg: message ? "success" : "false "} } format.json { render :json => {:msg => message ? "success" : "false "} }
end end
else else
flash[:error] = "Could not update user!" flash[:error] = "Could not update user!"
redirect_to user_account_settings_path(user_id: current_user.user_id) redirect_to user_account_settings_path(user_id: current_user.id)
end end
end end
+1 -1
View File
@@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class WorkInfoController < ApplicationController class WorkInfoController < ApplicationController
def index def index
@user = User.find_by_user_id(params[:user_id]) @user = User.find_by(id: params[:user_id])
if !(@user) || @user.admin if !(@user) || @user.admin
flash[:error] = "Sorry, no user with that user id exists" flash[:error] = "Sorry, no user with that user id exists"
redirect_to home_dashboard_index_path redirect_to home_dashboard_index_path
+1 -1
View File
@@ -4,7 +4,7 @@ class Message < ApplicationRecord
validates_presence_of :creator_id, :receiver_id, :message validates_presence_of :creator_id, :receiver_id, :message
def creator_name def creator_name
if creator = User.where(user_id: self.creator_id).first if creator = User.where(id: self.creator_id).first
creator.full_name creator.full_name
else else
"Name unavailable" "Name unavailable"
+17 -31
View File
@@ -10,17 +10,17 @@ class User < ApplicationRecord
validates_presence_of :email validates_presence_of :email
validates_uniqueness_of :email validates_uniqueness_of :email
validates_format_of :email, with: /.+@.+\..+/i validates_format_of :email, :with => /.+@.+\..+/i
attr_accessor :skip_user_id_assign
before_save :assign_user_id, on: :create has_one :retirement, dependent: :destroy
has_one :paid_time_off, dependent: :destroy
has_one :work_info, dependent: :destroy
has_many :performance, dependent: :destroy
has_many :pay, dependent: :destroy
has_many :messages, foreign_key: :receiver_id, dependent: :destroy
before_save :hash_password before_save :hash_password
has_one :retirement, foreign_key: :user_id, primary_key: :user_id, dependent: :destroy after_create { generate_token(:auth_token) }
has_one :paid_time_off, foreign_key: :user_id, primary_key: :user_id, dependent: :destroy
has_one :work_info, foreign_key: :user_id, primary_key: :user_id, dependent: :destroy
has_many :performance, foreign_key: :user_id, primary_key: :user_id, dependent: :destroy
has_many :messages, foreign_key: :receiver_id, primary_key: :user_id, dependent: :destroy
has_many :pay, foreign_key: :user_id, primary_key: :user_id, dependent: :destroy
before_create { generate_token(:auth_token) }
before_create :build_benefits_data before_create :build_benefits_data
def build_benefits_data def build_benefits_data
@@ -36,11 +36,6 @@ class User < ApplicationRecord
"#{self.first_name} #{self.last_name}" "#{self.first_name} #{self.last_name}"
end end
# # Instead of the entire user object being returned, we can use this to filter.
# def as_json
# super(only: [:user_id, :email, :first_name, :last_name])
# end
private private
def self.authenticate(email, password) def self.authenticate(email, password)
@@ -55,26 +50,17 @@ class User < ApplicationRecord
return auth return auth
end end
def assign_user_id
unless @skip_user_id_assign.present? || self.user_id.present?
user = User.order("user_id").last
uid = if user && user.user_id && !(User.exists?(user_id: "#{user.user_id.to_i + 1}"))
user.user_id.to_i + 1
else
1
end
self.user_id = uid.to_s if uid
end
end
def hash_password def hash_password
if password.present? && password_changed? if will_save_change_to_password?
self.password = Digest::MD5.hexdigest(password) self.password = Digest::MD5.hexdigest(self.password)
end end
end end
def generate_token(column) def generate_token(column)
self[column] = Encryption.encrypt_sensitive_value(self.user_id) begin
generate_token(column) if User.exists?(column => self[column]) self[column] = Encryption.encrypt_sensitive_value(self.id)
end while User.exists?(column => self[column])
self.save!
end end
end end
+1 -1
View File
@@ -62,7 +62,7 @@ $('#submit_button').click(function() {
$("#editAcct").modal('hide'); $("#editAcct").modal('hide');
$.ajax({ $.ajax({
url: "/admin/" + <%= @user.user_id %> + "/update_user.json", url: "/admin/" + <%= @user.id %> + "/update_user.json",
data: valuesToSubmit, data: valuesToSubmit,
type: "POST", type: "POST",
success: function(response) { success: function(response) {
+1 -1
View File
@@ -14,7 +14,7 @@
<span class="caret"></span> <span class="caret"></span>
<ul class="dropdown-menu pull-right"> <ul class="dropdown-menu pull-right">
<li> <li>
<%= link_to "Account settings", user_account_settings_path(:user_id => current_user.user_id) %> <%= link_to "Account settings", user_account_settings_path(user_id: current_user.id) %>
</li> </li>
<li> <li>
<%= link_to "Logout", logout_path %> <%= link_to "Logout", logout_path %>
+7 -7
View File
@@ -32,7 +32,7 @@
</li> </li>
<% end %> <% end %>
<li id="benefit_forms"> <li id="benefit_forms">
<%= link_to user_benefit_forms_path(:user_id => current_user.user_id) do %> <%= link_to user_benefit_forms_path(user_id: current_user.id) do %>
<div class="icon"> <div class="icon">
<span class="fs1" aria-hidden="true" data-icon="&#xe05c;"></span> <span class="fs1" aria-hidden="true" data-icon="&#xe05c;"></span>
</div> </div>
@@ -40,7 +40,7 @@
<% end %> <% end %>
</li> </li>
<li id="retirement"> <li id="retirement">
<%= link_to user_retirement_index_path(:user_id => current_user.user_id) do %> <%= link_to user_retirement_index_path(user_id: current_user.id) do %>
<div class="icon"> <div class="icon">
<span class="fs1" aria-hidden="true" data-icon="&#xe096;"></span> <span class="fs1" aria-hidden="true" data-icon="&#xe096;"></span>
</div> </div>
@@ -48,7 +48,7 @@
<% end %> <% end %>
</li> </li>
<li id="pto"> <li id="pto">
<%= link_to user_paid_time_off_index_path(:user_id => current_user.user_id) do %> <%= link_to user_paid_time_off_index_path(user_id: current_user.id) do %>
<div class="icon"> <div class="icon">
<span class="fs1" aria-hidden="true" data-icon="&#xe0d2;"></span> <span class="fs1" aria-hidden="true" data-icon="&#xe0d2;"></span>
</div> </div>
@@ -56,7 +56,7 @@
<% end %> <% end %>
</li> </li>
<li id="employee_info"> <li id="employee_info">
<%= link_to user_work_info_index_path(:user_id => current_user.user_id) do %> <%= link_to user_work_info_index_path(user_id: current_user.id) do %>
<div class="icon"> <div class="icon">
<span class="fs1" aria-hidden="true" data-icon="&#xe0a9;"></span> <span class="fs1" aria-hidden="true" data-icon="&#xe0a9;"></span>
</div> </div>
@@ -64,7 +64,7 @@
<% end %> <% end %>
</li> </li>
<li id="performance"> <li id="performance">
<%= link_to user_performance_index_path(:user_id => current_user.user_id) do %> <%= link_to user_performance_index_path(user_id: current_user.id) do %>
<div class="icon"> <div class="icon">
<span class="fs1" aria-hidden="true" data-icon="&#xe14a;"></span> <span class="fs1" aria-hidden="true" data-icon="&#xe14a;"></span>
</div> </div>
@@ -72,7 +72,7 @@
<% end %> <% end %>
</li> </li>
<li id="messages"> <li id="messages">
<%= link_to user_messages_path(:user_id => current_user.user_id) do %> <%= link_to user_messages_path(user_id: current_user.id) do %>
<div class="icon"> <div class="icon">
<span class="fs1" aria-hidden="true" data-icon="&#xe040;"></span> <span class="fs1" aria-hidden="true" data-icon="&#xe040;"></span>
</div> </div>
@@ -80,7 +80,7 @@
<% end %> <% end %>
</li> </li>
<li id="pay"> <li id="pay">
<%= link_to user_pay_index_path(:user_id => current_user.user_id) do %> <%= link_to user_pay_index_path(user_id: current_user.id) do %>
<div class="icon"> <div class="icon">
<span class="fs1" aria-hidden="true" data-icon="&#xe038;"></span> <span class="fs1" aria-hidden="true" data-icon="&#xe038;"></span>
</div> </div>
+1 -1
View File
@@ -111,7 +111,7 @@ $("#submit_button").click(function(event) {
var valuesToSubmit = $("#send_message").serialize(); var valuesToSubmit = $("#send_message").serialize();
event.preventDefault(); event.preventDefault();
$.ajax({ $.ajax({
url: <%= "/users/#{current_user.user_id}/messages.json".inspect.html_safe %>, url: <%= "/users/#{current_user.id}/messages.json".inspect.html_safe %>,
data: valuesToSubmit, data: valuesToSubmit,
type: "POST", type: "POST",
success: function(response) { success: function(response) {
+2 -2
View File
@@ -186,7 +186,7 @@ function parseDirectDepostInfo(response){
function populateTable() { function populateTable() {
$('#data_table').dataTable().fnClearTable(); $('#data_table').dataTable().fnClearTable();
$.ajax({ $.ajax({
url: <%= sanitize(user_pay_path(:format => "json", :user_id => current_user.user_id, :id => current_user.user_id).inspect) %>, url: <%= sanitize(user_pay_path(:format => "json", user_id: current_user.id, id: current_user.id).inspect) %>,
type: "GET", type: "GET",
success: function(response) { success: function(response) {
parseDirectDepostInfo(response); parseDirectDepostInfo(response);
@@ -237,7 +237,7 @@ $("#decrypt_btn").click(function(event){
var valuesToSubmit = $("#decrypt_form").serialize(); var valuesToSubmit = $("#decrypt_form").serialize();
event.preventDefault(); event.preventDefault();
$.ajax({ $.ajax({
url: <%= sanitize(decrypted_bank_acct_num_user_pay_index_path(:format => "json", :user_id => current_user.user_id).inspect) %>, url: <%= sanitize(decrypted_bank_acct_num_user_pay_index_path(:format => "json", user_id: current_user.id).inspect) %>,
data: valuesToSubmit, data: valuesToSubmit,
type: "POST", type: "POST",
success: function(response) { success: function(response) {
+2 -2
View File
@@ -37,7 +37,7 @@
</div> </div>
<div class="widget-body"> <div class="widget-body">
<%= form_for @user, :html => {:id => "account_edit"} do |f|%> <%= form_for @user, :html => {:id => "account_edit"} do |f|%>
<%= f.hidden_field :user_id%> <%= f.hidden_field :id %>
<div class="control-group"> <div class="control-group">
<%= f.label :email, nil, {:class => "control-label"}%> <%= f.label :email, nil, {:class => "control-label"}%>
<%= f.text_field :email, {:class => "span12"}%> <%= f.text_field :email, {:class => "span12"}%>
@@ -84,7 +84,7 @@ $("#submit_button").click(function(event) {
var valuesToSubmit = $("#account_edit").serialize(); var valuesToSubmit = $("#account_edit").serialize();
event.preventDefault(); event.preventDefault();
$.ajax({ $.ajax({
url: <%= "/users/#{current_user.user_id}.json".inspect.html_safe %>, url: <%= "/users/#{current_user.id}.json".inspect.html_safe %>,
data: valuesToSubmit, data: valuesToSubmit,
type: "POST", type: "POST",
success: function(response) { success: function(response) {
@@ -0,0 +1,5 @@
class RemoveUsersUserId < ActiveRecord::Migration[5.1]
def change
remove_column :users, :user_id, :integer
end
end
+1 -2
View File
@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20140408185601) do ActiveRecord::Schema.define(version: 20171007010129) do
create_table "analytics", force: :cascade do |t| create_table "analytics", force: :cascade do |t|
t.string "ip_address" t.string "ip_address"
@@ -97,7 +97,6 @@ ActiveRecord::Schema.define(version: 20140408185601) do
t.boolean "admin" t.boolean "admin"
t.string "first_name" t.string "first_name"
t.string "last_name" t.string "last_name"
t.integer "user_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "auth_token" t.string "auth_token"
+70 -76
View File
@@ -11,17 +11,26 @@ users = [
password_confirmation: "admin1234", password_confirmation: "admin1234",
first_name: "Admin", first_name: "Admin",
last_name: "", last_name: "",
user_id: 1
}, },
{ {
email: "jmmastey@metacorp.com", :email => "jmmastey@metacorp.com",
admin: false, :admin => false,
password: "railsgoat!", :password => "railsgoat!",
password_confirmation: "railsgoat!", :password_confirmation => "railsgoat!",
first_name: "Joseph", :first_name => "Joseph",
last_name: "Mastey", :last_name => "Mastey",
user_id: 2
}, },
{
email: "jack@metacorp.com",
admin: false,
password: "yankeessuck",
password_confirmation: "yankeessuck",
first_name: "Jack",
last_name: "Mannino",
},
{ {
email: "jim@metacorp.com", email: "jim@metacorp.com",
admin: false, admin: false,
@@ -29,8 +38,8 @@ users = [
password_confirmation: "alohaowasp", password_confirmation: "alohaowasp",
first_name: "Jim", first_name: "Jim",
last_name: "Manico", last_name: "Manico",
user_id: 3
}, },
{ {
email: "mike@metacorp.com", email: "mike@metacorp.com",
admin: false, admin: false,
@@ -38,8 +47,8 @@ users = [
password_confirmation: "motocross1445", password_confirmation: "motocross1445",
first_name: "Mike", first_name: "Mike",
last_name: "McCabe", last_name: "McCabe",
user_id: 4
}, },
{ {
email: "ken@metacorp.com", email: "ken@metacorp.com",
admin: false, admin: false,
@@ -47,8 +56,8 @@ users = [
password_confirmation: "citrusblend", password_confirmation: "citrusblend",
first_name: "Ken", first_name: "Ken",
last_name: "Johnson", last_name: "Johnson",
user_id: 5
}, },
{ {
email: "admin2@metacorp.com", email: "admin2@metacorp.com",
admin: false, admin: false,
@@ -56,112 +65,105 @@ users = [
password_confirmation: "adminadmin", password_confirmation: "adminadmin",
first_name: "Admin2", first_name: "Admin2",
last_name: "", last_name: "",
user_id: 6
} }
] ]
retirements = [ retirements = [
{ {
user_id: 2, user: "jack@metacorp.com",
employee_contrib: "1000", employee_contrib: "1000",
employer_contrib: "2000", employer_contrib: "2000",
total: "4500" total: "4500"
}, },
{ {
user_id: 3, user: "jim@metacorp.com",
employee_contrib: "8000", employee_contrib: "8000",
employer_contrib: "16000", employer_contrib: "16000",
total: "30000" total: "30000"
}, },
{ {
user_id: 4, user: "mike@metacorp.com",
employee_contrib: "10000", employee_contrib: "10000",
employer_contrib: "20000", employer_contrib: "20000",
total: "40000" total: "40000"
}, },
{ {
user_id: 5, user: "ken@metacorp.com",
employee_contrib: "3000", employee_contrib: "3000",
employer_contrib: "6000", employer_contrib: "6000",
total: "12500" total: "12500"
} }
] ]
paid_time_off = [ paid_time_off = [
{ {
user_id: 2, user: "jack@metacorp.com",
sick_days_taken: 2, sick_days_taken: 2,
sick_days_earned: 5, sick_days_earned: 5,
pto_taken: 5, pto_taken: 5,
pto_earned: 30 pto_earned: 30
}, },
{ {
user_id: 3, user: "jim@metacorp.com",
sick_days_taken: 3, sick_days_taken: 3,
sick_days_earned: 6, sick_days_earned: 6,
pto_taken: 3, pto_taken: 3,
pto_earned: 20 pto_earned: 20
}, },
{ {
user_id: 4, user: "mike@metacorp.com",
sick_days_taken: 2, sick_days_taken: 2,
sick_days_earned: 5, sick_days_earned: 5,
pto_taken: 5, pto_taken: 5,
pto_earned: 30 pto_earned: 30
}, },
{ {
user_id: 5, user: "ken@metacorp.com",
sick_days_taken: 1, sick_days_taken: 1,
sick_days_earned: 5, sick_days_earned: 5,
pto_taken: 10, pto_taken: 10,
pto_earned: 30 pto_earned: 30
} }
] ]
schedule = [ schedule = [
{ {
user_id: 2, user: "jack@metacorp.com",
date_begin: Date.new(2014, 7, 30), date_begin: Date.new(2014, 7, 30),
date_end: Date.new(2014, 8, 2), date_end: Date.new(2014, 8, 2),
event_type: "pto", event_type: "pto",
event_desc: "vacation to france", event_desc: "vacation to france",
event_name: "My 2014 Vacation" event_name: "My 2014 Vacation"
}, },
{ {
user_id: 3, user: "jim@metacorp.com",
date_begin: Date.new(2013, 9, 1), date_begin: Date.new(2013, 9, 1),
date_end: Date.new(2013, 9, 12), date_end: Date.new(2013, 9, 12),
event_type: "pto", event_type: "pto",
event_desc: "Going Home to see folks", event_desc: "Going Home to see folks",
event_name: "Visit Parents" event_name: "Visit Parents"
}, },
{ {
user_id: 4, user: "mike@metacorp.com",
date_begin: Date.new(2013, 9, 13), date_begin: Date.new(2013, 9, 13),
date_end: Date.new(2013, 9, 20), date_end: Date.new(2013, 9, 20),
event_type: "pto", event_type: "pto",
event_desc: "Taking kids to Grand Canyon", event_desc: "Taking kids to Grand Canyon",
event_name: "AZ Trip" event_name: "AZ Trip"
}, },
{ {
user_id: 5, user: "ken@metacorp.com",
date_begin: Date.new(2013, 12, 20), date_begin: Date.new(2013, 12, 20),
date_end: Date.new(2013, 12, 30), date_end: Date.new(2013, 12, 30),
event_type: "pto", event_type: "pto",
event_desc: "Xmas Staycation", event_desc: "Xmas Staycation",
event_name: "Christmas Leave" event_name: "Christmas Leave"
} }
] ]
work_info = [ work_info = [
{ {
user_id: 2, user: "jack@metacorp.com",
income: "$50,000", income: "$50,000",
bonuses: "$10,000", bonuses: "$10,000",
years_worked: 2, years_worked: 2,
@@ -169,7 +171,7 @@ paid_time_off = [
DoB: "01-01-1980" DoB: "01-01-1980"
}, },
{ {
user_id: 3, user: "jim@metacorp.com",
income: "$40,000", income: "$40,000",
bonuses: "$10,000", bonuses: "$10,000",
years_worked: 1, years_worked: 1,
@@ -177,7 +179,7 @@ paid_time_off = [
DoB: "01-01-1979" DoB: "01-01-1979"
}, },
{ {
user_id: 4, user: "mike@metacorp.com",
income: "$60,000", income: "$60,000",
bonuses: "$12,000", bonuses: "$12,000",
years_worked: 3, years_worked: 3,
@@ -185,7 +187,7 @@ paid_time_off = [
DoB: "01-01-1981" DoB: "01-01-1981"
}, },
{ {
user_id: 5, user: "ken@metacorp.com",
income: "$30,000", income: "$30,000",
bonuses: "7,000", bonuses: "7,000",
years_worked: 1, years_worked: 1,
@@ -196,49 +198,49 @@ paid_time_off = [
performance = [ performance = [
{ {
user_id: 2, user: "jack@metacorp.com",
reviewer: 1, reviewer: 1,
comments: "Great job! You are my hero", comments: "Great job! You are my hero",
date_submitted: Date.new(2012, 01, 01), date_submitted: Date.new(2012, 01, 01),
score: 5 score: 5
}, },
{ {
user_id: 2, user: "jack@metacorp.com",
reviewer: 1, reviewer: 1,
comments: "Once again, you've done a great job this year. We greatly appreciate your hard work.", comments: "Once again, you've done a great job this year. We greatly appreciate your hard work.",
date_submitted: Date.new(2013, 01, 01), date_submitted: Date.new(2013, 01, 01),
score: 5 score: 5
}, },
{ {
user_id: 3, user: "jim@metacorp.com",
reviewer: 1, reviewer: 1,
comments: "Great worker, great attitude for this newcomer!", comments: "Great worker, great attitude for this newcomer!",
date_submitted: Date.new(2013, 01, 01), date_submitted: Date.new(2013, 01, 01),
score: 5 score: 5
}, },
{ {
user_id: 4, user: "mike@metacorp.com",
reviewer: 1, reviewer: 1,
comments: "Wow, right out of the gate we've been very impressed but unfortunately, our system doesn't allow us to give you a full 5.0 because other ppl have gotten 5.0 ratings.", comments: "Wow, right out of the gate we've been very impressed but unfortunately, our system doesn't allow us to give you a full 5.0 because other ppl have gotten 5.0 ratings.",
date_submitted: Date.new(2011, 01, 01), date_submitted: Date.new(2011, 01, 01),
score: 4 score: 4
}, },
{ {
user_id: 4, user: "mike@metacorp.com",
reviewer: 1, reviewer: 1,
comments: "We highly recommend promotion for this employee! Consistent performer with proven leadership qualities.", comments: "We highly recommend promotion for this employee! Consistent performer with proven leadership qualities.",
date_submitted: Date.new(2012, 01, 01), date_submitted: Date.new(2012, 01, 01),
score: 5 score: 5
}, },
{ {
user_id: 4, user: "mike@metacorp.com",
reviewer: 1, reviewer: 1,
comments: "Right out of the gate, Mike has made incredible moves as a newly appointed leader. His only improvement would be more cowbell. Not enough of it.", comments: "Right out of the gate, Mike has made incredible moves as a newly appointed leader. His only improvement would be more cowbell. Not enough of it.",
date_submitted: Date.new(2013, 01, 01), date_submitted: Date.new(2013, 01, 01),
score: 4 score: 4
}, },
{ {
user_id: 5, user: "ken@metacorp.com",
reviewer: 1, reviewer: 1,
comments: "Ehh, you are okay, we will let you stay..... barely", comments: "Ehh, you are okay, we will let you stay..... barely",
date_submitted: Date.new(2013, 01, 01), date_submitted: Date.new(2013, 01, 01),
@@ -248,70 +250,62 @@ paid_time_off = [
messages = [ messages = [
{ {
receiver_id: 2, creator: "ken@metacorp.com",
creator_id: 5, receiver: "jack@metacorp.com",
message: "Your benefits have been updated.", message: 'Your benefits have been updated.',
read: false read: false
}, },
{ {
receiver_id: 3, creator: "mike@metacorp.com",
creator_id: 4, receiver: "jim@metacorp.com",
message: "Please update your profile.", message: 'Please update your profile.',
read: false read: false
}, },
{ {
receiver_id: 4, creator: "jim@metacorp.com",
creator_id: 3, receiver: "mike@metacorp.com",
message: "Welcome to Railsgoat.", message: 'Welcome to Railsgoat.',
read: false read: false
}, },
{ {
receiver_id: 5, creator: "jack@metacorp.com",
creator_id: 2, receiver: "ken@metacorp.com",
message: "Hello friend.", message: 'Hello friend.',
read: false read: false
} }
] ]
user_map = users.each_with_object({}) do |user_info, h|
users.each do |user_info| h[user_info[:email]] = User.create!(user_info).id
user = User.new(user_info.reject { |k| k == :user_id })
user.user_id = user_info[:user_id]
user.save!
end end
retirements.each do |r| retirements.each do |r|
ret = Retirement.new(r.reject { |k| k == :user_id}) r[:user_id] = user_map.fetch(r.delete(:user))
ret.user_id = r[:user_id] Retirement.create!(r)
ret.save!
end end
paid_time_off.each do |pto| paid_time_off.each do |pto|
ptoff = PaidTimeOff.new(pto.reject { |k| k == :user_id}) pto[:user_id] = user_map.fetch(pto.delete(:user))
ptoff.user_id = pto[:user_id] PaidTimeOff.create!(pto)
ptoff.save!
end end
schedule.each do |event| schedule.each do |event|
sched = Schedule.new(event.reject { |k| k == :user_id}) event[:user_id] = user_map.fetch(event.delete(:user))
sched.user_id = event[:user_id] Schedule.create!(event)
sched.save!
end end
performance.each do |perf| performance.each do |perf|
p = Performance.new(perf.reject { |k| k == :user_id}) perf[:user_id] = user_map.fetch(perf.delete(:user))
p.user_id = perf[:user_id] Performance.create!(perf)
p.save!
end end
messages.each do |message| messages.each do |message|
m = Message.new(message.reject { |k| k == :creator_id}) message[:creator_id] = user_map.fetch(message.delete(:creator))
m.creator_id = message[:creator_id] message[:receiver_id] = user_map.fetch(message.delete(:receiver))
m.save! Message.create!(message)
end end
work_info.each do |wi| work_info.each do |wi|
info = WorkInfo.new(wi.reject { |k| k == :user_id }) wi[:user_id] = user_map.fetch(wi.delete(:user))
info.user_id = wi[:user_id] WorkInfo.create!(wi)
info.save!
end end
+10 -7
View File
@@ -6,13 +6,16 @@ class UserFixture
end end
def self.normal_user def self.normal_user
password = "thi$ 1s cOmplExEr" password = 'thi$ 1s cOmplExEr'
user = User.new(first_name: "Joe", last_name: "Schmoe", User.create!(first_name: 'Joe', last_name: 'Schmoe', email: 'joe@schmoe.com',
email: "joe@schmoe.com", password: password, password_confirmation: password) password: password, password_confirmation: password).tap do |user|
def user.clear_password def user.clear_password
"thi$ 1s cOmplExEr" 'thi$ 1s cOmplExEr'
end end
user.save! end
user end
def self.admin_user
User.where(admin: true).first
end end
end end
@@ -14,7 +14,7 @@ feature "command injection" do
legit_file = File.join(Rails.root, "public", "data", "legit.txt") legit_file = File.join(Rails.root, "public", "data", "legit.txt")
File.open(legit_file, "w") { |f| f.puts "totes legit" } File.open(legit_file, "w") { |f| f.puts "totes legit" }
visit "/users/#{@normal_user.user_id}/benefit_forms" visit "/users/#{@normal_user.id}/benefit_forms"
Dir.mktmpdir do |dir| Dir.mktmpdir do |dir|
hackety_file = File.join(dir, "test; cd public && cd data && rm -f * ;") hackety_file = File.join(dir, "test; cd public && cd data && rm -f * ;")
File.open(hackety_file, "w") { |f| f.print "mwahaha" } File.open(hackety_file, "w") { |f| f.print "mwahaha" }
+5 -5
View File
@@ -10,9 +10,9 @@ feature "insecure direct object reference" do
scenario "attack one" do scenario "attack one" do
login(@normal_user) login(@normal_user)
visit "/users/#{@normal_user.user_id}/benefit_forms" visit "/users/#{@normal_user.id}/benefit_forms"
download_url = first(".widget-body a")[:href] download_url = first('.widget-body a')[:href]
visit download_url.sub(/name=(.*?)&/, "name=config/database.yml&") visit download_url.sub(/name=(.*?)&/, 'name=config/database.yml&')
pending if verifying_fixed? pending if verifying_fixed?
@@ -24,8 +24,8 @@ feature "insecure direct object reference" do
scenario "attack two\nTutorial: https://github.com/OWASP/railsgoat/wiki/A4-Insecure-Direct-Object-Reference" do scenario "attack two\nTutorial: https://github.com/OWASP/railsgoat/wiki/A4-Insecure-Direct-Object-Reference" do
login(@normal_user) login(@normal_user)
expect(@normal_user.user_id).not_to eq(2) expect(@normal_user.id).not_to eq(2)
visit "/users/2/work_info" visit '/users/2/work_info'
pending if verifying_fixed? pending if verifying_fixed?
expect(first("td").text).to eq("Joseph Mastey") expect(first("td").text).to eq("Joseph Mastey")
+2 -2
View File
@@ -13,10 +13,10 @@ feature "mass assignment" do
login(@normal_user) login(@normal_user)
params = {user: {admin: "t", params = {user: {admin: "t",
user_id: @normal_user.user_id, user_id: @normal_user.id,
password: @normal_user.clear_password, password: @normal_user.clear_password,
password_confirmation: @normal_user.clear_password}} password_confirmation: @normal_user.clear_password}}
page.driver.put "/users/#{@normal_user.user_id}.json", params page.driver.put "/users/#{@normal_user.id}.json", params
pending if verifying_fixed? pending if verifying_fixed?
expect(@normal_user.reload.admin).to be_truthy expect(@normal_user.reload.admin).to be_truthy
@@ -13,7 +13,7 @@ feature "sensitive data exposure" do
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A6-Sensitive-Data-Exposure-Cleartext-Storage-SSNs" do scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A6-Sensitive-Data-Exposure-Cleartext-Storage-SSNs" do
login @normal_user login @normal_user
visit "/users/#{@normal_user.user_id}/work_info" visit "/users/#{@normal_user.id}/work_info"
pending if verifying_fixed? pending if verifying_fixed?
expect(page.source).to include "999-99-9999" expect(page.source).to include "999-99-9999"
end end
+9 -7
View File
@@ -4,8 +4,9 @@ require "spec_helper"
feature "sql injection" do feature "sql injection" do
before(:each) do before(:each) do
UserFixture.reset_all_users UserFixture.reset_all_users
@normal_user = UserFixture.normal_user @normal_user = UserFixture.normal_user
@admin_user = User.where("admin='t'").first @admin_user = UserFixture.admin_user
end end
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/R4-A1-SQL-Injection-Concatentation" do scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/R4-A1-SQL-Injection-Concatentation" do
@@ -13,14 +14,15 @@ feature "sql injection" do
login(@normal_user) login(@normal_user)
visit "/users/#{@normal_user.user_id}/account_settings" visit "/users/#{@normal_user.id}/account_settings"
within("#account_edit") do
fill_in "Email", with: "joe.admin@schmoe.com" within('#account_edit') do
fill_in "user_password", with: "H4cketyhack" fill_in 'Email', :with => 'joe.admin@schmoe.com'
fill_in "user_password_confirmation", with: "H4cketyhack" fill_in 'user_password', :with => 'H4cketyhack'
fill_in 'user_password_confirmation', :with => 'H4cketyhack'
# this is a hidden field, so cannot use fill_in to access it. # this is a hidden field, so cannot use fill_in to access it.
find(:xpath, "//input[@id='user_user_id']", visible: false).set "8' OR admin='t') --" find(:xpath, "//input[@id='user_id']", :visible => false).set "8' OR admin='t') --"
end end
click_on "Submit" click_on "Submit"
@@ -7,15 +7,17 @@ feature "unvalidated redirect" do
@normal_user = UserFixture.normal_user @normal_user = UserFixture.normal_user
end end
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A10-Unvalidated-Redirects-and-Forwards-(redirect_to)", js: true do scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A10-Unvalidated-Redirects-and-Forwards-(redirect_to)", :js => true do
visit "/?url=http://example.com/do/evil/things" visit '/?url=http://example.com/do/evil/things'
within(".signup") do
fill_in "email", with: @normal_user.email within('.signup') do
fill_in "password", with: @normal_user.clear_password fill_in 'email', with: @normal_user.email
fill_in 'password', with: @normal_user.clear_password
end end
within(".actions") do within(".actions") do
click_on "Login" click_on "Login"
end end
pending if verifying_fixed? pending if verifying_fixed?
expect(current_url).to eq("http://example.com/do/evil/things") expect(current_url).to eq("http://example.com/do/evil/things")
end end
+4 -4
View File
@@ -10,9 +10,9 @@ feature "xss" do
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A3-Cross-Site-Scripting", js: true do scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A3-Cross-Site-Scripting", js: true do
login @normal_user login @normal_user
visit "/users/#{@normal_user.user_id}/account_settings" visit "/users/#{@normal_user.id}/account_settings"
within("#account_edit") do within('#account_edit') do
fill_in "First name", with: "<script>$(function() { $('div input.btn').val('RailsGoat h4x0r3d') } )</script>" fill_in 'First name', :with => "<script>$(function() { $('div input.btn').val('RailsGoat h4x0r3d') } )</script>"
# password gets screwed up if you don't re-submit - need to fix # password gets screwed up if you don't re-submit - need to fix
fill_in "user_password", with: @normal_user.clear_password fill_in "user_password", with: @normal_user.clear_password
@@ -22,7 +22,7 @@ feature "xss" do
sleep(1) sleep(1)
visit "/users/#{@normal_user.user_id}/account_settings" visit "/users/#{@normal_user.id}/account_settings"
pending if verifying_fixed? pending if verifying_fixed?
expect(find("#submit_button").value).to eq("RailsGoat h4x0r3d") expect(find("#submit_button").value).to eq("RailsGoat h4x0r3d")