This file is indexed.

/usr/share/perl5/Jifty/Notification.pm is in libjifty-perl 1.10518+dfsg-3ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
use warnings;
use strict;

package Jifty::Notification;

use base qw/Jifty::Object Class::Accessor::Fast/;
use Email::Send            ();
use Email::MIME::CreateHTML;

__PACKAGE__->mk_accessors(
    qw/body html_body preface footer subject from _recipients _to_list to cc bcc/);

=head1 NAME

Jifty::Notification - Send emails from Jifty

=head1 USAGE

It is recommended that you subclass L<Jifty::Notification> and
override C<body>, C<html_body>, C<subject>, C<recipients>, and C<from>
for each message.  (You may want a base class to provide C<from>,
C<preface> and C<footer> for example.)  This lets you keep all of your
notifications in the same place.

However, if you really want to make a notification type in code
without subclassing, you can create a C<Jifty::Notification> and call
the C<set_body>, C<set_subject>, and so on methods on it.

=head1 METHODS

=cut

=head2 new [KEY1 => VAL1, ...]

Creates a new L<Jifty::Notification>.  Any keyword args given are used
to call set accessors of the same name.

Then it calls C<setup>.

=cut

sub new {
    my $class = shift;
    my $self  = bless {}, $class;

    my %args = @_;

    # initialize message bits to avoid 'undef' warnings
    #for (qw(body preface footer subject)) { $self->$_(''); }
    $self->_recipients( [] );

    while ( my ( $arg, $value ) = each %args ) {
        if ( $self->can($arg) ) {
            $self->$arg($value);
        } else {
            $self->log->error(
                ( ref $self ) . " called with invalid argument $arg" );
        }
    }

    $self->setup;

    return $self;
}

=head2 setup

Your subclass should override this to set the various field values.

=cut

sub setup { }

=head2 send_one_message

Delivers the notification, using the L<Email::Send> mailer defined in
the C<Mailer> and C<MailerArgs> configuration arguments.  Returns true
if mail was actually sent.  Note errors are not the only cause of mail
not being sent -- for example, the recipients list could be empty.

If you wish to send HTML mail, set C<html_body>.  If this is not set
(for backwards compatibility) a plain-text email is sent.  If
C<html_body> and C<body> are both set, a multipart mail is sent.  See
L<Email::MIME::CreateHTML> for how this is done.

Be aware that if you haven't set C<recipients>, this will fail
silently and return without doing anything useful.

=cut

sub send_one_message {
    my $self       = shift;
    my @recipients = $self->recipients;
    my $to         = join( ', ',
        map { ( ref $_ && $_->can('email') ? $_->email : $_ ) } grep {$_} @recipients );
    $self->log->debug("Sending a ".ref($self)." to $to"); 
    return unless ($to);
    my $message = "";
    my $appname = Jifty->config->framework('ApplicationName');

    my %attrs = ( charset => 'UTF-8' );

    my $from = Encode::encode(
        'MIME-Header',
        $self->from || _('%1 <%2>' , $appname, Jifty->config->framework('AdminEmail'))
    );
    my $subj = Encode::encode(
        'MIME-Header',
        $self->subject || _("A notification from %1!",$appname )
    );

    my $cc  = Encode::encode('MIME-Header', $self->cc  || '');
    my $bcc = Encode::encode('MIME-Header', $self->bcc || '');

    if ( defined $self->html_body ) {

        # Email::MIME takes _bytes_, not characters, for the "body"
        # argument, so we need to encode the full_body into UTF8.
        # Modern Email::MIME->create takes a "body_str" argument which
        # does the encoding for us, but Email::MIME::CreateHTML
        # doesn't grok it.  See also L</parts> for the other location
        # which does the encode.
        $message = Email::MIME->create_html(
            header => [
                From    => $from,
                To      => $to,
                Cc      => $cc,
                Bcc     => $bcc,
                Subject => $subj,
            ],
            attributes           => \%attrs,
            text_body_attributes => \%attrs,
            body_attributes      => \%attrs,
            text_body            => Encode::encode_utf8( $self->full_body ),
            body                 => Encode::encode_utf8( $self->full_html ),
            embed                => 0,
            inline_css           => 0,
        );

        # Since the containing messsage will still be us-ascii otherwise
        $message->charset_set( $attrs{'charset'} );
    } else {
        $message = Email::MIME->create(
            header => [
                From    => $from,
                To      => $to,
                Cc      => $cc,
                Bcc     => $bcc,
                Subject => $subj,
            ],
            attributes => \%attrs,
            parts      => $self->parts,
        );
    }
    $message->encoding_set('8bit')
        if ( scalar $message->parts == 1 );
    $self->set_headers($message);

    my $method   = Jifty->config->framework('Mailer');
    my $args_ref = Jifty->config->framework('MailerArgs');
    $args_ref = [] unless defined $args_ref;

    my $sender
        = Email::Send->new( { mailer => $method, mailer_args => $args_ref } );

    my $ret = $sender->send($message);

    unless ($ret) {
        $self->log->error("Error sending mail: $ret");
    }

    $ret;
}

