]>
Commit | Line | Data |
---|---|---|
6473c56f TC |
1 | package BSE::AdminUsers; |
2 | use strict; | |
b553afa2 | 3 | use BSE::Util::Tags qw/tag_error_img/; |
9168c88c | 4 | use BSE::Permissions; |
3f9c8a96 | 5 | use BSE::Util::HTML qw(:default popup_menu); |
41f10371 | 6 | use BSE::CfgInfo qw(admin_base_url); |
4d764c34 | 7 | use BSE::Template; |
74b3689a TC |
8 | use BSE::TB::AdminUsers; |
9 | use BSE::TB::AdminGroups; | |
10 | use BSE::Util::Iterate; | |
6473c56f | 11 | |
e0ed81d7 | 12 | our $VERSION = "1.009"; |
cb7fd78d | 13 | |
6473c56f TC |
14 | my %actions = |
15 | ( | |
16 | users=>1, | |
17 | showuser=>1, | |
08123550 | 18 | showuserart=>1, |
6473c56f | 19 | saveuser=>1, |
08123550 | 20 | saveuserart=>1, |
a607032b | 21 | adduserform => 1, |
6473c56f | 22 | adduser=>1, |
74b3689a | 23 | unlock => 1, |
6473c56f | 24 | groups=>1, |
08123550 | 25 | showgroupart=>1, |
6473c56f TC |
26 | showgroup=>1, |
27 | savegroup=>1, | |
08123550 TC |
28 | savegroupart=>1, |
29 | showobjectart=>1, | |
a607032b | 30 | addgroupform=>1, |
6473c56f | 31 | addgroup=>1, |
08123550 TC |
32 | deluser=>1, |
33 | delgroup=>1, | |
6473c56f TC |
34 | ); |
35 | ||
36 | sub dispatch { | |
37 | my ($class, $req) = @_; | |
38 | ||
9168c88c TC |
39 | BSE::Permissions->check_logon($req) |
40 | or return BSE::Template->get_refresh($req->url('logon'), $req->cfg); | |
41 | ||
6473c56f TC |
42 | my $cgi = $req->cgi; |
43 | my $action; | |
44 | for my $check (keys %actions) { | |
45 | if ($cgi->param("a_$check")) { | |
46 | $action = $check; | |
47 | last; | |
48 | } | |
49 | } | |
50 | $action ||= 'users'; | |
51 | my $method = "req_$action"; | |
52 | $class->$method($req); | |
53 | } | |
54 | ||
55 | sub iter_get_users { | |
56 | my ($req) = @_; | |
57 | ||
6473c56f TC |
58 | return BSE::TB::AdminUsers->all; |
59 | } | |
60 | ||
61 | sub iter_get_groups { | |
62 | my ($req) = @_; | |
63 | ||
6473c56f TC |
64 | return BSE::TB::AdminGroups->all; |
65 | } | |
66 | ||
67 | sub iter_get_user_groups { | |
68 | my ($req, $args, $acts, $funcname, $templater) = @_; | |
69 | ||
70 | my $id = $templater->perform($acts, $args, 'id') | |
71 | or return; | |
72 | ||
73 | return BSE::DB->query(adminUsersGroups => $id); | |
74 | } | |
75 | ||
76 | sub iter_get_group_users { | |
77 | my ($req, $args, $acts, $funcname, $templater) = @_; | |
78 | ||
79 | my $id = $templater->perform($acts, $args, 'id') | |
80 | or return; | |
81 | ||
156a4907 | 82 | return BSE::TB::AdminGroups->group_members($id); |
6473c56f TC |
83 | } |
84 | ||
4010d92e TC |
85 | my @saltchars = ('.', '/', 0..9, 'A'..'Z', 'a'..'z'); |
86 | ||
87 | sub _save_htusers { | |
88 | my ($class, $req, $rmsg) = @_; | |
89 | ||
90 | my $cfg = $req->cfg; | |
91 | ||
92 | my $userfile = $cfg->entry('basic', 'htusers') | |
93 | or return 1; | |
94 | ||
95 | my @users = BSE::TB::AdminUsers->all; | |
96 | unless (@users) { | |
97 | $$rmsg = "No users to load into $userfile file"; | |
98 | return; | |
99 | } | |
100 | ||
101 | my $work = $userfile . ".tmp"; | |
102 | unless (open USERS, "> $work") { | |
103 | $$rmsg = "Cannot create work userfile $work: $!"; | |
104 | return; | |
105 | } | |
b190a4c1 TC |
106 | my $bad_count = 0; |
107 | my $bad_user; | |
4010d92e | 108 | for my $user (@users) { |
b190a4c1 TC |
109 | my $cryptpw; |
110 | if ($user->password_type eq "plain") { | |
111 | my $salt = join '', @saltchars[rand(@saltchars), rand(@saltchars)]; | |
112 | $cryptpw = crypt $user->{password}, $salt; | |
113 | } | |
114 | elsif ($user->password_type =~ /^crypt/) { | |
115 | $cryptpw = $user->password; | |
116 | } | |
117 | else { | |
118 | $bad_user = $user; | |
119 | ++$bad_count; | |
120 | } | |
4010d92e TC |
121 | print USERS "$user->{logon}:$cryptpw\n"; |
122 | } | |
b190a4c1 TC |
123 | if ($bad_count) { |
124 | $req->flash("Cannot handle password type " . $bad_user->password_type . " in userfile for up to $bad_count users"); | |
125 | } | |
4010d92e TC |
126 | close USERS; |
127 | chmod 0644, $work; | |
128 | unless (rename $work, $userfile) { | |
129 | $$rmsg = "Could not rename $work to $userfile: $!"; | |
130 | return; | |
131 | } | |
132 | ||
133 | return 1; | |
134 | } | |
135 | ||
6473c56f | 136 | sub common_tags { |
b553afa2 | 137 | my ($class, $req, $msg, $errors) = @_; |
6473c56f | 138 | |
7013529c | 139 | $msg = $req->message($errors || $msg); |
c63d905a | 140 | |
6473c56f TC |
141 | my @users; |
142 | my $user_index; | |
143 | my @groups; | |
144 | my $group_index; | |
74b3689a TC |
145 | $req->set_variable_class(users => "BSE::TB::AdminUsers"); |
146 | $req->set_variable_class(groups => "BSE::TB::AdminGroups"); | |
147 | my $ito = BSE::Util::Iterate::Objects->new; | |
6473c56f TC |
148 | return |
149 | ( | |
c63d905a | 150 | $req->admin_tags, |
6473c56f | 151 | message => $msg, |
74b3689a TC |
152 | $ito->make |
153 | ( | |
154 | code => [ all => "BSE::TB::AdminUsers" ], | |
155 | single => "iuser", | |
156 | plural => "users", | |
157 | data => \@users, | |
158 | index => \$user_index, | |
159 | ), | |
6473c56f TC |
160 | DevHelp::Tags->make_iterator2 |
161 | ([ \&iter_get_groups, $req ], 'igroup', 'groups', \@groups, | |
162 | \$group_index), | |
163 | DevHelp::Tags->make_iterator2 | |
164 | ([ \&iter_get_user_groups, $req, ], 'user_group', 'user_groups'), | |
165 | DevHelp::Tags->make_iterator2 | |
166 | ([ \&iter_get_group_users, $req, ], 'group_user', 'group_users'), | |
b553afa2 | 167 | error_img => [ \&tag_error_img, $req->cfg, $errors ], |
6473c56f TC |
168 | ); |
169 | } | |
170 | ||
171 | sub req_users { | |
b553afa2 | 172 | my ($class, $req, $msg, $errors) = @_; |
6473c56f TC |
173 | |
174 | my %acts; | |
b553afa2 | 175 | %acts = $class->common_tags($req, $msg, $errors); |
4d764c34 | 176 | return $req->dyn_response('admin/userlist', \%acts); |
6473c56f TC |
177 | } |
178 | ||
a607032b TC |
179 | sub req_adduserform { |
180 | my ($class, $req, $msg, $errors) = @_; | |
181 | ||
182 | $req->user_can('admin_user_add') | |
183 | or return $class->req_users($req, "You don't have admin_user_add access"); | |
184 | ||
185 | my %acts; | |
186 | %acts = $class->common_tags($req, $msg, $errors); | |
4d764c34 | 187 | return $req->dyn_response('admin/adduser', \%acts); |
a607032b TC |
188 | } |
189 | ||
6473c56f | 190 | sub req_groups { |
b553afa2 | 191 | my ($class, $req, $msg, $errors) = @_; |
6473c56f TC |
192 | |
193 | my %acts; | |
b553afa2 | 194 | %acts = $class->common_tags($req, $msg, $errors); |
08123550 | 195 | |
4d764c34 | 196 | return $req->dyn_response('admin/grouplist', \%acts); |
6473c56f TC |
197 | } |
198 | ||
a607032b TC |
199 | sub req_addgroupform { |
200 | my ($class, $req, $msg, $errors) = @_; | |
201 | ||
202 | my %acts; | |
4d764c34 TC |
203 | %acts = |
204 | ( | |
205 | $class->common_tags($req, $msg, $errors), | |
206 | template_set_popup => [ \&tag_template_set_popup, $req, undef ], | |
207 | ); | |
a607032b | 208 | |
4d764c34 | 209 | return $req->dyn_response('admin/addgroup', \%acts); |
a607032b TC |
210 | } |
211 | ||
6473c56f TC |
212 | sub refresh { |
213 | my ($class, $req, $target, @parms) = @_; | |
214 | ||
b553afa2 TC |
215 | my $url = $req->cgi->param('r'); |
216 | unless ($url) { | |
41f10371 | 217 | $url = admin_base_url($req->cfg); |
b553afa2 TC |
218 | $url .= $ENV{SCRIPT_NAME}; |
219 | $url .= "?$target=1"; | |
220 | while (my ($key, $value) = splice @parms, 0, 2) { | |
221 | $url .= "&$key=".escape_uri($value); | |
222 | } | |
6473c56f | 223 | } |
b553afa2 | 224 | |
6473c56f TC |
225 | return BSE::Template->get_refresh($url, $req->cfg); |
226 | } | |
227 | ||
228 | sub hash_tag { | |
229 | my ($hash, $args) = @_; | |
230 | ||
231 | my $value = $hash->{$args}; | |
232 | defined $value or $value = ''; | |
b553afa2 | 233 | escape_html($value); |
6473c56f TC |
234 | } |
235 | ||
236 | sub req_adduser { | |
237 | my ($class, $req) = @_; | |
238 | ||
9168c88c | 239 | $req->user_can('admin_user_add') |
a0a8147b | 240 | or return $class->req_users($req, "You don't have admin_user_add access"); |
9168c88c | 241 | |
6473c56f TC |
242 | my $cgi = $req->cgi; |
243 | my $logon = $cgi->param('logon'); | |
244 | my $name = $cgi->param('name'); | |
245 | my $password = $cgi->param('password'); | |
246 | my $confirm = $cgi->param('confirm'); | |
b553afa2 TC |
247 | my %errors; |
248 | ||
6473c56f | 249 | defined $logon && length $logon |
b553afa2 | 250 | or $errors{logon} = 'No logon supplied'; |
6473c56f | 251 | $name = '' unless defined $name; |
b553afa2 TC |
252 | if (defined $password && length $password) { |
253 | if (defined $confirm && length $confirm) { | |
254 | $password eq $confirm | |
255 | or $errors{confirm} = 'Password is different to confirmation password'; | |
256 | } | |
257 | else { | |
258 | $errors{confirm} = 'No confirmation password supplied'; | |
259 | } | |
260 | } | |
261 | else { | |
262 | $errors{password} = 'No password supplied'; | |
263 | defined $confirm && length $confirm | |
264 | or $errors{confirm} = 'No confirmation password supplied'; | |
265 | } | |
266 | ||
17a70173 TC |
267 | require BSE::TB::AdminUsers; |
268 | if (!$errors{password} && $logon) { | |
269 | my %others = map { $_ => scalar $cgi->param($_) } | |
270 | BSE::TB::AdminUser->password_check_fields; | |
271 | my @errors; | |
272 | unless (BSE::TB::AdminUser->check_password_rules | |
273 | ( | |
274 | password => $password, | |
275 | username => $logon, | |
276 | other => \%others, | |
277 | errors => \@errors, | |
278 | )) { | |
279 | $errors{password} = \@errors; | |
280 | } | |
281 | } | |
282 | ||
b553afa2 | 283 | keys %errors |
a607032b | 284 | and return $class->req_adduserform($req, undef, \%errors); |
6473c56f | 285 | |
6473c56f | 286 | my $old = BSE::TB::AdminUsers->getBy(logon=>$logon) |
a607032b | 287 | and return $class->req_adduserform($req, "Logon '$logon' already exists"); |
6473c56f TC |
288 | my %user = |
289 | ( | |
290 | type => 'u', | |
291 | logon => $logon, | |
292 | name => $name, | |
293 | password => $password, | |
294 | perm_map => '', | |
295 | ); | |
b190a4c1 | 296 | my $user = BSE::TB::AdminUsers->make(%user); |
4010d92e TC |
297 | |
298 | my $msg = "User $logon created"; | |
299 | ||
300 | $class->_save_htusers($req, \$msg); | |
301 | ||
8cc0eddc TC |
302 | $req->audit |
303 | ( | |
304 | component => "admin:users:adduser", | |
305 | object => $user, | |
289a65f1 AO |
306 | msg => "Admin User '".$user->logon."' created", |
307 | level => "notice", | |
8cc0eddc TC |
308 | ); |
309 | ||
6473c56f | 310 | return $class->refresh($req, 'a_showuser', userid=>$user->{id}, |
4010d92e | 311 | 'm'=>$msg); |
6473c56f TC |
312 | } |
313 | ||
314 | sub req_addgroup { | |
315 | my ($class, $req) = @_; | |
316 | ||
9168c88c | 317 | $req->user_can('admin_group_add') |
a0a8147b | 318 | or return $class->req_groups($req, "You don't have admin_group_add access"); |
9168c88c | 319 | |
6473c56f TC |
320 | my $cgi = $req->cgi; |
321 | my $name = $cgi->param('name'); | |
322 | my $description = $cgi->param('description'); | |
b553afa2 | 323 | my %errors; |
6473c56f | 324 | defined $name && length $name |
b553afa2 | 325 | or $errors{name} = 'No name supplied'; |
6473c56f | 326 | $description = '' unless defined $description; |
4d764c34 TC |
327 | require BSE::TB::AdminGroups; |
328 | my %valid_sets = map { $_ => 1 } | |
329 | BSE::TB::AdminGroups->group_template_set_values($req->cfg); | |
330 | my $template_set = $cgi->param('template_set'); | |
331 | defined $template_set or $template_set = ''; | |
332 | exists $valid_sets{$template_set} | |
333 | or $errors{template_set} = | |
334 | $req->text(bse_invalid_group_template_set => | |
335 | 'Please select a valid template_set'); | |
b190a4c1 | 336 | |
b553afa2 | 337 | keys %errors |
a607032b | 338 | and return $class->req_addgroupform($req, undef, \%errors); |
6473c56f | 339 | my $old = BSE::TB::AdminGroups->getBy(name=>$name) |
a607032b | 340 | and return $class->req_addgroupform($req, "Group '$name' already exists"); |
6473c56f TC |
341 | my %group = |
342 | ( | |
4d764c34 TC |
343 | type => 'g', |
344 | name => $name, | |
345 | description => $description, | |
346 | template_set => $template_set, | |
347 | perm_map => '', | |
6473c56f TC |
348 | ); |
349 | my @cols = BSE::TB::AdminGroup->columns; | |
350 | shift @cols; | |
351 | my $group = BSE::TB::AdminGroups->add(@group{@cols}); | |
352 | return $class->refresh($req, 'a_showgroup', groupid=>$group->{id}, | |
08123550 TC |
353 | 'm' =>"Group $name created"); |
354 | } | |
355 | ||
356 | sub tag_if_user_member_of { | |
357 | my ($members, $arg, $acts, $funcname, $templater) = @_; | |
358 | ||
359 | my $groupid = $templater->perform($acts, $arg, 'id') | |
360 | or return; | |
361 | ||
362 | return exists $members->{$groupid}; | |
363 | } | |
364 | ||
365 | sub iter_get_gperms { | |
366 | my ($cfg) = @_; | |
367 | ||
368 | require BSE::Permissions; | |
369 | my $perms = BSE::Permissions->new($cfg); | |
370 | ||
371 | return $perms->global_perms; | |
372 | } | |
373 | ||
374 | sub tag_if_gperm_set { | |
375 | my ($obj, $arg, $acts, $funcname, $templater) = @_; | |
376 | ||
377 | my $id = $templater->perform($acts, $arg, 'id'); | |
378 | $id =~ /\d/ | |
379 | or return; | |
380 | ||
381 | return unless $id < length($obj->{perm_map}); | |
382 | ||
383 | substr($obj->{perm_map}, $id, 1); | |
384 | } | |
385 | ||
4d764c34 TC |
386 | sub tag_template_set_popup { |
387 | my ($req, $group) = @_; | |
388 | ||
389 | my $set = $group ? $group->{template_set} : ''; | |
390 | require BSE::TB::AdminGroups; | |
391 | my @values = BSE::TB::AdminGroups->group_template_set_values($req->cfg); | |
392 | my %labels = BSE::TB::AdminGroups->group_template_set_labels($req); | |
393 | ||
394 | popup_menu(-name => 'template_set', | |
395 | -values => \@values, | |
396 | -labels => \%labels, | |
397 | -default => $set); | |
398 | } | |
399 | ||
08123550 | 400 | sub showuser_tags { |
b553afa2 | 401 | my ($class, $req, $user, $msg, $errors) = @_; |
08123550 TC |
402 | |
403 | my %members = map { $_->{group_id} => 1 } | |
404 | BSE::DB->query(userGroups=>$user->{id}); | |
405 | return | |
406 | ( | |
b553afa2 | 407 | $class->common_tags($req, $msg, $errors), |
08123550 TC |
408 | user => [ \&hash_tag, $user ], |
409 | ifMemberof => [ \&tag_if_user_member_of, \%members ], | |
410 | DevHelp::Tags->make_iterator2 | |
411 | ([ \&iter_get_gperms, $req->cfg ], 'gperm', 'gperms' ), | |
412 | ifGperm_set => | |
413 | [ \&tag_if_gperm_set, $user ], | |
414 | ); | |
6473c56f TC |
415 | } |
416 | ||
417 | sub req_showuser { | |
b553afa2 | 418 | my ($class, $req, $msg, $errors) = @_; |
6473c56f TC |
419 | |
420 | my $cgi = $req->cgi; | |
421 | my $userid = $cgi->param('userid'); | |
422 | $userid | |
08123550 | 423 | or return $class->req_users($req, 'No userid supplied'); |
6473c56f TC |
424 | require BSE::TB::AdminUsers; |
425 | my $user = BSE::TB::AdminUsers->getByPkey($userid) | |
08123550 | 426 | or return $class->req_users($req, "User id $userid not found"); |
74b3689a | 427 | $req->set_variable("user", $user); |
6473c56f TC |
428 | my %acts; |
429 | %acts = | |
430 | ( | |
b553afa2 | 431 | $class->showuser_tags($req, $user, $msg, $errors), |
6473c56f | 432 | ); |
08123550 | 433 | |
4d764c34 | 434 | return $req->dyn_response('admin/showuser', \%acts); |
6473c56f TC |
435 | } |
436 | ||
08123550 TC |
437 | sub iter_get_kids { |
438 | my ($article) = @_; | |
439 | ||
e0ed81d7 | 440 | require BSE::TB::Articles; |
08123550 | 441 | return sort { $b->{displayOrder} <=> $a->{displayOrder} } |
e0ed81d7 | 442 | BSE::TB::Articles->children($article->{id}); |
08123550 TC |
443 | } |
444 | ||
445 | sub iter_get_aperms { | |
446 | my ($perms) = @_; | |
447 | ||
448 | return $perms->article_perms; | |
449 | } | |
450 | ||
451 | sub tag_if_aperm_set { | |
452 | my ($perm, $arg, $acts, $funcname, $templater) = @_; | |
453 | ||
454 | return unless $perm; | |
455 | ||
456 | my $id = $templater->perform($acts, $arg, 'id'); | |
457 | $id =~ /\d/ | |
458 | or return ''; | |
459 | ||
460 | return '' unless $id < length($perm->{perm_map}); | |
461 | ||
462 | substr($perm->{perm_map}, $id, 1); | |
463 | } | |
464 | ||
b553afa2 TC |
465 | sub tag_typename { |
466 | my ($args, $acts, $funcname, $templater) = @_; | |
467 | ||
468 | exists $acts->{$args} or return "** need an article name **"; | |
469 | my $generator = $templater->perform($acts, $args, 'generator'); | |
470 | ||
471 | $generator =~ /^(?:BSE::)?Generate::(\w+)$/ | |
472 | or return "** invalid generator $generator **"; | |
473 | ||
474 | return $1; | |
475 | } | |
476 | ||
477 | sub iter_crumbs { | |
478 | my ($req, $article) = @_; | |
479 | ||
480 | return if $article->{id} == -1; | |
481 | ||
482 | my @parents; | |
483 | my $work = $article; | |
484 | while ($work->{parentid} != -1) { | |
485 | $work = $work->parent; | |
486 | unshift @parents, $work; | |
487 | } | |
488 | ||
489 | @parents; | |
490 | } | |
491 | ||
08123550 TC |
492 | sub article_tags { |
493 | my ($class, $req, $user, $article) = @_; | |
494 | ||
495 | my @children; | |
496 | my $child_index; | |
497 | my $parent; | |
498 | if ($article->{id} != -1) { | |
499 | if ($article->{parentid} != -1) { | |
500 | $parent = $article->parent; | |
501 | } | |
502 | else { | |
503 | $parent = | |
504 | { | |
505 | id=>-1, | |
506 | title=>'Your site', | |
9785c9c4 | 507 | generator => 'BSE::Generate::Site', # well... |
b553afa2 | 508 | level => 0, |
08123550 TC |
509 | }; |
510 | } | |
511 | } | |
512 | require BSE::Permissions; | |
513 | my $perms = BSE::Permissions->new($req->cfg); | |
514 | my $perm = $perms->get_article_perm($article->{id}, $user); | |
515 | return | |
516 | ( | |
517 | article => [ \&hash_tag, $article ], | |
518 | DevHelp::Tags->make_iterator2 | |
519 | ([ \&iter_get_kids, $article ], 'child', 'children', | |
520 | \@children, \$child_index), | |
521 | ifParent => !!$parent, | |
522 | parent => [ \&hash_tag, $parent ], | |
523 | DevHelp::Tags->make_iterator2 | |
524 | ([ \&iter_get_aperms, $perms ], 'aperm', 'aperms' ), | |
525 | ifAperm_set => | |
526 | [ \&tag_if_aperm_set, $perm ], | |
b553afa2 TC |
527 | typename => \&tag_typename, |
528 | articleType => escape_html | |
529 | (scalar($req->cfg->entry('level names', $article->{level}, "Site"))), | |
650a6188 TC |
530 | childtype => escape_html |
531 | (scalar($req->cfg->entry('level names', $article->{level}+1, ""))), | |
b553afa2 TC |
532 | DevHelp::Tags->make_iterator2 |
533 | ([ \&iter_crumbs, $req, $article ], 'crumb', 'crumbs'), | |
08123550 TC |
534 | ); |
535 | } | |
536 | ||
537 | sub get_article { | |
538 | my ($self, $id) = @_; | |
539 | ||
540 | if ($id eq '-1') { | |
541 | return | |
542 | { | |
543 | id=>-1, | |
544 | title=>'Your site', | |
650a6188 TC |
545 | level => 0, |
546 | parentid => 0, | |
08123550 TC |
547 | }; |
548 | } | |
549 | else { | |
e0ed81d7 AO |
550 | require BSE::TB::Articles; |
551 | return BSE::TB::Articles->getByPkey($id); | |
08123550 TC |
552 | } |
553 | } | |
554 | ||
555 | sub req_showuserart { | |
556 | my ($class, $req, $msg) = @_; | |
557 | ||
558 | my $cgi = $req->cgi; | |
559 | my $userid = $cgi->param('userid'); | |
560 | $userid | |
561 | or return $class->req_users($req, 'No userid supplied'); | |
562 | require BSE::TB::AdminUsers; | |
563 | my $user = BSE::TB::AdminUsers->getByPkey($userid) | |
564 | or return $class->req_users($req, "User id $userid not found"); | |
565 | my $artid = $cgi->param('id'); | |
566 | $artid | |
567 | or return $class->req_showuser($req, 'No article id supplied'); | |
568 | my $article = $class->get_article($artid) | |
569 | or return $class->req_showuser($req, 'No such article'); | |
570 | ||
571 | my %acts; | |
572 | %acts = | |
573 | ( | |
574 | $class->showuser_tags($req, $user, $msg), | |
575 | $class->article_tags($req, $user, $article), | |
576 | ); | |
577 | ||
4d764c34 | 578 | return $req->dyn_response('admin/showuserart', \%acts); |
08123550 TC |
579 | } |
580 | ||
581 | sub req_showgroupart { | |
6473c56f TC |
582 | my ($class, $req, $msg) = @_; |
583 | ||
584 | my $cgi = $req->cgi; | |
585 | my $groupid = $cgi->param('groupid'); | |
586 | $groupid | |
08123550 | 587 | or return $class->req_groups($req, 'No groupid supplied'); |
6473c56f TC |
588 | require BSE::TB::AdminGroups; |
589 | my $group = BSE::TB::AdminGroups->getByPkey($groupid) | |
08123550 TC |
590 | or return $class->req_groups($req, "Group id $groupid not found"); |
591 | my $artid = $cgi->param('id'); | |
592 | $artid | |
593 | or return $class->req_showgroup($req, 'No article id supplied'); | |
594 | my $article = $class->get_article($artid) | |
595 | or return $class->req_showgroup($req, 'No such article'); | |
596 | ||
6473c56f TC |
597 | my %acts; |
598 | %acts = | |
08123550 TC |
599 | ( |
600 | $class->showgroup_tags($req, $group, $msg), | |
601 | $class->article_tags($req, $group, $article), | |
602 | ); | |
603 | ||
4d764c34 | 604 | return $req->dyn_response('admin/showgroupart', \%acts); |
08123550 TC |
605 | } |
606 | ||
607 | sub req_showobjectart { | |
608 | my ($class, $req) = @_; | |
609 | ||
610 | my $cgi = $req->cgi; | |
611 | my $adminid = $cgi->param('adminid'); | |
612 | $adminid && $adminid =~ /^\d+$/ | |
613 | or return $class->req_users($req, 'No adminid supplied'); | |
614 | require BSE::TB::AdminBases; | |
615 | my $base = BSE::TB::AdminBases->getByPkey($adminid) | |
616 | or return $class->req_users($req, 'Unknown adminid'); | |
617 | my $artid = $cgi->param('id'); | |
618 | $artid | |
619 | or return $class->req_users($req, 'No article id supplied'); | |
620 | my $article = $class->get_article($artid) | |
621 | or return $class->req_users($req, 'No such article'); | |
622 | ||
623 | if ($base->{type} eq 'u') { | |
624 | return $class->refresh($req, a_showuserart => | |
625 | userid=>$adminid, | |
626 | id=>$artid); | |
627 | } | |
628 | else { | |
629 | return $class->refresh($req, a_showgroupart => | |
630 | groupid=>$adminid, | |
631 | id=>$artid); | |
632 | } | |
633 | } | |
634 | ||
635 | sub tag_if_member_of_group { | |
636 | my ($members, $arg, $acts, $funcname, $templater) = @_; | |
637 | ||
638 | my $userid = $templater->perform($acts, $arg, 'id') | |
639 | or return; | |
640 | ||
641 | return exists $members->{$userid}; | |
642 | } | |
643 | ||
644 | sub showgroup_tags { | |
b553afa2 | 645 | my ($class, $req, $group, $msg, $errors) = @_; |
08123550 TC |
646 | |
647 | my %members = map { $_->{user_id} => 1 } | |
648 | BSE::DB->query(groupUsers=>$group->{id}); | |
649 | return | |
6473c56f | 650 | ( |
b553afa2 | 651 | $class->common_tags($req, $msg, $errors), |
6473c56f | 652 | group => [ \&hash_tag, $group ], |
08123550 TC |
653 | ifMemberof => [ \&tag_if_member_of_group, \%members ], |
654 | DevHelp::Tags->make_iterator2 | |
655 | ([ \&iter_get_gperms, $req->cfg ], 'gperm', 'gperms' ), | |
656 | ifGperm_set => | |
657 | [ \&tag_if_gperm_set, $group ], | |
4d764c34 | 658 | template_set_popup => [ \&tag_template_set_popup, $req, $group ], |
08123550 TC |
659 | ); |
660 | } | |
661 | ||
662 | sub req_showgroup { | |
b553afa2 | 663 | my ($class, $req, $msg, $errors) = @_; |
08123550 TC |
664 | |
665 | my $cgi = $req->cgi; | |
666 | my $groupid = $cgi->param('groupid'); | |
667 | $groupid | |
668 | or return $class->req_groups($req, 'No groupid supplied'); | |
669 | require BSE::TB::AdminGroups; | |
670 | my $group = BSE::TB::AdminGroups->getByPkey($groupid) | |
671 | or return $class->req_groups($req, "Group id $groupid not found"); | |
672 | my %acts; | |
673 | %acts = | |
674 | ( | |
b553afa2 | 675 | $class->showgroup_tags($req, $group, $msg, $errors), |
6473c56f | 676 | ); |
08123550 | 677 | |
4d764c34 | 678 | return $req->dyn_response('admin/showgroup', \%acts); |
08123550 TC |
679 | } |
680 | ||
681 | sub req_saveuser { | |
682 | my ($class, $req) = @_; | |
683 | ||
9168c88c | 684 | $req->user_can('admin_user_save') |
a0a8147b | 685 | or return $class->req_users($req, "You don't have admin_user_save access"); |
9168c88c | 686 | |
08123550 TC |
687 | my $cgi = $req->cgi; |
688 | my $userid = $cgi->param('userid'); | |
689 | $userid | |
690 | or return $class->req_users($req, 'No userid supplied'); | |
691 | require BSE::TB::AdminUsers; | |
692 | my $user = BSE::TB::AdminUsers->getByPkey($userid) | |
693 | or return $class->req_users($req, "User id $userid not found"); | |
9168c88c | 694 | |
08123550 TC |
695 | my $name = $cgi->param('name'); |
696 | my $password = $cgi->param('password'); | |
697 | my $confirm = $cgi->param('confirm'); | |
b553afa2 TC |
698 | my %errors; |
699 | $user->{name} = $name if defined $name; | |
08123550 TC |
700 | if (defined $password && defined $confirm |
701 | && length $password) { | |
b553afa2 TC |
702 | if (length $confirm) { |
703 | if ($password eq $confirm) { | |
17a70173 TC |
704 | my %others = map { $_ => $user->$_() } |
705 | BSE::TB::AdminUser->password_check_fields; | |
706 | my @errors; | |
707 | if (BSE::TB::AdminUser->check_password_rules | |
708 | ( | |
709 | password => $password, | |
710 | username => $user->logon, | |
711 | other => \%others, | |
712 | errors => \@errors, | |
713 | )) { | |
714 | $user->changepw($password); | |
715 | } | |
716 | else { | |
717 | $errors{password} = \@errors; | |
718 | } | |
b553afa2 TC |
719 | } |
720 | else { | |
721 | $errors{confirm} = "Password and confirmation password didn't match" | |
722 | } | |
723 | } | |
724 | else { | |
725 | $errors{confirm} = "Enter both password and confirmation to change password"; | |
726 | } | |
08123550 | 727 | } |
b553afa2 TC |
728 | keys %errors |
729 | and return $class->req_showuser($req, undef, \%errors); | |
da6bc286 | 730 | if ($cgi->param('savegperms') && $req->user_can('admin_user_save_gperms')) { |
08123550 TC |
731 | my $perms = ''; |
732 | my @gperms = $cgi->param('gperms'); | |
733 | for my $id (@gperms) { | |
734 | if (length($perms) < $id) { | |
735 | $perms .= '0' x ($id - length $perms); | |
736 | } | |
737 | substr($perms, $id, 1) = '1'; | |
738 | } | |
739 | $user->{perm_map} = $perms; | |
740 | } | |
741 | $user->save; | |
742 | ||
da6bc286 | 743 | if ($cgi->param('savegroups') && $req->user_can("admin_user_save_groups")) { |
08123550 TC |
744 | require BSE::TB::AdminGroups; |
745 | require BSE::TB::AdminUsers; | |
746 | my @group_ids = map $_->{id}, BSE::TB::AdminGroups->all; | |
747 | my %want_groups = map { $_ => 1 } $cgi->param('groups'); | |
748 | my %current_groups = map { $_->{group_id} => 1 } | |
749 | BSE::DB->query(userGroups=>$user->{id}); | |
750 | ||
751 | for my $group_id (@group_ids) { | |
752 | if ($want_groups{$group_id} && !$current_groups{$group_id}) { | |
4ddf4827 | 753 | $user->add_to_group($group_id); |
08123550 TC |
754 | } |
755 | elsif (!$want_groups{$group_id} && $current_groups{$group_id}) { | |
4ddf4827 | 756 | $user->remove_from_group($group_id); |
08123550 TC |
757 | } |
758 | } | |
759 | } | |
760 | ||
4010d92e TC |
761 | my $msg = 'User saved'; |
762 | $class->_save_htusers($req, \$msg); | |
763 | ||
a607032b TC |
764 | my $t = $cgi->param('_t'); |
765 | my @extras; | |
766 | push @extras, _t => $t if defined $t and $t =~ /^\w+$/; | |
767 | ||
08123550 | 768 | return $class->refresh($req, a_showuser => userid => $user->{id}, |
a607032b | 769 | 'm' => $msg, @extras); |
08123550 TC |
770 | } |
771 | ||
772 | sub req_saveuserart { | |
773 | my ($class, $req) = @_; | |
774 | ||
9168c88c | 775 | $req->user_can("admin_user_save_artrights") |
a0a8147b | 776 | or return $class->req_users($req, "You don't have admin_user_save_artrights access"); |
9168c88c | 777 | |
08123550 TC |
778 | my $cgi = $req->cgi; |
779 | my $userid = $cgi->param('userid'); | |
780 | $userid | |
781 | or return $class->req_users($req, 'No userid supplied'); | |
782 | require BSE::TB::AdminUsers; | |
783 | my $user = BSE::TB::AdminUsers->getByPkey($userid) | |
784 | or return $class->req_users($req, "User id $userid not found"); | |
785 | my $artid = $cgi->param('id'); | |
786 | $artid | |
787 | or return $class->req_showuser($req, 'No article id supplied'); | |
788 | my $article = $class->get_article($artid) | |
789 | or return $class->req_showuser($req, 'No such article'); | |
790 | ||
791 | require BSE::Permissions; | |
792 | my $perms = BSE::Permissions->new($req->cfg); | |
793 | my $perm_map = ''; | |
794 | my @aperms = $cgi->param('aperms'); | |
795 | for my $id (@aperms) { | |
796 | if (length($perm_map) < $id) { | |
797 | $perm_map .= '0' x ($id - length $perm_map); | |
798 | } | |
799 | substr($perm_map, $id, 1) = '1'; | |
800 | } | |
801 | ||
802 | $perms->set_article_perm($artid, $user, $perm_map); | |
803 | ||
804 | return $class->refresh($req, a_showuserart => userid => $user->{id}, | |
805 | id=>$artid, 'm' => 'Permissions saved'); | |
806 | } | |
807 | ||
808 | sub req_savegroup { | |
809 | my ($class, $req, $msg) = @_; | |
810 | ||
9168c88c | 811 | $req->user_can("admin_group_save") |
a0a8147b | 812 | or return $class->req_groups($req, "You don't have admin_group_save access"); |
9168c88c | 813 | |
08123550 TC |
814 | my $cgi = $req->cgi; |
815 | my $groupid = $cgi->param('groupid'); | |
816 | $groupid | |
817 | or return $class->req_groups($req, 'No groupid supplied'); | |
818 | require BSE::TB::AdminGroups; | |
819 | my $group = BSE::TB::AdminGroups->getByPkey($groupid) | |
820 | or return $class->req_groups($req, "Group id $groupid not found"); | |
821 | my $description = $cgi->param('description'); | |
b553afa2 | 822 | my $name = $cgi->param('name'); |
4d764c34 TC |
823 | my %valid_sets = map { $_ => 1 } |
824 | BSE::TB::AdminGroups->group_template_set_values($req->cfg); | |
825 | my %errors; | |
826 | ||
827 | my $template_set = $cgi->param('template_set'); | |
828 | if (defined $template_set and !exists $valid_sets{$template_set}) { | |
829 | $errors{template_set} = "Invalid template set"; | |
830 | } | |
831 | ||
b553afa2 | 832 | if (defined $name) { |
4d764c34 TC |
833 | if (length $name) { |
834 | if (lc $name ne lc $group->{name}) { | |
835 | require BSE::TB::AdminGroups; | |
836 | my $old = BSE::TB::AdminGroups->getBy(name=>$name); | |
837 | if ($old) { | |
838 | $errors{name} = "Group '$name' already exists"; | |
839 | } | |
840 | } | |
841 | } | |
842 | else { | |
843 | $errors{name} = 'No name supplied'; | |
b553afa2 TC |
844 | } |
845 | } | |
08123550 | 846 | |
4d764c34 TC |
847 | keys %errors |
848 | and return $class->req_showgroup($req, undef, \%errors); | |
849 | ||
9168c88c | 850 | if ($cgi->param('savegperms') && $req->user_can("admin_group_save_gperms")) { |
08123550 TC |
851 | my $perms = ''; |
852 | my @gperms = $cgi->param('gperms'); | |
853 | for my $id (@gperms) { | |
854 | if (length($perms) < $id) { | |
855 | $perms .= '0' x ($id - length $perms); | |
856 | } | |
857 | substr($perms, $id, 1) = '1'; | |
858 | } | |
859 | $group->{perm_map} = $perms; | |
860 | } | |
4d764c34 TC |
861 | |
862 | defined $name and $group->{name} = $name; | |
863 | defined $template_set and $group->{template_set} = $template_set; | |
864 | defined $description and $group->{description} = $description; | |
865 | ||
08123550 TC |
866 | $group->save; |
867 | ||
da6bc286 | 868 | if ($cgi->param('saveusers') && $req->user_can("admin_group_save_users")) { |
9168c88c TC |
869 | require BSE::TB::AdminGroups; |
870 | require BSE::TB::AdminUsers; | |
871 | my @member_ids = map $_->{id}, BSE::TB::AdminUsers->all; | |
872 | my %want_users = map { $_ => 1 } $cgi->param('users'); | |
873 | my %current_users = map { $_->{user_id} => 1 } | |
874 | BSE::DB->query(groupUsers=>$group->{id}); | |
875 | ||
876 | for my $user_id (@member_ids) { | |
877 | if ($want_users{$user_id} && !$current_users{$user_id}) { | |
878 | BSE::DB->run(addUserToGroup=>$user_id, $group->{id}); | |
879 | } | |
880 | elsif (!$want_users{$user_id} && $current_users{$user_id}) { | |
881 | BSE::DB->run(delUserFromGroup=>$user_id, $group->{id}); | |
882 | } | |
08123550 TC |
883 | } |
884 | } | |
885 | ||
a607032b TC |
886 | my $t = $cgi->param('_t'); |
887 | my @extras; | |
888 | push @extras, _t => $t if defined $t and $t =~ /^\w+$/; | |
889 | ||
08123550 | 890 | return $class->refresh($req, a_showgroup => groupid => $group->{id}, |
a607032b | 891 | 'm' => 'Group saved', @extras); |
08123550 TC |
892 | } |
893 | ||
894 | sub req_savegroupart { | |
895 | my ($class, $req) = @_; | |
896 | ||
9168c88c | 897 | $req->user_can("admin_group_save_artrights") |
a0a8147b | 898 | or return $class->req_groups($req, "You don't have admin_group_save_artrights access"); |
9168c88c | 899 | |
08123550 TC |
900 | my $cgi = $req->cgi; |
901 | my $userid = $cgi->param('userid'); | |
902 | my $groupid = $cgi->param('groupid'); | |
903 | $groupid | |
904 | or return $class->req_groups($req, 'No groupid supplied'); | |
905 | require BSE::TB::AdminGroups; | |
906 | my $group = BSE::TB::AdminGroups->getByPkey($groupid) | |
907 | or return $class->req_groups($req, "Group id $groupid not found"); | |
908 | my $artid = $cgi->param('id'); | |
909 | $artid | |
910 | or return $class->req_showuser($req, 'No article id supplied'); | |
911 | my $article = $class->get_article($artid) | |
912 | or return $class->req_showuser($req, 'No such article'); | |
913 | ||
914 | require BSE::Permissions; | |
915 | my $perms = BSE::Permissions->new($req->cfg); | |
916 | my $perm_map = ''; | |
917 | my @aperms = $cgi->param('aperms'); | |
918 | for my $id (@aperms) { | |
919 | if (length($perm_map) < $id) { | |
920 | $perm_map .= '0' x ($id - length $perm_map); | |
921 | } | |
922 | substr($perm_map, $id, 1) = '1'; | |
923 | } | |
924 | ||
925 | $perms->set_article_perm($artid, $group, $perm_map); | |
926 | ||
927 | return $class->refresh($req, a_showgroupart => groupid => $group->{id}, | |
928 | id=>$artid, 'm' => 'Permissions saved'); | |
929 | } | |
930 | ||
931 | sub req_deluser { | |
932 | my ($class, $req) = @_; | |
933 | ||
9168c88c | 934 | $req->user_can("admin_user_del") |
a0a8147b | 935 | or return $class->req_users($req, "You don't have admin_user_del access"); |
9168c88c | 936 | |
08123550 TC |
937 | my $cgi = $req->cgi; |
938 | my $userid = $cgi->param('userid'); | |
939 | $userid | |
940 | or return $class->req_users($req, 'No userid supplied'); | |
941 | require BSE::TB::AdminUsers; | |
942 | my $user = BSE::TB::AdminUsers->getByPkey($userid) | |
943 | or return $class->req_users($req, "User id $userid not found"); | |
944 | ||
945 | my $logon = $user->{logon}; | |
946 | $user->remove; | |
947 | ||
4010d92e TC |
948 | my $msg = "User '$logon' deleted"; |
949 | ||
950 | $class->_save_htusers($req, \$msg); | |
951 | ||
289a65f1 AO |
952 | $req->audit |
953 | ( | |
954 | component => "admin:users:deluser", | |
955 | object => $user, | |
956 | msg => "Admin User '".$user->logon."' deleted", | |
957 | level => "notice", | |
958 | ); | |
959 | ||
08123550 | 960 | return $class->refresh($req, a_users => |
4010d92e | 961 | 'm' => $msg); |
08123550 TC |
962 | } |
963 | ||
964 | sub req_delgroup { | |
965 | my ($class, $req, $msg) = @_; | |
966 | ||
9168c88c | 967 | $req->user_can("admin_group_del") |
a0a8147b | 968 | or return $class->req_groups($req, "You don't have admin_group_del access"); |
9168c88c | 969 | |
08123550 TC |
970 | my $cgi = $req->cgi; |
971 | my $groupid = $cgi->param('groupid'); | |
972 | $groupid | |
973 | or return $class->req_groups($req, 'No groupid supplied'); | |
974 | require BSE::TB::AdminGroups; | |
975 | my $group = BSE::TB::AdminGroups->getByPkey($groupid) | |
976 | or return $class->req_groups($req, "Group id $groupid not found"); | |
977 | ||
978 | my $name = $group->{name}; | |
979 | $group->remove; | |
980 | ||
981 | return $class->refresh($req, a_groups => | |
982 | 'm' => "Group '$name' deleted"); | |
6473c56f TC |
983 | } |
984 | ||
74b3689a TC |
985 | sub req_unlock { |
986 | my ($class, $req) = @_; | |
987 | ||
988 | $req->user_can("bse_admin_user_unlock") | |
989 | or return $class->req_users($req, "You don't have bse_admin_user_unlock access"); | |
990 | ||
991 | my $cgi = $req->cgi; | |
992 | my $cfg = $req->cfg; | |
993 | my $userid = $cgi->param('userid'); | |
994 | $userid | |
995 | or return $class->req_users($req, 'No userid supplied'); | |
996 | require BSE::TB::AdminUsers; | |
997 | my $user = BSE::TB::AdminUsers->getByPkey($userid) | |
998 | or return $class->req_users($req, "User id $userid not found"); | |
999 | ||
1000 | $user->unlock(request => $req); | |
1001 | $req->flash_notice("msg:bse/admin/user/unlocked", [ $user ]); | |
1002 | ||
1003 | my $uri = $cgi->param("r") || $cfg->admin_url2("adminusers"); | |
1004 | ||
1005 | return $req->get_refresh($uri); | |
1006 | } | |
1007 | ||
1008 | ||
6473c56f | 1009 | 1; |