1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
class UsersController < ApplicationController
include PinnedToDefaultLocale
include RoleRequired
# Private
before_action :login_required
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, :grant_redaktion, :revoke_redaktion]
before_action :require_elevation_for_other_accounts, :only => [:edit, :update]
layout 'admin'
ROLE_PRESETS = {
"editor" => [],
"redaktion" => ["redaktion"],
}.freeze
GROUP_ORDER = [:admin, :redaktion, :editor, :alumni].freeze
def index
@users = User.order("login ASC").all.group_by(&:role_group)
end
def new
@user = User.new(:roles => ROLE_PRESETS.fetch(params[:preset], []))
end
def create
@user = User.new user_params
if @user.save_witnessed(:actor => current_user)
flash[:notice] = t("flash.users.created", :login => @user.login)
redirect_to user_path(@user)
else
render :new
end
end
def edit
end
def update
if roles_change_needs_elevation?
session[:elevation_return_to] = request.fullpath
return redirect_to new_elevation_path
end
permitted = user_params
desired = permitted.key?(:roles) ? permitted.delete(:roles) : nil
refusals = []
saved = false
User.transaction do
saved = @user.update(permitted)
raise ActiveRecord::Rollback unless saved
refusals = desired ? @user.update_roles!(desired, :actor => current_user) : []
raise ActiveRecord::Rollback if refusals.any?
end
if !saved
render :edit
elsif refusals.any?
flash.now[:error] = refusals.map { |r| t("flash.users.#{r}", :login => @user.login) }.to_sentence
render :edit
else
flash[:notice] = t("flash.users.updated", :login => @user.login)
redirect_to user_path(@user)
end
end
def show
end
def deactivate
if @user == current_user
flash[:error] = t("flash.users.cannot_deactivate_self")
elsif @user.deactivate!(:actor => current_user)
flash[:notice] = t("flash.users.deactivated", :login => @user.login)
end
redirect_to users_path
end
def reactivate
if @user.reactivate!(:actor => current_user)
flash[:notice] = t("flash.users.reactivated", :login => @user.login)
end
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)
redirect_to edit_user_path(@user)
end
private
def user_params
permitted = params.fetch(:user, {})
.permit(:login, :email, :password, :password_confirmation,
:roles => [])
# Checkbox arrays post a leading blank from the hidden field.
permitted[:roles] = Array(permitted[:roles]).reject(&:blank?) if permitted.key?(:roles)
permitted.delete(:roles) unless current_user.is_admin? && elevated?
permitted
end
def find_user
@user = User.find(params[:id])
end
def verify_status
@user ||= User.new
unless @user.id == current_user.id || current_user.admin
deny_user_access
end
end
def deny_user_access
deny_role_access(:admin_required)
end
def require_elevation_for_other_accounts
return if @user == current_user
require_elevation
end
def roles_change_needs_elevation?
return false unless params[:user].respond_to?(:key?) && params[:user].key?(:roles)
submitted = Array(params[:user][:roles]).reject(&:blank?).sort
return false if submitted == @user.roles.sort
!(current_user.is_admin? && elevated?)
end
end
|