Rate limiting & refactor

master
E. Almqvist 3 years ago
parent 3035a3ea3d
commit ce05aed461
  1. 4
      src/TODO.md
  2. 43
      src/app.rb
  3. 17
      src/const.rb
  4. 9
      src/lib/db_models.rb
  5. 6
      src/routes/auction.rb
  6. 2
      src/views/admin/index.slim
  7. 4
      src/views/auction/index.slim
  8. 1
      src/views/auction/view.slim
  9. 9
      src/views/stylesheets/style.sass

@ -1,6 +1,6 @@
# TODO # TODO
- Post editing & deleting - Ratelimiting
- User reviews - User reviews (+rep / -rep)
- Yardoc 50% - Yardoc 50%
- Film - Film

@ -32,18 +32,7 @@ end
enable :sessions enable :sessions
db_init db_init
before do RATE_LIMITS ||= Hash.new(Hash.new(0))
route_auth_needed = request.path_info.start_with?(*AUTH_ROUTES)
if !is_logged_in && route_auth_needed then
session[:ret] = request.fullpath # TODO: return the user to the previous route
session[:status] = 403
flash[:error] = AUTH_ERRORS[:needed]
redirect "/login"
elsif route_auth_needed && get_current_user.banned?
banned
end
end
not_found do not_found do
serve :"404" serve :"404"
@ -68,6 +57,36 @@ def error(ret=back)
auth_denied "Internal server error.", 500, ret auth_denied "Internal server error.", 500, ret
end end
def ratelimit(delta_time, ret="/")
auth_denied "Doing that a bit too fast... Please try again in #{delta_time} seconds.", 429, ret
end
before do
# Ratelimiting
# check if route contains any of the protected ones
# and if it is a POST request (dont care about GETs)
if request.path_info.start_with?(*RATE_LIMIT_ROUTES_ALL) and request.request_method == "POST" then
RATE_LIMIT_ROUTES.each do |t, cfg|
if request.path_info.start_with?(*cfg[:routes]) then
dt = Time.now.to_i - RATE_LIMITS[t][request.ip]
ratelimit(dt) unless dt > cfg[:time] # send a rate limit response if rate limited
RATE_LIMITS[t][request.ip] = Time.now.to_i
end
end
end
# Authentication check
route_auth_needed = request.path_info.start_with?(*AUTH_ROUTES)
if !is_logged_in && route_auth_needed then
session[:ret] = request.fullpath # TODO: return the user to the previous route
session[:status] = 403
flash[:error] = AUTH_ERRORS[:needed]
redirect "/login"
elsif route_auth_needed && get_current_user.banned?
banned
end
end
# Routes # Routes
get "/style.css" do get "/style.css" do
sass :"stylesheets/style", style: :compressed sass :"stylesheets/style", style: :compressed

@ -78,7 +78,22 @@ TIME_FORMATS = {
s: 1 s: 1
} }
# Routes that needs auth # Routes that needs auth
AUTH_ROUTES = %w[/settings /auction /user /admin] AUTH_ROUTES = %w[/settings /auction /user /admin]
# Rate limits in seconds for each route category
RATE_LIMIT_ROUTES = {
user: {
routes: %w[/user /settings /register /login /logout],
time: 1
},
auction: {
routes: %w[/auctions],
time: 1
}
}
RATE_LIMIT_ROUTES_ALL = [] # precompile all of the protected routes
RATE_LIMIT_ROUTES.each do |t, cfg|
RATE_LIMIT_ROUTES_ALL += cfg[:routes]
end

@ -383,6 +383,15 @@ class Auction < EntityModel
Auction.update data, "id = ?", @id Auction.update data, "id = ?", @id
end end
def delete
FileUtils.rm_rf("./public/auctions/#{@id}") # delete all images
Auction.delete "id = ?", @id # delete the actual post entry
Auction_Category_relation.delete "auction_id = ?", @id
Image.delete "auction_id = ?", @id
Bid.delete "auction_id = ?", @id
end
def poster def poster
User.find_by_id @user_id User.find_by_id @user_id
end end

@ -29,7 +29,6 @@ post "/auctions" do
flash[:error] = AUCTION_ERRORS[:imagecount] flash[:error] = AUCTION_ERRORS[:imagecount]
redirect "/auctions/new" redirect "/auctions/new"
end end
#
# Create the auction # Create the auction
newid, resp = Auction.create user_id, title, description, init_price, delta_time newid, resp = Auction.create user_id, title, description, init_price, delta_time
@ -91,12 +90,9 @@ get "/auctions/:id/delete" do
auth_denied unless auction.user_id == session[:userid] or get_current_user.admin? auth_denied unless auction.user_id == session[:userid] or get_current_user.admin?
# Delete everything related in the db # Delete everything related in the db
Auction.delete "id = ?", id auction.delete
Auction_Category_relation.delete "auction_id = ?", id
Bid.delete "auction_id = ?", id
flash[:success] = "Removed post." flash[:success] = "Removed post."
redirect "/auctions" redirect "/auctions"
else else
raise Sinatra::NotFound raise Sinatra::NotFound

@ -6,8 +6,6 @@ div
a.button href="#users" = "Users" a.button href="#users" = "Users"
li li
a.button href="#roles" = "Roles" a.button href="#roles" = "Roles"
li
a.button href="#auctions" = "Auctions"
li li
a.button href="#categories" = "Categories" a.button href="#categories" = "Categories"

@ -5,7 +5,7 @@
.form-container .form-container
form action="/auctions" method="get" form action="/auctions" method="get"
label Title label Title
input type="search" name="title" placeholder="ex: 'teapot'" input type="search" name="title" placeholder="ex: 'teapot'" value="#{params[:title]}"
label Price range label Price range
.range-container .range-container
@ -25,7 +25,7 @@
option value="#{category.id}" selected=("selected" if params[:categories] and params[:categories].include?(category.id.to_s)) style="color: #{category.color};" = "#{category.name}" option value="#{category.id}" selected=("selected" if params[:categories] and params[:categories].include?(category.id.to_s)) style="color: #{category.color};" = "#{category.name}"
input type="submit" value="Search" input type="submit" value="Search"
a.button href="/auctions" = "Clear Filters" a.button href="/auctions" = "Clear Filters"
article.post-container.card article.post-container.card
h2 Results h2 Results

@ -20,6 +20,7 @@
h2 h2
span span
| #{auction.title} | #{auction.title}
h3
- if auction.user_id == session_user.id or session_user.admin? - if auction.user_id == session_user.id or session_user.admin?
a.inlbutton href="/auctions/#{auction.id}/edit" a.inlbutton href="/auctions/#{auction.id}/edit"
| [Edit] | [Edit]

@ -474,7 +474,7 @@ ul.list-container
display: flex display: flex
flex-direction: row flex-direction: row
justify-content: center justify-content: center
height: inherit height: 90%
max-width: 70rem max-width: 70rem
a.button a.button
@ -482,10 +482,14 @@ ul.list-container
border-radius: $border_radius border-radius: $border_radius
aside.card aside.card
display: flex
//justify-content: center
flex-direction: column
width: 20rem width: 20rem
margin-right: 4rem margin-right: 4rem
margin-top: 4rem
.form-container .form-container
background: $bg_alt_clr
padding: 8px
form form
padding: 0 padding: 0
width: inherit width: inherit
@ -544,7 +548,6 @@ article.post-container
#auctions_new #auctions_new
display: grid display: grid
#auction-view #auction-view
display: grid display: grid
max-width: 70rem max-width: 70rem

Loading…
Cancel
Save