From bcfa571b0328a4b3e94479a31c027621ceb86ad5 Mon Sep 17 00:00:00 2001 From: Luke Shumaker <shumakl@purdue.edu> Date: Fri, 4 Apr 2014 20:35:16 -0400 Subject: Implement the new security mechanism --- app/controllers/alerts_controller.rb | 13 +---- app/controllers/application_controller.rb | 45 +++++++++++++++ app/controllers/games_controller.rb | 2 - app/controllers/matches_controller.rb | 54 +---------------- app/controllers/pms_controller.rb | 2 - app/controllers/servers_controller.rb | 2 - app/controllers/sessions_controller.rb | 8 ++- app/controllers/teams_controller.rb | 5 +- app/controllers/tournaments_controller.rb | 96 ++++++++++++++----------------- app/controllers/users_controller.rb | 21 +------ 10 files changed, 106 insertions(+), 142 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/alerts_controller.rb b/app/controllers/alerts_controller.rb index d2b1558..333022a 100644 --- a/app/controllers/alerts_controller.rb +++ b/app/controllers/alerts_controller.rb @@ -1,7 +1,4 @@ class AlertsController < ApplicationController - before_action :set_alert, only: [:show, :edit, :update, :destroy] - before_action :check_perms, only: [:new, :create, :edit, :update, :destroy] - # GET /alerts # GET /alerts.json def index @@ -63,18 +60,14 @@ class AlertsController < ApplicationController end private + # Use callbacks to share common setup or constraints between actions. def set_alert @alert = Alert.find(params[:id]) end - def check_perms - unless (signed_in? and (current_user.in_group?(:admin) or current_user.in_group?(:host))) - respond_to do |format| - format.html { render action: 'permission_denied', status: :forbidden } - format.json { render json: "Permission denied", status: :forbidden } - end - end + def is_owner?(object) + object.author == current_user end # Never trust parameters from the scary internet, only allow the white list through. diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0ac3486..85fc5b0 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,8 +1,53 @@ class ApplicationController < ActionController::Base + before_action :set_object, only: [:show] + before_action :check_create, only: [:new, :create] + before_action :check_edit, only: [:edit, :update] + before_action :check_delete, only: [:destroy] + # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception #include sessionhelper for the session controller and view include SessionsHelper + + def check_permission(verb, object=nil) + unless current_user.can?((verb.to_s+"_"+noun).to_sym) or (!object.nil? and is_owner?(object)) + respond_to do |format| + format.html do + if object.nil? + redirect_to send(noun.pluralize+"_url"), notice: "You don't have permission to #{verb} #{noun.pluralize}." + else + redirect_to object, notice: "You don't have permission to #{verb} this #{noun}." + end + end + format.json { render json: "Permission denied", status: :forbidden } + end + end + end + + def noun + @noun ||= self.class.name.underscore.sub(/_controller$/, '').singularize + end + + def set_object + object = send("set_"+noun) + end + + def check_create + check_permission(:create) + end + def check_edit + object = send("set_"+noun) + check_permission(:edit, object) + end + def check_delete + object = send("set_"+noun) + check_permission(:edit, object) + end + + # Override this + def is_owner?(object) + return false + end end diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb index e9620b4..f18a5ad 100644 --- a/app/controllers/games_controller.rb +++ b/app/controllers/games_controller.rb @@ -1,6 +1,4 @@ class GamesController < ApplicationController - before_action :set_game, only: [:show, :edit, :update, :destroy] - # GET /games # GET /games.json def index diff --git a/app/controllers/matches_controller.rb b/app/controllers/matches_controller.rb index ba6ab16..474ae04 100644 --- a/app/controllers/matches_controller.rb +++ b/app/controllers/matches_controller.rb @@ -1,6 +1,6 @@ class MatchesController < ApplicationController - before_action :set_tournament, only: [:index, :new, :create] - before_action :set_match, only: [:show, :edit, :update, :destroy] + before_action :set_tournament, only: [:index] + # GET /matches # GET /matches.json def index @@ -12,58 +12,10 @@ class MatchesController < ApplicationController def show end - # GET /matches/new - def new - end - - # GET /matches/1/edit - def edit - end - - # POST /matches - # POST /matches.json - def create - @match = @tournament.matches.build(match_params) - - respond_to do |format| - if @match.save - format.html { redirect_to tournament_matches_path, notice: 'Match was successfully created.' } - format.json { render action: 'show', status: :created, location: @match } - else - format.html { render action: 'new' } - format.json { render json: @match.errors, status: :unprocessable_entity } - end - end - end - - # PATCH/PUT /matches/1 - # PATCH/PUT /matches/1.json - def update - respond_to do |format| - if @match.update(match_params) - format.html { redirect_to [@tournament, @match], notice: 'Match was successfully updated.' } - format.json { head :no_content } - else - format.html { render action: 'edit' } - format.json { render json: @match.errors, status: :unprocessable_entity } - end - end - end - - # DELETE /matches/1 - # DELETE /matches/1.json - def destroy - @match.destroy - respond_to do |format| - format.html { redirect_to tournament_matches_path } - format.json { head :no_content } - end - end - private # Use callbacks to share common setup or constraints between actions. def set_match - @tournament = Tournament.find(params[:tournament_id]) + set_tournament @match = @tournament.matches.find(params[:id]); end def set_tournament diff --git a/app/controllers/pms_controller.rb b/app/controllers/pms_controller.rb index b62a6ef..af112d1 100644 --- a/app/controllers/pms_controller.rb +++ b/app/controllers/pms_controller.rb @@ -1,6 +1,4 @@ class PmsController < ApplicationController - before_action :set_pm, only: [:show, :edit, :update, :destroy] - # GET /pms # GET /pms.json def index diff --git a/app/controllers/servers_controller.rb b/app/controllers/servers_controller.rb index f23f2bf..3f11075 100644 --- a/app/controllers/servers_controller.rb +++ b/app/controllers/servers_controller.rb @@ -1,6 +1,4 @@ class ServersController < ApplicationController - before_action :set_server, only: [:show, :edit, :update, :destroy] - before_action :check_perms # GET /servers # GET /servers.json diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 1bae258..a0390ad 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,5 +1,4 @@ class SessionsController < ApplicationController - before_action :set_session, only: [:destroy] # GET /sessions/new def new @@ -41,11 +40,16 @@ class SessionsController < ApplicationController private # Use callbacks to share common setup or constraints between actions. def set_session - #@session = Session.find(cookies[:remember_token]) + @token = Session.hash_token(cookies[:remember_token]) + @session = Session.find_by(token: @token) end # Never trust parameters from the scary internet, only allow the white list through. def session_params params.require(:session).permit(:session_email, :session_user_name, :session_password) end + + def is_owner?(object) + object.user == current_user + end end diff --git a/app/controllers/teams_controller.rb b/app/controllers/teams_controller.rb index 05e7a12..57ae256 100644 --- a/app/controllers/teams_controller.rb +++ b/app/controllers/teams_controller.rb @@ -1,5 +1,4 @@ class TeamsController < ApplicationController - before_action :set_team, only: [:show, :edit, :update, :destroy] # GET /teams # GET /teams.json @@ -71,4 +70,8 @@ class TeamsController < ApplicationController def team_params params.require(:team).permit(:match_id) end + + def is_owner?(object) + object.users.include?(current_user) + end end diff --git a/app/controllers/tournaments_controller.rb b/app/controllers/tournaments_controller.rb index 9cf3404..2d63068 100644 --- a/app/controllers/tournaments_controller.rb +++ b/app/controllers/tournaments_controller.rb @@ -1,6 +1,4 @@ class TournamentsController < ApplicationController - before_action :set_tournament, only: [:show, :edit, :update, :destroy, :join] - before_action :check_perms, only: [:new, :create, :edit, :destroy] # GET /tournaments # GET /tournaments.json @@ -36,12 +34,7 @@ class TournamentsController < ApplicationController # GET /tournaments/1/edit def edit - if params['close_action'] == 'close' - @tournament.status = 1 - @tournament.save - @tournament.setup(@tournament) - redirect_to "/tournaments" - end + check_permission(:edit, @tournament) end # POST /tournaments @@ -64,9 +57,9 @@ class TournamentsController < ApplicationController # PATCH/PUT /tournaments/1 # PATCH/PUT /tournaments/1.json def update - - if params[:update_action].nil? - check_perms + case params[:update_action] + when nil + check_permission(:edit, @tournament) respond_to do |format| if @tournament.update(tournament_params) format.html { redirect_to @tournament, notice: 'Tournament was successfully updated.' } @@ -76,42 +69,40 @@ class TournamentsController < ApplicationController format.json { render json: @tournament.errors, status: :unprocessable_entity } end end - else - case params[:update_action] - when "join" - respond_to do |format| - if @tournament.join(current_user) - format.html { render action: 'show', notice: 'You have joined this tournament.' } - format.json { head :no_content } - end - format.html { render action: 'permission_denied', status: :forbidden } - format.json { render json: "Permission denied", status: :forbidden } + + when "join" + check_permission(:join) + respond_to do |format| + if @tournament.join(current_user) + format.html { render action: 'show', notice: 'You have joined this tournament.' } + format.json { head :no_content } end - when "leave" - respond_to do |format| - if @tournament.leave(current_user) - format.html {redirect_to tournaments_url, notice: 'You have left the tournament.' } - format.json { head :no_content } - end - format.html {redirect_to @tournament, notice: 'You were\'t a part of this tournament.' } - format.json { render json: "Permission denied", status: :forbidden } - end - when "open" - respond_to do |format| - if @tournament.setup - format.html { render action: 'show', notice: 'You have joined this tournament.' } - format.json { head :no_content } - end - format.html { render action: 'permission_denied', status: :forbidden } - format.json { render json: "Permission denied", status: :forbidden } + format.html { render action: 'permission_denied', status: :forbidden } + format.json { render json: "Permission denied", status: :forbidden } + end + when "leave" + respond_to do |format| + if @tournament.leave(current_user) + format.html {redirect_to tournaments_url, notice: 'You have left the tournament.' } + format.json { head :no_content } end - #when "close" - # TODO - else - respond_to do |format| - format.html { render action: 'show', notice: "Invalid action", status: :unprocessable_entity } - format.json { render json: @tournament.errors, status: :unprocessable_entity } + format.html {redirect_to @tournament, notice: 'You were\'t a part of this tournament.' } + format.json { render json: "Permission denied", status: :forbidden } + end + when "open" + check_permission(:edit, @tournament) + respond_to do |format| + if @tournament.setup + format.html { render action: 'show', notice: 'You have joined this tournament.' } + format.json { head :no_content } end + format.html { render action: 'permission_denied', status: :forbidden } + format.json { render json: "Permission denied", status: :forbidden } + end + else + respond_to do |format| + format.html { render action: 'show', notice: "Invalid action", status: :unprocessable_entity } + format.json { render json: @tournament.errors, status: :unprocessable_entity } end end end @@ -132,17 +123,16 @@ class TournamentsController < ApplicationController @tournament = Tournament.find(params[:id]) end - def check_perms - unless (signed_in? and current_user.in_group?(:host)) - respond_to do |format| - format.html { render action: 'permission_denied', status: :forbidden } - format.json { render json: "Permission denied", status: :forbidden } - end - end - end - # Never trust parameters from the scary internet, only allow the white list through. def tournament_params params.require(:tournament).permit(:game, :name, :game_id, :status, :min_players_per_team, :max_players_per_team, :min_teams_per_match, :max_teams_per_match, :set_rounds, :randomized_teams) end + + def is_owner?(object) + object.hosts.include?(current_user) + end + + # Turn of check_edit, since our #update is flexible + def check_edit + end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 60857f1..82edae7 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,7 +1,4 @@ class UsersController < ApplicationController - before_action :set_user, only: [:show, :edit, :update, :destroy] - before_action :perms_edit, only: [:edit, :update, :destroy] - before_action :perms_create, only: [:new, :create] # GET /users # GET /users.json @@ -69,22 +66,8 @@ class UsersController < ApplicationController @user = User.find(params[:id]) end - def perms_edit - unless (current_user == @user) or (signed_in? and current_user.in_group? :admin) - respond_to do |format| - format.html { render action: 'permission_denied', status: :forbidden } - format.json { render json: "Permission denied", status: :forbidden } - end - end - end - - def perms_create - if signed_in? - respond_to do |format| - format.html { render action: 'already_signed_in', status: :unprocessable_entity } - format.json { render json: "Already signed in", status: :unprocessable_entity } - end - end + def is_owner?(object) + object == current_user end # Never trust parameters from the scary internet, only allow the white list through. -- cgit v1.2.3-2-g168b