Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require "sqlite3"
- require "digest"
- require "securerandom"
- # Anmol Srivastava | asrivas2 | 114101433 | TA: JT, 12 PM
- # Things to fix - PART 1: (REMEMBER TO UPDATE DATA.DB IF YOU MAKE REAL CHANGES ON WEBSITE)
- # - Validate all command fields per BASH
- # - If user not allowed to use method, no action and FALSE
- # - @shell_pwd, @controller_pwd, latter is project directory path
- # - all session tokens revoked when an account is deleted.
- # - shell use restricted to project directory and its contents
- # - cannot delete data.db, controller.rb, or main.rb - SEE DIR AND FILE CLASSES IN RUBY
- # - database only allows access to menu and user profiles, not session data, etc.
- # Things to do - Part 2:
- # - salt hash thingy - expand
- def non_injecting(str)
- if str =~ %r{[;,--]} or str =~ %r{[<,>,",&]} # Comment out the "
- return false
- end
- return true
- end
- module Menu
- def create_menu(name)
- if non_injecting name and (authorize @session_id) != -1 then
- @db.execute_batch "INSERT INTO Menus (Name) VALUES(\"#{name}\")"
- end
- return false
- end
- def read_menu()
- if (authorize @session_id) != -1 then
- menus = []
- @db.execute "SELECT RowID, Name FROM Menus" do |menu|
- id, name = menu[0], menu[1]
- menus << { :id => id, :name => name }
- end
- return menus
- end
- return false
- end
- def update_menu(id, name)
- if non_injecting id and non_injecting name and (authorize @session_id) != -1 then
- @db.execute_batch "UPDATE Menus SET Name = \"#{name}\" WHERE RowID = #{id}"
- end
- return false
- end
- def delete_menu(id)
- if non_injecting id and (authorize @session_id) != -1 then
- @db.execute_batch "DELETE FROM Menus WHERE RowID = #{id}"
- end
- return false
- end
- end
- module Item
- def create_item(menu, name, price, description)
- if non_injecting menu and non_injecting name and non_injecting price and non_injecting description and (authorize @session_id) != -1 then
- @db.execute_batch "INSERT INTO Items (Menu, Name, Price, Description) VALUES(#{menu}, \"#{name}\", #{price}, \"#{description}\")"
- end
- return false
- end
- def read_item()
- if (authorize @session_id) != -1
- items = []
- @db.execute "SELECT RowID, Menu, Name, Price, Description FROM Items" do |item|
- id, menu, name, price, description = item[0], item[1], item[2], item[3], item[4]
- items << { :id => id, :menu => menu, :name => name, :price => price, :description => description }
- end
- return items
- end
- return false
- end
- def update_item(id, menu, name, price, description)
- if non_injecting id and non_injecting menu and non_injecting name and non_injecting price and non_injecting description and (authorize @session_id) != -1 then
- @db.execute_batch "UPDATE Items SET Menu = #{menu}, Name = \"#{name}\", Price = #{price}, Description = \"#{description}\" WHERE RowID = #{id}"
- end
- return false
- end
- def delete_item(id)
- if non_injecting id and (authorize @session_id) != -1 then
- @db.execute_batch "DELETE FROM Items WHERE RowID = #{id}"
- end
- return false
- end
- end
- module User
- def create_user(name, password, admin, salary)
- if non_injecting name and non_injecting password and non_injecting salary and admin? @session_id then
- @db.execute_batch "INSERT INTO Users (Name, Password, Admin, Salary) VALUES(\"#{name}\", \"#{password}\", #{admin}, #{salary})"
- end
- return false
- end
- def read_user()
- users = []
- @db.execute "SELECT RowID, Name, Password, Admin, Salary FROM Users" do |user|
- id, name, password, admin, salary = user[0], user[1], user[2], user[3], user[4]
- users << {:id => id, :name => name, :password => password, :admin => admin, :salary => salary}
- end
- if not admin?(@session_id) then
- user_id = authorize(@session_id)
- users.select! { |u| u[:id] == user_id }
- end
- return users
- end
- def update_user(id, name, password, admin, salary)
- if non_injecting name and non_injecting password and non_injecting salary and (authorize @session_id) != -1 then
- if admin? @session_id then
- @db.execute_batch "UPDATE Users SET " +
- "Name = \"#{name}\", Password = \"#{password}\", " +
- "Admin = #{admin}, Salary = #{salary} WHERE RowID = #{id}"
- else
- if (authorize @session_id) == id then
- @db.execute_batch "UPDATE Users SET " +
- "Name = \"#{name}\", Password = \"#{password}\" WHERE RowID = #{id}"
- else
- return false
- end
- end
- end
- return false
- end
- def delete_user(id)
- if authorize(@session_id) != id and admin? (@session_id) then
- @db.execute_batch "DELETE FROM Users WHERE RowID = #{id}"
- return true
- end
- return false
- end
- end
- module Access
- def create_session()
- random = Random.new
- session_id = random.rand(1000000000)
- @db.execute_batch "INSERT INTO Sessions (SessionID, UserID) VALUES(#{session_id}, -1)"
- return session_id
- end
- def authenticate(name, password)
- if non_injecting name and non_injecting password then
- session_id = create_session()
- user = nil
- @db.execute "SELECT RowID FROM Users WHERE Name = \"#{name}\" AND Password = \"#{password}\"" do |u|
- user_id = u[0]
- escalate(user_id, session_id)
- return session_id
- end
- return -1
- end
- return false
- end
- def escalate(user_id, session_id)
- @db.execute_batch "UPDATE Sessions SET UserID = #{user_id} WHERE SessionID = #{session_id}"
- end
- def admin?(session_id)
- user_id = authorize(session_id)
- @db.execute "SELECT Admin FROM Users WHERE RowID = #{user_id}" do |user|
- admin = user[0]
- return admin == 1
- end
- return false
- end
- def authorize(session_id)
- @db.execute "SELECT UserID FROM Sessions WHERE SessionID = #{session_id}" do |session|
- user_id = session[0]
- return user_id
- end
- return -1
- end
- def delete_session(session_id)
- @db.execute_batch "DELETE FROM Sessions WHERE SessionID = #{session_id}"
- end
- def guard(page)
- if page == :dashboard and admin? @session_id then
- return true
- end
- if page == :menu and ((admin? @session_id) or ((authorize @session_id) != -1)) then
- return true
- end
- if page == :users and ((admin? @session_id) or ((authorize @session_id) != -1)) then
- return true
- end
- return false
- end
- end
- module Terminal
- def shell(command)
- # Commands that = bad: deleting data.db, main.rb, controller.rb, or going out of p. dir./content
- if admin? @session_id then
- # navigate to the correct shell directory
- Dir.chdir @shell_pwd
- # if command is `cd` then navigate to and save the shell's new pwd
- if command =~ /cd\W+((?:[^\/]*\/)*.*)/ then
- if not $1 == "" then
- # If in p7, can't go up - otherwise can go up.
- if @shell_pwd == @controller_pwd and (Dir.glob @shell_pwd).include? $1 then
- Dir.chdir $1
- else
- end
- return false
- else
- Dir.chdir command[3..-1]
- end
- @shell_pwd = Dir.pwd # update the shell directory
- Dir.chdir @controller_pwd # return to the controller's home directory
- return ""
- # otherwise execute the command
- else
- output = `#{command}`
- Dir.chdir @controller_pwd # return to the controller's home directory
- return output
- end
- end
- return false
- end
- end
- #
- # NOTICE: You DO NOT need to modify anything below this point.
- # Modifications below this point may cause you to FAIL
- # our tests.
- #
- module Util
- def collate_menus()
- menus = []
- result = { :menus => menus }
- id_to_name = {}
- read_menu.each do |menu|
- id, name = menu[:id], menu[:name]
- id_to_name[id] = name
- menus << { :name => name, :items => [] }
- end
- read_item.each do |item|
- menu, name, price, description = item[:menu], item[:name], item[:price], item[:description]
- (menus.find { |m| m[:name] == id_to_name[menu] })[:items] << { :name => name, :price => price, :description => description }
- end
- return result
- end
- end
- class Controller
- include Menu
- include Item
- include User
- include Access
- include Terminal
- include Util
- attr_accessor :session_id, :shell_pwd
- attr_reader :db, :controller_pwd
- def initialize()
- @db = SQLite3::Database.new "data.db"
- @shell_pwd = Dir.pwd
- @controller_pwd = Dir.pwd
- @session_id = -1
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement