rvd_front.pl 59.4 KB
Newer Older
1
2
3
#!/usr/bin/env perl
use warnings;
use strict;
4
5
6
#####
use locale ':not_characters';
#####
7
use Carp qw(confess);
8
use Data::Dumper;
9
use Digest::SHA qw(sha256_hex);
10
use Hash::Util qw(lock_hash);
11
use Mojolicious::Lite 'Ravada::I18N';
Francesc Guasch's avatar
Francesc Guasch committed
12
use Mojo::JSON qw(decode_json encode_json);
13
use Time::Piece;
14
#use Mojolicious::Plugin::I18N;
15
use Mojo::Home;
16
#####
17
18
#my $self->plugin('I18N');
#package Ravada::I18N:en;
19
#####
20
21
22
#
no warnings "experimental::signatures";
use feature qw(signatures);
23

24
25
use lib 'lib';

26
use Ravada::Front;
27
use Ravada::Front::Domain;
Francesc Guasch's avatar
Francesc Guasch committed
28
use Ravada::Auth;
29
use POSIX qw(locale_h);
Francesc Guasch's avatar
Francesc Guasch committed
30
31

my $help;
Francesc Guasch's avatar
Francesc Guasch committed
32

Francesc Guasch's avatar
Francesc Guasch committed
33
34
35
my $FILE_CONFIG = "/etc/rvd_front.conf";

my $error_file_duplicated = 0;
36
for my $file ( "/etc/rvd_front.conf" , ($ENV{HOME} or '')."/rvd_front.conf") {
Francesc Guasch's avatar
Francesc Guasch committed
37
    warn "WARNING: Found config file at $file and at $FILE_CONFIG\n"
38
        if -e $file && $FILE_CONFIG && $file ne $FILE_CONFIG;
39
    $FILE_CONFIG = $file if -e $file;
Francesc Guasch's avatar
Francesc Guasch committed
40
    $error_file_duplicated++;
41
}
Francesc Guasch's avatar
Francesc Guasch committed
42
warn "WARNING: using $FILE_CONFIG\n"    if$error_file_duplicated>2;
43
44

my $FILE_CONFIG_RAVADA;
45
for my $file ( "/etc/ravada.conf" , ($ENV{HOME} or '')."/ravada.conf") {
46
47
48
    warn "WARNING: Found config file at $file and at $FILE_CONFIG_RAVADA\n"
        if -e $file && $FILE_CONFIG_RAVADA;
    $FILE_CONFIG_RAVADA = $file if -e $file;
Francesc Guasch's avatar
Francesc Guasch committed
49
}
50

amesones's avatar
amesones committed
51
52
53
my $CONFIG_FRONT = plugin Config => { default => {
                                                hypnotoad => {
                                                pid_file => 'log/rvd_front.pid'
fv3rdugo's avatar
Indent    
fv3rdugo committed
54
55
                                                ,listen => ['http://*:8081']
                                                }
56
                                              ,login_bg_file => '/img/intro-bg.jpg'
Francesc Guasch's avatar
Francesc Guasch committed
57
                                              ,login_header => 'Welcome'
58
                                              ,login_message => ''
59
                                              ,secrets => ['changeme0']
60
                                              ,guide => 0
fv3rdugo's avatar
fv3rdugo committed
61
                                              ,login_custom => ''
62
                                              ,footer => 'bootstrap/footer'
63
                                              ,monitoring => 0
64
                                              ,fallback => 0
65
                                              ,guide_custom => ''
66
67
                                              ,admin => {
                                                    hide_clones => 15
Francesc Guasch's avatar
Francesc Guasch committed
68
                                                    ,autostart => 0
amesones's avatar
amesones committed
69
                                              }
70
                                              ,config => $FILE_CONFIG_RAVADA
71
                                              ,auto_view => 0
amesones's avatar
amesones committed
72
                                              }
Francesc Guasch's avatar
Francesc Guasch committed
73
                                      ,file => $FILE_CONFIG
74
};
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#####
#####
#####
# Import locale-handling tool set from POSIX module.
# This example uses: setlocale -- the function call
#                    LC_CTYPE -- explained below

# query and save the old locale
my $old_locale = setlocale(LC_CTYPE);

setlocale(LC_CTYPE, "en_US.ISO8859-1");
# LC_CTYPE now in locale "English, US, codeset ISO 8859-1"

setlocale(LC_CTYPE, "");
# LC_CTYPE now reset to default defined by LC_ALL/LC_CTYPE/LANG
# environment variables.  See below for documentation.

# restore the old locale
setlocale(LC_CTYPE, $old_locale);
#####
#####
#####
98
plugin I18N => {namespace => 'Ravada::I18N', default => 'en'};
99
plugin 'RenderFile';
Francesc Guasch's avatar
Francesc Guasch committed
100

101
my %config;
102
%config = (config => $CONFIG_FRONT->{config}) if $CONFIG_FRONT->{config};
103
our $RAVADA = Ravada::Front->new(%config);
104

