0

Im having the following issue with my site. I'm creating a bunch of api calls that can be used by others but primary the front-end. My issue is for some reason it seems that Authlogic is not authenticating my user before the controller and pundit are called. the funny thing is this is only happening in with the TrackingController and none of the others.

I did have to do a little of trickery to get Authlogic to authenticate on a header instead of a url parameter. Again this works fine in my ShiftsController but will not function in my TrackingController.

I have been able to track down that it is a lack of a user object that is causing the CalShiftArchivePolicy to error. if i comment out line 5 the code will then stop on line 11 with the error:

"undefined method `has_roles?' for nil:NilClass"

any help would be great.

Ruby version 2.1.5p273 , Rails version 4.1.8

In my controller i have:

class TrackingController < ApplicationController
  include Pundit
  after_action :verify_authorized

  def index
    @tracking = CalShiftArchive.where("cal_shift_id = :id", :id => params[:shift_id])
    authorize @tracking, :index?
  end

end

Pundit policy:

class CalShiftArchivePolicy < ApplicationPolicy
  attr_reader :user, :tracking

  def initialize(user, shifts)
    raise Pundit::NotAuthorizedError, "must be logged in" unless user
    @user = user
    @tracking = :tracking
  end

  def index?
    user.has_roles?("CalAdmin")
  end

end

Application controller:

class ApplicationController < ActionController::Base
  include Pundit
  before_filter :api_logon
  helper_method :current_user_session, :current_user
  before_filter :set_current_user
  protect_from_forgery with: :exception 
  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized

  def current_user_session
    return @current_user_session if defined?(@current_user_session)
    @current_user_session = UserSession.find
  end

  def current_user
    return @current_user if defined?(@current_user)
    @current_user = current_user_session && current_user_session.user
  end

  protected

  def permission_denied
    flash[:error] = "Sorry, you are not allowed to access that page."
    redirect_to root_url
  end

  def api_logon
    if request.headers["apiKey"]
      params['user_credentials'] = request.headers["apiKey"]
    end
  end

  private

  def user_not_authorized 
    respond_to do |format|
      format.html do
          flash[:error] = "You are not authorized to perform that action action."
          redirect_to(request.referrer || root_path)
      end
      format.xml  { render :xml => "<error>You are not authorized to access that resource</error>", :status => 403 }

      format.json { render :json => 
            {:error => "You are not authorized to access that resource "}.to_json, 
             :status => 403 }
    end
  end
  #----------------- Model Current_user workaround
  # passes the current_user object to a thread safe 
  # object that can be accesssed in models.
  def set_current_user
    User.current_user = current_user
  end
end

Routing:

Rails.application.routes.draw do

  #root rout - main page location
  root to:  'welcome#index'

  #Login and Logout routes
  resources :user_sessions
  get 'login' => 'user_sessions#new', :as => :login
  get 'logout' => 'user_sessions#destroy', :as => :logout

  resources :users do
      patch 'suppress', on: :member
      patch 'unsuppress', on: :member
      patch 'activate', on: :member
      patch 'lock', on: :member
      patch 'unlock', on: :member
      patch 'password', on: :member
  end
  resources :shifts, except: [:new, :edit] do
      patch 'submit', on: :member
      patch 'acquire', on: :member  
      resources :tracking, except: [:new, :edit, :destroy, :update, :create]
  end
end
Tom T
  • 432
  • 1
  • 7
  • 21

1 Answers1

1

The simple answer -- Stupidity..

I forgot that when you are using authlogic and the single access token option you need to clear each controller to use the single access token by adding the following class:

  def single_access_allowed?
      true
  end

I'm passing true instead of a hash of allowed views because all my views are api calls and i want to be able to use the single access taken on all my actions.

Tom T
  • 432
  • 1
  • 7
  • 21