/[suikacvs]/test/suika-accounts/edit.cgi
Suika

Contents of /test/suika-accounts/edit.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations) (download)
Thu Oct 30 12:05:49 2008 UTC (15 years, 6 months ago) by wakaba
Branch: MAIN
Changes since 1.3: +4 -3 lines
Use redirect after changing member status

1 #!/usr/bin/perl
2 use strict;
3
4 use lib qw[/home/httpd/html/www/markup/html/whatpm
5 /home/wakaba/work/manakai2/lib];
6
7 use CGI::Carp qw[fatalsToBrowser];
8 require Message::CGI::Carp;
9
10 require 'users.pl';
11 require 'texts.pl';
12
13 require Message::CGI::HTTP;
14 require Encode;
15 my $cgi = Message::CGI::HTTP->new;
16 $cgi->{decoder}->{'#default'} = sub {
17 return Encode::decode ('utf-8', $_[1]);
18 };
19
20 our $Lang = 'ja'
21 if $cgi->get_meta_variable ('HTTP_ACCEPT_LANGUAGE') =~ /\bja\b/; ## TODO: ...
22
23 require Message::DOM::DOMImplementation;
24 my $dom = Message::DOM::DOMImplementation->new;
25
26 my $path = $cgi->path_info;
27 $path = '' unless defined $path;
28
29 my @path = split m#/#, percent_decode ($path), -1;
30 shift @path;
31
32 if (@path == 3 and
33 $path[0] eq 'users' and
34 $path[1] =~ /\A[0-9a-z-]+\z/) {
35 my $user_id = $path[1];
36 my $ac = check_access_right (allowed_users => {$user_id => 1},
37 allowed_groups => {'admin-users' => 1});
38
39 if ($path[2] eq '') {
40 my $user_prop = get_user_prop ($user_id);
41 if ($user_prop) {
42 binmode STDOUT, ':encoding(utf-8)';
43
44 my $e_user_id = htescape ($user_id);
45
46 print q[Content-Type: text/html; charset=utf-8
47
48 <!DOCTYPE HTML>
49 <html lang=en>
50 <title>];
51 print_text ('User %s', sub { print $e_user_id });
52 print q[</title>
53 <link rel=stylesheet href="/www/style/html/xhtml">
54 <h1>];
55 print_text ('User %s', sub { print $e_user_id });
56 print q[</h1>];
57
58 my @joined;
59 my @requested;
60 my @invited;
61 my @can_join;
62 my @can_request;
63 for my $group_id (get_all_groups ()) {
64 my $gs = $user_prop->{'group.' . $group_id};
65 if ($gs->{member}) {
66 push @joined, $group_id;
67 } elsif ($gs->{no_approval}) {
68 push @requested, $group_id;
69 } elsif ($gs->{invited}) {
70 push @invited, $group_id;
71 } else {
72 my $group_prop = get_group_prop ($group_id);
73 if ($group_prop->{join_condition}->{invitation}) {
74 #
75 } elsif ($group_prop->{join_condition}->{approval}) {
76 push @can_request, $group_id;
77 } else {
78 push @can_join, $group_id;
79 }
80 }
81 }
82
83 print q[<section id=groups><h2>];
84 print_text ('Groups');
85 print q[</h2>];
86
87 if (@joined) {
88 print_list_section
89 (id => 'groups-joined',
90 title => 'Groups you have joined',
91 items => \@joined,
92 print_item => sub {
93 my $group_id = shift;
94 print q[<form action="group.] . htescape ($group_id);
95 print q[" accept-charset=utf-8 method=post>];
96 print q[<a href="../../groups/].htescape ($group_id) . '/';
97 print q[">] . htescape ($group_id), q[</a> ];
98 print q[<input type=hidden name=action value=leave>];
99 print q[<input type=submit value="];
100 print_text ('Leave this group');
101 print q["></form>];
102 });
103 }
104
105 if (@requested) {
106 print_list_section
107 (id => 'groups-requested',
108 title => 'Groups you have requested to join but not approved yet',
109 items => \@requested,
110 print_item => sub {
111 my $group_id = shift;
112 print q[<form action="group.] . htescape ($group_id);
113 print q[" accept-charset=utf-8 method=post>];
114 print q[<a href="../../groups/].htescape ($group_id) . '/';
115 print q[">] . htescape ($group_id), q[</a> ];
116 print q[<input type=hidden name=action value=leave>];
117 print q[<input type=submit value="];
118 print_text ('Cancel the request');
119 print q["></form>];
120 });
121 }
122
123 if (@invited) {
124 print_list_section
125 (id => 'groups-invited',
126 title => 'Groups you have been invited but not joined yet, or you have left',
127 items => \@invited,
128 print_item => sub {
129 my $group_id = shift;
130 print q[<form action="group.] . htescape ($group_id);
131 print q[" accept-charset=utf-8 method=post>];
132 print q[<a href="../../groups/].htescape ($group_id) . '/';
133 print q[">] . htescape ($group_id), q[</a> ];
134 print q[<input type=hidden name=action value=join>];
135 print q[<input type=submit value="];
136 print_text ('Join this group');
137 print q["></form>];
138 });
139 }
140
141 if (@can_join) {
142 print_list_section
143 (id => 'groups-can-join',
144 title => 'Groups you can join now (without approval)',
145 items => \@can_join,
146 print_item => sub {
147 my $group_id = shift;
148 print q[<form action="group.] . htescape ($group_id);
149 print q[" accept-charset=utf-8 method=post>];
150 print q[<a href="../../groups/].htescape ($group_id) . '/';
151 print q[">] . htescape ($group_id), q[</a>];
152 print q[<input type=hidden name=action value=join> ];
153 print q[<input type=submit value="];
154 print_text ('Join this group');
155 print q["></form>];
156 });
157 }
158
159 if (@can_request) {
160 print_list_section
161 (id => 'groups-can-request',
162 title => 'Groups you can request to join (approval required to join)',
163 items => \@can_request,
164 print_item => sub {
165 my $group_id = shift;
166 print q[<form action="group.] . htescape ($group_id);
167 print q[" accept-charset=utf-8 method=post>];
168 print q[<a href="../../groups/].htescape ($group_id) . '/';
169 print q[">] . htescape ($group_id), q[</a> ];
170 print q[<input type=hidden name=action value=join>];
171 print q[<input type=submit value="];
172 print_text ('Join this group');
173 print q["></form>];
174 });
175 }
176
177 print q[</section><section id=props><h2>];
178 print_text ('Properties');
179 print q[</h2><p><em>];
180 print_text (q[Don't expose any confidential data.]);
181 print q[</em>];
182
183 print_prop_list ($ac, $user_prop,
184 {
185 name => 'full_name',
186 label => 'Full name',
187 field_type => 'text',
188 },
189 {
190 name => 'mail_addr',
191 label => 'Mail address',
192 field_type => 'email',
193 },
194 {
195 name => 'home_url',
196 label => 'Web site URL',
197 field_type => 'url',
198 },
199 );
200
201 print qq[</section><section id=password><h2>];
202 print_text ('Password');
203 print q[</h2>
204
205 <form action=password method=post accept-charset=utf-8>
206
207 <p>];
208 print_text ('You can change the password.');
209
210 print q[<p><strong>];
211 print_text ('New password');
212 print q[</strong>: <input type=password name=user-pass
213 size=10 required pattern=".{4,}"> (];
214 print_text ('Type 4 characters at minimum');
215 print q[) <p><strong>];
216 print_text ('New password');
217 print q[</strong> (];
218 print_text ('type again');
219 print q[): <input type=password
220 name=user-pass2 size=10 required pattern=".{4,}">
221
222 <p><input type=submit value="];
223 print_text ('Change');
224 print q[">
225
226 </form>
227 </section>
228
229 <section id=disable-account><h2>];
230 print_text ('Disable account');
231 print q[</h2>
232
233 <form action=disabled method=post accept-charset=utf-8>
234
235 <p><label><input type=checkbox name=action value=enable ];
236 print 'checked' unless $user_prop->{disabled};
237 print q[> ];
238 print_text ('Enable this account');
239 print q[</label>
240
241 <p><strong>];
242 print_text ('Caution!');
243 print q[</strong> ];
244 print_text ('Once you disable your own account, you cannot enable your account by yourself.');
245
246 print q[<p><input type=submit value="];
247 print_text ('Change');
248
249 print q["></form></section>];
250
251 exit;
252 }
253 } elsif ($path[2] =~ /\Agroup\.([0-9a-z-]+)\z/) {
254 my $group_id = $1;
255 if ($cgi->request_method eq 'POST') {
256 lock_start ();
257 binmode STDOUT, ':encoding(utf-8)';
258
259 my $user_prop = get_user_prop ($user_id);
260 my $group_prop = get_group_prop ($group_id);
261
262 if ($user_prop and $group_prop) {
263 my $gs = ($user_prop->{'group.' . $group_id} ||= {});
264
265 my $action = $cgi->get_parameter ('action');
266 my $status;
267 if ($action eq 'join') {
268 if (scalar $cgi->get_parameter ('agreed')) {
269 if ($gs->{member}) {
270 $status = q[You are a member];
271 #
272 } elsif ($gs->{no_approval}) {
273 $status = q[You are waiting for an approval];
274 #
275 } elsif ($gs->{invited}) {
276 $gs->{member} = 1;
277 $status = q[Registered];
278 #
279 } else {
280 if ($group_prop->{join_condition}->{invitation}) {
281 print_error (403, 'You are not invited to this group');
282 exit;
283 } elsif ($group_prop->{join_condition}->{approval}) {
284 $gs->{no_approval} = 1;
285 $status = q[Request submitted];
286 #
287 } else {
288 $gs->{member} = 1;
289 $status = q[Registered];
290 #
291 }
292 }
293 } else {
294 my $e_group_id = htescape ($group_id);
295 print q[Content-Type: text/html; charset=utf-8
296
297 <!DOCTYPE HTML>
298 <html lang=en>
299 <title>];
300 print_text ('Joining the group %s', sub { print $e_group_id });
301 print q[</title>
302 <link rel=stylesheet href="/www/style/html/xhtml">
303 <h1>];
304 print_text ('Joining the group %s', sub { print $e_group_id });
305 print q[</h1>
306
307 <dl>
308 <dt>];
309 print_text ('Description');
310 print qq[<dd>@{[$group_prop->{desc}]}
311 </dl>
312
313 <form action="@{[htescape ($cgi->request_uri)]}" accept-charset=utf-8 method=post>
314 <input type=hidden name=action value=join>
315
316 <p>];
317 print_text ('Do you really want to join this group?');
318 print q[ <input type=submit name=agreed value="];
319 print_text ('Yes');
320 print q["> <input type=button value="];
321 print_text ('No');
322 print q[" onclick="history.back ()"></form>];
323 exit;
324 }
325 } elsif ($action eq 'leave') {
326 if ($gs->{member}) {
327 delete $gs->{member};
328 $gs->{invited} = 1;
329 $status = 'Unregistered';
330 #
331 } elsif ($gs->{no_approval}) {
332 delete $gs->{no_approval};
333 delete $gs->{invited};
334 $status = 'Request canceled';
335 #
336 } else {
337 $status = 'You are not a member';
338 #
339 }
340 } else {
341 print_error (400, 'Bad action parameter');
342 exit;
343 }
344
345 set_user_prop ($user_id, $user_prop);
346 regenerate_htpasswd_and_htgroup ();
347 commit ();
348
349 redirect (303, $status, './#groups');
350 exit;
351 }
352 }
353 } elsif ($path[2] eq 'password') {
354 if ($cgi->request_method eq 'POST') {
355 lock_start ();
356 binmode STDOUT, ':encoding(utf-8)';
357
358 my $user_prop = get_user_prop ($user_id);
359
360 if ($user_prop) {
361 $user_prop->{pass_crypted} = check_password ($cgi);
362
363 set_user_prop ($user_id, $user_prop);
364 regenerate_htpasswd_and_htgroup ();
365 commit ();
366
367 ## Browsers do not support 205.
368 #print qq[Status: 205 Password changed\n\n];
369 print qq[Status: 204 Password changed\n\n];
370 exit;
371 }
372 }
373 } elsif ($path[2] eq 'disabled') {
374 if ($cgi->request_method eq 'POST') {
375 lock_start ();
376 binmode STDOUT, ':encoding(utf-8)';
377
378 my $user_prop = get_user_prop ($user_id);
379
380 if ($user_prop) {
381 my $action = $cgi->get_parameter ('action');
382 if (defined $action and $action eq 'enable') {
383 delete $user_prop->{disabled};
384 } else {
385 $user_prop->{disabled} = 1;
386 }
387
388 set_user_prop ($user_id, $user_prop);
389 regenerate_htpasswd_and_htgroup ();
390 commit ();
391
392 print "Status: 204 Property updated\n\n";
393 exit;
394 }
395 }
396 } elsif ($path[2] eq 'prop') {
397 if ($cgi->request_method eq 'POST') {
398 lock_start ();
399 my $user_prop = get_user_prop ($user_id);
400 if ($user_prop) {
401 binmode STDOUT, ':encoding(utf-8)';
402
403 my $prop_name = $cgi->get_parameter ('name');
404 if (defined $prop_name and
405 {
406 full_name => 1,
407 mail_addr => 1,
408 home_url => 1,
409 }->{$prop_name}) {
410 $user_prop->{$prop_name} = $cgi->get_parameter ('value');
411
412 set_user_prop ($user_id, $user_prop);
413 commit ();
414
415 print "Status: 204 Property updated\n\n";
416 exit;
417 } else {
418 print_error (400, 'Bad property');
419 exit;
420 }
421 }
422 }
423 }
424 } elsif (@path == 3 and
425 $path[0] eq 'groups' and
426 $path[1] =~ /\A[0-9a-z-]+\z/) {
427 my $group_id = $path[1];
428 my $ac = check_access_right (allowed_groups => {'admin-groups' => 1},
429 group_context => $group_id);
430
431 if ($path[2] eq '') {
432 my $group_prop = get_group_prop ($group_id);
433 if ($group_prop) {
434 binmode STDOUT, ':encoding(utf-8)';
435
436 my $e_group_id = htescape ($group_id);
437
438 print q[Content-Type: text/html; charset=utf-8
439
440 <!DOCTYPE HTML>
441 <html lang=en>
442 <title>];
443 print_text ('Group %s', sub { print $e_group_id });
444 print q[</title>
445 <link rel=stylesheet href="/www/style/html/xhtml">
446 <h1>];
447 print_text ('Group %s', sub { print $e_group_id });
448 print q[</h1>];
449
450 print q[<section id=props><h2>];
451 print_text ('Properties');
452 print q[</h2>];
453
454 print_prop_list ($ac, $group_prop,
455 {
456 name => 'desc',
457 label => 'Description',
458 field_type => 'textarea',
459 public => 1,
460 },
461 {
462 name => 'admin_group',
463 label => 'Administrative group',
464 field_type => 'text',
465 },
466 );
467
468 print q[</section><section id=members><h2>];
469 print_text ('Members');
470 print q[</h2>];
471
472 if ($ac->{read_group_member_list}) {
473 my @members;
474 my @apps;
475 my @invited;
476 for my $user_id (get_all_users ()) {
477 my $user_prop = get_user_prop ($user_id);
478 my $gs = $user_prop->{'group.' . $group_id};
479 if ($gs->{member}) {
480 push @members, $user_id;
481 } elsif ($gs->{no_approval}) {
482 push @apps, $user_id;
483 } elsif ($gs->{invited}) {
484 push @invited, $user_id;
485 }
486 }
487
488 if (@members) {
489 print_list_section
490 (id => 'formal-members',
491 title => 'Formal members',
492 items => \@members,
493 print_item => sub {
494 my $user_id = shift;
495 print q[<form action="user.] . htescape ($user_id);
496 print q[" accept-charset=utf-8 method=post>];
497 print qq[<a href="../../users/@{[htescape ($user_id)]}/">];
498 print '' . htescape ($user_id) . q[</a> ];
499 print q[<input type=hidden name=action value=unapprove>];
500 print q[<input type=submit value="];
501 print_text ('Kick');
502 print q["></form>];
503 });
504 }
505
506 if (@apps) {
507 print_list_section
508 (id => 'non-approved-users',
509 title => 'Users who are waiting for the approval to join',
510 items => \@apps,
511 print_item => sub {
512 my $user_id = shift;
513 print q[<form action="user.] . htescape ($user_id);
514 print q[" accept-charset=utf-8 method=post>];
515 print qq[<a href="../../users/@{[htescape ($user_id)]}/">];
516 print '' . htescape ($user_id) . q[</a> ];
517 print q[<input type=hidden name=action value=approve>];
518 print q[<input type=submit value="];
519 print_text ('Approve');
520 print q["></form>];
521 });
522 }
523
524 if (@invited) {
525 print_list_section
526 (id => 'invited-users',
527 title => 'Users who are invited but not joined or are leaved',
528 items => \@invited,
529 print_item => sub {
530 my $user_id = shift;
531 print q[<form action="user.] . htescape ($user_id);
532 print q[" accept-charset=utf-8 method=post>];
533 print qq[<a href="../../users/@{[htescape ($user_id)]}/">];
534 print '' . htescape ($user_id), q[</a> ];
535 print q[<input type=hidden name=action value=unapprove>];
536 print q[<input type=submit value="];
537 print_text ('Cancel invitation');
538 print q["></form>];
539 });
540 }
541 }
542
543 my $join_condition = $group_prop->{join_condition};
544 my $disabled = $ac->{write} ? '' : 'disabled';
545 print qq[<section id=member-approval><h3>];
546 print_text ('Member approval policy');
547 print qq[</h3>
548
549 <form action=join-condition method=post accept-charset=utf-8>
550
551 <p><label><input type=radio name=condition value=invitation $disabled
552 @{[$join_condition->{invitation} ? 'checked' : '']}> ];
553 print_text ('A user who is invited by an administrator of the group can join the group.');
554 print qq[</label>
555
556 <p><label><input type=radio name=condition value=approval $disabled
557 @{[(not $join_condition->{invitation} and $join_condition->{approval})
558 ? 'checked' : '']}> ];
559 print_text ('A user who is invited or approved by an administrator of the group can join the group.');
560 print qq[</label>
561
562 <p><label><input type=radio name=condition value=anyone $disabled
563 @{[(not $join_condition->{invitation} and not
564 $join_condition->{approval}) ? 'checked' : '']}> ];
565 print_text ('Any user can join the group.');
566 print q[</label>];
567 unless ($disabled) {
568 print q[<p><input type=submit value="];
569 print_text ('Change');
570 print q[">];
571 }
572 print q[</form></section>];
573
574 if ($ac->{write}) {
575 print q[<section id=member-invitation><h3>];
576 print_text ('Invite a user');
577 print q[</h3>
578
579 <form action=invite-user accept-charset=utf-8 method=post>
580
581 <p><strong>];
582 print_text ('User id');
583 print q[</strong>: <input type=text name=user-id
584 maxlength=20 size=10 required pattern="[0-9a-z-]{4,20}">
585
586 <p><input type=submit value="];
587 print_text ('Invite');
588 print q["></form></section>];
589 }
590
591 print q[</section>];
592
593 exit;
594 }
595 } elsif ($path[2] eq 'join-condition') {
596 forbidden () unless $ac->{write};
597
598 if ($cgi->request_method eq 'POST') {
599 lock_start ();
600 my $group_prop = get_group_prop ($group_id);
601 if ($group_prop) {
602 binmode STDOUT, ':encoding(utf-8)';
603
604 my $new_condition = $cgi->get_parameter ('condition');
605 if ($new_condition eq 'invitation') {
606 $group_prop->{join_condition}->{invitation} = 1;
607 $group_prop->{join_condition}->{approval} = 1;
608 } elsif ($new_condition eq 'approval') {
609 $group_prop->{join_condition}->{approval} = 1;
610 delete $group_prop->{join_condition}->{invitation};
611 } else {
612 delete $group_prop->{join_condition}->{invitation};
613 delete $group_prop->{join_condition}->{approval};
614 }
615
616 set_group_prop ($group_id, $group_prop);
617 commit ();
618
619 print "Status: 204 join-condition property updated\n\n";
620 exit;
621 }
622 }
623 } elsif ($path[2] eq 'prop') {
624 forbidden () unless $ac->{write};
625
626 if ($cgi->request_method eq 'POST') {
627 lock_start ();
628 my $group_prop = get_group_prop ($group_id);
629 if ($group_prop) {
630 binmode STDOUT, ':encoding(utf-8)';
631
632 my $prop_name = $cgi->get_parameter ('name');
633 if (defined $prop_name and
634 {desc => 1, admin_group => 1}->{$prop_name}) {
635 $group_prop->{$prop_name} = $cgi->get_parameter ('value');
636
637 set_group_prop ($group_id, $group_prop);
638 commit ();
639
640 print "Status: 204 Property updated\n\n";
641 exit;
642 } else {
643 print_error (400, 'Bad property');
644 exit;
645 }
646 }
647 }
648 } elsif ($path[2] =~ /\Auser\.([0-9a-z-]+)\z/ or
649 $path[2] eq 'invite-user') {
650 my $user_id = $1 // $cgi->get_parameter ('user-id') // '';
651 if ($user_id =~ /\A[0-9a-z-]+\z/ and
652 $cgi->request_method eq 'POST') {
653 forbidden () unless $ac->{write};
654
655 lock_start ();
656 my $group_prop = get_group_prop ($group_id);
657 my $user_prop = get_user_prop ($user_id);
658 if ($group_prop and $user_prop) {
659 binmode STDOUT, ':encoding(utf-8)';
660
661 my $gs = ($user_prop->{'group.' . $group_id} ||= {});
662
663 my $action = $cgi->get_parameter ('action');
664 $action = 'approve' if $path[2] eq 'invite-user';
665 my $status;
666 if ($action eq 'approve') {
667 if ($gs->{member}) {
668 $status = 'He is a member';
669 #
670 } elsif ($gs->{no_approval}) {
671 $gs->{member} = 1;
672 delete $gs->{no_approval};
673 $status = 'Registered';
674 #
675 } elsif ($gs->{invited}) {
676 $status = 'He has been invited';
677 #
678 } else {
679 $gs->{invited} = 1;
680 $status = 'Invited';
681 #
682 }
683 } elsif ($action eq 'unapprove') {
684 if ($gs->{member}) {
685 delete $gs->{member};
686 delete $gs->{invited};
687 $status = 'Unregistered';
688 #
689 } elsif ($gs->{invited}) {
690 delete $gs->{invited};
691 $status = 'Invitation canceled';
692 #
693 } else {
694 $status = 'Not a member';
695 #
696 }
697 } else {
698 print_error (400, 'Bad action parameter');
699 exit;
700 }
701
702 set_user_prop ($user_id, $user_prop);
703 regenerate_htpasswd_and_htgroup ();
704 commit ();
705
706 #print "Status: 204 $status\n\n";
707 redirect (303, $status, './#members');
708 exit;
709 }
710 }
711 }
712 } elsif (@path == 1 and $path[0] eq 'new-group') {
713 check_access_right (allowed_groups => {'admin-groups' => 1});
714
715 if ($cgi->request_method eq 'POST') {
716 lock_start ();
717 binmode STDOUT, ':encoding(utf-8)';
718
719 my $group_id = $cgi->get_parameter ('group-id');
720
721 if ($group_id !~ /\A[0-9a-z-]{4,20}\z/) {
722 print_error (400,
723 q[Group id %s is invalid; use characters [0-9a-z-]{4,20}],
724 $group_id);
725 exit;
726 }
727
728 if (get_group_prop ($group_id)) {
729 print_error (400, q[Group id %s is already used], $group_id);
730 exit;
731 }
732
733 my $group_prop = {id => $group_id};
734 set_group_prop ($group_id, $group_prop);
735
736 commit ();
737
738 my $group_url = get_absolute_url ('groups/' . $group_id . '/');
739
740 print qq[Status: 201 Group registered
741 Location: $group_url
742 Content-Type: text/html; charset=utf-8
743
744 <!DOCTYPE HTML>
745 <html lang=en>
746 <title>];
747 print_text ('Group %s registered', sub { print '', htescape ($group_id) });
748 print q[</title>
749 <link rel=stylesheet href="/www/style/html/xhtml">
750 <h1>];
751 print_text ('Group %s registered', sub { print '', htescape ($group_id) });
752 print q[</h1><p>];
753 print_text ('The new group is created successfully.');
754 print q[<p>];
755 print_text ('See %s.', sub {
756 print qq[<a href="@{[htescape ($group_url)]}">];
757 print_text ('the group information page');
758 print qq[</a>];
759 });
760 exit;
761 } else {
762 binmode STDOUT, ":encoding(utf-8)";
763 print q[Content-Type: text/html; charset=utf-8
764
765 <!DOCTYPE HTML>
766 <html lang=en>
767 <title>];
768 print_text ('Create a new group');
769 print q[</title>
770 <link rel=stylesheet href="/www/style/html/xhtml">
771 <h1>];
772 print_text ('Create a new group');
773 print q[</h1>
774
775 <form action=new-group accept-charset=utf-8 method=post>
776
777 <p><strong>];
778 print_text ('Group id');
779 print q[</strong>: <input type=text name=group-id
780 maxlength=20 size=10 required pattern="[0-9a-z-]{4,20}"> (];
781 print_text ('Use [0-9a-z-]{4,20}.');
782 print q[) <p><input type=submit value="];
783 print_text ('Create');
784 print q["></form>];
785 exit;
786 }
787 } elsif (@path == 1 and $path[0] eq '') {
788 my $user_id = $cgi->remote_user;
789 forbidden () if not defined $user_id or $user_id !~ /\A[0-9a-z-]+\z/;
790
791 redirect (303, 'See other', 'users/' . $user_id . '/');
792 exit;
793 } elsif (@path == 0) {
794 redirect (301, 'Moved', 'edit/');
795 exit;
796 }
797
798 print_error (404, 'Not found');
799 exit;
800
801 sub print_list_section (%) {
802 my %opt = @_;
803 $opt{level} ||= 3;
804
805 print q[<section id="] . htescape ($opt{id});
806 print q["><h] . $opt{level} . q[>];
807 print_text ($opt{title});
808 print q[</h] . $opt{level} . q[><ul>];
809 for my $item (sort {$a cmp $b} @{$opt{items}}) {
810 print q[<li>];
811 $opt{print_item}->($item);
812 }
813 print q[</ul></section>];
814 } # print_list_section
815
816 sub print_prop_list ($$@) {
817 my $ac = shift;
818 my $prop_hash = shift;
819
820 for my $prop (@_) {
821 if ($prop->{public}) {
822 print q[<p><strong>];
823 print_text ($prop->{label});
824 print q[</strong>: ];
825 print $prop_hash->{$prop->{name}};
826 }
827
828 if ($ac->{write}) {
829 print q[<form action="prop" accept-charset=utf-8 method=post>];
830 print q[<input type=hidden name=name value="], htescape ($prop->{name}), q[">];
831 if ($prop->{field_type} eq 'textarea') {
832 print q[<p><label><strong>];
833 print_text ($prop->{label});
834 print q[</strong>: <br><textarea name="value"];
835 print q[>], htescape ($prop_hash->{$prop->{name}} // '');
836 print q[</textarea></label>];
837 print q[<p><input type=submit value="];
838 print_text ('Save');
839 print q[">];
840 } else {
841 print q[<p><label><strong>];
842 print_text ($prop->{label});
843 print q[</strong>: <input type="] . $prop->{field_type};
844 print q[" name="value" ];
845 print q[value="], htescape ($prop_hash->{$prop->{name}} // '');
846 print q["></label> ];
847 print q[<input type=submit value="];
848 print_text ('Save');
849 print q[">];
850 }
851 print q[</form>];
852 }
853 }
854 } # print_prop_list
855
856 sub check_access_right (%) {
857 my %opt = @_;
858
859 my $user_id = $cgi->remote_user;
860 forbidden () if not defined $user_id or $user_id !~ /\A[0-9a-z-]+\z/;
861
862 my $user_prop = get_user_prop ($user_id);
863 forbidden () unless $user_prop;
864
865 my $ac = {};
866 my $return_ac;
867
868 if ($opt{allowed_users}->{$user_id}) {
869 $ac->{write} = 1;
870 $return_ac = 1;
871 }
872
873 for my $group_id (keys %{$opt{allowed_groups} or {}}) {
874 my $group_prop = get_group_prop ($group_id);
875 next unless $group_prop;
876
877 my $gs = $user_prop->{'group.' . $group_id};
878 if ($gs->{member}) {
879 return {write => 1, read_group_member_list => 1};
880 }
881 }
882
883 if (defined $opt{group_context}) {
884 my $group_prop = get_group_prop ($opt{group_context});
885 if ($group_prop) {
886 if (defined $group_prop->{admin_group}) {
887 my $ag_prop = get_group_prop ($group_prop->{admin_group});
888 if ($ag_prop and
889 $user_prop->{'group.' . $group_prop->{admin_group}}->{member}) {
890 return {write => 1, read_group_member_list => 1};
891 }
892 }
893
894 my $gs = $user_prop->{'group.' . $opt{group_context}};
895 if ($gs->{member}) {
896 $return_ac = 1;
897 } elsif ($gs->{invited}) {
898 $return_ac = 1;
899 } elsif ($group_prop->{join_condition}->{acception}) {
900 $return_ac = 1;
901 } elsif (not $group_prop->{join_condition}->{invitation}) {
902 $return_ac = 1;
903 }
904 }
905 }
906
907 return $ac if $return_ac;
908
909 forbidden ();
910 } # check_access_right
911
912 sub forbidden () {
913 my $user = $cgi->remote_user;
914 if (defined $user) {
915 print_error (403, q[Forbidden (you've logged in as %s)], $user);
916 } else {
917 print_error (403, 'Forbidden');
918 }
919 exit;
920 } # forbidden
921
922 sub redirect ($$$) {
923 my ($code, $status, $url) = @_;
924
925 my $abs_url = get_absolute_url ($url);
926
927 print qq[Status: $code $status
928 Location: $abs_url
929 Content-Type: text/html; charset=us-ascii
930
931 See <a href="@{[htescape ($abs_url)]}">other page</a>.];
932 } # redirect
933
934 sub percent_decode ($) {
935 return $dom->create_uri_reference ($_[0])
936 ->get_iri_reference
937 ->uri_reference;
938 } # percent_decode
939
940 sub get_absolute_url ($) {
941 return $dom->create_uri_reference ($_[0])
942 ->get_absolute_reference ($cgi->request_uri)
943 ->get_iri_reference
944 ->uri_reference;
945 } # get_absolute_url

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24