105
our $USER;
Francesc Guasch's avatar
Francesc Guasch committed
106

107
# TODO: get those from the config file
108
our $DOCUMENT_ROOT = "/var/www";
109
110

# session times out in 5 minutes
111
our $SESSION_TIMEOUT = ($CONFIG_FRONT->{session_timeout} or 5 * 60);
112
# session times out in 15 minutes for admin users
113
our $SESSION_TIMEOUT_ADMIN = ($CONFIG_FRONT->{session_timeout_admin} or 15 * 60);
114

Francesc Guasch's avatar
Francesc Guasch committed
115
116
init();
############################################################################3
117

118
119
120
hook before_routes => sub {
  my $c = shift;

121
122
  $USER = undef;

Francesc Guasch's avatar
Francesc Guasch committed
123
  $c->stash(version => $RAVADA->version);
124
  my $url = $c->req->url->to_abs->path;
fv3rdugo's avatar
fv3rdugo committed
125
  my $host = $c->req->url->to_abs->host;
126
  $c->stash(css=>['/css/sb-admin.css']
Francesc Guasch's avatar
Francesc Guasch committed
127
128
            ,js=>[
                '/js/ravada.js'
129
130
131
                ]
            ,csssnippets => []
            ,navbar_custom => 0
Francesc Guasch's avatar
Francesc Guasch committed
132
133
134
135
            ,url => undef
            ,_logged_in => undef
            ,_anonymous => undef
            ,_user => undef
136
            ,footer=> $CONFIG_FRONT->{footer}
137
            ,monitoring => 0
fv3rdugo's avatar
fv3rdugo committed
138
            ,fallback => $CONFIG_FRONT->{fallback}
139
            ,check_netdata => 0
140
            ,guide => $CONFIG_FRONT->{guide}
fv3rdugo's avatar
fv3rdugo committed
141
            ,host => $host
142
            );
143

Francesc Guasch's avatar
Francesc Guasch committed
144
145
146
    return if _logged_in($c);
    return if $url =~ m{^/(anonymous|login|logout|requirements|robots.txt)}
           || $url =~ m{^/(css|font|img|js)};
147

Francesc Guasch's avatar
Francesc Guasch committed
148
149
150
151
152
153
154
155
156
    # anonymous URLs
    if (($url =~ m{^/machine/(clone|display|info|view)/}
        || $url =~ m{^/(list_bases_anonymous|request/)}i
        ) && !_logged_in($c)) {
        $USER = _anonymous_user($c);
        return if $USER->is_temporary;
    }
    return access_denied($c)
        if $url =~ /(screenshot|\.json)/
157
        && !_logged_in($c);
Francesc Guasch's avatar
Francesc Guasch committed
158
    return login($c) if !_logged_in($c);
159

160
161
162
163
164
165
    if ($USER && $USER->is_admin && $CONFIG_FRONT->{monitoring}) {
        if (!defined $c->session('monitoring')) {
            $c->stash(check_netdata => "https://$host:19999/index.html");
        }
        $c->stash( monitoring => 1) if $c->session('monitoring');
    }
166
        $c->stash( fallback => 1) if $c->session('fallback');
167
168
169
170
171
};


############################################################################3

Francesc Guasch's avatar
Francesc Guasch committed
172
173
174
175
176
any '/robots.txt' => sub {
    my $c = shift;
    return $c->render(text => "User-agent: *\nDisallow: /\n", format => 'text');
};

177
any '/' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
178
    my $c = shift;
179
    return quick_start($c);
Francesc Guasch's avatar
Francesc Guasch committed
180
181
};

Francesc Guasch's avatar
Francesc Guasch committed
182
183
any '/index.html' => sub {
    my $c = shift;
184
    return quick_start($c);
Francesc Guasch's avatar
Francesc Guasch committed
185
186
};

187
188
any '/login' => sub {
    my $c = shift;
189
    return login($c);
190
191
};

Francesc Guasch's avatar
Francesc Guasch committed
192
193
194
195
196
197
198
199
200
any '/test' => sub {
    my $c = shift;
    my $logged = _logged_in($c);
    my $count = $c->session('count');
    $c->session(count => ++$count);

    my $name_mojo = $c->signed_cookie('mojolicious');

    my $dump_log = ''.(Dumper($logged) or '');
Francesc Guasch's avatar
Francesc Guasch committed
201
202
203
204
205
    return $c->render(text => "$count ".($name_mojo or '')."<br> ".$dump_log
        ."<br>"
        ."<script>alert(window.screen.availWidth"
        ."+\" \"+window.screen.availHeight)</script>"
    );
Francesc Guasch's avatar
Francesc Guasch committed
206
207
};

Francesc Guasch's avatar
Francesc Guasch committed
208
209
any '/logout' => sub {
    my $c = shift;
210
    logout($c);
Francesc Guasch's avatar
Francesc Guasch committed
211
212
213
    $c->redirect_to('/');
};

