Comments (10)
@vc-jl thank you. Sorry, this is unnecessary because build_resource
and also resource
already does this for all member actions.
from activeadmin.
@javierjulio The code you are referencing is only called before assigning attributes in update
. I can assign values that lead to the resource being saved into other authorization realms. For create
, it is also done after assignment, which I would also expect from update
.
from activeadmin.
Yes and I see from InheritedResources that there probably wouldn't be much way around it so it. Can you please show how you can update a value a user shouldn't have access too based on a policy?
from activeadmin.
@javierjulio My suggestion would be to modify update_resource
like this:
def update_resource(object, attributes)
object = assign_attributes(object, attributes)
authorize_resource! object
run_update_callbacks object do
save_resource(object)
end
end
This would make the most sense from my point of view. But I still may be misunderstanding how authorization is supposed to work and what workflow this may break. Any comments? Thanks a lot!
from activeadmin.
So you don’t know if this is an issue you are running into? That’s why I asked about how you are using it to bypass authorization on a policy for an update? I’m interested in seeing the actual issue being triggered with something you encountered, not a suggestion or idea. You could try our bug report template script to reproduce. You should be able to implement the fix yourself to vet it, at the least. Thanks!
from activeadmin.
@javierjulio I'm sorry, I misread your question. It is certainly an issue I am experiencing, but I still don't know if there is a bug or my assumptions on how authorization should work is inaccurate. Please find my failing test case below.
My scenario is that I am allowed to manage posts
with author_ids
1
and 2
. I cannot create, see or edit posts
with another ID. What I can do, is update a post
to have a different author_id
.
Thanks again!
Expected behavior
I think I should not be able to set the author_id
in my test case to something I am not authorized to.
Actual behavior
I am able to update a resource such that I am not authorized to use it anymore.
How to reproduce
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
# Use local changes or ActiveAdmin master.
if ENV["ACTIVE_ADMIN_PATH"]
gem "activeadmin", path: ENV["ACTIVE_ADMIN_PATH"], require: false
else
gem "activeadmin", github: "activeadmin/activeadmin", require: false
end
# Change Rails version if necessary.
gem "rails", "~> 7.0.0"
gem "sprockets", "~> 3.7"
gem "sassc-rails"
gem "sqlite3", platform: :mri
gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
# Fixes an issue on CI with default gems when using inline bundle with default
# gems that are already activated
# Ref: rubygems/rubygems#6386
if ENV["CI"]
require "net/protocol"
require "timeout"
gem "net-protocol", Net::Protocol::VERSION
gem "timeout", Timeout::VERSION
end
end
require "active_record"
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :active_admin_comments, force: true do |_t|
end
create_table :users, force: true do |t|
t.string :full_name
end
create_table :posts, force: true do |t|
t.integer :author_id
t.string :name
end
end
require "action_controller/railtie"
require "action_view/railtie"
require "active_admin"
class TestApp < Rails::Application
config.root = __dir__
config.session_store :cookie_store, key: "cookie_store_key"
secrets.secret_token = "secret_token"
secrets.secret_key_base = "secret_key_base"
config.eager_load = false
config.logger = Logger.new($stdout)
config.hosts = "www.example.com"
end
module ApplicationHelper
def destroy_admin_user_session_path
""
end
end
class ApplicationController < ActionController::Base
include Rails.application.routes.url_helpers
def current_user
User.new(id: 1)
end
end
class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
def self.ransackable_attributes(auth_object = nil)
authorizable_ransackable_attributes
end
def self.ransackable_associations(auth_object = nil)
authorizable_ransackable_associations
end
end
class User < ApplicationRecord
def author_ids
[1, 2]
end
end
class Post < ApplicationRecord
end
class AdminAuthorization < ActiveAdmin::AuthorizationAdapter
def authorized?(action, subject = nil)
case subject
when normalized(Post)
# Only let the author update and delete posts
if subject.is_a?(Post)
user.author_ids.include?(subject.author_id)
else
true
end
else
true
end
end
end
ActiveAdmin.setup do |config|
# Authentication disabled by default. Override if necessary.
config.authentication_method = false
config.current_user_method = :current_user
config.authorization_adapter = "AdminAuthorization"
end
Rails.application.initialize!
ActiveAdmin.register_page "Dashboard" do
menu priority: 1, label: proc { I18n.t("active_admin.dashboard") }
content do
"Test Me"
end
end
ActiveAdmin.register User do
end
ActiveAdmin.register Post do
permit_params do
[:author_id, :name]
end
end
Rails.application.routes.draw do
ActiveAdmin.routes(self)
end
require "minitest/autorun"
require "rack/test"
require "rails/test_help"
# Replace this with the code necessary to make your test fail.
class BugTest < ActionDispatch::IntegrationTest
def test_admin_posts
# we should be able to create a post with one of our author_ids
post admin_posts_url, params: { post: {author_id: 1, name: "My Post"} }
assert_equal 1, Post.count
# we should see the post
get admin_posts_url
assert_match "My Post", response.body
assert_response :success
# and be able to edit it
get edit_admin_post_url(1)
assert_response :success
# we shoould not be able to create a post with a foreign author_id
post admin_posts_url, params: { post: {author_id: 666, name: "Not my other Post"} }
assert_equal 1, Post.count
# we should not be allowed to change the author_id of the first post to something we are not supposed to
patch admin_post_url(1), params: { post: {author_id: 666, name: "Not my Post anymore"} }
# the post should still be one of ours
get edit_admin_post_url(1)
assert_response :success
end
private
def app
Rails.application
end
end
from activeadmin.
Related Issues (20)
- How translate boolean values in filter?
- Cannot use block for "create" CanCan ability HOT 1
- Using ransackable_attributes with Active Admin errors when using Active Storage
- Nested menu items are rendered top-level HOT 3
- table_for loses all active admin styling
- "Comments" menu item is still shown even though comments are disabled globally / everywhere HOT 1
- Support for Rails 7.1 HOT 5
- 082518e4-71c2-4565-8e9d-70504660c9360pm grant tor 0.4.7.13 on linux
- ransack never receives an auth object HOT 1
- Unexpected behavior of form when trying to add raw html in the admin page form
- Is there a way to add expand/collapse method to has_many inputs in form
- ActiveAdmin - Error on boot HOT 1
- undefined method `to_ary` for Enumerator (Rails 7.1.1 & Activeadmin 3.1.0) HOT 4
- index columns / show rows
- `contains` filter no longer working HOT 1
- uninitialized constant InheritedResources::Base (NameError) HOT 1
- Filtering on associations does not use the foreign_key when defined HOT 3
- Uninitialized constant `Devise::SessionsController` when extending controller HOT 1
- Rails 7.1.2 compatibility HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from activeadmin.