1# --
2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/
3# --
4# This software comes with ABSOLUTELY NO WARRANTY. For details, see
5# the enclosed file COPYING for license information (GPL). If you
6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
7# --
8
9package Kernel::System::Web::UploadCache::DB;
10
11use strict;
12use warnings;
13
14use MIME::Base64;
15
16our @ObjectDependencies = (
17    'Kernel::Config',
18    'Kernel::System::DB',
19    'Kernel::System::Encode',
20    'Kernel::System::Log',
21    'Kernel::System::Main',
22);
23
24sub new {
25    my ( $Type, %Param ) = @_;
26
27    # allocate new hash for object
28    my $Self = {};
29    bless( $Self, $Type );
30
31    return $Self;
32}
33
34sub FormIDCreate {
35    my ( $Self, %Param ) = @_;
36
37    # return requested form id
38    return time() . '.' . rand(12341241);
39}
40
41sub FormIDRemove {
42    my ( $Self, %Param ) = @_;
43
44    for (qw(FormID)) {
45        if ( !$Param{$_} ) {
46            $Kernel::OM->Get('Kernel::System::Log')->Log(
47                Priority => 'error',
48                Message  => "Need $_!"
49            );
50            return;
51        }
52    }
53
54    return if !$Kernel::OM->Get('Kernel::System::DB')->Do(
55        SQL => '
56            DELETE FROM web_upload_cache
57            WHERE form_id = ?',
58        Bind => [ \$Param{FormID} ],
59    );
60
61    return 1;
62}
63
64sub FormIDAddFile {
65    my ( $Self, %Param ) = @_;
66
67    for (qw(FormID Filename ContentType)) {
68        if ( !$Param{$_} ) {
69            $Kernel::OM->Get('Kernel::System::Log')->Log(
70                Priority => 'error',
71                Message  => "Need $_!"
72            );
73            return;
74        }
75    }
76
77    $Param{Content} = '' if !defined( $Param{Content} );
78
79    # get file size
80    $Param{Filesize} = bytes::length( $Param{Content} );
81
82    # get database object
83    my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
84
85    # encode attachment if it's a postgresql backend!!!
86    if ( !$DBObject->GetDatabaseFunction('DirectBlob') ) {
87
88        $Kernel::OM->Get('Kernel::System::Encode')->EncodeOutput( \$Param{Content} );
89
90        $Param{Content} = encode_base64( $Param{Content} );
91    }
92
93    # create content id
94    my $ContentID   = $Param{ContentID};
95    my $Disposition = $Param{Disposition} || '';
96    if ( !$ContentID && lc $Disposition eq 'inline' ) {
97
98        my $Random = rand 999999;
99        my $FQDN   = $Kernel::OM->Get('Kernel::Config')->Get('FQDN');
100
101        $ContentID = "$Disposition$Random.$Param{FormID}\@$FQDN";
102    }
103
104    # write attachment to db
105    my $Time = time();
106
107    return if !$DBObject->Do(
108        SQL => '
109            INSERT INTO web_upload_cache (form_id, filename, content_type, content_size, content,
110                create_time_unix, content_id, disposition)
111            VALUES  (?, ?, ?, ?, ?, ?, ?, ?)',
112        Bind => [
113            \$Param{FormID}, \$Param{Filename}, \$Param{ContentType}, \$Param{Filesize},
114            \$Param{Content}, \$Time, \$ContentID, \$Param{Disposition}
115        ],
116    );
117
118    return 1;
119}
120
121sub FormIDRemoveFile {
122    my ( $Self, %Param ) = @_;
123
124    for (qw(FormID FileID)) {
125        if ( !$Param{$_} ) {
126            $Kernel::OM->Get('Kernel::System::Log')->Log(
127                Priority => 'error',
128                Message  => "Need $_!"
129            );
130            return;
131        }
132    }
133
134    my @Index = @{ $Self->FormIDGetAllFilesMeta(%Param) };
135
136    # finish if files have been already removed by other process
137    return if !@Index;
138
139    my $ID = $Param{FileID} - 1;
140    $Param{Filename} = $Index[$ID]->{Filename};
141
142    return if !$Kernel::OM->Get('Kernel::System::DB')->Do(
143        SQL => '
144            DELETE FROM web_upload_cache
145            WHERE form_id = ?
146                AND filename = ?',
147        Bind => [ \$Param{FormID}, \$Param{Filename} ],
148    );
149
150    return 1;
151}
152
153sub FormIDGetAllFilesData {
154    my ( $Self, %Param ) = @_;
155
156    my $Counter = 0;
157    my @Data;
158    for (qw(FormID)) {
159        if ( !$Param{$_} ) {
160            $Kernel::OM->Get('Kernel::System::Log')->Log(
161                Priority => 'error',
162                Message  => "Need $_!"
163            );
164            return;
165        }
166    }
167
168    # get database object
169    my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
170
171    $DBObject->Prepare(
172        SQL => '
173            SELECT filename, content_type, content_size, content, content_id, disposition
174            FROM web_upload_cache
175            WHERE form_id = ?
176            ORDER BY create_time_unix',
177        Bind   => [ \$Param{FormID} ],
178        Encode => [ 1, 1, 1, 0, 1, 1 ],
179    );
180
181    while ( my @Row = $DBObject->FetchrowArray() ) {
182        $Counter++;
183
184        # encode attachment if it's a postgresql backend!!!
185        if ( !$DBObject->GetDatabaseFunction('DirectBlob') ) {
186            $Row[3] = decode_base64( $Row[3] );
187        }
188
189        # add the info
190        push(
191            @Data,
192            {
193                Content     => $Row[3],
194                ContentID   => $Row[4],
195                ContentType => $Row[1],
196                Filename    => $Row[0],
197                Filesize    => $Row[2],
198                Disposition => $Row[5],
199                FileID      => $Counter,
200            }
201        );
202    }
203
204    return \@Data;
205}
206
207sub FormIDGetAllFilesMeta {
208    my ( $Self, %Param ) = @_;
209
210    my $Counter = 0;
211    my @Data;
212    for (qw(FormID)) {
213        if ( !$Param{$_} ) {
214            $Kernel::OM->Get('Kernel::System::Log')->Log(
215                Priority => 'error',
216                Message  => "Need $_!"
217            );
218            return;
219        }
220    }
221
222    # get database object
223    my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
224
225    $DBObject->Prepare(
226        SQL => '
227            SELECT filename, content_type, content_size, content_id, disposition
228            FROM web_upload_cache
229            WHERE form_id = ?
230            ORDER BY create_time_unix',
231        Bind => [ \$Param{FormID} ],
232    );
233
234    while ( my @Row = $DBObject->FetchrowArray() ) {
235        $Counter++;
236
237        # add the info
238        push(
239            @Data,
240            {
241                ContentID   => $Row[3],
242                ContentType => $Row[1],
243                Filename    => $Row[0],
244                Filesize    => $Row[2],
245                Disposition => $Row[4],
246                FileID      => $Counter,
247            }
248        );
249    }
250    return \@Data;
251}
252
253sub FormIDCleanUp {
254    my ( $Self, %Param ) = @_;
255
256    my $CurrentTile = time() - ( 60 * 60 * 24 * 1 );
257
258    return if !$Kernel::OM->Get('Kernel::System::DB')->Do(
259        SQL => '
260            DELETE FROM web_upload_cache
261            WHERE create_time_unix < ?',
262        Bind => [ \$CurrentTile ],
263    );
264
265    return 1;
266}
267
2681;
269