214
get '/anonymous' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
215
    my $c = shift;
216
#    $c->render(template => 'bases', base => list_bases());
217
    $USER = _anonymous_user($c);
218
    return list_bases_anonymous($c);
Francesc Guasch's avatar
Francesc Guasch committed
219
220
};

221
get '/anonymous_logout.html' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
222
    my $c = shift;
223
224
    $c->session('anonymous_user' => '');
    return $c->redirect_to('/');
Francesc Guasch's avatar
Francesc Guasch committed
225
226
};

227
get '/anonymous/(#base_id).html' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
228
229
    my $c = shift;

230
    $c->stash(_anonymous => 1 , _logged_in => 0);
231
    _init_error($c);
232
    my $base_id = $c->stash('base_id');
233
234
    my $base = $RAVADA->search_domain_by_id($base_id);

235
    $USER = _anonymous_user($c);
236
    return quick_start_domain($c,$base->id, $USER->name);
Francesc Guasch's avatar
Francesc Guasch committed
237
238
};

239
any '/admin/#type' => sub {
240
  my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
241

242
243
244
  return admin($c)  if $c->stash('type') eq 'machines'
                        && $USER->is_operator;

245
246
  return access_denied($c)    if !$USER->is_operator;

amesones's avatar
amesones committed
247
  return admin($c);
Francesc Guasch's avatar
Francesc Guasch committed
248
249
};

250
any '/new_machine' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
251
    my $c = shift;
252
    return access_denied($c)    if !$USER->can_create_machine;
253
    return new_machine($c);
Francesc Guasch's avatar
Francesc Guasch committed
254
255
};

256
get '/domain/new.html' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
257
258
    my $c = shift;

259
260
    return access_denied($c) if !_logged_in($c) || !$USER->is_admin();
    $c->stash(error => []);
amesones's avatar
amesones committed
261
    return $c->render(template => "main/new_machine");
Francesc Guasch's avatar
Francesc Guasch committed
262
263
264

};

265
266
get '/list_vm_types.json' => sub {
    my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
267
    $c->render(json => $RAVADA->list_vm_types);
268
269
};

270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
get '/list_nodes.json' => sub {
    my $c = shift;
    $c->render(json => [$RAVADA->list_vms]);
};

get '/node/enable/(:id).json' => sub {
    my $c = shift;
    return access_denied($c) if !$USER->is_admin;
    return $c->render(json => {enabled => $RAVADA->enable_node($c->stash('id'),1)});
};

get '/node/disable/(:id).json' => sub {
    my $c = shift;
    return access_denied($c) if !$USER->is_admin;
    return $c->render(json => {enabled => $RAVADA->enable_node($c->stash('id'),0)});
};
286
287
288
289
290
get '/node/remove/(:id).json' => sub {
    my $c = shift;
    return access_denied($c) if !$USER->is_admin;
    return $c->render(json => {remove => $RAVADA->remove_node($c->stash('id'),1)});
};
291
292
293
294
295
296
297

any '/new_node' => sub {
    my $c = shift;
    return access_denied($c)    if !$USER->is_admin;
    return new_node($c);
};

298
299
get '/list_bases.json' => sub {
    my $c = shift;
300
301
302
303
304
305
306
307
308
309
310

    my $domains = $RAVADA->list_bases();
    my @domains_show = @$domains;
    if (!$USER->is_admin) {
        @domains_show = ();
        for (@$domains) {
            push @domains_show,($_) if $_->{is_public};
        }
    }
    $c->render(json => [@domains_show]);

311
312
313
314
};

get '/list_images.json' => sub {
    my $c = shift;
315

elodin1's avatar
elodin1 committed
316
317
318
    return access_denied($c) unless _logged_in($c)
        && $USER->can_create_machine();

319
320
321
    my $vm_name = $c->param('backend');

    $c->render(json => $RAVADA->list_iso_images($vm_name or undef));
322
323
};

324
get '/iso_file.json' => sub {
joelalju's avatar
joelalju committed
325
    my $c = shift;
elodin1's avatar
elodin1 committed
326
327
    return access_denied($c) unless _logged_in($c)
        && $USER->can_create_machine();
328
329
330
    my @isos =('<NONE>');
    push @isos,(@{$RAVADA->iso_file});
    $c->render(json => \@isos);
joelalju's avatar
joelalju committed
331
332
};

333
get '/list_machines.json' => sub {
334
    my $c = shift;
335

336
    return access_denied($c) unless _logged_in($c)
337
338
339
340
341
        && (
            $USER->can_list_machines
            || $USER->can_list_own_machines()
            || $USER->can_list_clones()
            || $USER->can_list_clones_from_own_base()
342
343
344
            || $USER->is_admin()
        );

345
    return $c->render( json => $RAVADA->list_machines($USER) );
346

347
};
Francesc Guasch's avatar
Francesc Guasch committed
348

