Project

General

Profile

Actions

Bug #18662

closed

Ensure Taxonomix empty default scope isn't overridden by association scopes

Added by Dominic Cleal over 7 years ago. Updated over 6 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Rails
Target version:
Difficulty:
Triaged:
Fixed in Releases:
Found in Releases:

Description

Since #16982, the following test fails on Rails 5:

HostsControllerTest#test_0009_should create new host with hostgroup inherited fields [/home/travis/build/domcleal/foreman/test/controllers/hosts_controller_test.rb:114]:
--- expected
++ actual
@ -1 +1 @
-nil
#<Environment id: 334344675, name: "production", created_at: "2017-02-23 13:29:27", updated_at: "2017-02-23 13:29:27">

(Note that actual/expected are the wrong way around.)

When a Taxonomix resource (e.g. Environment) has a default scope that is empty, i.e. the user has access to no resources, returning the scope where(:id => []) under Rails 5 causes an issue with associations.

An association accessor merges rather than appending a scope to the default scope, so host#environment essentially merges a where(:id => environment_id) scope to the default. On Rails 4.2, this doesn't merge correctly and so effectively ANDs the two where(:id..) clauses, so no record is found.

irb(main):001:0> Hostgroup.unscoped.first.environment
2017-02-24T10:13:41 [sql] [D] Hostgroup Load (0.6ms) SELECT "hostgroups".* FROM "hostgroups" ORDER BY "hostgroups"."id" ASC LIMIT 1
2017-02-24T10:13:41 [sql] [D] (0.1ms) SELECT "environments"."id" FROM "environments"
2017-02-24T10:13:41 [sql] [D] (0.4ms) SELECT "environments"."id" FROM "environments"
2017-02-24T10:13:41 [sql] [D] Environment Load (0.5ms) SELECT "environments".* FROM "environments" WHERE 1=0 AND "environments"."id" = ? ORDER BY environments.name LIMIT 1 [["id", 1]]
=> nil
irb(main):002:0> Hostgroup.unscoped.first.environment_id
2017-02-24T10:13:45 [sql] [D] Hostgroup Load (0.5ms) SELECT "hostgroups".* FROM "hostgroups" ORDER BY "hostgroups"."id" ASC LIMIT 1
=> 1

On Rails 5.0, this merges fully and so returns a simple where(:id => environment_id) scope. This overrides the default scope, so host#environment now returns the environment even if the default scope doesn't permit access to it.

irb(main):001:0> Hostgroup.unscoped.first.environment
2017-02-24T10:13:05 [sql] [D] Hostgroup Load (0.2ms) SELECT "hostgroups".* FROM "hostgroups" ORDER BY "hostgroups"."id" ASC LIMIT ? [["LIMIT", 1]]
2017-02-24T10:13:05 [sql] [D] (0.1ms) SELECT "environments"."id" FROM "environments"
2017-02-24T10:13:05 [sql] [D] (0.1ms) SELECT "environments"."id" FROM "environments"
2017-02-24T10:13:05 [sql] [D] Environment Load (0.3ms) SELECT "environments".* FROM "environments" WHERE "environments"."id" = ? ORDER BY environments.name LIMIT ? [["id", 1], ["LIMIT", 1]]
[..]
1 row in set

Changing the default scope to generate a SQL string ('1=0') ensures the two clauses are combined rather than the default being overridden.

Also worth noting is that on develop, the test is checking that host.environment is nil, because hostgroup.environment now returns nil due to the default scope. It used to test, and should test, that the environment is present.


Related issues 1 (0 open1 closed)

Related to Foreman - Bug #16982: CVE-2016-7078 - User with no organizations or locations can see all resourcesClosedDaniel Lobato Garcia10/18/2016Actions
Actions

Also available in: Atom PDF