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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations) (download)
Wed Oct 29 16:27:15 2008 UTC (16 years, 1 month ago) by wakaba
Branch: MAIN
Changes since 1.1: +200 -46 lines
Properties

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24