349
350
351
get '/list_machines_user.json' => sub {
    my $c = shift;
    return $c->render( json => $RAVADA->list_machines_user($USER));
352
};
Francesc Guasch's avatar
Francesc Guasch committed
353

354
355
356
357
358
359
360
get '/list_bases_anonymous.json' => sub {
    my $c = shift;

    # shouldn't this be "list_bases" ?
    $c->render(json => $RAVADA->list_bases_anonymous(_remote_ip($c)));
};

Francesc Guasch's avatar
Francesc Guasch committed
361
get '/list_lxc_templates.json' => sub {
fv3rdugo's avatar
fv3rdugo committed
362
    my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
363
    $c->render(json => $RAVADA->list_lxc_templates);
fv3rdugo's avatar
fv3rdugo committed
364
365
};

joansp's avatar
udpate    
joansp committed
366
367
368
369
370
get '/pingbackend.json' => sub {

    my $c = shift;
    $c->render(json => $RAVADA->ping_backend);
};
fv3rdugo's avatar
fv3rdugo committed
371

372
373
# machine commands

374
get '/machine/info/(:id).(:type)' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
375
    my $c = shift;
376
    my $id = $c->stash('id');
Francesc Guasch's avatar
Francesc Guasch committed
377
    die "No id " if !$id;
378

joelalju's avatar
joelalju committed
379
380
381
    my ($domain) = _search_requested_machine($c);
    return access_denied($c)    if !$domain;

Francesc Guasch's avatar
Francesc Guasch committed
382
383
384
385
386
    return access_denied($c,"Access denied to user ".$USER->name) unless $USER->is_admin
                              || $domain->id_owner == $USER->id
                              || $USER->can_change_settings($domain->id)
                              || $USER->can_remove_machine($domain->id)
                              || $USER->can_clone_all;
Francesc Guasch's avatar
Francesc Guasch committed
387

388
389
390
391
392
    my $info = $domain->info($USER);
    if ($domain->is_active && !$info->{ip}) {
        Ravada::Request->refresh_machine(id_domain => $domain->id);
    }
    return $c->render(json => $info);
Francesc Guasch's avatar
Francesc Guasch committed
393
394
};

Francesc Guasch's avatar
Francesc Guasch committed
395
get '/machine/requests/(:id).json' => sub {
396
    my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
397
398
    my $id_domain = $c->stash('id');
    return access_denied($c) if !$USER->can_manage_machine($id_domain);
joelalju's avatar
joelalju committed
399

Francesc Guasch's avatar
Francesc Guasch committed
400
401
    $c->render(json => $RAVADA->list_requests($id_domain,10));
};
joelalju's avatar
joelalju committed
402

403
any '/machine/manage/(:id).(:type)' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
404
405
   	 my $c = shift;
     return manage_machine($c);
406
};
joelalju's avatar
joelalju committed
407

Francesc Guasch's avatar
Francesc Guasch committed
408
409
410
any '/hardware/(:id).(:type)' => sub {
   	 my $c = shift;
     return $c->render(template => 'main/hardware');
411
412
};

413
get '/machine/view/(:id).(:type)' => sub {
414
    my $c = shift;
415
416
    my $id = $c->stash('id');
    my $type = $c->stash('type');
Francesc Guasch's avatar
Francesc Guasch committed
417

joelalju's avatar
joelalju committed
418
419
420
421
422
423
    my ($domain) = _search_requested_machine($c);
    return access_denied($c)    if !$domain;

    return access_denied($c) unless $USER->is_admin
                              || $domain->id_owner == $USER->id;

424
425
426
    return view_machine($c);
};

Francesc Guasch's avatar
Francesc Guasch committed
427
any '/machine/clone/(:id).(:type)' => sub {
Joel Alarcón's avatar
Joel Alarcón committed
428
    my $c = shift;
429

Francesc Guasch's avatar
Francesc Guasch committed
430
431
432
433
434
435
436
437
438
439
440
    return clone_machine($c)    if $USER && $USER->can_clone() && !$USER->is_temporary();

    my $bases_anonymous = $RAVADA->list_bases_anonymous(_remote_ip($c));
    for (@$bases_anonymous) {
        if ($_->{id} == $c->stash('id') ) {
            return clone_machine($c,1);
        }
    }

    return login($c)    if !$USER || $USER->is_temporary;
    return access_denied($c);
441
};
Francesc Guasch's avatar
Francesc Guasch committed
442

443
get '/machine/shutdown/(:id).(:type)' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
444
        my $c = shift;
445
    return access_denied($c)        if !$USER ->can_shutdown($c->stash('id'));
Francesc Guasch's avatar
Francesc Guasch committed
446
447
448
449

        return shutdown_machine($c);
};

450
any '/machine/remove/(:id).(:type)' => sub {
joansp's avatar
joansp committed
451
        my $c = shift;
452
    return access_denied($c)       if !$USER->can_remove_machine($c->stash('id'));
joansp's avatar
joansp committed
453
454
        return remove_machine($c);
};
455
456

