af26687e319176f899e012fb6484ac0b279463ba
[manu/RT-Extension-MessageSizeLimit.git] / lib / RT / Extension / MessageSizeLimit.pm
1 use strict;
2 use warnings;
3 package RT::Extension::MessageSizeLimit;
4
5 our $VERSION = '0.01';
6
7 =head1 NAME
8
9 RT-Extension-MessageSizeLimit - Force web message size limit on ticket create/update
10
11 =head1 DESCRIPTION
12
13 This RT extension enforces a certain message size limit when a user create a
14 ticket or make a comment/correspondance on it.
15
16 It uses a guess of outgoing mail size based on subject/content/attachments. It
17 may miss a few bytes from mail headers, templates contents.
18
19 You would typically set the limit a little bit lower than your outgoing MTA
20 limit.
21
22 See the configuration example under L</INSTALLATION>.
23
24 =head1 INSTALLATION
25
26 =over
27
28 =item C<perl Makefile.PL>
29
30 =item C<make>
31
32 =item C<make install>
33
34 May need root permissions
35
36 =item Edit your F</opt/rt4/etc/RT_SiteConfig.pm>
37
38 If you are using RT 4.2 or greater, add this line:
39
40     Plugin('RT::Extension::MessageSizeLimit');
41
42 For RT 4.0, add this line:
43
44     Set(@Plugins, qw(RT::Extension::MessageSizeLimit));
45
46 or add C<RT::Extension::MessageSizeLimit> to your existing C<@Plugins> line.
47
48 Then configure the limit (default 9MB) using the C<$MessageSizeLimit>
49 config option.  This option takes the generic form of:
50
51     Set( $MessageSizeLimit, BYTES );
52
53 =item Clear your mason cache
54
55     rm -rf /opt/rt4/var/mason_data/obj
56
57 =item Restart your webserver
58
59 =back
60
61 =head1 IMPLEMENTATION DETAILS
62
63 =head2 Methods
64
65 =head3 BytesToHuman
66
67 Take BYTES, returns a basic human readable representation of it.
68
69 =cut
70
71 sub BytesToHuman {
72     my $bytes = shift;
73
74     if ( $bytes >= 1000 * 1000 * 1000 ) {
75         return sprintf("%0.2f%s", $bytes / 1000 / 1000 / 1000, "GB");
76     } elsif ( $bytes >= 1000 * 1000 ) {
77         return sprintf("%0.2f%s", $bytes / 1000 / 1000, "MB");
78     } elsif ( $bytes >= 1000 ) {
79         return sprintf("%0.2f%s", $bytes / 1000, "kB");
80     } else {
81         return sprintf("%0.2f%s", $bytes, "B");
82     }
83 }
84
85 =head3 CheckMessageSizeLimit
86
87 This is the main routine, it takes args from RT callbacks and validate message size.
88
89 Returns undef if size isn't exceeded, localized error message if it has been exceeded.
90
91 =cut
92
93 sub CheckMessageSizeLimit {
94     my %args = (
95         Subject     => '',
96         Content     => '',
97         Attachments => undef,
98         CurrentUser => undef,
99         @_
100     );
101
102     my $max_size = RT->Config->Get('MessageSizeLimit') || 9 * 1000 * 1000;
103     my $size = 0;
104
105     # Compute subject size
106     $size += length($args{Subject}) if ( $args{Subject} );
107
108     # Compute body size
109     $size += length($args{Content}) if ( $args{Content} );
110
111     # Add attachments sizes if any
112     foreach my $file_name ( keys %{$args{'Attachments'}} ) {
113         my $attach_size = length($args{'Attachments'}{$file_name}->as_string);
114
115         RT->Logger->debug("Attachment size: $attach_size B");
116         $size += $attach_size;
117     }
118
119     RT->Logger->debug("Message size: $size");
120
121     if ( $size && $size > $max_size ) {
122         RT->Logger->info("Message size limit exceeded: $size / $max_size");
123         return $args{'CurrentUser'}->loc("Message size limit exceeded"). " (".BytesToHuman($size)." / ".BytesToHuman($max_size)."), ".$args{'CurrentUser'}->loc("please reduce message size or remove attachments");
124     }
125     
126     return undef;
127 }
128
129
130 =head1 TODO
131
132 =over 4
133
134 =item Dynamic enforcement using javascript
135
136 =item Allow translation of size units
137
138 =back
139
140 =head1 AUTHOR
141
142 Emmanuel Lacour, E<lt>elacour@home-dn.netE<gt>
143
144 =head1 BUGS
145
146 All bugs should be reported via email to
147
148     L<bug-RT-Extension-MessageSizeLimit@rt.cpan.org|mailto:bug-RT-Extension-MessageSizeLimit@rt.cpan.org>
149
150 or via the web at
151
152     L<rt.cpan.org|http://rt.cpan.org/Public/Dist/Display.html?Name=RT-Extension-MessageSizeLimit>.
153
154 =head1 LICENSE AND COPYRIGHT
155
156 This software is Copyright (c) 2016 by Emmanuel Lacour <elacour@home-dn.net>
157
158 This is free software, licensed under:
159
160   The GNU General Public License, Version 2, June 1991
161
162 =cut
163
164 1;