everytime I submit a form here (that I scaffolded) localhost:3000/syllabus_requests/new
The rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
from my ApplicationController.rb file gets raised and I'm not sure why because in the policy class I have a create? method and it returns true
i'm using
ruby '2.3.1'
gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
gem 'pundit', '~> 1.1'
I have a policy
class SyllabusRequestPolicy < ApplicationPolicy
attr_reader :current_user, :model
def initialize(current_user, model)
#current_user = current_user || User.new
#model = model #this is the syllabus_request record from the syllabus_requests table as a rails model object
end
def index?
#current_user.role == "admin"
end
def show?
#current_user.role == "admin"
end
def create?
true
end
def edit?
#current_user.role == "admin"
end
def update?
#current_user.role == "admin"
end
def destroy?
#current_user.role == "admin"
end
end
I have a controller
class SyllabusRequestsController < ApplicationController
before_action :set_syllabus_request, only: [:show, :edit, :update, :destroy]
# GET /syllabus_requests
# GET /syllabus_requests.json
def index
#syllabus_requests = SyllabusRequest.all
authorize #syllabus_requests
end
# GET /syllabus_requests/1
# GET /syllabus_requests/1.json
def show
authorize #syllabus_request
end
# GET /syllabus_requests/new
def new
#syllabus_request = SyllabusRequest.new
authorize #syllabus_request
end
# GET /syllabus_requests/1/edit
def edit
authorize #syllabus_request
end
# POST /syllabus_requests
# POST /syllabus_requests.json
def create
#syllabus_request = SyllabusRequest.new(syllabus_request_params)
authorize #syllabus_request
respond_to do |format|
if #syllabus_request.save
format.html { redirect_to #syllabus_request, notice: 'Syllabus request was successfully created.' }
format.json { render :show, status: :created, location: #syllabus_request }
else
format.html { render :new }
format.json { render json: #syllabus_request.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /syllabus_requests/1
# PATCH/PUT /syllabus_requests/1.json
def update
authorize #syllabus_request
respond_to do |format|
if #syllabus_request.update(syllabus_request_params)
format.html { redirect_to #syllabus_request, notice: 'Syllabus request was successfully updated.' }
format.json { render :show, status: :ok, location: #syllabus_request }
else
format.html { render :edit }
format.json { render json: #syllabus_request.errors, status: :unprocessable_entity }
end
end
end
# DELETE /syllabus_requests/1
# DELETE /syllabus_requests/1.json
def destroy
authorize #syllabus_request
#syllabus_request.destroy
respond_to do |format|
format.html { redirect_to syllabus_requests_url, notice: 'Syllabus request was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_syllabus_request
#syllabus_request = SyllabusRequest.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def syllabus_request_params
params.require(:syllabus_request).permit(:full_name, :email)
end
end
my ApplicationPolicy.rb file looks like this
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
#user = user
#record = record
end
def index?
false
end
def show?
scope.where(:id => record.id).exists?
end
def create?
binding.pry # this should not hit if I'm overriding it
false
end
def new?
binding.pry
create?
end
def update?
false
end
def edit?
update?
end
def destroy?
false
end
def scope
Pundit.policy_scope!(user, record.class)
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
#user = user
#scope = scope
end
def resolve
scope
end
end
end
My ApplicationController.rb looks like this
include Pundit
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
devise_parameter_sanitizer.permit(:account_update, keys: [:name])
end
private
def user_not_authorized
# binding.pry
flash[:alert] = "You are not authorized to perform this action."
redirect_to(request.referrer || root_path)
end
end
Did you try to add a new? method in your SyllabusRequestPolicy ?
Related
Im trying to make an app in Rails 4.
I am using Pundit (or trying to).
I have an application policy and an article policy.
Something isn't working. If I set my article policy for show? to be false, I expect not to be able to see the show page for articles. Instead, I can see the show page - I can't figure out what's wrong.
My application policy is:
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
#user = user
#record = record
end
def index?
false
end
def show?
scope.where(:id => record.id).exists?
end
def create?
false
end
def new?
create?
end
def update?
false
end
def edit?
update?
end
def destroy?
false
end
def scope
Pundit.policy_scope!(user, record.class)
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
#user = user
#scope = scope
end
def resolve
scope
end
end
end
My article policy is:
class ArticlePolicy < ApplicationPolicy
def index?
true
end
def show?
false
# user.present?
end
def create?
user.present?
user && user.profile.addresses.exists?(address.id)
end
def update?
user && user.article.exists?(article.id) && user.article.created_at < 15.minutes.ago
# user.present? #&& user == article.user
end
def destroy?
# user.admin?
# user.present?
user && user.article.exists?(article.id)
end
private
def article
record
end
end
Can anyone see what I've done wrong?
Articles controller:
class ArticlesController < ApplicationController
before_action :set_article, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show, :search]
respond_to :html, :json
# GET /articles
# GET /articles.json
def index
query = params[:query].presence || "*"
#articles = Article.search(query)
end
# def index
# if params[:query].present?
# #books = Book.search(params[:query], page: params[:page])
# else
# #books = Book.all.page params[:page]
# end
# end
# GET /articles/1
# GET /articles/1.json
def show
end
# GET /articles/new
def new
#article = Article.new
#article.comments.build
end
# GET /articles/1/edit
def edit
end
# POST /articles
# POST /articles.json
def create
# before_action :authenticate_user!
# authorize #article
#article = Article.new(article_params)
respond_to do |format|
if #article.save
format.html { redirect_to(#article) }
format.json { render :show, status: :created, location: #article }
else
format.html { render :new }
format.json { render json: #article.errors, status: :unprocessable_entity }
end
end
end
def search
if params[:search].present?
#articless = Article.search(params[:search])
else
#articles = Articles.all
end
end
# PATCH/PUT /articles/1
# PATCH/PUT /articles/1.json
def update
# before_action :authenticate_user!
authorize #article
respond_to do |format|
# if #article.update(article_params)
# format.json { render :show, status: :ok, location: #article }
# else
# format.html { render :edit }
# format.json { render json: #article.errors, status: :unprocessable_entity }
# end
# end
if #article.update(article_params)
format.json { render :show, status: :ok, location: #article }
else
format.json { render json: #article.errors, status: :unprocessable_entity }
end
format.html { render :edit }
end
end
# DELETE /articles/1
# DELETE /articles/1.json
def destroy
before_action :authenticate_user!
authorize #article
#article.destroy
respond_to do |format|
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_article
#article = Article.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def article_params
params[:article].permit(:user_id, :body, :title, :image, :tag_list,
comment_attributes: [:opinion])
end
end
I use cancan and devise, I can update delete and show but I can't create profile.
why I can't create new profile ("ActiveModel::ForbiddenAttributesError")
class Ability
include CanCan::Ability
def initialize(user)
if user.is_a?(Admin)
can :manage, :all
elsif user.is_a?(User)
can :read, Profile do |profile|
profile.try(:user) == user
end
can :update, Profile do |profile|
profile.try(:user) == user
end
can :destroy, Profile do |profile|
profile.try(:user) == user
end
can :create, Profile do |profile|
profile.try(:user) == user
else
can :read, :all
end
end
end
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
load_and_authorize_resource
# GET /profiles
# GET /profiles.json
def index
user = User.find(params[:user_id])
#profiles = user.profiles
respond_to do |format|
format.html
format.xml {render :xml => #profiles}
end
end
# GET /profiles/1
# GET /profiles/1.json
def show
user = User.find(params[:user_id])
#profiles = user.profiles.find(params[:id])
respond_to do |format|
format.html
format.xml {render :xml => #profile}
end
end
# GET /profiles/new
def new
user = User.find(params[:user_id])
#profile = user.profiles.build
respond_to do |format|
format.html
format.xml {render :xml => #profile}
end
end
# GET /profiles/1/edit
def edit
user = User.find(params[:user_id])
#profiles = user.profiles.find(params[:id])
end
# POST /profiles
# POST /profiles.json
def create
user = User.find(params[:user_id])
#profile = user.profiles.create(profile_params)
respond_to do |format|
if #profile.save
format.html { redirect_to user_profiles_url, notice: 'Profile was successfully created.' }
format.json { render action: 'show', status: :created, location: #profile }
else
format.html { render action: 'new' }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /profiles/1
# PATCH/PUT /profiles/1.json
def update
user = User.find(params[:user_id])
#profiles = user.profiles.find(params[:id])
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to user_profile_url, notice: 'Profile was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
user = User.find(params[:user_id])
#profiles = user.profiles.find(params[:id])
#profile.destroy
respond_to do |format|
format.html { redirect_to job_hunters_path }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_profile
#profile = Profile.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def profile_params
params.require(:profile).permit(:full_name, :phone_number, :email, :position, :years_of_experiance, :cover_letter, :resume, :reference)
end
end
If you already have load_and_authorize_resource in your controller code, you need to take another step in sanitizing your inputs via a create_params method call in your controller.
Here's a link to a useful resource
Firstly: your CanCan user ability can be re-written as follows:
can :create, :read, :update, :destroy, Profile, user_id: user.id
Secondly: your admin abilities should be written after your normal user abilities, thus overriding them more successfully:
def initialize(user)
# I prefer to alias CRUD actions to keep my ability files more succint
alias_action :create, :read, :update, :destroy, to: :crud
cannot :manage, :all #Failsafe
can :crud, Profile, user_id: user.id
... #additional abilities for user
if user.admin?
can :manage, :all #Override previous failsafe
Lastly: if your Profile class belongs_to a User, you ought to rewrite it as such. Thus, your profile_params would contain a user_id field.
If you were to follow that (correct) paradigm, your ProfilesController's #create action would look something like:
class ProfilesController < ApplicationController
load_and_authorize_resource
def create
#profile = Profile.new(profile_params)
if #profile.save
...
else
...
end
end
private
def profile_params
params.require(:profile).permit(:user_id, ...)
end
end
I'm trying to make a very simple web app using Rails and I'm using the Sorcery gem to authenticate users. I followed the tutorial here on their GitHub page, and I'm getting no where with it.
I have 2 issues which I believe are probably linked.
The first being, when I use this before_filter skip_before_filter :require_login, only: [:index, :new, :create], users can still access the page without logging in.
The other issue is, when a user tries to log in, they aren't redirected, and when I use the built in helper logged_in?, it always returns false. Even though there was no error message when logging in.
I've added the appropriate controllers, let me know if you need to look at anything else.
Thanks.
user_sessions_controller.rb
class UserSessionsController < ApplicationController
skip_before_filter :require_login, :except => [:destroy]
def new
#user = User.new
end
def create
if #user = login(params[:email], params[:password])
redirect_back_or_to(:users, :notice => 'Login successfull.')
else
flash.now[:alert] = 'Login failed'
render action: 'new'
end
end
def destroy
logout
redirect_to(:users, :notice => 'Logged out!')
end
end
users_controller.rb
class UsersController < ApplicationController
skip_before_filter :require_login, only: [:index, :new, :create]
# GET /users
# GET /users.json
def index
#users = User.all
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to :users, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
#def user_params
# params.require(:user).permit(:email, :crypted_password, :salt)
#end
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
end
application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
# protect_from_forgery with: :exception
protect_from_forgery
before_filter :require_login
private
def not_authenticated
redirect_to(login_path, :alert => "Please login first")
end
end
Everyone has access to Users pages due to this line skip_before_filter :require_login, only: [:index, :new, :create]. This literally means "don't check authorization". Just remove this line.
Generally you should skip require_login filter only on public pages and login pages (i.e. UserSessionsController#create etc).
And the second issue: do you have authenticates_with_sorcery! in your User model?
Good afternoon,
I've done a scaffold of a class, here the example: User - At the moment I was executing the test I saw this bug:
Minitest::Assertion: "User.count" didn't change by 1.
Expected: 3
Actual: 2
test/controllers/users_controller_test.rb:20:in `block in <class:UsersControllerTest>'
the refering code of the bug is this one:
test "should create user" do
assert_difference('User.count') do
post :create, user: { name: 'test', password: 'secret', password_confirmation: 'secret' }
end
assert_redirected_to user_path(assigns(:user))
end
So the code above was created by the scaffold, I just change the name reference.
UserController:
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy, :reset_password]
# GET /users
# GET /users.json
def index
#users = super
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: get_action_message }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
#user.update(user_params)
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: get_action_message }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: get_action_message }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:name, :password, :password_confirmation)
end
def search_params
super - ['password_digest']
end
def show_attributes
#show_attributes = super - ['password_digest']
end
end
UserModel
class User < ActiveRecord::Base
nilify_blanks
validates :name, presence: true, uniqueness: true;
has_secure_password
end
For what I was able to understand, the "create" it's not being executed. I've put the breakpoint on the Controller create but its not stoping there..
What am I doing wrong, besides my poor english skills?
Tks for the helping!!
Thks guys,
I found this bug.
I had forgotten to put in the user Session
I have a really strange error, when i submit my form to create a new admin i get this error:
NoMethodError in AdminsController#create
undefined method `admin?' for #<Admin:0x6c7f098>
in line:
if #admin.save
How is this error produced? I mainly used scaffold code and i only deletet the views of the controller! Here is my controller: I thank everybody for help!
class AdminsController < ApplicationController
before_action :set_admin, only: [ :edit, :update, :destroy]
# GET /admins/new
def new
#admin = Admin.new
end
# GET /admins/1/edit
def edit
end
# POST /admins
# POST /admins.json
def create
#admin = Admin.new(admin_params)
respond_to do |format|
if #admin.save
format.html { redirect_to adminpage_index_path, notice: 'Admin was successfully created.' }
else
redirect_to adminpage_index_path
end
end
end
# PATCH/PUT /admins/1
# PATCH/PUT /admins/1.json
def update
respond_to do |format|
if #admin.update(admin_params)
format.html { redirect_to adminpage_index_path , notice: 'Admin was successfully updated.' }
format.json { head :no_content }
else
redirect_to adminpage_index_path
end
end
end
# DELETE /admins/1
# DELETE /admins/1.json
def destroy
#admin.destroy
respond_to do |format|
format.html { redirect_to adminpage_index_path }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_admin
#admin = Admin.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def admin_params
params.require(:admin).permit(:username, :vorname, :nachname, :strasse, :ort, :plz, :telefon, :handy, :email, :password, :password_confirmation)
end
end
From what I can see, your Admin model probably does not inherit from ActiveRecord::Base. Make sure it does. The model should look like this:
class Admin < ActiveRecord::Base
# ...
end
Your admin model has a callback of some kind. i.e. before_save, after_save, after_validations. Something like that that is trying to call admin?
Post admin.rb file and the stack trace of the error and this should be easy to find.