summaryrefslogtreecommitdiff
path: root/rt/html/REST/1.0/Forms
diff options
context:
space:
mode:
Diffstat (limited to 'rt/html/REST/1.0/Forms')
-rw-r--r--rt/html/REST/1.0/Forms/queue/default123
-rw-r--r--rt/html/REST/1.0/Forms/queue/ns38
-rw-r--r--rt/html/REST/1.0/Forms/ticket/attachments107
-rw-r--r--rt/html/REST/1.0/Forms/ticket/default253
-rw-r--r--rt/html/REST/1.0/Forms/ticket/history144
-rw-r--r--rt/html/REST/1.0/Forms/ticket/links148
-rw-r--r--rt/html/REST/1.0/Forms/user/default141
-rw-r--r--rt/html/REST/1.0/Forms/user/ns41
8 files changed, 995 insertions, 0 deletions
diff --git a/rt/html/REST/1.0/Forms/queue/default b/rt/html/REST/1.0/Forms/queue/default
new file mode 100644
index 0000000..ce54088
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/queue/default
@@ -0,0 +1,123 @@
+%# REST/1.0/Forms/queue/default
+%#
+<%ARGS>
+$id
+$format => 's'
+$changes => {}
+</%ARGS>
+<%perl>
+my @comments;
+my ($c, $o, $k, $e) = ("", [], {}, 0);
+my %data = %$changes;
+my $queue = new RT::Queue $session{CurrentUser};
+my @fields = qw(Name Description CorrespondAddress CommentAddress
+ InitialPriority FinalPriority DefaultDueIn);
+my %fields = map { lc $_ => $_ } @fields;
+
+if ($id ne 'new') {
+ $queue->Load($id);
+ if (!$queue->Id) {
+ return [ "# Queue $id does not exist.", [], {}, 1 ];
+ }
+}
+else {
+ if (%data == 0) {
+ return [
+ "# Required: Name",
+ [ "id", @fields ],
+ {
+ id => 'queue/new',
+ Name => '<queue name>',
+ Description => "",
+ CommentAddress => "",
+ CorrespondAddress => "",
+ InitialPriority => "",
+ FinalPriority => "",
+ DefaultDueIn => "",
+ },
+ 0
+ ];
+ }
+ else {
+ my %v;
+ my %create = %fields;
+
+ foreach my $k (keys %data) {
+ if (exists $create{lc $k}) {
+ $v{$create{lc $k}} = delete $data{$k};
+ }
+ }
+
+ if ($v{Name} eq '<queue name>') {
+ my %o = keys %$changes;
+ delete @o{"id", @fields};
+ return [
+ "# Please set the queue name.",
+ [ "id", @fields, keys %o ], $changes, 1
+ ];
+ }
+
+ $queue->Create(%v);
+ unless ($queue->Id) {
+ return [ "# Could not create queue.", [], {}, 1 ];
+ }
+
+ delete $data{id};
+ $id = $queue->Id;
+ push(@comments, "# Queue $id created.");
+ goto DONE if %data == 0;
+ }
+}
+
+if (%data == 0) {
+ my @data;
+
+ push @data, [ id => "queue/".$queue->Id ];
+ foreach my $key (@fields) {
+ push @data, [ $key => $queue->$key ];
+ }
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+}
+else {
+ my ($get, $set, $key, $val, $n, $s);
+
+ foreach $key (keys %data) {
+ $val = $data{$key};
+ $key = lc $key;
+ $n = 1;
+
+ if (exists $fields{$key}) {
+ $key = $fields{$key};
+ $set = "Set$key";
+
+ next if $val eq $queue->$key;
+ ($n, $s) = $queue->$set($val);
+ }
+ elsif ($key ne 'id') {
+ $n = 0;
+ $s = "Unknown field.";
+ }
+
+ SET:
+ if ($n == 0) {
+ $e = 1;
+ push @comments, "# $key: $s";
+ unless (@$o) {
+ my %o = keys %$changes;
+ delete @o{"id", @fields};
+ @$o = ("id", @fields, keys %o);
+ $k = $changes;
+ }
+ }
+ }
+
+ push(@comments, "# Queue $id updated.") unless $n == 0;
+}
+
+DONE:
+$c ||= join("\n", @comments) if @comments;
+return [ $c, $o, $k, $e ];
+</%perl>
diff --git a/rt/html/REST/1.0/Forms/queue/ns b/rt/html/REST/1.0/Forms/queue/ns
new file mode 100644
index 0000000..360eea8
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/queue/ns
@@ -0,0 +1,38 @@
+%# BEGIN LICENSE BLOCK
+%#
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%#
+%# (Except where explictly superceded by other copyright notices)
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%# General Public License for more details.
+%#
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%#
+%#
+%# END LICENSE BLOCK
+%# REST/1.0/Forms/queue/ns
+%#
+<%ARGS>
+$id
+</%ARGS>
+<%perl>
+use RT::Queues;
+
+my $queues = new RT::Queues $session{CurrentUser};
+$queues->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => $id);
+if ($queues->Count == 0) {
+ return (0, "No queue named $id exists.");
+}
+return $queues->Next->Id;
+</%perl>
diff --git a/rt/html/REST/1.0/Forms/ticket/attachments b/rt/html/REST/1.0/Forms/ticket/attachments
new file mode 100644
index 0000000..bcb571a
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/ticket/attachments
@@ -0,0 +1,107 @@
+%# BEGIN LICENSE BLOCK
+%#
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%#
+%# (Except where explictly superceded by other copyright notices)
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%# General Public License for more details.
+%#
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%#
+%#
+%# END LICENSE BLOCK
+%# REST/1.0/Forms/ticket/attachments
+%#
+<%ARGS>
+$id
+$args => undef
+</%ARGS>
+<%perl>
+my @data;
+my ($c, $o, $k, $e) = ("", [], {}, "");
+my $ticket = new RT::Ticket $session{CurrentUser};
+
+$ticket->Load($id);
+unless ($ticket->Id) {
+ return [ "# Ticket $id does not exist.", [], {}, 1 ];
+}
+
+my @arglist = split('/', $args);
+my ($aid, $content);
+
+if ($arglist[1] eq 'content') {
+ $aid = $arglist[0];
+ $content = 1;
+} else {
+ $aid = $args;
+ $content = 0;
+}
+
+if ($aid) {
+ unless ($aid =~ /^\d+$/) {
+ return [ "# Invalid attachment id: $aid", [], {}, 1 ];
+ }
+ my $attachment = new RT::Attachment $session{CurrentUser};
+ $attachment->Load($aid);
+ unless ($attachment->Id eq $aid) {
+ return [ "# Invalid attachment id: $aid", [], {}, 1 ];
+ }
+ if ($content) {
+ $c = $attachment->Content;
+ } else {
+ my @data;
+ push @data, [ id => $attachment->Id ];
+ push @data, [ Subject => $attachment->Subject ];
+ push @data, [ Creator => $attachment->Creator ];
+ push @data, [ Created => $attachment->Created ];
+ push @data, [ Transaction => $attachment->TransactionId ];
+ push @data, [ Parent => $attachment->Parent ];
+ push @data, [ MessageId => $attachment->MessageId ];
+ push @data, [ Filename => $attachment->Filename ];
+ push @data, [ ContentType => $attachment->ContentType ];
+ push @data, [ ContentEncoding => $attachment->ContentEncoding ];
+ push @data, [ Headers => $attachment->Headers ];
+ push @data, [ Content => $attachment->Content ];
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+ }
+
+}
+else {
+ my @attachments;
+ my $transactions = $ticket->Transactions;
+ while (my $t = $transactions->Next) {
+ my $attachments = $t->Attachments;
+ while (my $a = $attachments->Next) {
+ next unless $a->Filename;
+ my $size = length($a->Content);
+ if ($size > 1024) { $size = int($size/102.4)/10 . "k" }
+ else { $size .= "b" }
+ push @attachments, $a->Id.": ".$a->Filename." (".$size.")";
+ }
+ }
+
+ if (@attachments) {
+ $o = [ "id", "Attachments" ];
+ $k = {
+ id => "ticket/".$ticket->Id."/attachments",
+ Attachments => \@attachments
+ };
+ }
+}
+
+return [ $c, $o, $k, $e ];
+</%perl>
diff --git a/rt/html/REST/1.0/Forms/ticket/default b/rt/html/REST/1.0/Forms/ticket/default
new file mode 100644
index 0000000..fec499b
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/ticket/default
@@ -0,0 +1,253 @@
+%# REST/1.0/Forms/ticket/default
+%#
+<%ARGS>
+$id
+$changes => {}
+$fields => undef
+</%ARGS>
+<%perl>
+use MIME::Entity;
+
+my @comments;
+my ($c, $o, $k, $e) = ("", [], {}, 0);
+my %data = %$changes;
+my $ticket = new RT::Ticket $session{CurrentUser};
+my @dates = qw(Created Starts Started Due Resolved Told);
+my @people = qw(Requestors Cc AdminCc);
+my @create = qw(Queue Requestor Subject Cc AdminCc Owner Status Priority
+ InitialPriority FinalPriority TimeEstimated TimeWorked
+ TimeLeft Starts Started Due Resolved);
+my @simple = qw(Subject Status Priority Disabled TimeEstimated TimeWorked
+ TimeLeft InitialPriority FinalPriority);
+my %dates = map {lc $_ => $_} @dates;
+my %people = map {lc $_ => $_} @people;
+my %create = map {lc $_ => $_} @create;
+my %simple = map {lc $_ => $_} @simple;
+
+# Are we dealing with an existing ticket?
+if ($id ne 'new') {
+ $ticket->Load($id);
+ if (!$ticket->Id) {
+ return [ "# Ticket $id does not exist.", [], {}, 1 ];
+ }
+ elsif (!$ticket->CurrentUserHasRight('ShowTicket') ||
+ (%data && !$ticket->CurrentUserHasRight('ModifyTicket')))
+ {
+ my $act = %data ? "modify" : "display";
+ return [ "# You are not allowed to $act ticket $id.", [], {}, 1 ];
+ }
+}
+else {
+ if (%data == 0) {
+ # GET ticket/new: Return a suitable default form.
+ # We get defaults from queue/1 (XXX: What if it isn't there?).
+ my $due = new RT::Date $session{CurrentUser};
+ my $queue = new RT::Queue $session{CurrentUser};
+ my $starts = new RT::Date $session{CurrentUser};
+ $queue->Load(1);
+ $due->SetToNow;
+ $due->AddDays($queue->DefaultDueIn) if $queue->DefaultDueIn;
+ $starts->SetToNow;
+
+ return [
+ "# Required: Queue, Requestor, Subject",
+ [ qw(id Queue Requestor Subject Cc AdminCc Owner Status Priority
+ InitialPriority FinalPriority TimeEstimated Starts Due Text) ],
+ {
+ id => "ticket/new",
+ Queue => $queue->Name,
+ Requestor => $session{CurrentUser}->Name,
+ Subject => "",
+ Cc => [],
+ AdminCc => [],
+ Owner => "",
+ Status => "new",
+ Priority => $queue->InitialPriority,
+ InitialPriority => $queue->InitialPriority,
+ FinalPriority => $queue->FinalPriority,
+ TimeEstimated => 0,
+ Starts => $starts->ISO,
+ Due => $due->ISO,
+ Text => "",
+ },
+ 0
+ ];
+ }
+ else {
+ # We'll create a new ticket, and fall through to set fields that
+ # can't be set in the call to Create().
+ my (%v, $text);
+
+ foreach my $k (keys %data) {
+ if (exists $create{lc $k}) {
+ $v{$create{lc $k}} = delete $data{$k};
+ }
+ elsif (lc $k eq 'text') {
+ $text = delete $data{$k};
+ }
+ }
+
+ if ($text) {
+ $v{MIMEObj} =
+ MIME::Entity->build(
+ From => $session{CurrentUser}->EmailAddress,
+ Subject => $v{Subject},
+ Data => $text
+ );
+ }
+
+ $ticket->Create(%v);
+ unless ($ticket->Id) {
+ return [ "# Could not create ticket.", [], {}, 1 ];
+ }
+
+ delete $data{id};
+ $id = $ticket->Id;
+ push(@comments, "# Ticket $id created.");
+ goto DONE if %data == 0;
+ }
+}
+
+# Now we know we're dealing with an existing ticket.
+if (%data == 0) {
+ my ($time, $key, $val, @data);
+
+ push @data, [ id => "ticket/".$ticket->Id ];
+ push @data, [ Queue => $ticket->QueueObj->Name ]
+ if (!%$fields || exists $fields->{lc 'Queue'});
+ push @data, [ Owner => $ticket->OwnerObj->Name ]
+ if (!%$fields || exists $fields->{lc 'Owner'});
+ push @data, [ Creator => $ticket->CreatorObj->Name ]
+ if (!%$fields || exists $fields->{lc 'Creator'});
+
+ foreach (qw(Subject Status Priority InitialPriority FinalPriority)) {
+ next unless (!%$fields || (exists $fields->{lc $_}));
+ push @data, [$_ => $ticket->$_ ];
+ }
+
+ foreach $key (@people) {
+ next unless (!%$fields || (exists $fields->{lc $key}));
+ push @data, [ $key => [ $ticket->$key->MemberEmailAddresses ] ];
+ }
+
+ $time = new RT::Date ($session{CurrentUser});
+ foreach $key (@dates) {
+ next unless (!%$fields || (exists $fields->{lc $key}));
+ $time->Set(Format => 'sql', Value => $ticket->$key);
+ push @data, [ $key => $time->AsString ];
+ }
+
+ $time = new RT::Date ($session{CurrentUser});
+ foreach $key (qw(TimeEstimated TimeWorked TimeLeft)) {
+ next unless (!%$fields || (exists $fields->{lc $key}));
+ $val = $ticket->$key || 0;
+ $val = $time->DurationAsString($val*60) if $val;
+ push @data, [ $key => $val ];
+ }
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+}
+else {
+ my ($get, $set, $key, $val, $n, $s);
+
+ foreach $key (keys %data) {
+ $val = $data{$key};
+ $key = lc $key;
+ $n = 1;
+
+ if (ref $val eq 'ARRAY') {
+ unless ($key =~ /^(?:Requestors|Cc|AdminCc)$/i) {
+ $n = 0;
+ $s = "$key may have only one value.";
+ goto SET;
+ }
+ }
+
+ if ($key =~ /^queue$/i) {
+ next if $val eq $ticket->QueueObj->Name;
+ ($n, $s) = $ticket->SetQueue($val);
+ }
+ elsif ($key =~ /^owner$/i) {
+ next if $val eq $ticket->OwnerObj->Name;
+ ($n, $s) = $ticket->SetOwner($val);
+ }
+ elsif (exists $simple{$key}) {
+ $key = $simple{$key};
+ $set = "Set$key";
+
+ next if $val eq $ticket->$key;
+ ($n, $s) = $ticket->$set($val);
+ }
+ elsif (exists $dates{$key}) {
+ $key = $dates{$key};
+ $set = "Set$key";
+
+ my $time = new RT::Date $session{CurrentUser};
+ $time->Set(Format => 'sql', Value => $ticket->$key);
+ next if ($val =~ /^not set$/i || $val eq $time->AsString);
+ ($n, $s) = $ticket->$set($val);
+ }
+ elsif (exists $people{$key}) {
+ $key = $people{$key};
+ my ($p, @msgs);
+
+ my %new = map {$_=>1} @{ vsplit($val) };
+ my %old = map {$_=>1} $ticket->$key->MemberEmailAddresses;
+ my $type = $key eq 'Requestors' ? 'Requestor' : $key;
+
+ foreach $p (keys %old) {
+ unless (exists $new{$p}) {
+ ($s, $n) = $ticket->DeleteWatcher(Type => $type,
+ Email => $p);
+ push @msgs, [ $s, $n ];
+ }
+ }
+ foreach $p (keys %new) {
+ # XXX: This is a stupid test.
+ unless ($p =~ /^[\w.+-]+\@([\w.-]+\.)*\w+.?$/) {
+ $s = 0;
+ $n = "$p is not a valid email address.";
+ push @msgs, [ $s, $n ];
+ next;
+ }
+ unless ($ticket->IsWatcher(Type => $type, Email => $p)) {
+ ($s, $n) = $ticket->AddWatcher(Type => $type,
+ Email => $p);
+ push @msgs, [ $s, $n ];
+ }
+ }
+
+ $n = 1;
+ if (@msgs = grep {$_->[0] == 0} @msgs) {
+ $n = 0;
+ $s = join "\n", map {"# ".$_->[1]} @msgs;
+ $s =~ s/^# //;
+ }
+ }
+ elsif ($key ne 'id' && $key ne 'type') {
+ $n = 0;
+ $s = "Unknown field.";
+ }
+
+ SET:
+ if ($n == 0) {
+ $e = 1;
+ push @comments, "# $key: $s";
+ unless (@$o) {
+ my %o = keys %$changes;
+ delete $o{id};
+ @$o = ("id", keys %o);
+ $k = $changes;
+ }
+ }
+ }
+ push(@comments, "# Ticket ".$ticket->id." updated.") unless $n == 0;
+}
+
+DONE:
+$c ||= join("\n", @comments) if @comments;
+return [$c, $o, $k, $e];
+
+</%perl>
diff --git a/rt/html/REST/1.0/Forms/ticket/history b/rt/html/REST/1.0/Forms/ticket/history
new file mode 100644
index 0000000..f5c1dc9
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/ticket/history
@@ -0,0 +1,144 @@
+%# REST/1.0/Forms/ticket/history
+%#
+<%ARGS>
+$id
+$args => undef
+$format => undef
+$fields => undef
+</%ARGS>
+<%perl>
+my $ticket = new RT::Ticket $session{CurrentUser};
+my ($c, $o, $k, $e) = ("", [], {}, "");
+
+$ticket->Load($id);
+unless ($ticket->Id) {
+ return [ "# Ticket $id does not exist.", [], {}, 1 ];
+}
+
+my $trans = $ticket->Transactions();
+my $total = $trans->Count();
+
+chomp $args;
+my @arglist = split('/', $args);
+my ($type, $tid);
+
+if ($arglist[0] eq 'type') {
+ $type = $arglist[1];
+} elsif ($arglist[0] eq 'id') {
+ $tid = $arglist[1];
+} else {
+ $type = $args;
+}
+
+if ($type) {
+ # Create, Set, Status, Correspond, Comment, Give, Steal, Take, Told
+ # CustomField, AddLink, DeleteLink, AddWatcher, DelWatcher
+ if ($args =~ /^links?$/) {
+ $trans->Limit(FIELD => 'Type', OPERATOR => 'LIKE', VALUE => '%Link');
+ }
+ elsif ($args =~ /^watchers?$/) {
+ $trans->Limit(FIELD => 'Type', OPERATOR => 'LIKE', VALUE => '%Watcher');
+ }
+ else {
+ $trans->Limit(FIELD => 'Type', OPERATOR => '=', VALUE => $type);
+ }
+} elsif ($tid) {
+ $trans->Limit(FIELD => 'Id', OPERATOR => '=', VALUE => $tid);
+}
+
+if ($tid) {
+ my @data;
+ my $t = new RT::Transaction $session{CurrentUser};
+ $t->Load($tid);
+
+ push @data, [ id => $t->Id ];
+ push @data, [ EffectiveTicket => $t->EffectiveTicket ]
+ if (!%$fields || exists $fields->{lc 'EffectiveTicket'});
+ push @data, [ Ticket => $t->Ticket ]
+ if (!%$fields || exists $fields->{lc 'Ticket'});
+ push @data, [ TimeTaken => $t->TimeTaken ]
+ if (!%$fields || exists $fields->{lc 'TimeTaken'});
+ push @data, [ Type => $t->Type ]
+ if (!%$fields || exists $fields->{lc 'Type'});
+ push @data, [ Field => $t->Field ]
+ if (!%$fields || exists $fields->{lc 'Field'});
+ push @data, [ OldValue => $t->OldValue ]
+ if (!%$fields || exists $fields->{lc 'OldValue'});
+ push @data, [ NewValue => $t->NewValue ]
+ if (!%$fields || exists $fields->{lc 'NewValue'});
+ push @data, [ Data => $t->Data ]
+ if (!%$fields || exists $fields->{lc 'Data'});
+ push @data, [ Description => $t->Description ]
+ if (!%$fields || exists $fields->{lc 'Description'});
+ push @data, [ Content => $t->Content ]
+ if (!%$fields || exists $fields->{lc 'Content'});
+
+
+ if (!%$fields || exists $fields->{lc 'Content'}) {
+ my $creator = new RT::User $session{CurrentUser};
+ $creator->Load($t->Creator);
+ push @data, [ Creator => $creator->Name ];
+ }
+ push @data, [ Created => $t->Created ]
+ if (!%$fields || exists $fields->{lc 'Created'});
+
+ if (!%$fields || exists $fields->{lc 'Attachments'}) {
+ my $attachlist;
+ my $attachments = $t->Attachments;
+ while (my $a = $attachments->Next) {
+ my $size = length($a->Content);
+ if ($size > 1024) { $size = int($size/102.4)/10 . "k" }
+ else { $size .= "b" }
+ $attachlist .= "\n" . $a->Id.": ".($a->Filename || "untitled")." (".$size.")";
+ }
+
+ push @data, [Attachments => $attachlist];
+ }
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+
+} else {
+ my (@data, $tids);
+ $format ||= "s";
+ $format = "l" if (%$fields);
+
+ while (my $t = $trans->Next) {
+ my $tid = $t->Id;
+
+ if ($format eq "l") {
+ $tids .= "," if $tids;
+ $tids .= $tid;
+ } else {
+ push @$o, $tid;
+ $k->{$tid} = $t->Description;
+ }
+ }
+
+ if ($format eq "l") {
+ my @tid;
+ push @tid, "ticket/$id/history/id/$tids";
+ my $fieldstring;
+ foreach my $key (keys %$fields) {
+ $fieldstring .= "," if $fieldstring;
+ $fieldstring .= $key;
+ }
+ my ($content, $forms);
+
+ $m->subexec("$RT::WebPath/REST/1.0/show",
+ id => \@tid,
+ format => $format,
+ fields => $fieldstring);
+ return [ $c, $o, $k, $e ];
+ }
+}
+
+if (!$c) {
+ my $sub = $trans->Count();
+ $c = "# $sub/$total ($args/total)";
+}
+
+return [ $c, $o, $k, $e ];
+
+</%perl>
diff --git a/rt/html/REST/1.0/Forms/ticket/links b/rt/html/REST/1.0/Forms/ticket/links
new file mode 100644
index 0000000..8ac9dc2
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/ticket/links
@@ -0,0 +1,148 @@
+%# BEGIN LICENSE BLOCK
+%#
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%#
+%# (Except where explictly superceded by other copyright notices)
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%# General Public License for more details.
+%#
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%#
+%#
+%# END LICENSE BLOCK
+%# REST/1.0/Forms/ticket/links
+%#
+<%ARGS>
+$id
+$format => 's'
+$changes => undef
+</%ARGS>
+<%perl>
+my @data;
+my $ticket = new RT::Ticket $session{CurrentUser};
+
+$ticket->Load($id);
+if (!$ticket->Id) {
+ return [ "# Ticket $id does not exist.", [], {}, 1 ];
+}
+
+my ($c, $o, $k, $e) = ("", [], {}, 0);
+my @fields = qw(DependsOn DependedOnBy RefersTo ReferredToBy Members MemberOf);
+my %fields = map { lc $_ => $_ } @fields;
+
+my %lfields = (
+ Members => { Type => 'MemberOf', Mode => 'Base' },
+ ReferredToBy => { Type => 'RefersTo', Mode => 'Base' },
+ DependedOnBy => { Type => 'DependsOn', Mode => 'Base' },
+ MemberOf => { Type => 'MemberOf', Mode => 'Target' },
+ RefersTo => { Type => 'RefersTo', Mode => 'Target' },
+ DependsOn => { Type => 'DependsOn', Mode => 'Target' },
+);
+
+if ($changes) {
+ my ($get, $set, $key, $val, $n, $s);
+ my %data = %$changes;
+ my @comments;
+
+ foreach $key (keys %data) {
+ $val = $data{$key};
+ $key = lc $key;
+ $n = 1;
+
+ if (exists $fields{$key}) {
+ $key = $fields{$key};
+
+ my %old;
+ my $field = $lfields{$key}->{Mode};
+ while (my $link = $ticket->$key->Next) {
+ $old{$link->$field} = 1;
+ }
+
+ my %new;
+ foreach my $nkey (@{vsplit($val)}) {
+ if ($nkey =~ /^\d+$/) {
+ my $uri = new RT::URI $session{CurrentUser};
+ my $tick = new RT::Ticket $session{CurrentUser};
+ $tick->Load($nkey);
+ if ($tick->Id) {
+ $nkey = $uri->FromObject($tick);
+ }
+ else {
+ $n = 0;
+ $s = "Ticket $nkey does not exist.";
+ goto SET;
+ }
+ }
+ $new{$nkey} = 1;
+ }
+
+ foreach my $u (keys %old) {
+ if (exists $new{$u}) {
+ delete $new{$u};
+ }
+ else {
+ my $type = $lfields{$key}->{Type};
+ my $mode = $lfields{$key}->{Mode};
+ ($n, $s) = $ticket->DeleteLink(Type => $type, $mode => $u);
+ goto SET;
+ }
+ }
+ foreach my $u (keys %new) {
+ my $type = $lfields{$key}->{Type};
+ my $mode = $lfields{$key}->{Mode};
+ ($n, $s) = $ticket->AddLink(Type => $type, $mode => $u);
+ goto SET;
+ }
+ }
+ elsif ($key ne 'id' && $key ne 'type') {
+ $n = 0;
+ $s = "Unknown field: $key";
+ }
+
+ SET:
+ if ($n == 0) {
+ $e = 1;
+ push @comments, "# $key: $s";
+ unless (@$o) {
+ @$o = ("id", @fields);
+ %$k = %data;
+ }
+ }
+ }
+
+ push(@comments, "# Links for ticket $id updated.") unless @comments;
+ $c = join("\n", @comments) if @comments;
+}
+else {
+ my @data;
+
+ push @data, [ id => "ticket/".$ticket->Id."/links" ];
+ foreach my $key (@fields) {
+ my @val;
+
+ my $field = $lfields{$key}->{Mode};
+ while (my $link = $ticket->$key->Next) {
+ push @val, $link->$field;
+ }
+ push(@val, "") if (@val == 0 && $format eq 'l');
+ push @data, [ $key => [ @val ] ] if @val;
+ }
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+}
+
+return [ $c, $o, $k, $e ];
+</%perl>
diff --git a/rt/html/REST/1.0/Forms/user/default b/rt/html/REST/1.0/Forms/user/default
new file mode 100644
index 0000000..6b216e0
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/user/default
@@ -0,0 +1,141 @@
+%# REST/1.0/Forms/user/default
+%#
+<%ARGS>
+$id
+$format => 's'
+$changes => {}
+</%ARGS>
+<%perl>
+my @comments;
+my ($c, $o, $k, $e) = ("", [], {}, 0);
+my %data = %$changes;
+my $user = new RT::User $session{CurrentUser};
+my @fields = qw(RealName NickName Gecos Organization Address1 Address2 City
+ State Zip Country HomePhone WorkPhone MobilePhone PagerPhone
+ FreeformContactInfo Comments Signature Lang EmailEncoding
+ WebEncoding ExternalContactInfoId ContactInfoSystem
+ ExternalAuthId AuthSystem);
+my %fields = map { lc $_ => $_ } @fields;
+
+if ($id ne 'new') {
+ $user->Load($id);
+ if (!$user->Id) {
+ return [ "# User $id does not exist.", [], {}, 1 ];
+ }
+}
+else {
+ if (%data == 0) {
+ return [
+ "# Required: Name, EmailAddress",
+ [ qw(id Name EmailAddress Organization Password Comments) ],
+ {
+ id => "user/new",
+ Name => "",
+ EmailAddress => "",
+ Organization => "",
+ Password => "",
+ Comments => ""
+ },
+ 0
+ ];
+ }
+ else {
+ my %v;
+ my %create = %fields;
+ $create{name} = "Name";
+ $create{password} = "Password";
+ $create{emailaddress} = "EmailAddress";
+ $create{contactinfo} = "FreeformContactInfo";
+ # Do any fields need to be excluded here?
+
+ foreach my $k (keys %data) {
+ if (exists $create{lc $k}) {
+ $v{$create{lc $k}} = delete $data{$k};
+ }
+ }
+
+ $user->Create(%v);
+ unless ($user->Id) {
+ return [ "# Could not create user.", [], {}, 1 ];
+ }
+
+ $id = $user->Id;
+ delete $data{id};
+ push(@comments, "# User $id created.");
+ goto DONE if %data == 0;
+ }
+}
+
+if (%data == 0) {
+ my @data;
+
+ push @data, [ id => "user/".$user->Id ];
+ push @data, [ Name => $user->Name ];
+ push @data, [ Password => '********' ];
+ push @data, [ EmailAddress => $user->EmailAddress ];
+
+ foreach my $key (@fields) {
+ my $val = $user->$key;
+
+ if ($format eq 'l' || (defined $val && $val ne '')) {
+ $key = "ContactInfo" if $key eq 'FreeformContactInfo';
+ push @data, [ $key => $val ];
+ }
+ }
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+}
+else {
+ my ($get, $set, $key, $val, $n, $s);
+
+ foreach $key (keys %data) {
+ $val = $data{$key};
+ $key = lc $key;
+ $n = 1;
+
+ if ($key eq 'name' || $key eq 'emailaddress' ||
+ $key eq 'contactinfo' || exists $fields{$key})
+ {
+ if (exists $fields{$key}) {
+ $key = $fields{$key};
+ }
+ else {
+ $key = "FreeformContactInfo" if $key eq 'contactinfo';
+ $key = "EmailAddress" if $key eq 'emailaddress';
+ $key = "Name" if $key eq 'name';
+ }
+ $set = "Set$key";
+
+ next if $val eq $user->$key;
+ ($n, $s) = $user->$set($val);
+ }
+ elsif ($key eq 'password') {
+ ($n, $s) = $user->SetPassword($val) unless $val =~ /^\**$/;
+ }
+ elsif ($key ne 'id') {
+ $n = 0;
+ $s = "Unknown field.";
+ }
+
+ SET:
+ if ($n == 0) {
+ $e = 1;
+ push @comments, "# $key: $s";
+ unless (@$o) {
+ my %o = keys %$changes;
+ delete @o{"id", @fields};
+ @$o = ("id", @fields, keys %o);
+ $k = $changes;
+ }
+ }
+ }
+
+ push(@comments, "# User $id updated.") unless $n == 0;
+}
+
+DONE:
+$c ||= join("\n", @comments) if @comments;
+return [ $c, $o, $k, $e ];
+</%perl>
diff --git a/rt/html/REST/1.0/Forms/user/ns b/rt/html/REST/1.0/Forms/user/ns
new file mode 100644
index 0000000..36b3237
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/user/ns
@@ -0,0 +1,41 @@
+%# BEGIN LICENSE BLOCK
+%#
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%#
+%# (Except where explictly superceded by other copyright notices)
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%# General Public License for more details.
+%#
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%#
+%#
+%# END LICENSE BLOCK
+%# REST/1.0/Forms/user/ns
+%#
+<%ARGS>
+$id
+</%ARGS>
+<%perl>
+use RT::Users;
+
+my $field = "Name";
+$field = "EmailAddress" if $id =~ /\@/;
+
+my $users = new RT::Users $session{CurrentUser};
+$users->Limit(FIELD => $field, OPERATOR => '=', VALUE => $id);
+if ($users->Count == 0) {
+ return (0, "No user named $id exists.");
+}
+return $users->Next->Id;
+</%perl>