]> ruin.nu Git - ndwebbie.git/blob - lib/NDWeb/Controller/JSRPC.pm
Add jsrpc/addscans
[ndwebbie.git] / lib / NDWeb / Controller / JSRPC.pm
1 package NDWeb::Controller::JSRPC;
2
3 use strict;
4 use warnings;
5 use parent 'Catalyst::Controller';
6
7 use DateTime::TimeZone;
8
9 =head1 NAME
10
11 NDWeb::Controller::JSRPC - Catalyst Controller
12
13 =head1 DESCRIPTION
14
15 Catalyst Controller.
16
17 =head1 METHODS
18
19 =cut
20
21
22 =head2 index 
23
24 =cut
25
26 sub index :Path :Args(0) {
27         my ( $self, $c ) = @_;
28
29         $c->response->body('Matched NDWeb::Controller::JSRPC in JSRPC.');
30 }
31
32 sub update : Local {
33         my ($self, $c, $raid, $from, $target) = @_;
34         my $dbh = $c->model;
35
36         $c->forward('/raids/findRaid');
37         $raid = $c->stash->{raid};
38
39         my $targets;;
40         if ($from){
41                 my ($timestamp) = $dbh->selectrow_array(q{SELECT MAX(modified)::timestamp AS modified
42                         FROM raid_targets WHERE raid = $1},undef,$raid->{id});
43                 $c->stash(timestamp => $timestamp);
44                 $targets = $dbh->prepare(q{SELECT r.id,r.pid FROM raid_targets r
45                         WHERE r.raid = ? AND modified > ?
46                 });
47                 $targets->execute($raid->{id},$from);
48         }elsif($target){
49                 $targets = $dbh->prepare(q{SELECT r.id,r.pid FROM raid_targets r
50                         WHERE r.raid = $1 AND r.id = $2
51                 });
52                 $targets->execute($raid->{id},$target);
53         }
54
55         my $claims =  $dbh->prepare(qq{ SELECT username,joinable,launched FROM raid_claims
56                 NATURAL JOIN users WHERE target = ? AND wave = ?});
57         my @targets;
58         while (my $target = $targets->fetchrow_hashref){
59                 my %target;
60                 $target{id} = $target->{id};
61                 my @waves;
62                 for (my $i = 1; $i <= $raid->{waves}; $i++){
63                         my %wave;
64                         $wave{id} = $i;
65                         $claims->execute($target->{id},$i);
66                         my $joinable = 0;
67                         my $claimers;
68                         if ($claims->rows != 0){
69                                 my $owner = 0;
70                                 my @claimers;
71                                 while (my $claim = $claims->fetchrow_hashref){
72                                         $owner = 1 if ($c->user->username eq $claim->{username});
73                                         $joinable = 1 if ($claim->{joinable});
74                                         $claim->{username} .= '*' if ($claim->{launched});
75                                         push @claimers,$claim->{username};
76                                 }
77                                 $claimers = join '/', @claimers;
78                                 if ($owner){
79                                         $wave{command} = 'unclaim';
80                                 }elsif ($joinable){
81                                         $wave{command} = 'join';
82                                 }else{
83                                         $wave{command} = 'taken';
84                                 }
85                         }else{
86                                 $wave{command} = 'claim';
87                         }
88                         $wave{claimers} = $claimers;
89                         $wave{joinable} = $joinable;
90                         push @waves,\%wave;
91                 }
92                 $target{waves} = \@waves;
93                 push @targets,\%target;
94         }
95         $c->stash(targets => \@targets);
96
97 }
98
99 sub claim : Local {
100         my ($self, $c, $raid, $from, $target, $wave) = @_;
101         my $dbh = $c->model;
102
103         $dbh->begin_work;
104         $c->forward('assertTarget');
105
106         my $claims = $dbh->prepare(qq{SELECT username FROM raid_claims
107                 NATURAL JOIN users WHERE target = ? AND wave = ?
108                 });
109         $claims->execute($target,$wave);
110         if ($claims->rows == 0){
111                 my $query = $dbh->prepare(q{INSERT INTO raid_claims (target,uid,wave) VALUES(?,?,?)});
112                 $query->execute($target,$c->user->id,$wave);
113                 $c->forward('/raids/log',[$raid, "Claimed target $target wave $wave"]);
114                 $c->forward('/listTargets');
115         }
116         $dbh->commit;
117
118         $c->stash(template => 'jsrpc/update.tt2');
119         $c->forward('update');
120 }
121
122
123 sub join : Local {
124         my ($self, $c, $raid, $from, $target, $wave) = @_;
125         my $dbh = $c->model;
126
127         $dbh->begin_work;
128         $c->forward('assertTarget');
129
130         my $claims = $dbh->prepare(q{SELECT username FROM raid_claims
131                 NATURAL JOIN users WHERE target = ? AND wave = ? AND joinable = TRUE
132                 });
133         $claims->execute($target,$wave);
134         if ($claims->rows != 0){
135                 my $query = $dbh->prepare(q{INSERT INTO raid_claims (target,uid,wave,joinable)
136                         VALUES(?,?,?,TRUE)
137                 });
138                 $query->execute($target,$c->user->id,$wave);
139                 $c->forward('/raids/log',[$raid, "Joined target $target wave $wave"]);
140                 $c->forward('/listTargets');
141         }
142         $dbh->commit;
143
144         $c->stash(template => 'jsrpc/update.tt2');
145         $c->forward('update');
146 }
147
148 sub unclaim : Local {
149         my ($self, $c, $raid, $from, $target, $wave) = @_;
150         my $dbh = $c->model;
151
152         $dbh->begin_work;
153         my $query = $dbh->prepare(q{DELETE FROM raid_claims WHERE target = ?
154                 AND uid = ? AND wave = ?
155                 });
156         $query->execute($target,$c->user->id,$wave);
157         $c->forward('/raids/log',[$raid, "Unclaimed target $target wave $wave"]);
158         $dbh->commit;
159
160         $c->stash(template => 'jsrpc/update.tt2');
161         $c->forward('/listTargets');
162         $c->forward('update');
163 }
164
165 sub joinable : Local {
166         my ($self, $c, $raid, $from, $target, $wave,$joinable) = @_;
167         my $dbh = $c->model;
168
169         my $claims = $dbh->prepare(q{SELECT username FROM raid_claims NATURAL JOIN users
170                 WHERE target = ? AND wave = ? AND uid = ?
171                 });
172         $claims->execute($target,$wave,$c->user->id);
173         if ($claims->rows != 0){
174                 my $query = $dbh->prepare(q{UPDATE raid_claims SET joinable = NOT ?
175                         WHERE target = ? AND wave = ?
176                 });
177                 $query->execute($joinable,$target,$wave);
178         }
179
180         $c->stash(template => 'jsrpc/update.tt2');
181         $c->forward('/listTargets');
182         $c->forward('update');
183 }
184
185 sub listTargets : Local {
186         my ($self, $c) = @_;
187
188         $c->stash(template => 'jsrpc/update.tt2');
189         $c->forward('/listTargets');
190 }
191
192 sub tzcountries : Local {
193         my ($self, $c, $cat) = @_;
194
195         my @countries = DateTime::TimeZone->names_in_category($cat);
196         $c->stash(tzcountries => \@countries);
197 }
198
199 sub access_denied : Private {
200         my ($self, $c) = @_;
201         $c->stash(template => 'jsrpc/access_denied.tt2');
202         $c->res->status(403);
203 }
204
205 sub assertTarget : Private {
206         my ($self, $c, $raid, $from, $target, $wave) = @_;
207         my $dbh = $c->model;
208
209         my $findtarget = $dbh->prepare(q{SELECT rt.id FROM raid_targets rt
210                 NATURAL JOIN raid_access ra NATURAL JOIN groupmembers
211                 WHERE uid = ? AND id = ?
212                 FOR UPDATE
213         });
214
215         my $result = $dbh->selectrow_array($findtarget,undef,$c->user->id,$target);
216         if ($result != $target){
217                 $dbh->rollback;
218                 die 'Access denied';
219         }
220 }
221
222 sub addscans : Local {
223         my ( $self, $c ) = @_;
224         my $dbh = $c->model;
225
226         my $findscan = $dbh->prepare(q{SELECT scan_id FROM scans
227                 WHERE scan_id = LOWER(?) AND tick >= tick() - 168 AND groupscan = ?
228                 });
229         my $addscan = $dbh->prepare(q{INSERT INTO scans (scan_id,tick,uid,groupscan)
230                 VALUES (LOWER(?),tick(),?,?)
231                 });
232         my $addpoint = $dbh->prepare(q{UPDATE users SET scan_points = scan_points + 1
233                 WHERE uid = ?
234                 });
235         my $message = $c->req->param('message');
236         my @scans;
237         while ($message =~ m{scan(_id|_grp)?=(\w+)}g){
238                 my $groupscan = (defined $1 && $1 eq '_grp') || 0;
239                 my %scan;
240                 $scan{id} = $2;
241                 $scan{group} = $groupscan;
242                 $findscan->execute($2,$groupscan);
243                 if ($findscan->rows == 0){
244                         if ($addscan->execute($2,$c->stash->{UID},$groupscan)){
245                                 $addpoint->execute($c->stash->{UID}) unless $groupscan;
246                                 $scan{added} = 1;
247                         }
248                 }else{
249                         $scan{message} = 'already exists';
250                 }
251                 push @scans,\%scan;
252         }
253 }
254
255 sub end : ActionClass('RenderView') {
256         my ($self,$c) = @_;
257         $c->res->content_type('application/xml');
258
259         if (scalar @{ $c->error } ){
260                 if ($c->error->[0] =~ m/Can't call method "id" on an undefined value at/){
261                         $c->stash->{template} = 'jsrpc/access_denied.tt2';
262                         $c->res->status(403);
263                         $c->clear_errors;
264                 }elsif ($c->error->[0] =~ m/Missing roles: /){
265                         $c->stash->{template} = 'jsrpc/access_denied.tt2';
266                         $c->res->status(403);
267                         $c->clear_errors;
268                 }
269         }
270 }
271
272 =head1 AUTHOR
273
274 Michael Andreen (harv@ruin.nu)
275
276 =head1 LICENSE
277
278 GPL 2.0, or later
279
280 =cut
281
282 1;