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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations) (download)
Thu Oct 30 12:11:51 2008 UTC (16 years ago) by wakaba
Branch: MAIN
Changes since 1.4: +17 -3 lines
Favicon support

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 if (defined $group_prop->{favicon_url}) {
447 print q[<link rel=icon href="], htescape ($group_prop->{favicon_url});
448 print q[">];
449 }
450 print q[<h1>];
451 if (defined $group_prop->{favicon_url}) {
452 print q[<img src="], htescape ($group_prop->{favicon_url});
453 print q[" alt="">];
454 }
455 print_text ('Group %s', sub { print $e_group_id });
456 print q[</h1>];
457
458 print q[<section id=props><h2>];
459 print_text ('Properties');
460 print q[</h2>];
461
462 print_prop_list ($ac, $group_prop,
463 {
464 name => 'desc',
465 label => 'Description',
466 field_type => 'textarea',
467 public => 1,
468 },
469 {
470 name => 'admin_group',
471 label => 'Administrative group',
472 field_type => 'text',
473 },
474 {
475 name => 'favicon_url',
476 label => 'Group icon URL',
477 field_type => 'url',
478 },
479 );
480
481 print q[</section><section id=members><h2>];
482 print_text ('Members');
483 print q[</h2>];
484
485 if ($ac->{read_group_member_list}) {
486 my @members;
487 my @apps;
488 my @invited;
489 for my $user_id (get_all_users ()) {
490 my $user_prop = get_user_prop ($user_id);
491 my $gs = $user_prop->{'group.' . $group_id};
492 if ($gs->{member}) {
493 push @members, $user_id;
494 } elsif ($gs->{no_approval}) {
495 push @apps, $user_id;
496 } elsif ($gs->{invited}) {
497 push @invited, $user_id;
498 }
499 }
500
501 if (@members) {
502 print_list_section
503 (id => 'formal-members',
504 title => 'Formal members',
505 items => \@members,
506 print_item => sub {
507 my $user_id = shift;
508 print q[<form action="user.] . htescape ($user_id);
509 print q[" accept-charset=utf-8 method=post>];
510 print qq[<a href="../../users/@{[htescape ($user_id)]}/">];
511 print '' . htescape ($user_id) . q[</a> ];
512 print q[<input type=hidden name=action value=unapprove>];
513 print q[<input type=submit value="];
514 print_text ('Kick');
515 print q["></form>];
516 });
517 }
518
519 if (@apps) {
520 print_list_section
521 (id => 'non-approved-users',
522 title => 'Users who are waiting for the approval to join',
523 items => \@apps,
524 print_item => sub {
525 my $user_id = shift;
526 print q[<form action="user.] . htescape ($user_id);
527 print q[" accept-charset=utf-8 method=post>];
528 print qq[<a href="../../users/@{[htescape ($user_id)]}/">];
529 print '' . htescape ($user_id) . q[</a> ];
530 print q[<input type=hidden name=action value=approve>];
531 print q[<input type=submit value="];
532 print_text ('Approve');
533 print q["></form>];
534 });
535 }
536
537 if (@invited) {
538 print_list_section
539 (id => 'invited-users',
540 title => 'Users who are invited but not joined or are leaved',
541 items => \@invited,
542 print_item => sub {
543 my $user_id = shift;
544 print q[<form action="user.] . htescape ($user_id);
545 print q[" accept-charset=utf-8 method=post>];
546 print qq[<a href="../../users/@{[htescape ($user_id)]}/">];
547 print '' . htescape ($user_id), q[</a> ];
548 print q[<input type=hidden name=action value=unapprove>];
549 print q[<input type=submit value="];
550 print_text ('Cancel invitation');
551 print q["></form>];
552 });
553 }
554 }
555
556 my $join_condition = $group_prop->{join_condition};
557 my $disabled = $ac->{write} ? '' : 'disabled';
558 print qq[<section id=member-approval><h3>];
559 print_text ('Member approval policy');
560 print qq[</h3>
561
562 <form action=join-condition method=post accept-charset=utf-8>
563
564 <p><label><input type=radio name=condition value=invitation $disabled
565 @{[$join_condition->{invitation} ? 'checked' : '']}> ];
566 print_text ('A user who is invited by an administrator of the group can join the group.');
567 print qq[</label>
568
569 <p><label><input type=radio name=condition value=approval $disabled
570 @{[(not $join_condition->{invitation} and $join_condition->{approval})
571 ? 'checked' : '']}> ];
572 print_text ('A user who is invited or approved by an administrator of the group can join the group.');
573 print qq[</label>
574
575 <p><label><input type=radio name=condition value=anyone $disabled
576 @{[(not $join_condition->{invitation} and not
577 $join_condition->{approval}) ? 'checked' : '']}> ];
578 print_text ('Any user can join the group.');
579 print q[</label>];
580 unless ($disabled) {
581 print q[<p><input type=submit value="];
582 print_text ('Change');
583 print q[">];
584 }
585 print q[</form></section>];
586
587 if ($ac->{write}) {
588 print q[<section id=member-invitation><h3>];
589 print_text ('Invite a user');
590 print q[</h3>
591
592 <form action=invite-user accept-charset=utf-8 method=post>
593
594 <p><strong>];
595 print_text ('User id');
596 print q[</strong>: <input type=text name=user-id
597 maxlength=20 size=10 required pattern="[0-9a-z-]{4,20}">
598
599 <p><input type=submit value="];
600 print_text ('Invite');
601 print q["></form></section>];
602 }
603
604 print q[</section>];
605
606 exit;
607 }
608 } elsif ($path[2] eq 'join-condition') {
609 forbidden () unless $ac->{write};
610
611 if ($cgi->request_method eq 'POST') {
612 lock_start ();
613 my $group_prop = get_group_prop ($group_id);
614 if ($group_prop) {
615 binmode STDOUT, ':encoding(utf-8)';
616
617 my $new_condition = $cgi->get_parameter ('condition');
618 if ($new_condition eq 'invitation') {
619 $group_prop->{join_condition}->{invitation} = 1;
620 $group_prop->{join_condition}->{approval} = 1;
621 } elsif ($new_condition eq 'approval') {
622 $group_prop->{join_condition}->{approval} = 1;
623 delete $group_prop->{join_condition}->{invitation};
624 } else {
625 delete $group_prop->{join_condition}->{invitation};
626 delete $group_prop->{join_condition}->{approval};
627 }
628
629 set_group_prop ($group_id, $group_prop);
630 commit ();
631
632 print "Status: 204 join-condition property updated\n\n";
633 exit;
634 }
635 }
636 } elsif ($path[2] eq 'prop') {
637 forbidden () unless $ac->{write};
638
639 if ($cgi->request_method eq 'POST') {
640 lock_start ();
641 my $group_prop = get_group_prop ($group_id);
642 if ($group_prop) {
643 binmode STDOUT, ':encoding(utf-8)';
644
645 my $prop_name = $cgi->get_parameter ('name');
646 if (defined $prop_name and
647 {desc => 1, admin_group => 1,
648 favicon_url => 1}->{$prop_name}) {
649 $group_prop->{$prop_name} = $cgi->get_parameter ('value');
650
651 set_group_prop ($group_id, $group_prop);
652 commit ();
653
654 print "Status: 204 Property updated\n\n";
655 exit;
656 } else {
657 print_error (400, 'Bad property');
658 exit;
659 }
660 }
661 }
662 } elsif ($path[2] =~ /\Auser\.([0-9a-z-]+)\z/ or
663 $path[2] eq 'invite-user') {
664 my $user_id = $1 // $cgi->get_parameter ('user-id') // '';
665 if ($user_id =~ /\A[0-9a-z-]+\z/ and
666 $cgi->request_method eq 'POST') {
667 forbidden () unless $ac->{write};
668
669 lock_start ();
670 my $group_prop = get_group_prop ($group_id);
671 my $user_prop = get_user_prop ($user_id);
672 if ($group_prop and $user_prop) {
673 binmode STDOUT, ':encoding(utf-8)';
674
675 my $gs = ($user_prop->{'group.' . $group_id} ||= {});
676
677 my $action = $cgi->get_parameter ('action');
678 $action = 'approve' if $path[2] eq 'invite-user';
679 my $status;
680 if ($action eq 'approve') {
681 if ($gs->{member}) {
682 $status = 'He is a member';
683 #
684 } elsif ($gs->{no_approval}) {
685 $gs->{member} = 1;
686 delete $gs->{no_approval};
687 $status = 'Registered';
688 #
689 } elsif ($gs->{invited}) {
690 $status = 'He has been invited';
691 #
692 } else {
693 $gs->{invited} = 1;
694 $status = 'Invited';
695 #
696 }
697 } elsif ($action eq 'unapprove') {
698 if ($gs->{member}) {
699 delete $gs->{member};
700 delete $gs->{invited};
701 $status = 'Unregistered';
702 #
703 } elsif ($gs->{invited}) {
704 delete $gs->{invited};
705 $status = 'Invitation canceled';
706 #
707 } else {
708 $status = 'Not a member';
709 #
710 }
711 } else {
712 print_error (400, 'Bad action parameter');
713 exit;
714 }
715
716 set_user_prop ($user_id, $user_prop);
717 regenerate_htpasswd_and_htgroup ();
718 commit ();
719
720 #print "Status: 204 $status\n\n";
721 redirect (303, $status, './#members');
722 exit;
723 }
724 }
725 }
726 } elsif (@path == 1 and $path[0] eq 'new-group') {
727 check_access_right (allowed_groups => {'admin-groups' => 1});
728
729 if ($cgi->request_method eq 'POST') {
730 lock_start ();
731 binmode STDOUT, ':encoding(utf-8)';
732
733 my $group_id = $cgi->get_parameter ('group-id');
734
735 if ($group_id !~ /\A[0-9a-z-]{4,20}\z/) {
736 print_error (400,
737 q[Group id %s is invalid; use characters [0-9a-z-]{4,20}],
738 $group_id);
739 exit;
740 }
741
742 if (get_group_prop ($group_id)) {
743 print_error (400, q[Group id %s is already used], $group_id);
744 exit;
745 }
746
747 my $group_prop = {id => $group_id};
748 set_group_prop ($group_id, $group_prop);
749
750 commit ();
751
752 my $group_url = get_absolute_url ('groups/' . $group_id . '/');
753
754 print qq[Status: 201 Group registered
755 Location: $group_url
756 Content-Type: text/html; charset=utf-8
757
758 <!DOCTYPE HTML>
759 <html lang=en>
760 <title>];
761 print_text ('Group %s registered', sub { print '', htescape ($group_id) });
762 print q[</title>
763 <link rel=stylesheet href="/www/style/html/xhtml">
764 <h1>];
765 print_text ('Group %s registered', sub { print '', htescape ($group_id) });
766 print q[</h1><p>];
767 print_text ('The new group is created successfully.');
768 print q[<p>];
769 print_text ('See %s.', sub {
770 print qq[<a href="@{[htescape ($group_url)]}">];
771 print_text ('the group information page');
772 print qq[</a>];
773 });
774 exit;
775 } else {
776 binmode STDOUT, ":encoding(utf-8)";
777 print q[Content-Type: text/html; charset=utf-8
778
779 <!DOCTYPE HTML>
780 <html lang=en>
781 <title>];
782 print_text ('Create a new group');
783 print q[</title>
784 <link rel=stylesheet href="/www/style/html/xhtml">
785 <h1>];
786 print_text ('Create a new group');
787 print q[</h1>
788
789 <form action=new-group accept-charset=utf-8 method=post>
790
791 <p><strong>];
792 print_text ('Group id');
793 print q[</strong>: <input type=text name=group-id
794 maxlength=20 size=10 required pattern="[0-9a-z-]{4,20}"> (];
795 print_text ('Use [0-9a-z-]{4,20}.');
796 print q[) <p><input type=submit value="];
797 print_text ('Create');
798 print q["></form>];
799 exit;
800 }
801 } elsif (@path == 1 and $path[0] eq '') {
802 my $user_id = $cgi->remote_user;
803 forbidden () if not defined $user_id or $user_id !~ /\A[0-9a-z-]+\z/;
804
805 redirect (303, 'See other', 'users/' . $user_id . '/');
806 exit;
807 } elsif (@path == 0) {
808 redirect (301, 'Moved', 'edit/');
809 exit;
810 }
811
812 print_error (404, 'Not found');
813 exit;
814
815 sub print_list_section (%) {
816 my %opt = @_;
817 $opt{level} ||= 3;
818
819 print q[<section id="] . htescape ($opt{id});
820 print q["><h] . $opt{level} . q[>];
821 print_text ($opt{title});
822 print q[</h] . $opt{level} . q[><ul>];
823 for my $item (sort {$a cmp $b} @{$opt{items}}) {
824 print q[<li>];
825 $opt{print_item}->($item);
826 }
827 print q[</ul></section>];
828 } # print_list_section
829
830 sub print_prop_list ($$@) {
831 my $ac = shift;
832 my $prop_hash = shift;
833
834 for my $prop (@_) {
835 if ($prop->{public}) {
836 print q[<p><strong>];
837 print_text ($prop->{label});
838 print q[</strong>: ];
839 print $prop_hash->{$prop->{name}};
840 }
841
842 if ($ac->{write}) {
843 print q[<form action="prop" accept-charset=utf-8 method=post>];
844 print q[<input type=hidden name=name value="], htescape ($prop->{name}), q[">];
845 if ($prop->{field_type} eq 'textarea') {
846 print q[<p><label><strong>];
847 print_text ($prop->{label});
848 print q[</strong>: <br><textarea name="value"];
849 print q[>], htescape ($prop_hash->{$prop->{name}} // '');
850 print q[</textarea></label>];
851 print q[<p><input type=submit value="];
852 print_text ('Save');
853 print q[">];
854 } else {
855 print q[<p><label><strong>];
856 print_text ($prop->{label});
857 print q[</strong>: <input type="] . $prop->{field_type};
858 print q[" name="value" ];
859 print q[value="], htescape ($prop_hash->{$prop->{name}} // '');
860 print q["></label> ];
861 print q[<input type=submit value="];
862 print_text ('Save');
863 print q[">];
864 }
865 print q[</form>];
866 }
867 }
868 } # print_prop_list
869
870 sub check_access_right (%) {
871 my %opt = @_;
872
873 my $user_id = $cgi->remote_user;
874 forbidden () if not defined $user_id or $user_id !~ /\A[0-9a-z-]+\z/;
875
876 my $user_prop = get_user_prop ($user_id);
877 forbidden () unless $user_prop;
878
879 my $ac = {};
880 my $return_ac;
881
882 if ($opt{allowed_users}->{$user_id}) {
883 $ac->{write} = 1;
884 $return_ac = 1;
885 }
886
887 for my $group_id (keys %{$opt{allowed_groups} or {}}) {
888 my $group_prop = get_group_prop ($group_id);
889 next unless $group_prop;
890
891 my $gs = $user_prop->{'group.' . $group_id};
892 if ($gs->{member}) {
893 return {write => 1, read_group_member_list => 1};
894 }
895 }
896
897 if (defined $opt{group_context}) {
898 my $group_prop = get_group_prop ($opt{group_context});
899 if ($group_prop) {
900 if (defined $group_prop->{admin_group}) {
901 my $ag_prop = get_group_prop ($group_prop->{admin_group});
902 if ($ag_prop and
903 $user_prop->{'group.' . $group_prop->{admin_group}}->{member}) {
904 return {write => 1, read_group_member_list => 1};
905 }
906 }
907
908 my $gs = $user_prop->{'group.' . $opt{group_context}};
909 if ($gs->{member}) {
910 $return_ac = 1;
911 } elsif ($gs->{invited}) {
912 $return_ac = 1;
913 } elsif ($group_prop->{join_condition}->{acception}) {
914 $return_ac = 1;
915 } elsif (not $group_prop->{join_condition}->{invitation}) {
916 $return_ac = 1;
917 }
918 }
919 }
920
921 return $ac if $return_ac;
922
923 forbidden ();
924 } # check_access_right
925
926 sub forbidden () {
927 my $user = $cgi->remote_user;
928 if (defined $user) {
929 print_error (403, q[Forbidden (you've logged in as %s)], $user);
930 } else {
931 print_error (403, 'Forbidden');
932 }
933 exit;
934 } # forbidden
935
936 sub redirect ($$$) {
937 my ($code, $status, $url) = @_;
938
939 my $abs_url = get_absolute_url ($url);
940
941 print qq[Status: $code $status
942 Location: $abs_url
943 Content-Type: text/html; charset=us-ascii
944
945 See <a href="@{[htescape ($abs_url)]}">other page</a>.];
946 } # redirect
947
948 sub percent_decode ($) {
949 return $dom->create_uri_reference ($_[0])
950 ->get_iri_reference
951 ->uri_reference;
952 } # percent_decode
953
954 sub get_absolute_url ($) {
955 return $dom->create_uri_reference ($_[0])
956 ->get_absolute_reference ($cgi->request_uri)
957 ->get_iri_reference
958 ->uri_reference;
959 } # get_absolute_url

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24