]> git.imager.perl.org - bse.git/blame - site/cgi-bin/modules/BSE/AdminUsers.pm
use new style field macros for the file edit page
[bse.git] / site / cgi-bin / modules / BSE / AdminUsers.pm
CommitLineData
6473c56f
TC
1package BSE::AdminUsers;
2use strict;
b553afa2 3use BSE::Util::Tags qw/tag_error_img/;
9168c88c 4use BSE::Permissions;
3f9c8a96 5use BSE::Util::HTML qw(:default popup_menu);
41f10371 6use BSE::CfgInfo qw(admin_base_url);
4d764c34 7use BSE::Template;
74b3689a
TC
8use BSE::TB::AdminUsers;
9use BSE::TB::AdminGroups;
10use BSE::Util::Iterate;
6473c56f 11
e0ed81d7 12our $VERSION = "1.009";
cb7fd78d 13
6473c56f
TC
14my %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
36sub 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
55sub iter_get_users {
56 my ($req) = @_;
57
6473c56f
TC
58 return BSE::TB::AdminUsers->all;
59}
60
61sub iter_get_groups {
62 my ($req) = @_;
63
6473c56f
TC
64 return BSE::TB::AdminGroups->all;
65}
66
67sub 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
76sub 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
85my @saltchars = ('.', '/', 0..9, 'A'..'Z', 'a'..'z');
86
87sub _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 136sub 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
171sub 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
179sub 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 190sub 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
199sub 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
212sub 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
228sub 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
236sub 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
314sub 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
356sub 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
365sub 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
374sub 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
386sub 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 400sub 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
417sub 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
437sub 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
445sub iter_get_aperms {
446 my ($perms) = @_;
447
448 return $perms->article_perms;
449}
450
451sub 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
465sub 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
477sub 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
492sub 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
537sub 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
555sub 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
581sub 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
607sub 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
635sub 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
644sub 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
662sub 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
681sub 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
772sub 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
808sub 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
894sub 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
931sub 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
964sub 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
985sub 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 10091;