Default-deny access control with group flags and access enumeration
Some checks failed
Some checks failed
Replaces the implicit "empty allowed_groups means public" rule with explicit default-deny across both OIDC and ForwardAuth. Adds two boolean flags on Group — auto_assign (Keycloak-style auto-join on user create) and admin (members can reach the admin panel) — and drops the users.admin column entirely. Adds "Users with access" and "Accessible applications" panels with via-group badges on the application/user show pages. BEHAVIOR CHANGE: a ForwardAuth app with no allowed_groups previously bypassed authentication entirely; it now returns 403 like any other unauthorized request. The data migration seeds an "everyone" group and attaches it to all previously group-less apps to preserve behavior on existing installs. An "admins" group is seeded and backfilled from any user with the old admin column. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -135,23 +135,36 @@ class UserTest < ActiveSupport::TestCase
|
||||
assert_equal user, found_user
|
||||
end
|
||||
|
||||
test "admin scope" do
|
||||
admin_user = User.create!(
|
||||
email_address: "admin@example.com",
|
||||
password: "password123",
|
||||
admin: true
|
||||
)
|
||||
regular_user = User.create!(
|
||||
email_address: "user@example.com",
|
||||
password: "password123",
|
||||
admin: false
|
||||
)
|
||||
test "admin scope returns users in admin groups" do
|
||||
admin_group = groups(:admin_group)
|
||||
admin_user = User.create!(email_address: "admin@example.com", password: "password123")
|
||||
admin_user.groups << admin_group
|
||||
regular_user = User.create!(email_address: "user@example.com", password: "password123")
|
||||
|
||||
admins = User.admins
|
||||
assert_includes admins, admin_user
|
||||
assert_not_includes admins, regular_user
|
||||
end
|
||||
|
||||
test "admin? reflects membership in any admin: true group" do
|
||||
user = User.create!(email_address: "promoted@example.com", password: "password123")
|
||||
assert_not user.admin?
|
||||
user.groups << groups(:admin_group)
|
||||
assert user.reload.admin?
|
||||
end
|
||||
|
||||
test "after_create auto-joins all auto_assign groups" do
|
||||
user = User.create!(email_address: "newbie@example.com", password: "password123")
|
||||
assert_includes user.groups, groups(:everyone)
|
||||
end
|
||||
|
||||
test "skip_auto_assign disables the after_create callback" do
|
||||
user = User.new(email_address: "skipper@example.com", password: "password123")
|
||||
user.skip_auto_assign = true
|
||||
user.save!
|
||||
assert_not_includes user.groups, groups(:everyone)
|
||||
end
|
||||
|
||||
test "validates email address format" do
|
||||
user = User.new(email_address: "invalid-email", password: "password123")
|
||||
assert_not user.valid?
|
||||
|
||||
Reference in New Issue
Block a user