diff options
Diffstat (limited to 'rt/share/html/NoAuth/Calendar/dhandler')
-rw-r--r-- | rt/share/html/NoAuth/Calendar/dhandler | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/rt/share/html/NoAuth/Calendar/dhandler b/rt/share/html/NoAuth/Calendar/dhandler new file mode 100644 index 0000000..4b4aa63 --- /dev/null +++ b/rt/share/html/NoAuth/Calendar/dhandler @@ -0,0 +1,159 @@ +<%init> + +use Data::ICal; +use Data::ICal::Entry::Todo; +use Data::ICal::Entry::Event; +use Date::ICal; + +$RT::ICalTicketType ||= "Data::ICal::Entry::Todo"; +$RT::ICalReminderType ||= "Data::ICal::Entry::Event"; + +my ($UserId, $SearchId, $MagicNumber); +my $arg = $m->dhandler_arg; + +if ($arg =~ m{^(\d+)@(\d+)/(.*)$}) { + $UserId = $1; + $SearchId = $2; + $MagicNumber = $3; +} elsif ($arg =~ m{^(\d+)/(.*)}) { + $UserId = $1; + $MagicNumber = $2; +} else { + Abort("Corrupted URL."); +} + +my $CurrentUser = new RT::CurrentUser(); +$CurrentUser->LoadById($UserId); +my $user = $CurrentUser->Name; + +# if no user, abort +unless ($CurrentUser->Id) { + $RT::Logger->error("No such user id $UserId from $ENV{'REMOTE_ADDR'}"); + $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n"); + $m->abort; +} + +# verify user has LoadSavedSearch right +if ($SearchId and not $CurrentUser->HasRight( Right => 'LoadSavedSearch', + Object=> $RT::System )) { + $RT::Logger->error("not enough rights for user $user from $ENV{'REMOTE_ADDR'}"); + $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n"); + $m->abort; +} + + +# if MagicNumber doesn't match the one stored in database, abort +my $Search; +my $ICalAttribute; +if ($SearchId) { + $Search = $CurrentUser->Attributes->WithId($SearchId); + $ICalAttribute = $Search->FirstAttribute('ICalURL'); +} else { + $ICalAttribute = $CurrentUser->UserObj->FirstAttribute('ICalURL'); +} + +unless ($ICalAttribute) { + $RT::Logger->error("No such ICal feed for $user from $ENV{'REMOTE_ADDR'}"); + $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n"); + $m->abort; +} + + +if ($MagicNumber ne $ICalAttribute->Content) { + $RT::Logger->error("FAILED LOGIN for $user from $ENV{'REMOTE_ADDR'}"); + $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n"); + $m->abort; +} + +my $Tickets = RT::Tickets->new($CurrentUser); + +my $Query = "( Status = 'new' OR Status = 'open' OR Status = 'stalled') + AND ( Owner = '" . $CurrentUser->Id ."' OR Owner = 'Nobody' ) + AND ( Type = 'reminder' OR 'Type' = 'ticket' )"; + +$Query = $Search->SubValue('Query') + if $Search; + +$Query .= " AND ( Due > '1970-01-01' OR Starts > '1970-01-01' )"; + +$Tickets->FromSQL($Query); + +$Tickets->OrderBy(FIELD => 'Due', ORDER => 'ASC'); + +my $calendar = Data::ICal->new(); + +my ($uid) = $RT::WebURL =~ m{https?://([^:]+)}; + +while (my $Ticket = $Tickets->Next ) { + + my $event; + if ($Ticket->Type eq 'ticket') { + $event = add_todo($Ticket, $uid); + } else { + $event = add_event($Ticket, $uid); + } + next unless $event; + $calendar->add_entry($event); +} + +my $cal = $calendar->as_string; + +$r->content_type('text/calendar;charset=utf-8'); +$m->clear_buffer(); +$m->out($cal); +$m->abort; + +sub add_event { + my ($Reminder, $uid) = @_; + + return unless defined $Reminder->RefersTo->First; + my $Ticket = $Reminder->RefersTo->First->TargetObj; + + my %event = ( + summary => $Reminder->Subject ? $Reminder->Subject : '', + url => "${RT::WebURL}/Ticket/Display.html?id=" . $Ticket->id, + uid => Date::ICal->new( epoch => time() )->ical() . "-" . $Reminder->Id . "@" . $uid, + categories => $Ticket->QueueObj->Name, + dtstart => Date::ICal->new( epoch => $Reminder->DueObj->Unix )->ical, + ); + + my $event = $RT::ICalReminderType->new(); + $event->add_properties(%event); + + return $event; +} + +sub add_todo { + my ($Ticket, $uid) = @_; + + my %vtodo = ( + summary => $Ticket->Subject ? $Ticket->Subject : '', + dtstart => Date::ICal->new( epoch => $Ticket->CreatedObj->Unix )->ical, + url => "${RT::WebURL}/Ticket/Display.html?id=" . $Ticket->id, + uid => Date::ICal->new( epoch => time() )->ical() . "-" . $Ticket->Id . "@" . $uid, + categories => $Ticket->QueueObj->Name, + ); + + $vtodo{due} = Date::ICal->new( epoch => $Ticket->DueObj->Unix )->ical, + if $Ticket->DueObj; + + if ($Ticket->OwnerObj->Id != $RT::Nobody->Id and $Ticket->OwnerObj->EmailAddress) { + $vtodo{organizer} = "MAILTO:" . $Ticket->OwnerObj->EmailAddress; + $vtodo{attendee} = "MAILTO:" . $Ticket->OwnerObj->EmailAddress; + } elsif ($Ticket->QueueObj->CommentAddress) { + $vtodo{organizer} = "MAILTO:" . $Ticket->QueueObj->CommentAddress; + $vtodo{attendee} = "MAILTO:" . $Ticket->QueueObj->CommentAddress; + } + + $vtodo{priority} = $Ticket->Priority + if $Ticket->Priority; + + my $vtodo = $RT::ICalTicketType->new(); + $vtodo->add_properties(%vtodo); + + return $vtodo; +} + + + +</%init> |