any '/machine/remove_clones/(:id).(:type)' => sub {
457
458
459
460
461
462
    my $c = shift;

    # TODO : call to $domain->_allow_remove();
	return access_denied($c)
        unless
            $USER -> can_remove_clone_all()
Francesc Guasch's avatar
Francesc Guasch committed
463
464
	        || $USER->can_remove_clone()
            || $USER->can_remove_all();
465
    return remove_clones($c);
466
467
};

468
get '/machine/prepare/(:id).(:type)' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
469
470
471
472
        my $c = shift;
        return prepare_machine($c);
};

473
474
475
476
477
get '/machine/toggle_base_vm/(:id_vm)/(:id_domain).(:type)' => sub {
    my $c = shift;
    return toggle_base_vm($c);
};

478
get '/machine/remove_b/(:id).(:type)' => sub {
joansp's avatar
joansp committed
479
480
481
482
        my $c = shift;
        return remove_base($c);
};

483
get '/machine/remove_base/(:id).(:type)' => sub {
484
485
486
487
    my $c = shift;
    return remove_base($c);
};

488
get '/machine/screenshot/(:id).(:type)' => sub {
489
        my $c = shift;
490
491
        my $domain = _search_requested_machine($c);
        return access_denied($c)   if (!$USER->can_screenshot() || $domain->is_base());
492
493
494
        return screenshot_machine($c);
};

495
get '/machine/copy_screenshot/(:id).(:type)' => sub {
496
497
498
        my $c = shift; 
        my $domain = _search_requested_machine($c);
        return access_denied($c) if (!$USER->is_admin() || $domain->id_base() == NULL );
499
500
501
        return copy_screenshot($c);
};

502
get '/machine/pause/(:id).(:type)' => sub {
joansp's avatar
joansp committed
503
504
505
506
        my $c = shift;
        return pause_machine($c);
};

507
get '/machine/hibernate/(:id).(:type)' => sub {
508
        my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
509
          return access_denied($c)
Francesc Guasch's avatar
Francesc Guasch committed
510
             unless $USER->is_admin() || $USER->can_shutdown($c->stash('id'));
Francesc Guasch's avatar
Francesc Guasch committed
511

512
513
514
        return hybernate_machine($c);
};

515
get '/machine/resume/(:id).(:type)' => sub {
joansp's avatar
joansp committed
516
517
518
519
        my $c = shift;
        return resume_machine($c);
};

520
get '/machine/start/(:id).(:type)' => sub {
joansp's avatar
joansp committed
521
522
523
        my $c = shift;
        return start_machine($c);
};
joansp's avatar
joansp committed
524

525
get '/machine/exists/#name' => sub {
526
    my $c = shift;
527
    my $name = $c->stash('name');
528
529
530
531
532
533
    #TODO
    # return failure if it can't find the name in the URL

    return $c->render(json => $RAVADA->domain_exists($name));

};
joansp's avatar
joansp committed
534

535
536
537
538
539
540
541
get '/node/exists/#name' => sub {
    my $c = shift;
    my $name = $c->stash('name');

    return $c->render(json => $RAVADA->node_exists($name));

};
542
get '/machine/rename/#id/#value' => sub {
543
    my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
544
    return access_denied($c)       if !$USER->can_manage_machine($c->stash('id'));
545
546
547
    return rename_machine($c);
};

548
549
any '/machine/copy' => sub {
    my $c = shift;
550
    return access_denied($c)    if !$USER -> can_clone_all();
551
552
553
    return copy_machine($c);
};

554
555
556
557
558
559
get '/machine/public/#id' => sub {
    my $c = shift;
    return machine_is_public($c);
};

get '/machine/public/#id/#value' => sub {
560
561
562
563
    my $c = shift;
    return machine_is_public($c);
};

564
565
566
567
568
569
570
571
572
573
get '/machine/autostart/#id/#value' => sub {
    my $c = shift;
    my $req = Ravada::Request->domain_autostart(
        id_domain => $c->stash('id')
           ,value => $c->stash('value')
             ,uid => $USER->id
    );
    return $c->render(json => { request => $req->id});
};

574
get '/machine/display/(:id).vv' => sub {
575
576
577
578
579
580
581
582
583
584
585
586
    my $c = shift;

    my $id = $c->stash('id');

    my $domain = $RAVADA->search_domain_by_id($id);
    return $c->render(text => "unknown machine id=$id") if !$id;

    return access_denied($c)
        if $USER->id ne $domain->id_owner
        && !$USER->is_admin;

    $c->res->headers->content_type('application/x-virt-viewer');
587
588
        $c->res->headers->content_disposition(
        "inline;filename=".$domain->id.".vv");
589

590
    return $c->render(data => $domain->display_file($USER), format => 'vv');
591
592
};

593
594
# Users ##########################################################3

Laura Figuerola's avatar
Laura Figuerola committed
595
596
##add user