=head2 set_headers MESSAGE

Takes a L<Email::MIME> object C<MESSAGE>, and modifies it as
necessary before sending it out.  As the method name implies, this is
usually used to add or modify headers.  By default, does nothing; this
method is meant to be overridden.

=cut

sub set_headers {}

=head2 body [BODY]

Gets or sets the body of the notification, as a string.

=head2 subject [SUBJECT]

Gets or sets the subject of the notification, as a string.

=head2 from [FROM]

Gets or sets the from address of the notification, as a string.

=head2 recipients [RECIPIENT, ...]

Gets or sets the addresses of the recipients of the notification, as a
list of strings (not a reference).

=cut

sub recipients {
    my $self = shift;
    $self->_recipients( [@_] ) if @_;
    return @{ $self->_recipients };
}

=head2 email_from OBJECT

Returns the email address from the given object.  This defaults to
calling an 'email' method on the object.  This method will be called
by L</send> to get email addresses (for L</to>) out of the list of
L</recipients>.

=cut

sub email_from {
    my $self = shift;
    my ($obj) = @_;
    if ( $obj->can('email') ) {
        return $obj->email;
    } else {
        die "No 'email' method on " . ref($obj) . "; override 'email_from'";
    }
}

=head2 to_list [OBJECT, OBJECT...]

Gets or sets the list of objects that the message will be sent to.
Each one is sent a separate copy of the email.  If passed no
parameters, returns the objects that have been set.  This also
suppresses duplicates.

=cut

sub to_list {
    my $self = shift;
    if (@_) {
        my %ids = ();
        $ids{ $self->to->id } = undef if $self->to;
        $ids{ $_->id } = $_ for @_;
        $self->_to_list( [ grep defined, values %ids ] );
    }
    return @{ $self->_to_list || [] };
}

=head2 send

Sends an individual email to every user in L</to_list>; it does this by
setting L</to> and L</recipient> to the first user in L</to_list>
calling L<Jifty::Notification>'s C<send> method, and progressing down
the list.

Additionally, if L</to> was set elsewhere, sends an email to that
person, as well.

=cut

sub send {
    my $self = shift;
    my $currentuser_object_class = Jifty->app_class("CurrentUser");
    for my $to ( grep {defined} ($self->to, $self->to_list) ) {
        if ($to->can('id')) {
        next if     $currentuser_object_class->can("nobody")
                and $currentuser_object_class->nobody->id
                and $to->id == $currentuser_object_class->nobody->id;
                
        next if $to->id == $currentuser_object_class->superuser->id;
        } 
        $self->to($to);
        $self->recipients($to);
        $self->send_one_message(@_);
    }
}

=head2 to

Of the list of users that C<to> provided, returns the one which mail
is currently being sent to.  This is set by the L</send> method, such
that it is available to all of the methods that
L<Jifty::Notification>'s C<send> method calls.

=cut

=head2 preface

Print a header for the message. You want to override this to print a message.

Returns the message as a scalar.

=cut

=head2 footer

Print a footer for the message. You want to override this to print a message.

Returns the message as a scalar.

=cut

=head2 full_body

The main, plain-text part of the message.  This is the preface,
body, and footer joined by newlines.

=cut

sub full_body {
  my $self = shift;
  return join( "\n", grep { defined } $self->preface, $self->body, $self->footer );
}

=head2 full_html

Same as full_body, but with HTML.

=cut

sub full_html {
  my $self = shift;
  return join( "\n", grep { defined } $self->preface, $self->html_body, $self->footer );
}

=head2 parts

The parts of the message.  You want to override this if you want to
send multi-part mail.  By default, this method returns a single
part consisting of the result of calling C<< $self->full_body >>.

Returns the parts as an array reference.

=cut

sub parts {
  my $self = shift;
# NOTICE: we should keep string in perl string (with utf8 flag)
# rather then encode it into octets. Email::MIME would call Encode::encode in 
# its create function.
  return [ Email::MIME->create(
      attributes => { charset => 'UTF-8' },
      body       => Encode::encode_utf8( $self->full_body ),
    ) ];
}

=head2 magic_letme_token_for PATH

Returns a L<Jifty::LetMe> token which allows the current user to access a path on the
site. 

=cut

sub magic_letme_token_for {
    my $self = shift;
    my $path = shift;
    my %args = @_;

    my $letme = Jifty::LetMe->new();
    $letme->email( $self->to->email );
    $letme->path($path);
    $letme->args( \%args );
    return ( $letme->as_url );
}

1;