From abd7ee1fc2ecc15b50944db30c59bedc26ec41b6 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Sat, 1 Aug 2026 04:14:00 +0200 Subject: Let Redaktion grant and revoke its own role Any holder may add or remove another account, witnessed as redaktion_grant/revoke so the vouching is legible. Not behind elevation: onboarding must not wait for a keyholder, and a compromised Redaktion account can already publish. --- app/controllers/users_controller.rb | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 583ebac0..9b9d64e5 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -5,17 +5,17 @@ class UsersController < ApplicationController # Private before_action :login_required - before_action :find_user, :only => [:show, :edit, :update, :reset_otp, :deactivate, :reactivate] - before_action :require_admin, :only => [:index, :new, :create, :reset_otp, :deactivate, :reactivate] + before_action :find_user, :only => [:show, :edit, :update, :reset_otp, :deactivate, :reactivate, :grant_redaktion, :revoke_redaktion] + before_action :require_redaktion, :only => [:index] + before_action :require_admin, :only => [:new, :create, :reset_otp, :deactivate, :reactivate] before_action :require_elevation, :only => [:new, :create, :reset_otp, :deactivate, :reactivate] - before_action :verify_status, :except => [:index] + before_action :verify_status, :except => [:index, :grant_redaktion, :revoke_redaktion] layout 'admin' ROLE_PRESETS = { "editor" => [], "redaktion" => ["redaktion"], - "admin" => ["admin", "redaktion"] }.freeze GROUP_ORDER = [:admin, :redaktion, :editor, :alumni].freeze @@ -74,6 +74,28 @@ class UsersController < ApplicationController redirect_to users_path end + def grant_redaktion + return deny_role_access(:redaktion_required) unless current_user.redaktion? + + case @user.grant_redaktion!(:actor => current_user) + when :granted then flash[:notice] = t("flash.users.redaktion_granted", :login => @user.login) + when :no_second_factor then flash[:error] = t("flash.users.redaktion_needs_otp", :login => @user.login) + end + + redirect_to users_path + end + + def revoke_redaktion + return deny_role_access(:redaktion_required) unless current_user.redaktion? + + case @user.revoke_redaktion!(:actor => current_user) + when :revoked then flash[:notice] = t("flash.users.redaktion_revoked", :login => @user.login) + when :self then flash[:error] = t("flash.users.redaktion_not_self") + end + + redirect_to users_path + end + def reset_otp @user.disable_otp!(:actor => current_user) flash[:notice] = t("flash.users.otp_reset", :login => @user.login) -- cgit v1.3