597
any '/users/register' => sub {
598

Laura Figuerola's avatar
Laura Figuerola committed
599
       my $c = shift;
600
       return access_denied($c) if !$USER->is_admin();
Laura Figuerola's avatar
Laura Figuerola committed
601
602
603
       return register($c);
};

Francesc Guasch's avatar
Francesc Guasch committed
604
605
any '/admin/user/(:id).(:type)' => sub {
    my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
606
    return access_denied($c) if !$USER->can_manage_users() && !$USER->can_grant();
Francesc Guasch's avatar
Francesc Guasch committed
607
608
609
610
611
612

    my $user = Ravada::Auth::SQL->search_by_id($c->stash('id'));

    return $c->render(text => "Unknown user id: ".$c->stash('id'))
        if !$user;

Francesc Guasch's avatar
Francesc Guasch committed
613
614
615
616
617
    if ($c->param('make_admin')) {
        $USER->make_admin($c->stash('id'))  if $c->param('is_admin');
        $USER->remove_admin($c->stash('id'))if !$c->param('is_admin');
        $user = Ravada::Auth::SQL->search_by_id($c->stash('id'));
    }
618
619
620
621
622
623
624
625
626
627
628
    if ($c->param('grant')) {
        return access_denied($c)    if !$USER->can_grant();
        my %grant;
        for my $param_name (@{$c->req->params->names}) {
            if ( $param_name =~ /^perm_(.*)/ ) {
                $grant{$1} = 1;
            } elsif ($param_name =~ /^off_perm_(.*)/) {
                $grant{$1} = 0 if !exists $grant{$1};
            }
        }
        for my $perm (keys %grant) {
629
            if ( $grant{$perm} ) {
630
631
632
633
634
635
                $USER->grant($user, $perm);
            } else {
                $USER->revoke($user, $perm);
            }
        }
    }
Francesc Guasch's avatar
Francesc Guasch committed
636
637
638
    $c->stash(user => $user);
    return $c->render(template => 'main/manage_user');
};
Laura Figuerola's avatar
Laura Figuerola committed
639

640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
get '/list_ldap_attributes/(#cn)' => sub {
    my $c = shift;

    return _access_denied($c) if !$USER->is_admin;

    my $cn = $c->stash('cn');
    my $user;
    eval {
        ($user) = Ravada::Auth::LDAP::search_user($cn);
    };
    return $c->render(json => { error => $@ }) if $@;
    return $c->render(json => []) if !$user;

    $c->session(ldap_attributes_cn => $cn) if $user;
    return $c->render(json => {attributes => [$user->attributes]});
};

get '/count_ldap_entries/(#attribute)/(#value)' => sub {
    my $c = shift;

    return _access_denied($c) if !$USER->is_admin;

    my @entries;
    eval {
        @entries = Ravada::Auth::LDAP::search_user(
            field => $c->stash('attribute')
            ,name => $c->stash('value')
            ,typesonly => 1
        );
    };
    @entries = [ 'too many' ] if $@ =~ /Sizelimit exceeded/;
    return $c->render(json => { entries => scalar @entries });
};

get '/add_ldap_access/(#id_domain)/(#attribute)/(#value)/(#allowed)' => sub {
    my $c = shift;

    return _access_denied($c) if !$USER->is_admin;

    my $domain_id = $c->stash('id_domain');
    my $domain = Ravada::Front::Domain->open($domain_id);

    my $attribute = $c->stash('attribute');
    my $value = $c->stash('value');
    my $allowed = 1;
    if ($c->stash('allowed') eq 'false') {
        $allowed = 0;
    }

    eval { $domain->allow_ldap_access($attribute => $value, $allowed ) };
    _fix_default_ldap_access($c, $domain, $allowed) if !$@;
    return $c->render(json => { error => $@ }) if $@;
    return $c->render(json => { ok => 1 });

};

sub _fix_default_ldap_access($c, $domain, $allowed) {
    my @list = $domain->list_ldap_access();
    my $default_found;
    for ( @list ) {
        if ( $_->{value} eq '*' ) {
            $default_found = $_->{id};
        }
    }
    if ( $default_found ) {
        $domain->move_ldap_access($default_found, +1);
        return;
    }
    my $allowed_default = 0;
    $allowed_default = 1 if !$allowed;
    eval { $domain->allow_ldap_access('DEFAULT' => '*', $allowed_default ) };
    warn $@ if $@;
}

get '/delete_ldap_access/(#id_domain)/(#id_access)' => sub {
    my $c = shift;

    return _access_denied($c) if !$USER->is_admin;

    my $domain_id = $c->stash('id_domain');
    my $domain = Ravada::Front::Domain->open($domain_id);

    $domain->delete_ldap_access($c->stash('id_access'));

    return $c->render(json => { ok => 1 });
};

