]> mj.ucw.cz Git - pciids.git/blob - PciIds/Html/Admin.pm
c1ef0517a6ff110923607cfdcc294b4fd66437d2
[pciids.git] / PciIds / Html / Admin.pm
1 package PciIds::Html::Admin;
2 use strict;
3 use warnings;
4 use PciIds::Users;
5 use PciIds::Html::Util;
6 use PciIds::Html::Users;
7 use PciIds::Html::Forms;
8 use PciIds::Notifications;
9 use PciIds::Address;
10 use PciIds::Log;
11 use Apache2::Const qw(:common :http);
12
13 sub safeEncode( $ ) {
14         my( $text ) = @_;
15         return encode( $text ) if defined $text;
16         return '';
17 }
18
19 sub mailEncode( $ ) {
20         my( $email ) = @_;
21         return '' unless defined $email;
22         return "<a href='mailto:$email'>".encode( $email )."</a>";
23 }
24
25 sub genNewAdminForm( $$$$$ ) {
26         my( $req, $args, $tables, $error, $auth ) = @_;
27         my $address = PciIds::Address::new( $req->uri() );
28         my $prefix = $address->get();
29         $prefix = '' if( $args->{'global'} );
30         my $caption = 'Administration '.( $args->{'global'} ? '(Global)' : '('.encode( $address->pretty() ).')' );
31         genHtmlHead( $req, $caption, undef );
32         my $glob = delete $args->{'global'};
33         genCustomHead( $req, $args, $address, $caption, [ $address->canAddItem() ? [ 'Add item', 'newitem' ] : (), $address->canDiscuss() ? [ 'Discuss', 'newhistory' ] : (), $glob ? [ 'Local', 'admin' ] : [ 'Global', 'admin?global=1' ], [ 'Help', 'help', 'admin' ], [ '', 'jump' ] ], [ [ 'Log out', 'logout' ] ] );
34         print "<div class='error'>$error</div>\n" if( defined $error );
35         print "<form name='admin' id='admin' class='admin' method='POST' action=''>\n";
36         my $lastId;
37         my $started = 0;
38         my $cnt = 0;
39         my $hiscnt = 0;
40         my $subcnt;
41         print "<p><input type='checkbox' name='default-seen' value='default-seen' checked='checked'> Any action approves all discussion\n";
42         print "<table class='admin'>\n";
43         print "<col class='id-col'><col class='name-col'><col class='note-col'><col class='disc-col'><col class='auth-col'><col class='control-col' span='3'>\n";
44         print "<tr class='head'><th>ID<th>Name<th>Note<th>Discussion<th>Author<th>Ok<th>Sel<th>Del\n";
45         foreach( @{$tables->adminDump( $prefix )} ) {
46                 my( $locId, $actName, $actNote, $actHist, $actUser, $actDisc,
47                         $hist, $disc, $name, $note, $user ) = @{$_};
48                 if( !defined( $lastId ) || ( $lastId ne $locId ) ) {
49                         last if( $hiscnt > 80 );
50                         $lastId = $locId;
51                         $started = 1;
52                         my $addr = PciIds::Address::new( $locId );
53                         if( defined( $actHist ) ) {
54                                 print "<tr class='item'>";
55                         } else {
56                                 print "<tr class='unnamedItem'>";
57                         }
58                         print "<td><a href='/read/".$addr->get()."'>".encode( $addr->pretty() )."</a><td>".safeEncode( $actName )."<td>".safeEncode( $actNote )."<td>".safeEncode( $actDisc )."<td>".mailEncode( $actUser );
59
60                         print "<input type='hidden' name='loc-$cnt-subcnt' value='$subcnt'>" if( $subcnt );
61                         $subcnt = 0;
62                         $cnt++;
63                         print "<input type='hidden' name='loc-$cnt' value='".$addr->get()."'>\n";
64                         print "<td class='empty'>";
65                         print "<td><input type='radio' name='loc-$cnt-sel' value='curr' checked='checked'>";
66                         if( hasRight( $auth->{'accrights'}, 'prune' ) || ( !defined $actHist && !$tables->hasChildren( $addr->get() ) ) ) {
67                                 print "<td><input type='checkbox' name='loc-$cnt-del' value='del'>\n";
68                         } else {
69                                 print "<td class='empty'>";
70                         }
71                         print "<tr class='new'><td>New:<td><input type='text' name='name-$cnt' class='text'><td><input type='text' name='note-$cnt' class='text'><td><textarea name='disc-$cnt'></textarea>\n";
72                         print "<td colspan='3'>";
73                         genPathBare( $req, $addr, 0, 0 );
74                         print "<td><input type='checkbox' name='loc-$cnt-softdel' value='del'>\n";
75                 }
76                 print "<tr class='unseen-history'><td class='empty'><td>".safeEncode( ( defined $name && $name eq '' ) ? 'Deletion request' : $name )."<td>".safeEncode( $note )."<td>".safeEncode( $disc )."<td>".mailEncode( $user );
77                 $hiscnt ++;
78                 $subcnt ++;
79                 print "<input type='hidden' name='his-$cnt-$subcnt' value='$hist'>";
80                 print "<td><input type='checkbox' name='appr-$hiscnt' value='appr-$hist'>";
81                 if( defined $name ) {
82                         print "<td><input type='radio' name='loc-$cnt-sel' value='$hist'>";
83                 } else {
84                         print "<td class='empty'>";
85                 }
86                 print "<td><input type='checkbox' name='del-$hiscnt' value='del-$hist'>";
87                 print "<input type='hidden' name='owner-$hist' value='$lastId'>\n";
88         }
89         print "</table>\n";
90         print "<input type='hidden' name='subcnt-$cnt' value='$subcnt'>\n" if( defined( $subcnt ) );
91         if( $started ) {
92                 print "<input type='hidden' name='loc-$cnt-subcnt' value='$subcnt'>" if( $subcnt );
93                 print "<p><input type='submit' name='submit' value='Submit'>\n";
94                 print "<input type='hidden' name='max-cnt' value='$cnt'><input type='hidden' name='max-hiscnt' value='$hiscnt'>\n";
95         } else {
96                 print "<p>No pending items.\n";
97         }
98         print "</form>\n";
99         genHtmlTail();
100         return OK;
101 }
102
103 sub adminForm( $$$$ ) {
104         my( $req, $args, $tables, $auth ) = @_;
105         if( defined( $auth->{'authid'} ) && hasRight( $auth->{'accrights'}, 'validate' ) ) {
106                 return genNewAdminForm( $req, $args, $tables, undef, $auth );
107         } else {
108                 return notLoggedComplaint( $req, $args, $auth );
109         }
110 }
111
112 my $errors;
113
114 sub appendError( $ ) {
115         if( $errors eq '' ) {
116                 $errors = "<p>".shift;
117         } else {
118                 $errors .= "<br>".shift;
119         }
120 }
121
122 sub submitAdminForm( $$$$ ) {
123         my( $req, $args, $tables, $auth ) = @_;
124         my $authid = $auth->{'authid'};
125         if( defined( $authid ) && hasRight( $auth->{'accrights'}, 'validate' ) ) {
126                 my( %deleted, %approved );
127                 my $maxcnt = getFormValue( 'max-cnt', 0 );
128                 my $maxhiscnt = getFormValue( 'max-hiscnt', 0 );
129                 $errors = '';
130                 # Scan for approved and deleted items
131                 for( my $i = 1; $i <= $maxhiscnt; $i ++ ) {
132                         my( $del ) = getFormValue( "del-$i", '' ) =~ /^del-(\d+)$/;
133                         $deleted{$del} = 1 if( defined $del && $del ne '' );
134                         my( $appr ) = getFormValue( "appr-$i", '' ) =~ /^appr-(\d+)$/;
135                         $approved{$appr} = 1 if( defined $appr && $appr ne '' );
136                 }
137                 for( my $i = 1; $i <= $maxcnt; $i ++ ) {
138                         my( $sel ) = getFormValue( "loc-$i-sel", '' ) =~ /^(\d+)$/;
139                         $approved{$sel} = 1 if( defined $sel && $sel ne '' );
140                 }
141                 # Check for collisions
142                 my %collision;
143                 foreach my $id ( keys %deleted ) {
144                         if( $approved{$id} ) {
145                                 my $owner = getFormValue( "owner-$id", '' );
146                                 appendError( "You can not approve and delete history at the same time, not modifying item ".PciIds::Address::new( $owner )->pretty() );
147                                 $collision{$owner} = $_;
148                                 delete $deleted{$id};
149                                 delete $approved{$id};
150                         }
151                 }
152                 #Do the deletes and approves
153                 foreach my $del ( keys %deleted ) {
154                         $tables->deleteHistory( $del );
155                         tulog( $authid, "Discussion deleted $del" );
156                 }
157                 foreach my $appr ( keys %approved ) {
158                         $tables->markChecked( $appr );
159                         tulog( $authid, "Discussion checked $appr" );
160                 }
161                 #Handle the items
162                 my $defaultSeen = getFormValue( 'default-seen', '' ) =~ /^default-seen$/;
163                 for( my $i = 1; $i <= $maxcnt; $i ++ ) {
164                         my $addr = PciIds::Address::new( getFormValue( "loc-$i", '' ) );
165                         next if $collision{$addr->get()};
166                         next unless defined $addr;
167                         my $del = getFormValue( "loc-$i-del", '' );
168                         if( defined $del && $del eq 'del' && ( hasRight( $auth->{'accrights'}, 'prune' ) || ( !$tables->hasChildren( $addr->get() ) && !$tables->hasMain( $addr->get() ) ) ) ) {
169                                 $tables->deleteItem( $addr->get() );
170                                 tulog( $authid, "Item deleted (recursive) ".$addr->get() );
171                                 next;
172                         }
173                         my $name = getFormValue( "name-$i", undef );
174                         $name = undef if defined $name && $name eq '';
175                         my $note = getFormValue( "note-$i", undef );
176                         $note = undef if defined $note && $note eq '';
177                         my $discussion = getFormValue( "disc-$i", '' );
178                         $discussion = undef if defined $discussion && $discussion eq '';
179                         my $delete = 0;
180                         if( getFormValue( "loc-$i-softdel", '' ) =~ /^del$/ ) {
181                                 $delete = 1;
182                                 $name = undef;
183                                 $note = undef;
184                         }
185                         if( defined $note && !defined $name ) {
186                                 appendError( "You must specify name if you set note at item ".$addr->pretty() );
187                                 next;
188                         }
189                         my( $select ) = getFormValue( "loc-$i-sel", '' ) =~ /^(\d+)$/;
190                         my $action = 0;
191                         if( defined $name || defined $discussion || $delete ) {
192                                 my $histId = $tables->submitHistory( { 'name' => $name, 'note' => $note, 'text' => $discussion, 'delete' => $delete }, $auth, $addr );
193                                 $tables->markChecked( $histId );
194                                 $select = $histId if defined $name || $delete;
195                                 tulog( $authid, "Discussion submited (admin) $histId ".$addr->get()." ".logEscape( $name )." ".logEscape( $note )." ".logEscape( $discussion ) );
196                                 $action = 1;
197                                 notify( $tables, $addr->get(), $histId, defined $name ? 1 : 0, 1 );
198                         }
199                         if( defined $select && select ne '' ) {
200                                 $tables->setMainHistory( $addr->get(), $select );
201                                 tulog( $authid, "Item main history changed ".$addr->get()." $select" );
202                                 $action = 1;
203                                 notify( $tables, $addr->get(), $select, 2, 2 );
204                         }
205                         if( $action && $defaultSeen ) {#Approve anything in this item
206                                 my $subcnt = getFormValue( "loc-$i-subcnt", 0 );
207                                 for( my $j = 1;  $j <= $subcnt; $j ++ ) {
208                                         my( $id ) = getFormValue( "his-$i-$j", '' ) =~ /^(\d+)$/;
209                                         next unless defined $id;
210                                         next if $approved{$id} || $deleted{$id};
211                                         $tables->markChecked( $id );
212                                         tulog( $authid, "Discussion checked $id" );
213                                 }
214                         }
215                 }
216                 return genNewAdminForm( $req, $args, $tables, $errors, $auth );
217         } else {
218                 return notLoggedComplaint( $req, $args, $auth );
219         }
220 }
221
222 1;