require 'navbar' require 'post_menu' require 'url_generator' require 'digest/sha1' # The filters added to this controller will be run for all controllers in the application. # Likewise will all the methods added be available for all controllers. class ApplicationController < ActionController::Base # Hub single sign-on support. require 'hub_sso_lib' include HubSsoLib::Core before_filter :hubssolib_beforehand after_filter :hubssolib_afterwards # Standard RForum gubbins follows. model :forum, :post, :topic, :user helper :application session :session_expires => Time.now + 1.years include RForum::Localization layout 'default' before_filter :check_block, :setup_user, :setup_url_generator, :setup_local, \ :setup_skin before_filter :detect_site if RForum::CONFIG[:use_sites] before_filter :get_forums after_filter :finish_user, :remember_location # Default index action: redirect to start page def index redirect_to :controller => 'forum', :action => 'list' end protected def rescue_action(e) if e.is_a?(RForum::SecurityError) redirect_to :controller => 'security', :action => 'access_denied' else super end end # Check if the client IP is blocked def check_block if BlockedIp.blocked?(@request.remote_ip) # don't waste any time on template rendering render_text 'blocked', 403 return false end end # Get a unique name from the Hub user, in abstracted form. # While it must be unique, its content is irrelevant in the # Hub integrated RForum as it doesn't get displayed to any # normal user. # def get_hub_user_name Digest::SHA1.hexdigest("#{hubssolib_get_user_address} (#{hubssolib_get_user_id})") end # Map a Hub user's parameters to an RForum User model's # parameters. Returns a hash appropriate for updating an # existing model or to create a brand new RForum User. # def map_hub_user_to_forum_user return { :name => get_hub_user_name, # Must be unique and <= 60 characters; SHA1 digest keeps it to 40 :firstname => hubssolib_unique_name, :email => hubssolib_get_user_address, :surname => '' } end def hub_user_is_rforum_admin? hubssolib_get_user_roles.include?('admin,webmaster') ? true : false end # Filter method that sets up the current user parameters # by mapping in the currently logged in Hub user to a new # or updated RForum user. # def setup_user @user = nil if (hubssolib_logged_in?) @user = User.find_by_name(get_hub_user_name) # This for now is the quick and dirty code. We either create # a new user on a default map of parameters from Hub to # RForum user, or we update the Hub parts - on each and every # action in RForum. This is, obviously, very slow. if (@user) @user.update_attributes(map_hub_user_to_forum_user) else # There is no user with the same unique ID, but there may be # a user with the same e-mail address - somebody might have # deleted and recreated their account, or a person may have # given up an e-mail address but it could have been claimed # by an entirely new user. In any event, a new ID with the # same e-mail address implies the old address is stale; Hub # insists on unique addreses. We don't want to delete that # user because their user name is associated with posts, so # instead, clear its email address. @other_user = User.find_by_email(hubssolib_get_user_address) if @other_user @other_user.email = '' @other_user.save! end # Now create the shiny new account and save it. @user = User.new(map_hub_user_to_forum_user) @user.save! end # The role column requires special attention admin = hub_user_is_rforum_admin? if (admin != @user.admin?) @user.role = admin ? 'Admin' : 'User' @user.save! # Although we think we just modified this user, the model is # part of a class hierarchy for administration or normal user # profiles. Reloading the model makes sure we get an Admin or # User underneath; without that, we'll have a role string that # may be updated, but the class type will be unchanged for the # remainder of this action (but would update on the next one, # since the model gets reloaded each time). @user = User.find_by_name(get_hub_user_name) end else @user = Guest.new(@session[:guest_name], @session[:guest_email]) if @user.nil? end raise RForum::SecurityError if @user.nil? # if @params['user_id'] and @params['key'] # @user = User.find_by_token(@params['user_id'], @params['key']) # @authenticated_by_token = true # # set the token to expire in no more than next 10 minutes # if @user # @user.token_expiry = [@user.token_expiry, Time.at(Time.now.to_i + 600 * 1000)].min # @user.save # end # elsif @session[:user_id] # @user = User.find(@session[:user_id]) # else # @user = Guest.new(@session[:guest_name], @session[:guest_email]) if @user.nil? # end # # raise RForum::SecurityError if @user.nil? # # rescue => e # reset_session # if retried? # raise e # else # retried = true # retry # end end def setup_url_generator UrlGenerator.controller = self end def finish_user @session[:user_id] = @user.id @session[:guest_name] = @user.guest_name @session[:guest_email] = @user.guest_email end @@REMEMBER_NOT = ['user', 'security', 'feed'] def remember_location if @response.headers['Status'] == '200 OK' @session[:return_to] = url_for unless @@REMEMBER_NOT.include? controller_name end end def return_to_last_remembered begin redirect_to_url(@session[:return_to] || '/') rescue RForum::SecurityError redirect_to_url('/') end end def setup_local @headers["Content-Type"] = "text/html; charset=#{RForum::CONFIG[:web_charset]}" end def setup_skin if @params['set_skin'] @session[:skin] = @params['set_skin'] end @skin = @session[:skin] || RForum::CONFIG[:skin] end def detect_site @site = Site.find(:first, :conditions => ["host = ?", request.host]) if @site self.class.layout @site.layout || 'default' @skin = @session[:skin] || @site.skin || 'default' end end def get_forums if @site @forums = @site.forums.find(:all, :order => 'position') else @forums = Forum.find(:all, :order => 'site_id, position') end end def redirect_if_site_doesnt_match if @site && @forum && @forum.site && (@site != @forum.site) headers["Status"] = "301 Moved Permanently" redirect_to_url 'http://' + @forum.site.host + request.path return true end return false end end module RForum # Security error. Controllers throw these in situations where a user is trying to access a # function that he is not authorized to access. # Normally, RForum does not show URLs that would allow the user to access such features. class SecurityError < StandardError end end