get '/list_ldap_access/(#id_domain)' => sub {
    my $c = shift;

    return _access_denied($c) if !$USER->is_admin;

    my $domain_id = $c->stash('id_domain');
    my $domain = Ravada::Front::Domain->open($domain_id);

    my @ldap_access = $domain->list_ldap_access();
    my $default = {};
737
    if (scalar @ldap_access && $ldap_access[-1]->{value} eq '*') {
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
        $default = pop @ldap_access;
    }
    return $c->render(json => {list => \@ldap_access, default => $default} );
};

get '/move_ldap_access/(#id_domain)/(#id_access)/(#count)' => sub {
    my $c = shift;

    return _access_denied($c) if !$USER->is_admin;

    my $domain_id = $c->stash('id_domain');
    my $domain = Ravada::Front::Domain->open($domain_id);

    $domain->move_ldap_access($c->stash('id_access'), $c->stash('count'));

    return $c->render(json => { ok => 1});
};

get '/set_ldap_access/(#id_domain)/(#id_access)/(#allowed)' => sub {
    my $c = shift;

    return _access_denied($c) if !$USER->is_admin;

    my $domain_id = $c->stash('id_domain');
    my $domain = Ravada::Front::Domain->open($domain_id);

    my $allowed = $c->stash('allowed');
    if ($allowed =~ /false/ || !$allowed) {
        $allowed = 0;
    } else {
        $allowed = 1;
    }

    $domain->set_ldap_access($c->stash('id_access'), $allowed);
    return $c->render(json => { ok => 1});
};
774
##############################################
Laura Figuerola's avatar
Laura Figuerola committed
775

776

777
get '/request/(:id).(:type)' => sub {
778
    my $c = shift;
779
    my $id = $c->stash('id');
780

Francesc Guasch's avatar
Francesc Guasch committed
781
782
783
    if (!$USER) {
        $USER = _get_anonymous_user($c) or access_denied($c);
    }
784
785
786
787
    if ($c->stash('type') eq 'json') {
        my $request = Ravada::Request->open($id);
        return $c->render(json => $request->info($USER));
    }
788
789
790
    return _show_request($c,$id);
};

791
792
793
794
795
796
797
798
799
get '/anonymous/request/(:id).(:type)' => sub {
    my $c = shift;
    my $id = $c->stash('id');

    $USER = _anonymous_user($c);

    return _show_request($c,$id);
};

Francesc Guasch's avatar
Francesc Guasch committed
800
801
get '/requests.json' => sub {
    my $c = shift;
elodin1's avatar
elodin1 committed
802
803
    return access_denied($c) unless _logged_in($c)
        && $USER->is_admin;
Francesc Guasch's avatar
Francesc Guasch committed
804
805
806
    return list_requests($c);
};

joansp's avatar
joansp committed
807
get '/messages.json' => sub {
joansp's avatar
joansp committed
808
809
810
811
812
813
    my $c = shift;


    return $c->render( json => [$USER->messages()] );
};

814
get '/unshown_messages.json' => sub {
815
816
817
818
    my $c = shift;

    return $c->redirect_to('/login') if !_logged_in($c);

819
    return $c->render( json => [$USER->unshown_messages()] );
Antonio's avatar
Antonio committed
820
821
822
};


joansp's avatar
joansp committed
823
824
825
get '/messages/read/all.html' => sub {
    my $c = shift;
    $USER->mark_all_messages_read;
826
    return $c->render(inline => "1");
827
828
};

829
get '/messages/read/(#id).json' => sub {
830
    my $c = shift;
831
    my $id = $c->stash('id');
joansp's avatar
joansp committed
832
    $USER->mark_message_read($id);
833
    return $c->render(inline => "1");
joansp's avatar
joansp committed
834
};
835

amesones's avatar
amesones committed
836
get '/messages/unread/(#id).json' => sub {
joansp's avatar
joansp committed
837
    my $c = shift;
838
    my $id = $c->stash('id');
joansp's avatar
joansp committed
839
    $USER->mark_message_unread($id);
840
    return $c->render(inline => "1");
joansp's avatar
joansp committed
841
842
};

843
get '/messages/view/(#id).html' => sub {
844
    my $c = shift;
845
846
    my $id = $c->stash('id');
    return $c->render( json => $USER->show_message($id) );
847
848
};

849
850
851
852
853
854
any '/ng-templates/(#template).html' => sub {
  my $c = shift;
  my $id = $c->stash('template');
  return $c->render(template => 'ng-templates/'.$id);
};

855
any '/about' => sub {
fv3rdugo's avatar
fv3rdugo committed
856
857
    my $c = shift;

amesones's avatar
amesones committed
858
    $c->render(template => 'main/about');
fv3rdugo's avatar
fv3rdugo committed
859
860
};

861

862
863
864
any '/requirements' => sub {
    my $c = shift;

amesones's avatar
amesones committed
865
    $c->render(template => 'main/requirements');
866
867
};

868
869
870
871
872
873

