3 #################################################################################
4 # Xestia Scanner Server (xsdss.cgi) #
5 # Main program script #
9 # Copyright (C) 2005-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk> #
11 # This code has been forked from Kiriwrite <http://xestia.co.uk/kiriwrite>. #
12 # Save development time, recycle your code where possible! #
14 # This program is free software: you can redistribute it and/or modify #
15 # it under the terms of the GNU General Public License as published by #
16 # the Free Software Foundation, version 3 of the License. #
18 # This program is distributed in the hope that it will be useful, #
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
21 # GNU General Public License for more details. #
23 # You should have received a copy of the GNU General Public License #
24 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
25 #################################################################################
33 use MIME::Base64 3.13 qw(decode_base64url);
35 binmode STDOUT, ':utf8';
37 # This is commented out because it uses a fair bit of CPU usage.
39 #use CGI::Carp('fatalsToBrowser'); # Output errors to the browser.
41 # Declare global variables for Xestia Scanner Server settings and languages.
43 our ($xestiascan_config, %xestiascan_config, %xestiascan_lang, $xestiascan_lang, $xestiascan_version, %xestiascan_version, $xestiascan_env, %xestiascan_env, $xestiascan_presmodule, $xestiascan_authmodule, $xestiascan_script_name, $xestiascan_env_path);
44 our ($form_data, %form_data);
46 our $successful_auth = 0;
48 # If you are using mod_perl please change these settings to the correct
49 # directory where this script is being run from.
54 # Load the common functions module.
56 use Modules::System::Common;
58 # Setup the version information for Xestia Scanner Version.
60 %xestiascan_version = (
66 xestiascan_initialise; # Initialise the Xestia Scanner Server enviroment.
67 xestiascan_settings_load; # Load the configuration options.
69 my $query_lite = new CGI::Lite;
70 $form_data = $query_lite->parse_form_data();
72 # Check to see if the user is logged in and present a form if not.
74 use Modules::System::Auth;
76 # Check to see if the module is a multiuser module.
78 my %authmodule_capabilities = $xestiascan_authmodule->capabilities();
80 if ($authmodule_capabilities{'multiuser'} eq 0){
82 # Module does not have multiuser support so don't do
89 my $auth_username = "";
90 my $auth_password = "";
92 my $auth_stayloggedin = "";
93 my $auth_validinput = 1;
94 my $cookie_expirestime = 0;
95 my $auth_failure = int(0);
97 my $auth_result = "none";
99 my $cookie_data = $query_lite->parse_cookies;
101 $auth_username = decode_base64url($cookie_data->{ $main::xestiascan_config{'database_tableprefix'} . '_auth_username'});
102 $auth_seed = $cookie_data->{ $main::xestiascan_config{'database_tableprefix'} . '_auth_seed'};
104 if (!$auth_username || !$auth_seed){
106 # The authentication data contains invalid input.
108 $auth_validinput = 0;
112 # Check to see if the username and seed are valid and
113 # skip to the login form if it isn't.
115 if ($auth_validinput eq 1){
117 # Connect to the database server and authenticate.
119 $xestiascan_authmodule->connect();
121 # Check if any errors occured while connecting to the database server.
123 if ($main::xestiascan_authmodule->geterror eq "AuthConnectionError"){
125 # A database connection error has occured so return
128 xestiascan_error("authconnectionerror", $main::xestiascan_authmodule->geterror(1));
132 $auth_result = $xestiascan_authmodule->userauth("seed", $auth_username, $auth_seed);
134 if ($xestiascan_authmodule->geterror eq "DatabaseError"){
136 # A database error has occured so return an error with
137 # the extended error information.
139 xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
143 $successful_auth = 1 if $auth_result eq 1;
144 $auth_failure = 1 if $auth_result ne 1;
145 $auth_failure = 0 if (!$auth_seed || $auth_seed eq "");
147 # Disconnect from the database server.
149 #$xestiascan_authmodule->disconnect();
153 if ($form_data->{'mode'} && $form_data->{'mode'} eq "auth" && $successful_auth eq 0){
155 $auth_username = $form_data->{'username'};
156 $auth_password = $form_data->{'password'};
157 $auth_stayloggedin = $form_data->{'stayloggedin'};
159 if (!$auth_stayloggedin || $auth_stayloggedin ne "on"){
161 $auth_stayloggedin = 0;
162 $cookie_expirestime = 10800;
166 $auth_stayloggedin = 1;
167 $cookie_expirestime = 31536000;
171 $xestiascan_authmodule->connect();
173 # Check if any errors occured while connecting to the database server.
175 if ($main::xestiascan_authmodule->geterror eq "AuthConnectionError"){
177 # A database connection error has occured so return
180 xestiascan_error("authconnectionerror", $main::xestiascan_authmodule->geterror(1));
184 ($auth_result, $auth_seed) = $xestiascan_authmodule->userauth("password", $auth_username, $auth_password, $auth_stayloggedin);
186 if ($xestiascan_authmodule->geterror eq "DatabaseError"){
188 # A database error has occured so return an error with
189 # the extended error information.
191 xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
195 $successful_auth = 1 if $auth_result eq 1;
196 $auth_failure = 1 if $auth_result ne 1;
198 # Disconnect from the database server.
200 #$xestiascan_authmodule->disconnect();
202 $form_data->{'mode'} = "";
208 if ($successful_auth eq 0) {
210 # No valid authenication credentials are available so write a form.
212 my $authpagedata = xestiascan_auth_authenticate($auth_failure);
214 xestiascan_output_header;
215 xestiascan_output_page("Login", $authpagedata, "none");
220 if ($successful_auth eq 1){
222 $loggedin_user = $auth_username;
228 # Check if a mode has been specified and if a mode has been specified, continue
229 # and work out what mode has been specified.
231 if ($form_data->{'mode'}){
232 my $http_query_mode = $form_data->{'mode'};
234 if ($http_query_mode eq "scan"){
236 use Modules::System::Scan;
238 if ($form_data->{'action'}){
240 my $http_query_action = $form_data->{'action'};
242 if ($http_query_action eq "scan"){
244 my $http_query_previewdocument = $form_data->{'previewdocument'};
245 my $http_query_switch = $form_data->{'switch'};
247 $http_query_previewdocument = "no" if !$http_query_previewdocument;
248 $http_query_switch = "no" if !$http_query_switch;
250 # Get the variables needed for the subroutine.
254 $previewoptions{ScannerID} = $form_data->{'scanner'};
255 $previewoptions{Brightness} = $form_data->{'brightness'};
256 $previewoptions{Contrast} = $form_data->{'contrast'};
257 $previewoptions{Rotate} = $form_data->{'rotate'};
258 $previewoptions{Colour} = $form_data->{'colourtype'};
259 $previewoptions{Resolution} = $form_data->{'imagedpi'};
260 $previewoptions{TopLeftX} = $form_data->{'topleftx'};
261 $previewoptions{TopLeftY} = $form_data->{'toplefty'};
262 $previewoptions{BottomRightX} = $form_data->{'bottomrightx'};
263 $previewoptions{BottomRightY} = $form_data->{'bottomrighty'};
265 $previewoptions{TopLeftX} = "0" if !$previewoptions{TopLeftX};
267 if ($http_query_switch eq "switched"){
269 # Switching scanners so don't need to scan.
271 my $pagedata = xestiascan_scan_preview("off", %previewoptions);
273 # Output the header to browser/console/stdout.
275 xestiascan_output_header;
276 xestiascan_output_page($xestiascan_lang{scan}{scanconfig}, $pagedata, "database"); # Output the page to browser/console/stdout.
277 exit; # End the script.
281 if ($http_query_previewdocument eq "on"){
283 # No action specified so write out default form.
285 my $pagedata = xestiascan_scan_preview("on", %previewoptions);
287 # Output the header to browser/console/stdout.
289 xestiascan_output_header;
290 xestiascan_output_page($xestiascan_lang{scan}{scanconfig}, $pagedata, "database"); # Output the page to browser/console/stdout.
291 exit; # End the script.
295 my $http_query_outputformat = $form_data->{'outputformat'};
296 my $http_query_formatswitch = $form_data->{'formatswitch'};
297 my $http_query_confirm = $form_data->{'confirm'};
298 my $http_query_imagehex = $form_data->{'imagehex'};
300 $http_query_formatswitch = "no" if !$http_query_formatswitch;
301 $previewoptions{Switched} = $http_query_formatswitch;
303 if (!$http_query_confirm){
304 $http_query_confirm = 0;
307 if ($http_query_formatswitch eq "yes"){
308 $http_query_confirm = 0;
311 $previewoptions{ImageHex} = $http_query_imagehex if $http_query_imagehex;
312 $previewoptions{OutputFormat} = $http_query_outputformat if $http_query_outputformat;
314 my $pagedata = xestiascan_scan_final($http_query_confirm, %previewoptions);
316 xestiascan_output_header;
317 xestiascan_output_page($xestiascan_lang{scan}{picturesettings}, $pagedata, "database"); # Output the page to browser/console/stdout.
318 exit; # End the script.
322 } elsif ($http_query_action eq "getpreviewimage"){
324 my $http_query_pictureid = $form_data->{'pictureid'};
325 my $http_query_dontclear = $form_data->{'dontclear'};
327 if (!$http_query_dontclear){
328 $http_query_dontclear = 0;
331 xestiascan_scan_getpreviewimage($http_query_pictureid, $http_query_dontclear);
338 # No action specified so write out default form.
340 my $pagedata = xestiascan_scan_preview();
342 # Output the header to browser/console/stdout.
344 xestiascan_output_header;
345 xestiascan_output_page($xestiascan_lang{scan}{scanconfig}, $pagedata, "database"); # Output the page to browser/console/stdout.
346 exit; # End the script.
348 } elsif ($http_query_mode eq "users"){
350 use Modules::System::Users;
352 if ($form_data->{'action'}){
354 my $http_query_action = $form_data->{'action'};
356 if ($http_query_action eq "add"){
358 my $http_query_confirm = $form_data->{'confirm'};
360 if (!$http_query_confirm){
362 # The http_query_confirm variable is uninitialised, so place a
363 # '0' (meaning an unconfirmed action).
365 $http_query_confirm = 0;
369 if ($http_query_confirm eq 1){
372 my $hs = new Hash::Search;
374 %form_data = $query_lite->parse_form_data();
376 $http_userinfo{'Username'} = $form_data->{'username'};
377 $http_userinfo{'Name'} = $form_data->{'name'};
378 $http_userinfo{'Password'} = $form_data->{'password'};
379 $http_userinfo{'ConfirmPassword'} = $form_data->{'confirmpassword'};
380 $http_userinfo{'Admin'} = $form_data->{'admin'};
381 $http_userinfo{'Enabled'} = $form_data->{'enabled'};
383 # Get the list of scanners from the query.
385 $hs->hash_search("^scanner_", %form_data);
386 my %http_scanner = $hs->hash_search_resultdata;
388 # Get the list of output modules from the query.
390 $hs->hash_search("^outputmodule_", %form_data);
391 my %http_outputmodules = $hs->hash_search_resultdata;
393 # Get the list of export modules from the query.
395 $hs->hash_search("^exportmodule_", %form_data);
396 my %http_exportmodules = $hs->hash_search_resultdata;
398 my $pagedata = xestiascan_users_add($http_userinfo{Username}, \%http_userinfo, \%http_scanner, \%http_outputmodules, \%http_exportmodules, $http_query_confirm);
400 xestiascan_output_header; # Output the header to browser/console/stdout;
401 xestiascan_output_page($xestiascan_lang{users}{adduser}, $pagedata, "users"); # Output the page to browser/console/stdout;
402 exit; # End the script.
406 my $pagedata = xestiascan_users_add;
408 xestiascan_output_header; # Output the header to browser/console/stdout;
409 xestiascan_output_page($xestiascan_lang{users}{adduser}, $pagedata, "users"); # Output the page to browser/console/stdout;
410 exit; # End the script.
412 } elsif ($http_query_action eq "edit"){
414 my $http_query_confirm = $form_data->{'confirm'};
415 my $http_query_username = $form_data->{'user'};
417 if (!$http_query_confirm){
419 # The http_query_confirm variable is uninitialised, so place a
420 # '0' (meaning an unconfirmed action).
422 $http_query_confirm = 0;
426 if ($http_query_confirm eq 1){
428 # The action to edit the user has been confirmed so collect
429 # the information needed for the xestiascan_users_edit
433 my $hs = new Hash::Search;
435 my %form_data = $query_lite->parse_form_data();
437 my $confirm = $form_data->{'confirm'};
438 $http_userinfo{'OriginalUsername'} = $form_data->{'username_original'};
439 $http_userinfo{'NewUsername'} = $form_data->{'username'};
440 $http_userinfo{'Name'} = $form_data->{'name'};
441 $http_userinfo{'Password'} = $form_data->{'password'};
442 $http_userinfo{'ConfirmPassword'} = $form_data->{'confirmpassword'};
443 $http_userinfo{'Admin'} = $form_data->{'admin'};
444 $http_userinfo{'Enabled'} = $form_data->{'enabled'};
446 # Get the list of scanners from the query.
448 $hs->hash_search("^scanner_", %form_data);
449 my %http_scanner = $hs->hash_search_resultdata;
451 # Get the list of output modules from the query.
453 $hs->hash_search("^outputmodule_", %form_data);
454 my %http_outputmodules = $hs->hash_search_resultdata;
456 # Get the list of export modules from the query.
458 $hs->hash_search("^exportmodule_", %form_data);
459 my %http_exportmodules = $hs->hash_search_resultdata;
461 my $pagedata = xestiascan_users_edit($http_userinfo{OriginalUsername}, \%http_userinfo, \%http_scanner, \%http_outputmodules, \%http_exportmodules, $confirm);
463 xestiascan_output_header; # Output the header to browser/console/stdout;
464 xestiascan_output_page($xestiascan_lang{users}{edituser}, $pagedata, "users"); # Output the page to browser/console/stdout;
465 exit; # End the script.
469 my $pagedata = xestiascan_users_edit($http_query_username);
471 xestiascan_output_header; # Output the header to browser/console/stdout;
472 xestiascan_output_page($xestiascan_lang{users}{edituser}, $pagedata, "users"); # Output the page to browser/console/stdout;
473 exit; # End the script.
475 } elsif ($http_query_action eq "delete"){
477 my $http_query_confirm = $form_data->{'confirm'};
478 my $http_query_username = $form_data->{'user'};
480 if (!$http_query_confirm){
482 # The http_query_confirm variable is uninitialised, so place a
483 # '0' (meaning an unconfirmed action).
485 $http_query_confirm = 0;
489 if ($http_query_confirm eq 1){
491 # The action to delete a user has been confirmed.
493 my $pagedata = xestiascan_users_delete($http_query_username, $http_query_confirm);
495 xestiascan_output_header; # Output the header to browser/console/stdout;
496 xestiascan_output_page($xestiascan_lang{users}{deleteuser}, $pagedata, "users"); # Output the page to browser/console/stdout;
497 exit; # End the script.
501 my $pagedata = xestiascan_users_delete($http_query_username);
503 xestiascan_output_header; # Output the header to browser/console/stdout;
504 xestiascan_output_page($xestiascan_lang{users}{deleteuser}, $pagedata, "users"); # Output the page to browser/console/stdout;
505 exit; # End the script.
507 } elsif ($http_query_action eq "flush"){
509 my $http_query_confirm = $form_data->{'confirm'};
511 $http_query_confirm = 0 if !$http_query_confirm;
513 my $pagedata = xestiascan_users_flush($http_query_confirm);
515 xestiascan_output_header; # Output the header to browser/console/stdout;
516 xestiascan_output_page($xestiascan_lang{users}{logoutallusers}, $pagedata, "users"); # Output the page to browser/console/stdout;
517 exit; # End the script.
521 # The action specified was something else other than those
522 # above, so return an error.
524 xestiascan_error("invalidaction");
530 my $showdeactivated = 0;
532 if ($form_data->{'showdeactivated'} && $form_data->{'showdeactivated'} eq "on"){
534 $showdeactivated = 1;
538 my $pagedata = xestiascan_users_list({ ShowDeactivatedUsers => $showdeactivated });
540 xestiascan_output_header; # Output the header to browser/console/stdout;
541 xestiascan_output_page($xestiascan_lang{users}{userslist}, $pagedata, "users"); # Output the page to browser/console/stdout;
542 exit; # End the script.
544 } elsif ($http_query_mode eq "settings"){
546 use Modules::System::Settings;
548 if ($form_data->{'action'}){
549 my $http_query_action = $form_data->{'action'};
551 if ($http_query_action eq "edit"){
553 # The action specified is to edit the settings. Check if the action
554 # to edit the settings has been confirmed.
556 my $http_query_confirm = $form_data->{'confirm'};
558 if (!$http_query_confirm){
560 # The confirm value is blank, so set it to 0.
562 $http_query_confirm = 0;
566 if ($http_query_confirm eq 1){
568 # The action to edit the settings has been confirmed. Get the
569 # required settings from the HTTP query.
571 my $http_query_imagesuri = $form_data->{'imagesuripath'};
572 my $http_query_scansuri = $form_data->{'scansuripath'};
573 my $http_query_scansfs = $form_data->{'scansfspath'};
574 my $http_query_datetimeformat = $form_data->{'datetime'};
575 my $http_query_systemlanguage = $form_data->{'language'};
576 my $http_query_presmodule = $form_data->{'presmodule'};
577 my $http_query_authmodule = $form_data->{'authmodule'};
578 my $http_query_outputmodule = $form_data->{'outputmodule'};
580 my $http_query_database_server = $form_data->{'database_server'};
581 my $http_query_database_port = $form_data->{'database_port'};
582 my $http_query_database_protocol = $form_data->{'database_protocol'};
583 my $http_query_database_sqldatabase = $form_data->{'database_sqldatabase'};
584 my $http_query_database_username = $form_data->{'database_username'};
585 my $http_query_database_passwordkeep = $form_data->{'database_password_keep'};
586 my $http_query_database_password = $form_data->{'database_password'};
587 my $http_query_database_tableprefix = $form_data->{'database_tableprefix'};
589 my $pagedata = xestiascan_settings_edit({ ImagesURIPath => $http_query_imagesuri, ScansURIPath => $http_query_scansuri, ScansFSPath => $http_query_scansfs, DateTimeFormat => $http_query_datetimeformat, SystemLanguage => $http_query_systemlanguage, PresentationModule => $http_query_presmodule, OutputModule => $http_query_outputmodule, AuthModule => $http_query_authmodule, DatabaseServer => $http_query_database_server, DatabasePort => $http_query_database_port, DatabaseProtocol => $http_query_database_protocol, DatabaseSQLDatabase => $http_query_database_sqldatabase, DatabaseUsername => $http_query_database_username, DatabasePasswordKeep => $http_query_database_passwordkeep, DatabasePassword => $http_query_database_password, DatabaseTablePrefix => $http_query_database_tableprefix, Confirm => 1 });
591 xestiascan_output_header; # Output the header to browser/console/stdout.
592 xestiascan_output_page($xestiascan_lang{setting}{editsettings}, $pagedata, "settings"); # Output the page to browser/console/stdout.
593 exit; # End the script.
597 # The action to edit the settings has not been confirmed.
599 my $pagedata = xestiascan_settings_edit();
601 xestiascan_output_header; # Output the header to browser/console/stdout.
602 xestiascan_output_page($xestiascan_lang{setting}{editsettings}, $pagedata, "settings"); # Output the page to browser/console/stdout.
603 exit; # End the script.
607 # The action specified was something else other than those
608 # above, so return an error.
610 xestiascan_error("invalidaction");
616 # No action has been specified, so print out the list of settings currently being used.
618 my $pagedata = xestiascan_settings_view();
620 xestiascan_output_header; # Output the header to browser/console/stdout.
621 xestiascan_output_page($xestiascan_lang{setting}{viewsettings}, $pagedata, "settings"); # Output the page to browser/console/stdout.
622 exit; # End the script.
624 } elsif ($http_query_mode eq "logout"){
626 # The mode selected is to logout the user.
628 my $pagedata = xestiascan_auth_logout();
630 xestiascan_output_header("cookie_logout"); # Output the header to browser/console/stdout.
631 xestiascan_output_page($xestiascan_lang{setting}{logout}, $pagedata, "settings"); # Output the page to browser/console/stdout.
632 exit; # End the script.
636 # An invalid mode has been specified so return
639 xestiascan_error("invalidmode");
645 # No mode has been specified, so print the default "first-run" view of the
648 use Modules::System::Scan;
650 my $pagedata = xestiascan_scan_preview();
652 # Output the header to browser/console/stdout.
654 if ($print_cookie eq 1){
655 xestiascan_output_header("cookie", $auth_username, $auth_seed, $cookie_expirestime);
657 xestiascan_output_header;
660 xestiascan_output_page($xestiascan_lang{scan}{scanconfig}, $pagedata, "database"); # Output the page to browser/console/stdout.
661 exit; # End the script.