1 #################################################################################
2 # Xestia Scanner Server Database Module - PostgreSQL Database Module #
3 # Database module for mainipulating data in a PostgreSQL database. #
5 # Copyright (C) 2010-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk> #
7 # This module is licensed under the same license as Xestia Scanner Server which #
8 # is the GPL version 3. #
10 # This program is free software: you can redistribute it and/or modify #
11 # it under the terms of the GNU General Public License as published by #
12 # the Free Software Foundation, version 3 of the License. #
14 # This program is distributed in the hope that it will be useful, #
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
17 # GNU General Public License for more details. #
19 # You should have received a copy of the GNU General Public License #
20 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
21 #################################################################################
23 # Define the package (perl module) name.
25 package Modules::Auth::PostgreSQL;
27 # Enable strict and use warnings.
35 # Load the following Perl modules.
37 use DBI qw(:sql_types);
39 # Set the following values.
41 our $VERSION = "0.1.0";
42 my ($options, %options);
47 my $database_filename;
48 my $second_database_filename;
50 #################################################################################
51 # Generic Subroutines. #
52 #################################################################################
55 #################################################################################
56 # new: Create an instance of the PostgreSQL module. #
60 # $dbmodule = PostgreSQL->new(); #
61 #################################################################################
63 # Get the perl module name.
68 return bless($self, $class);
73 #################################################################################
74 # capabilities: Get the capabilities for this module as a hash. #
78 # $dbmodule->capabilities(); #
79 #################################################################################
92 #################################################################################
93 # loadsettings: Loads settings into the PostgreSQL authentication module #
97 # $dbmodule->loadsettings(options); #
99 # options Specifies the following options (in any order). #
101 # DateTime Specifies the date and time format to use. #
102 # Server Specifies the server to use. #
103 # Database Specifies the database to use. #
104 # Username Specifies the username to use. #
105 # Password Specifies the password to use. #
106 # Port Specifies the server port to use. #
107 # Protocol Specifies the protocol to use. #
108 # TablePrefix Specifies the table prefix to use. #
109 #################################################################################
111 # Get the data passed to the subroutine.
114 my ($passedoptions) = @_;
116 # Add the directory setting to the list of options (as it's the only
117 # one needed for this database module).
120 "Directory" => $passedoptions->{"Directory"},
121 "DateTime" => $passedoptions->{"DateTime"},
122 "Server" => $passedoptions->{"Server"},
123 "Database" => $passedoptions->{"Database"},
124 "Username" => $passedoptions->{"Username"},
125 "Password" => $passedoptions->{"Password"},
126 "Port" => $passedoptions->{"Port"},
127 "Protocol" => $passedoptions->{"Protocol"},
128 "TablePrefix" => $passedoptions->{"TablePrefix"}
134 #################################################################################
135 # convert: Converts data into SQL formatted data. #
139 # $dbmodule->convert(data); #
141 # data Specifies the data to convert. #
142 #################################################################################
144 # Get the data passed to the subroutine.
161 #################################################################################
162 # dateconvert: Converts a SQL date into a proper date. #
166 # $dbmodule->dateconvert(date); #
168 # date Specifies the date to convert. #
169 #################################################################################
171 # Get the date passed to the subroutine.
176 # Convert the date given into the proper date.
178 # Create the following varialbes to be used later.
205 # Split the date and time.
207 $length = length($data);
213 # Get the character and check if it is a space.
215 $char = substr($data, $seek, 1);
219 # The character is a space, so get the date and time.
221 $date = substr($data, 0, $seek);
222 $timelength = $length - $seek - 1;
223 $time = substr($data, $seek + 1, $timelength);
229 } until ($seek eq $length);
231 # Get the year, month and date.
233 $length = length($date);
238 # Get the character and check if it is a dash.
240 $char = substr($date, $seek, 1);
244 # The character is a dash, so get the year, month or day.
246 $datelength = $seek - $startchar;
250 # Get the year from the date.
252 $year = substr($date, 0, $datelength) + 1900;
256 # Get the last two characters to get the short year
259 $year_short = substr($year, 2, 2);
261 } elsif ($count eq 1){
263 # Get the month and day from the date.
265 $month = substr($date, $startchar + 1, $datelength - 1) + 1;
267 # Check if the month is less then 10, if it is
268 # add a zero to the value.
272 $month_full = '0' . $month;
276 $month_full = $month;
283 $daylength = $length - $seek + 1;
284 $day = substr($date, $startchar + 1, $daylength);
288 # Check if the day is less than 10, if it is
289 # add a zero to the value.
293 $day_full = '0' . $day;
307 } until ($seek eq $length);
309 # Get the length of the time value and reset certain
312 $length = length($time);
319 # Get the character and check if it is a colon.
321 $char = substr($time, $seek, 1);
325 # The character is a colon, so get the hour, minute and day.
327 $timelength = $seek - $startchar;
331 # Get the hour from the time.
333 $hour = substr($time, 0, $timelength);
338 # If the hour is less than ten then add a
343 $hour_full = '0' . $hour;
351 } elsif ($count eq 1){
353 # Get the minute and second from the time.
355 $minute = substr($time, $startchar + 1, $timelength - 1);
359 # If the minute is less than ten then add a
364 $minute_full = '0' . $minute;
368 $minute_full = $minute;
374 $secondlength = $length - $seek + 1;
375 $second = substr($time, $startchar + 1, $secondlength);
378 # If the second is less than ten then add a
383 $second_full = '0' . $second;
387 $second_full = $second;
397 } until ($seek eq $length);
399 # Get the setting for displaying the date and time.
401 $data = $options{"DateTime"};
403 # Process the setting for displaying the date and time
404 # using regular expressions
406 $data =~ s/DD/$day_full/g;
408 $data =~ s/MM/$month_full/g;
409 $data =~ s/M/$month/g;
410 $data =~ s/YY/$year/g;
411 $data =~ s/Y/$year_short/g;
413 $data =~ s/hh/$hour_full/g;
414 $data =~ s/h/$hour/g;
415 $data =~ s/mm/$minute_full/g;
416 $data =~ s/m/$minute/g;
417 $data =~ s/ss/$second_full/g;
418 $data =~ s/s/$second/g;
427 #################################################################################
428 # geterror: Gets the error message (or extended error message). #
432 # $dbmodule->geterror(extended); #
434 # Extended Specifies if the extended error should be retrieved. #
435 #################################################################################
437 # Get the data passed to the subroutine.
440 my $extended = shift;
454 # Check to see if extended information should be returned.
458 # Extended information should be returned.
464 # Basic information should be returned.
472 #################################################################################
473 # General subroutines. #
474 #################################################################################
477 #################################################################################
478 # connect: Connect to the server. #
482 # $dbmodule->connect(); #
483 #################################################################################
488 # Connect to the server.
490 $database_handle = DBI->connect("DBI:Pg:dbname=" . $options{"Database"} . ";host=" . $options{"Server"} . ";port=" . $options{"Port"}, $options{"Username"}, $options{"Password"}) or ( $error = "AuthConnectionError", $errorext = DBI->errstr, return );
491 $database_handle->do("SET CLIENT_ENCODING TO 'UTF8'");
492 #$database_handle->do('SET NAMES utf8');
497 #################################################################################
498 # connect: Disconnect from the server. #
502 # $dbmodule->disconnect(); #
503 #################################################################################
505 # Disconnect from the server.
507 if ($statement_handle){
509 $statement_handle->finish();
513 if ($database_handle){
515 $database_handle->disconnect();
522 #################################################################################
523 # getuserlist: Get the user list. #
527 # $dbmodule->getuserlist(options); #
529 # options Specifies the following options in any order. #
531 # Reduced Gets a reduced version of the user list. #
532 # ShowDeactivated Show users that are deactivated from the list. #
533 #################################################################################
538 # Get the values passed to the subroutine.
541 my ($passedoptions) = @_;
547 tie(%user_list, 'Tie::IxHash');
549 my $reduced_list = $passedoptions->{"Reduced"};
550 my $deactivated_show = $passedoptions->{"ShowDeactivated"};
551 $deactivated_show = 0 if !$passedoptions->{"ShowDeactivated"};
553 # Check if a reduced version of the user list should be retreived.
555 if ($reduced_list eq 1){
557 # Get the list of users with reduced information.
559 $sqlquery = 'SELECT username, name, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_users';
563 # Get the list of users.
565 $sqlquery = 'SELECT * FROM ' . $class->convert($options{"TablePrefix"}) . '_users';
569 # Check if the deactivated users should be hidden.
571 if ($deactivated_show eq 0){
573 # The deactivated users should be hidden from the list.
575 $sqlquery = $sqlquery . ' WHERE enabled=TRUE';
579 $sqlquery = $sqlquery . ' ORDER BY username';
583 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
584 $statement_handle->execute();
586 # Process the user list.
588 while (@user_data = $statement_handle->fetchrow_array()){
590 $user_list{$user_seek}{username} = decode_utf8($user_data[0]);
591 $user_list{$user_seek}{name} = decode_utf8($user_data[1]);
593 if ($user_data[2] eq 0){
595 $user_list{$user_seek}{deactivated} = 1;
599 $user_list{$user_seek}{deactivated} = 0;
612 #################################################################################
613 # getpermissions: Get the permissions for scanner or module. #
617 # $dbmodule->getpermissions(options); #
619 # options Specifies the following options in any order. #
621 # Username Specifies the username to get permissions for. #
622 # PermissionType Specifies the permission type. #
623 # PermissionName Get a specific permission name. #
625 # If no permission name is specified then a list of permissions will be #
626 # returned as hash otherwise the value will be returned as a normal string. #
627 #################################################################################
632 # Get the value passed to the subroutine.
635 my ($passedoptions) = @_;
637 my $username = $passedoptions->{'Username'};
638 my $permissiontype = $passedoptions->{'PermissionType'};
639 my $permissionname = $passedoptions->{'PermissionName'};
643 my $permissionresult = 0;
650 # The username is blank so return an error.
652 $error = "UsernameBlank";
657 if (!$permissiontype){
659 # The permissions type is blank so return an error.
661 $error = "PermissionTypeBlank";
666 #if (!$permissionname){
668 # The permissions name is blank so return a list of
669 # permissions for that type.
671 # my %user_permissions;
673 # return %user_permissions;
677 # Get the user ID number.
679 $sqlquery = 'SELECT uid, username FROM ' . $class->convert($options{"TablePrefix"}) . '_users WHERE username=\'' . $class->convert(decode_utf8($username)) . '\'';
683 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
684 $statement_handle->execute();
686 while(@userdata = $statement_handle->fetchrow_array()){
692 if ($permissiontype eq "OutputModule"){
694 if (!$permissionname){
698 # No permission name was specified so get the list of
699 # scanner permissions.
701 $sqlquery = 'SELECT uid, moduletype, modulename, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_modules WHERE uid=\'' . $class->convert($uid) . '\' AND moduletype=\'Output\'';
705 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
706 $statement_handle->execute();
708 # Process the list of permissions.
710 while(@permissiondata = $statement_handle->fetchrow_array()){
712 $useroutputinfo{$permissiondata[2]} = $permissiondata[3];
716 return %useroutputinfo;
720 $sqlquery = 'SELECT uid, moduletype, modulename, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_modules WHERE uid=\'' . $class->convert($uid) . '\' AND moduletype=\'Output\' AND modulename=\'' . $class->convert($permissionname) . '\'';
724 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
725 $statement_handle->execute();
727 # Check to see the value of the permission.
729 while(@permissiondata = $statement_handle->fetchrow_array()){
731 if ($permissiondata[3] eq 1){
733 $permissionresult = 1;
737 $permissionresult = 0;
743 } elsif ($permissiontype eq "ExportModule"){
745 if (!$permissionname){
749 # No permission name was specified so get the list of
750 # scanner permissions.
752 $sqlquery = 'SELECT uid, moduletype, modulename, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_modules WHERE uid=\'' . $class->convert($uid) . '\' AND moduletype=\'Export\'';
756 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
757 $statement_handle->execute();
759 # Process the list of permissions.
761 while(@permissiondata = $statement_handle->fetchrow_array()){
763 $userexportinfo{$permissiondata[2]} = $permissiondata[3];
767 return %userexportinfo;
771 $sqlquery = 'SELECT uid, moduletype, modulename, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_modules WHERE uid=\'' . $class->convert($uid) . '\' AND moduletype=\'Export\' AND modulename=\'' . $class->convert($permissionname) . '\'';
775 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
776 $statement_handle->execute();
778 # Check to see the value of the permission.
780 while(@permissiondata = $statement_handle->fetchrow_array()){
782 if ($permissiondata[3] eq 1){
784 $permissionresult = 1;
788 $permissionresult = 0;
794 } elsif ($permissiontype eq "Scanner"){
796 # The permission type is a Scanner permission.
798 if (!$permissionname){
802 # No permission name was specified so get the list of
803 # scanner permissions.
805 $sqlquery = 'SELECT uid, scannerid, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_scanners WHERE uid=\'' . $class->convert($uid) . '\'';
809 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
810 $statement_handle->execute();
812 # Process the list of permissions.
814 while(@permissiondata = $statement_handle->fetchrow_array()){
816 $userscannerinfo{$permissiondata[1]} = $permissiondata[2];
820 return %userscannerinfo;
824 # The permission type is a Scanner permission.
826 $sqlquery = 'SELECT uid, scannerid, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_scanners WHERE uid=\'' . $class->convert($uid) . '\' AND scannerid=\'' . $class->convert($permissionname) . '\'';
830 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
831 $statement_handle->execute();
833 # Check to see the value of the permission.
835 while(@permissiondata = $statement_handle->fetchrow_array()){
837 if ($permissiondata[2] eq 1){
839 $permissionresult = 1;
843 $permissionresult = 0;
849 } elsif ($permissiontype eq "Admin"){
851 # Check to see if the user has administrative permissions.
853 $sqlquery = 'SELECT uid, admin FROM ' . $class->convert($options{"TablePrefix"}) . '_users WHERE uid=\'' . $class->convert($uid) . '\' AND admin=TRUE AND enabled=TRUE';
857 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
858 $statement_handle->execute();
860 # Check to see the value of the admin permission.
862 while(@permissiondata = $statement_handle->fetchrow_array()){
864 if ($permissiondata[1] eq 1){
866 $permissionresult = 1;
870 $permissionresult = 0;
876 } elsif ($permissiontype eq "UserInfo"){
880 # Get the details of the user.
882 $sqlquery = 'SELECT uid, username, name, admin, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_users WHERE uid=\'' . $class->convert($uid) . '\'';
886 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
887 $statement_handle->execute();
889 while(@permissiondata = $statement_handle->fetchrow_array()){
891 $userinfo{UID} = $permissiondata[0];
892 $userinfo{Username} = decode_utf8($permissiondata[1]);
893 $userinfo{Name} = decode_utf8($permissiondata[2]);
894 $userinfo{Admin} = $permissiondata[3];
895 $userinfo{Enabled} = $permissiondata[4];
903 return $permissionresult;
908 #################################################################################
909 # adduser: Add a user to the user list with specific permissions. #
913 # $dbmodule->adduser(username, userinfo); #
915 # username Specifies the username. #
916 # userinfo Specifies the user information hash. #
917 #################################################################################
924 my $username = shift;
929 # The username is blank so return an error.
931 $error = "UsernameBlank";
936 # Check if the username exists.
941 $sqlquery = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username='" . $class->convert($username) . "'";
943 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
944 $statement_handle->execute();
946 while (@user_data = $statement_handle->fetchrow_array()){
952 if ($user_exists eq 1){
954 $error = "UserExists";
961 my $adminpriv = "FALSE";
962 my $enabledpriv = "FALSE";
964 if (!$userinfo{"Enabled"}){
966 $userinfo{"Enabled"} = "off";
970 if (!$userinfo{"Admin"}){
972 $userinfo{"Admin"} = "off";
976 $adminpriv = "TRUE" if $userinfo{Admin} eq "on";
977 $enabledpriv = "TRUE" if $userinfo{Enabled} eq "on";
979 # Generate a random salt for the password and combine it
982 my $digest = Digest->new("SHA-512");
984 my $salt = uc(sprintf("%x",int(rand(50000000))));
986 $digest->add(decode_utf8($userinfo{Password}));
989 $sqlquery = "INSERT INTO " . $class->convert($options{"TablePrefix"}) . "_users (username, password, salt, version, name, admin, enabled) VALUES(";
990 $sqlquery = $sqlquery . "'" . $class->convert(decode_utf8($userinfo{Username})) . "',";
991 $sqlquery = $sqlquery . "'" . $digest->hexdigest . "',";
992 $sqlquery = $sqlquery . "'" . $salt . "',";
993 $sqlquery = $sqlquery . "1,";
994 $sqlquery = $sqlquery . "'" . $class->convert(decode_utf8($userinfo{Name})) . "',";
995 $sqlquery = $sqlquery . $adminpriv . ",";
996 $sqlquery = $sqlquery . $enabledpriv;
997 $sqlquery = $sqlquery . ")";
999 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1000 $statement_handle->execute();
1007 #################################################################################
1008 # edituser: Edit a user on the user list. #
1012 # $dbmodule->edituser(username, type, data); #
1016 # username Specifies the username to edit. #
1017 # type Specifies the type of data to edit. #
1018 # data Specifies the data to use (as a hash). #
1019 #################################################################################
1026 my $username = shift;
1030 #(%permissions) = @_;
1031 #my %permissions_final;
1032 #my $user_exists = 0;
1036 # The username is blank so return an error.
1038 # $error = "UsernameBlank";
1043 #$username = $data{OriginalUsername};
1047 # The username is blank so return an error.
1049 $error = "UsernameBlank";
1056 # The type is blank so return an error.
1058 $error = "TypeBlank";
1063 # Check if the username exists.
1067 my $user_exists = 0;
1069 $sqlquery = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username='" . decode_utf8($username) . "'";
1071 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1072 $statement_handle->execute();
1074 while (@user_data = $statement_handle->fetchrow_array()){
1080 if ($user_exists ne 1){
1082 $error = "UserDoesNotExist";
1087 # Check what type of data is being updated.
1089 # Get the user ID (UID) number.
1092 $sqlquery = 'SELECT uid, username FROM ' . $class->convert($options{"TablePrefix"}) . '_users WHERE username=\'' . $class->convert(decode_utf8($username)) . '\'';
1097 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1098 $statement_handle->execute();
1100 while(@user_data = $statement_handle->fetchrow_array()){
1102 $uid = $user_data[0];
1106 if ($type eq "User"){
1108 # Update the user information.
1110 $sqlquery = "UPDATE " . $class->convert($options{"TablePrefix"}) . "_users SET";
1112 if (!$data{"Enabled"}){
1114 $data{"Enabled"} = "off";
1118 if (!$data{"Admin"}){
1120 $data{"Admin"} = "off";
1124 # Check if the account is enabled or not.
1126 if ($data{Enabled} eq "on"){
1128 $sqlquery = $sqlquery . " enabled = TRUE";
1132 $sqlquery = $sqlquery . " enabled = FALSE";
1136 # Check if the account has administrative status or not.
1138 if ($data{Admin} eq "on"){
1140 $sqlquery = $sqlquery . ", admin = TRUE";
1144 $sqlquery = $sqlquery . ", admin = FALSE";
1148 # Add the name to query.
1150 $sqlquery = $sqlquery . ", name = '" . $class->convert(decode_utf8($data{Name})) . "'";
1152 # Check if the user with the new username already exists.
1156 if (decode_utf8($username) ne decode_utf8($data{NewUsername})){
1158 my $sqlqueryusername = "";
1160 $sqlqueryusername = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username='" . $class->convert(decode_utf8($data{NewUsername})) . "'";
1162 $statement_handle = $database_handle->prepare($sqlqueryusername) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1163 $statement_handle->execute();
1165 while (@user_data = $statement_handle->fetchrow_array()){
1171 if ($user_exists eq 1){
1173 $error = "NewUsernameAlreadyExists";
1178 $sqlquery = $sqlquery . ", username = \'" . $class->convert(decode_utf8($data{NewUsername})) . "\'";
1182 # Check if the password needs to be changed.
1184 if ($data{Password} ne ""){
1186 if ($data{Password} eq $data{ConfirmPassword}){
1188 # Generate a random salt for the password and combine it
1189 # with the password.
1191 my $digest = Digest->new("SHA-512");
1193 my $salt = uc(sprintf("%x\n",int(rand(50000000))));
1195 $digest->add(decode_utf8($data{Password}));
1196 $digest->add($salt);
1198 $sqlquery = $sqlquery . ", password = \'" . $class->convert($digest->hexdigest) . "\'";
1199 $sqlquery = $sqlquery . ", salt = \'" . $class->convert($salt) . "\'";
1200 $sqlquery = $sqlquery . ", version = 1";
1206 # Add the user id on the end.
1208 $sqlquery = $sqlquery . " WHERE uid = '" . $class->convert($uid) . "'";
1212 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1213 $statement_handle->execute();
1215 } elsif ($type eq "Scanner"){
1217 # Drop all scanner information for this user.
1219 $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_scanners WHERE uid =\'" . $class->convert($uid) . "\'";
1223 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1224 $statement_handle->execute();
1228 # Insert the new scanner information for this user.
1232 $sqlquery = "INSERT INTO xestiascan_scanners (uid, scannerid, enabled) VALUES";
1234 # Process the hash passed to the subroutine.
1239 foreach $datakeyname (keys %data){
1241 if ($firstline eq 1){
1243 $sqlquery = $sqlquery . "(" . $class->convert($uid) . ",\'" . $class->convert($datakeyname) . "\',";
1248 $sqlquery = $sqlquery . ",(" . $class->convert($uid) . ",\'" . $class->convert($datakeyname) . "\',";
1252 if ($data{$datakeyname} eq "on"){
1254 $sqlquery = $sqlquery . "TRUE)";
1258 $sqlquery = $sqlquery . "FALSE)";
1266 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1267 $statement_handle->execute();
1269 } elsif ($type eq "OutputModule"){
1271 # Drop all output module information for this user.
1273 $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_modules WHERE uid ='" . $class->convert($uid) . "' AND moduletype ='Output'";
1277 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1278 $statement_handle->execute();
1282 # Insert the new output module information for this user.
1286 $sqlquery = "INSERT INTO xestiascan_modules (uid, moduletype, modulename, enabled) VALUES";
1288 # Process the hash passed to the subroutine.
1293 foreach $datakeyname (keys %data){
1295 if ($firstline eq 1){
1297 $sqlquery = $sqlquery . "(" . $class->convert($uid) . ",'Output','" . $class->convert($datakeyname) . "',";
1302 $sqlquery = $sqlquery . ",(" . $class->convert($uid) . ",'Output','" . $class->convert($datakeyname) . "',";
1306 if ($data{$datakeyname} eq "on"){
1308 $sqlquery = $sqlquery . "TRUE)";
1312 $sqlquery = $sqlquery . "FALSE)";
1320 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1321 $statement_handle->execute();
1323 } elsif ($type eq "ExportModule"){
1325 # Drop all export module information for this user.
1327 $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_modules WHERE uid ='" . $class->convert($uid) . "' AND moduletype ='Export'";
1331 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1332 $statement_handle->execute();
1336 # Insert the new export module information for this user.
1340 $sqlquery = "INSERT INTO xestiascan_modules (uid, moduletype, modulename, enabled) VALUES";
1342 # Process the hash passed to the subroutine.
1347 foreach $datakeyname (keys %data){
1349 if ($firstline eq 1){
1351 $sqlquery = $sqlquery . "(" . $class->convert($uid) . ",\'Export',\'" . $class->convert($datakeyname) . "\',";
1356 $sqlquery = $sqlquery . ",(" . $class->convert($uid) . ",\'Export\',\'" . $class->convert($datakeyname) . "\',";
1360 if ($data{$datakeyname} eq "on"){
1362 $sqlquery = $sqlquery . "TRUE)";
1366 $sqlquery = $sqlquery . "FALSE)";
1374 $statement_handle = $database_handle->prepare($sqlquery) or die; #( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1375 $statement_handle->execute();
1382 #################################################################################
1383 # deleteuser: Delete a user from the user list. #
1387 # $dbmodule->deleteuser(username); #
1389 # username Specifies the username to delete from the user list. #
1390 #################################################################################
1397 my $username = shift;
1401 # User name is blank so return an error.
1403 $error = "UsernameBlank";
1408 # Check if the user exists before deleting.
1410 my $user_exists = 0;
1413 my $sqlquery = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username=\'" . $class->convert(decode_utf8($username)) . "\' LIMIT 1";
1415 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1416 $statement_handle->execute();
1418 while (@user_data = $statement_handle->fetchrow_array()){
1424 if ($user_exists eq 0){
1426 $error = "UserDoesNotExist";
1431 # Get the user ID (UID) number.
1434 $sqlquery = 'SELECT uid, username FROM ' . $class->convert($options{"TablePrefix"}) . '_users WHERE username=\'' . $class->convert(decode_utf8($username)) . '\'';
1439 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1440 $statement_handle->execute();
1442 while(@user_data = $statement_handle->fetchrow_array()){
1444 $uid = $user_data[0];
1448 # Delete the module permissions from the modules table.
1450 $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_scanners where uid=\'" . $class->convert($uid) . "\'";
1452 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1453 $statement_handle->execute();
1455 # Delete the scanner permissions from the scanners table.
1457 $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_modules where uid=\'" . $class->convert($uid) . "\'";
1459 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1460 $statement_handle->execute();
1462 # Delete the user from the users table.
1464 $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_users where username=\'" . $class->convert(decode_utf8($username)) . "\'";
1466 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1467 $statement_handle->execute();
1472 #################################################################################
1473 # authuser: Authenticate a user. #
1477 # $dbmodule->authuser(type, user, password, keeploggedin); #
1479 # type Specifies the type of authentication. #
1480 # user Specifies the name of the user. #
1481 # password Specifies the password or authentication token. #
1482 # keeploggedin Specifies if the user should stay logged in for one year. #
1483 #################################################################################
1491 my $username = shift;
1492 my $password = shift;
1493 my $keeploggedin = shift;
1495 my $user_exists = 0;
1498 # Check to see if the user exists before authenticating.
1501 my $sqlquery = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username=\'" . $class->convert(decode_utf8($username)) . "\' LIMIT 1";
1503 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1504 $statement_handle->execute();
1506 while (@user_data = $statement_handle->fetchrow_array()){
1512 if ($user_exists eq 0){
1514 $error = "UserDoesNotExist";
1519 # Authenticate the user.
1522 my $valid_login = 0;
1524 if ($type eq "seed"){
1526 $sqlquery = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_sessions WHERE username=\'" . $class->convert(decode_utf8($username)) . "\' AND seed=\'" . $class->convert($password) . "\' AND expires > now() LIMIT 1";
1528 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1529 $statement_handle->execute();
1531 while (@auth_data = $statement_handle->fetchrow_array()){
1537 return $valid_login;
1539 } elsif ($type eq "password") {
1541 $sqlquery = "SELECT username, salt, enabled FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username=\'" . $class->convert(decode_utf8($username)) . "\' LIMIT 1";
1543 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1544 $statement_handle->execute();
1546 my $digest = Digest->new("SHA-512");
1550 while (@auth_data = $statement_handle->fetchrow_array()){
1554 # Check if the user account has been disabled.
1556 if ($auth_data[2] eq 0){
1558 # Account has been disabled so login is invalid.
1564 # Generate the passsword hash using the password and salt given.
1566 $salt = $auth_data[1];
1567 $digest->add(decode_utf8($password));
1568 $digest->add($salt);
1574 return if $valid_login eq 0;
1576 $sqlquery = "SELECT username, password, enabled FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username=\'" . $class->convert(decode_utf8($username)) . "\' AND password =\'" . $class->convert($digest->hexdigest) . "\' LIMIT 1";
1578 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1579 $statement_handle->execute();
1583 while (@auth_data = $statement_handle->fetchrow_array()){
1587 # Check if the user account has been disabled.
1589 if ($auth_data[2] eq 0){
1591 # Account has been disabled so login is invalid.
1599 if ($valid_login eq 1){
1601 my $auth_seed_unique = "yes";
1605 # Check if the auth seed already exists and generate
1606 # a new random number if it does exist.
1610 $auth_seed_unique = "yes";
1611 $new_auth_seed = int(rand(192000000));
1613 $sqlquery = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_sessions WHERE seed=\'" . $class->convert($new_auth_seed) . "\' LIMIT 1";
1615 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1616 $statement_handle->execute();
1618 while (@auth_seed_data = $statement_handle->fetchrow_array()){
1620 $auth_seed_unique = "no";
1624 } until ($auth_seed_unique eq "yes");
1626 # Insert this into the sessions database.
1628 if ($keeploggedin eq 1){
1630 $sqlquery = "INSERT INTO " . $class->convert($options{"TablePrefix"}) . "_sessions (username, seed, expires) VALUES( '" . $class->convert(decode_utf8($username)) . "', '" . $class->convert($new_auth_seed) . "', 'now'::timestamp + '1 year'::interval);";
1634 $sqlquery = "INSERT INTO " . $class->convert($options{"TablePrefix"}) . "_sessions (username, seed, expires) VALUES( '" . $class->convert(decode_utf8($username)) . "', '" . $class->convert($new_auth_seed) . "', 'now'::timestamp + '3 hours'::interval);";
1638 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1639 $statement_handle->execute();
1641 return ($valid_login, $new_auth_seed);
1645 # Return the result.
1647 return $valid_login;
1654 #################################################################################
1655 # flushusers: Flush all users from the sessions table. #
1659 # $dbmodule->flushusers(); #
1660 #################################################################################
1665 # Flush all users from the sessions table. (This includes the user who
1666 # called the action to flush the table).
1670 my $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_sessions";
1672 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1673 $statement_handle->execute();
1678 #################################################################################
1679 # populatetables: Populate the database with tables. #
1683 # type Specifies the type of table to populate. #
1684 # forcerecreate Force recreates the table (delete and create). #
1685 #################################################################################
1693 my $forcerecreate = shift;
1697 if ($type eq "modules"){
1699 if ($forcerecreate eq 1){
1701 $sqlquery = "DROP TABLE " . $class->convert($options{"TablePrefix"}) . "_modules";
1703 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1704 $statement_handle->execute();
1708 $error = "DatabaseError";
1709 $errorext = $DBI::errstr;
1716 $sqlquery = "CREATE TABLE " . $class->convert($options{"TablePrefix"}) . "_modules (
1717 uid bigint NOT NULL,
1718 moduletype varchar(12) NOT NULL,
1719 modulename varchar(256) NOT NULL,
1720 enabled boolean NOT NULL
1723 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1724 $statement_handle->execute();
1728 $error = "DatabaseError";
1729 $errorext = $DBI::errstr;
1734 } elsif ($type eq "scanners"){
1736 if ($forcerecreate eq 1){
1738 $sqlquery = "DROP TABLE " . $class->convert($options{"TablePrefix"}) . "_scanners";
1740 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1741 $statement_handle->execute();
1745 $error = "DatabaseError";
1746 $errorext = $DBI::errstr;
1753 $sqlquery = "CREATE TABLE " . $class->convert($options{"TablePrefix"}) . "_scanners (
1754 uid bigint NOT NULL,
1755 scannerid varchar(256) NOT NULL,
1756 enabled boolean NOT NULL
1759 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1760 $statement_handle->execute();
1764 $error = "DatabaseError";
1765 $errorext = $DBI::errstr;
1770 } elsif ($type eq "sessions"){
1772 if ($forcerecreate eq 1){
1774 $sqlquery = "DROP TABLE " . $class->convert($options{"TablePrefix"}) . "_sessions";
1776 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1777 $statement_handle->execute();
1781 $error = "DatabaseError";
1782 $errorext = $DBI::errstr;
1789 $sqlquery = "CREATE TABLE " . $class->convert($options{"TablePrefix"}) . "_sessions (
1790 seed varchar(32) UNIQUE PRIMARY KEY NOT NULL,
1791 username text NOT NULL,
1792 expires timestamp NOT NULL
1795 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1796 $statement_handle->execute();
1800 $error = "DatabaseError";
1801 $errorext = $DBI::errstr;
1806 } elsif ($type eq "users"){
1808 if ($forcerecreate eq 1){
1810 $sqlquery = "DROP TABLE " . $class->convert($options{"TablePrefix"}) . "_users";
1812 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1813 $statement_handle->execute();
1817 $error = "DatabaseError";
1818 $errorext = $DBI::errstr;
1825 $sqlquery = "CREATE TABLE " . $class->convert($options{"TablePrefix"}) . "_users (
1826 uid SERIAL PRIMARY KEY,
1827 username varchar(64) UNIQUE NOT NULL,
1828 password text NOT NULL,
1829 salt varchar(512) NOT NULL,
1830 version integer NOT NULL,
1831 name varchar(128) NOT NULL,
1832 admin boolean NOT NULL,
1833 enabled boolean NOT NULL
1836 $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
1837 $statement_handle->execute();
1841 $error = "DatabaseError";
1842 $errorext = $DBI::errstr;