any '/settings' => sub {
    my $c = shift;

    $c->stash(version => $RAVADA->version );

amesones's avatar
amesones committed
874
    $c->render(template => 'main/settings');
875
876
};

fv3rdugo's avatar
fv3rdugo committed
877
878
879
880
881
882
any '/admin/monitoring' => sub {
    my $c = shift;

    $c->render(template => 'main/monitoring');
};

883
any '/auto_view/(#value)/' => sub {
884
885
886
    my $c = shift;
    my $value = $c->stash('value');
    if ($value =~ /toggle/i) {
887
        $value = $c->session('auto_view');
888
889
890
891
892
893
        if ($value) {
            $value = 0;
        } else {
            $value = 1;
        }
    }
894
895
    $c->session('auto_view' => $value);
    return $c->render(json => {auto_view => $c->session('auto_view') });
896
897
};

898
get '/auto_view' => sub {
899
    my $c = shift;
900
    return $c->render(json => {auto_view => $c->session('auto_view') });
901
902
};

Francesc Guasch's avatar
Francesc Guasch committed
903
get '/machine/hardware/remove/(#id_domain)/(#hardware)/(#index)' => sub {
904
905
906
    my $c = shift;
    my $hardware = $c->stash('hardware');
    my $index = $c->stash('index');
Francesc Guasch's avatar
Francesc Guasch committed
907
908
909
910
911
912
    my $domain_id = $c->stash('id_domain');

    my $domain = Ravada::Front::Domain->open($domain_id);

    return access_denied($c)
        unless $USER->id == $domain->id_owner || $USER->is_admin;
913
914
915
916
917
918
919
920
921
922
923
924
    
    my $req = Ravada::Request->remove_hardware(uid => $USER->id
        , id_domain => $domain_id
        , name => $hardware
        , index => $index
    );
    
    $RAVADA->wait_request($req,60);  
    
    return $c->render( json => { ok => "Hardware Modified" });
};

Francesc Guasch's avatar
Francesc Guasch committed
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
get '/machine/hardware/add/(#id_domain)/(#hardware)/(#number)' => sub {
    my $c = shift;

    my $domain = Ravada::Front::Domain->open($c->stash('id_domain'));
    return access_denied($c)
        unless $USER->id == $domain->id_owner || $USER->is_admin;

    my $req = Ravada::Request->add_hardware(
        uid => $USER->id
        ,name => $c->stash('hardware')
        ,id_domain => $c->stash('id_domain')
        ,number => $c->stash('number')
    );
    return $c->render( json => { request => $req->id } );
};
940
941
942
###################################################

## user_settings
943

944
945
946
947
any '/user_settings' => sub {
    my $c = shift;
    user_settings($c);
};
948

949
950
sub user_settings {
    my $c = shift;
joelalju's avatar
joelalju committed
951
952
    my $changed_lang;
    my $changed_pass;
953
    if ($c->req->method('POST')) {
954
955
956
        $USER->language($c->param('tongue'));
        $changed_lang = $c->param('tongue');
        _logged_in($c);
957
    }
958
    $c->param('tongue' => $USER->language);
joelalju's avatar
joelalju committed
959
    my @errors;
960
    if ($c->param('button_click')) {
961
        if (($c->param('password') eq "") || ($c->param('conf_password') eq "") || ($c->param('current_password') eq "")) {
962
            push @errors,("Some of the password's fields are empty");
fv3rdugo's avatar
fv3rdugo committed
963
        }
964
965
        else {
            if ($c->param('password') eq $c->param('conf_password')) {
fv3rdugo's avatar
fv3rdugo committed
966
967
                eval {
                    $USER->change_password($c->param('password'));
968
969
970
971
972
973
974
                    _logged_in($c);
                };
                if ($@ =~ /Password too small/) {
                    push @errors,("Password too small")
                }
                else {
                    $changed_pass = 1;
975
976
977
                }
            }
            else {
fv3rdugo's avatar
fv3rdugo committed
978
                    push @errors,("Password fields aren't equal")
979
            }
980
        }
981
    }
joelalju's avatar
joelalju committed
982
983
    $c->render(template => 'bootstrap/user_settings', changed_lang=> $changed_lang, changed_pass => $changed_pass
      ,errors =>\@errors);
984
985
};

986
987
988
989
990
get '/img/screenshots/:file' => sub {
    my $c = shift;

    my $file = $c->param('file');
    my $path = $DOCUMENT_ROOT."/".$c->req->url->to_abs->path;
991

992
993
994
995
996
997
998
999
1000
    my ($id_domain ) =$path =~ m{/(\d+)\..+$};
    if (!$id_domain) {
        warn"ERROR : no id domain in $path";
        return $c->reply->not_found;
    }
    if (!$USER->is_admin) {
        my $domain = $RAVADA->search_domain_by_id($id_domain);
        return $c->reply->not_found if !$domain;
        unless ($domain->is_base && $domain->is_public) {
For faster browsing, not all history is shown. View entire blame