[Rt-commit] rt branch 5.0/current-interface created. rt-5.0.2-39-gaeb59e0bc2

BPS Git Server git at git.bestpractical.com
Wed Nov 24 13:21:44 UTC 2021


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt".

The branch, 5.0/current-interface has been created
        at  aeb59e0bc206e1876ce9bced9fb6ddb885a3acf3 (commit)

- Log -----------------------------------------------------------------
commit aeb59e0bc206e1876ce9bced9fb6ddb885a3acf3
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat Nov 20 04:07:06 2021 +0800

    Add tests for current interface

diff --git a/t/ticket/interface.t b/t/ticket/interface.t
new file mode 100644
index 0000000000..2c97f27b7a
--- /dev/null
+++ b/t/ticket/interface.t
@@ -0,0 +1,125 @@
+use strict;
+use warnings;
+
+use RT::Test tests => undef, actual_server => 1;
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+
+my $queue = RT::Test->load_or_create_queue( Name => 'General' );
+my $cf    = RT::Test->load_or_create_custom_field( Name => 'Interface', Type => 'FreeformSingle', Queue => $queue->Id );
+
+my $scrip = RT::Scrip->new( RT->SystemUser );
+my ( $ret, $msg ) = $scrip->Create(
+    Queue             => $queue->id,
+    ScripCondition    => 'On Create',
+    ScripAction       => 'User Defined',
+    CustomPrepareCode => 'return 1',
+    CustomCommitCode  => q{
+        $self->TicketObj->AddCustomFieldValue( Field => 'Interface', Value => RT->CurrentInterface );
+    },
+    Template => 'Blank',
+);
+ok( $ret, $msg );
+
+
+diag 'Test API interface';
+my $ticket = RT::Ticket->new( RT->SystemUser );
+( $ret, undef, $msg ) = $ticket->Create( Queue => $queue, Subject => 'Test API interface' );
+ok( $ret, $msg );
+is( $ticket->FirstCustomFieldValue('Interface'), 'API', 'Interface is set to API' );
+
+
+diag 'Test CLI interface';
+my $template = RT::Template->new( RT->SystemUser );
+$template->Create( Name => 'CLICreateTicket', Content => <<'EOF');
+===Create-Ticket: test
+Queue: General
+Subject: Test CLI interface
+Content: test
+ENDOFCONTENT
+EOF
+
+my $root = RT::Test->load_or_create_user( Name => 'root' );
+$root->SetGecos( ( getpwuid($<) )[0] );
+
+system(
+    "$RT::BinPath/rt-crontool", '--search',      'RT::Search::FromSQL',       '--search-arg',
+    "id = " . $ticket->Id,      '--action',      'RT::Action::CreateTickets', '--template',
+    $template->Id,              '--transaction', 'first',
+) && die $?;
+
+$ticket = RT::Test->last_ticket;
+is( $ticket->Subject,                            'Test CLI interface', 'Created ticket via rt-crontool' );
+is( $ticket->FirstCustomFieldValue('Interface'), 'CLI',                'Interface is set to CLI' );
+
+
+diag 'Test Email interface';
+my ( $status, $id ) = RT::Test->send_via_mailgate_and_http(<<'EOF');
+From: root at localhost
+Subject: Test Email interface
+
+Test
+EOF
+is( $status >> 8, 0, "The mail gateway exited normally" );
+ok( $id, "Created ticket" );
+$ticket = RT::Test->last_ticket;
+is( $ticket->FirstCustomFieldValue('Interface'), 'Email', 'Interface is set to Email' );
+
+
+diag 'Test Web interface';
+ok( $m->login(), 'Logged in' );
+$m->goto_create_ticket( $queue->Id );
+$m->submit_form( form_name => 'TicketCreate', fields => { Subject => 'Test Web interface' }, button => 'SubmitTicket' );
+$ticket = RT::Test->last_ticket;
+is( $ticket->FirstCustomFieldValue('Interface'), 'Web', 'Interface is set to Web' );
+
+
+diag 'Test REST interface';
+my $content = "id: ticket/new
+Queue: General
+Requestor: root
+Subject: Test REST interface
+Cc:
+AdminCc:
+Text: Test
+";
+
+$m->post(
+    "$baseurl/REST/1.0/ticket/new",
+    [
+        user    => 'root',
+        pass    => 'password',
+        content => $content,
+    ],
+    Content_Type => 'form-data'
+);
+
+($id) = $m->content =~ /Ticket (\d+) created/;
+ok( $id, "Created ticket #$id" );
+
+$ticket->Load($id);
+is( $ticket->FirstCustomFieldValue('Interface'), 'REST', 'Interface is set to REST' );
+
+
+diag 'Test REST2 interface';
+require RT::Test::REST2;
+my $user = RT::Test::REST2->user;
+$user->PrincipalObj->GrantRight( Right => $_ )
+    for qw/CreateTicket SeeQueue ShowTicket ModifyCustomField SeeCustomField/;
+my $rest2_m = RT::Test::REST2->mech;
+
+my $res = $rest2_m->post_json(
+    "/REST/2.0/ticket",
+    {
+        Subject => 'Test REST2 interface',
+        Queue   => 'General',
+        Content => 'Test',
+    },
+    'Authorization' => RT::Test::REST2->authorization_header,
+);
+is( $res->code, 201 );
+ok( ($id) = $res->header('location') =~ qr[/ticket/(\d+)] );
+$ticket->Load($id);
+is( $ticket->FirstCustomFieldValue('Interface'), 'REST2', 'Interface is set to REST2' );
+
+done_testing;

commit 0c57e2302764ef8827cdf430531c727984bed5d8
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Nov 19 04:38:39 2021 +0800

    Abstract methods to get/set/reset current interface and use them accordingly
    
    Currently we have 6 interfaces: API, CLI, Email, REST, REST2 and Web.
    
    Note that previously we used "Mobile" for /m/ pages, which is merged
    into 'Web', considering /m/ is kinda obsolete and default web UI
    supports mobile generally fine nowadays.
    
    CLI is just for scripts that use RT::Interface::CLI, like "rt-crontool".

diff --git a/lib/RT.pm b/lib/RT.pm
index bc980da00b..3e143dae41 100644
--- a/lib/RT.pm
+++ b/lib/RT.pm
@@ -59,7 +59,7 @@ use Cwd ();
 use Scalar::Util qw(blessed);
 use UNIVERSAL::require;
 
-use vars qw($Config $System $SystemUser $Nobody $Handle $Logger $_Privileged $_Unprivileged $_INSTALL_MODE);
+use vars qw($Config $System $SystemUser $Nobody $Handle $Logger $CurrentInterface $_Privileged $_Unprivileged $_INSTALL_MODE);
 
 use vars qw($BasePath
  $EtcPath
@@ -672,6 +672,34 @@ sub UnprivilegedUsers {
 }
 
 
+=head2 CurrentInterface
+
+Returns current interface. Possible values are: API, CLI, Email, REST, REST2 and Web.
+Note that CLI is set for scripts that use RT::Interface::CLI.
+
+=cut
+
+sub CurrentInterface { return $CurrentInterface || 'API' }
+
+=head2 SetCurrentInterface API|CLI|Email|REST|REST2|Web
+
+Sets current interface and returns it.
+
+=cut
+
+sub SetCurrentInterface {
+    shift if ( $_[0] // '' ) eq 'RT'; # shift package info
+    $CurrentInterface = shift;
+}
+
+=head2 ResetCurrentInterface
+
+Resets current interface(i.e. it will default to API)
+
+=cut
+
+sub ResetCurrentInterface { $CurrentInterface = undef }
+
 =head2 Plugins
 
 Returns a listref of all Plugins currently configured for this RT instance.
diff --git a/lib/RT/Condition/ViaInterface.pm b/lib/RT/Condition/ViaInterface.pm
index 849e107183..dac72e757a 100644
--- a/lib/RT/Condition/ViaInterface.pm
+++ b/lib/RT/Condition/ViaInterface.pm
@@ -65,11 +65,8 @@ sub IsApplicable {
     return 0 unless $self->Argument;
     my @interfaces = split /,/, $self->Argument;
 
-    if (my $msg = $self->TransactionObj->Message->First) {
-        my $interface = $msg->GetHeader('X-RT-Interface');
-        return 0 unless $interface;
-        return 1 if grep { lc $interface eq lc $_ } @interfaces;
-    }
+    my $current_interface = lc RT->CurrentInterface;
+    return 1 if grep { $current_interface eq lc $_ } @interfaces;
     return 0;
 }
 
diff --git a/lib/RT/Interface/CLI.pm b/lib/RT/Interface/CLI.pm
index 79bb1da5aa..8fdc151a29 100644
--- a/lib/RT/Interface/CLI.pm
+++ b/lib/RT/Interface/CLI.pm
@@ -225,6 +225,7 @@ sub Init {
           if not $exists{help} and $hash->{help};
 
     require RT;
+    RT->SetCurrentInterface('CLI');
     RT::LoadConfig();
 
     if (not $exists{quiet} and $hash->{quiet}) {
diff --git a/lib/RT/Interface/Email.pm b/lib/RT/Interface/Email.pm
index 21abf0ec46..8bf96ac12b 100644
--- a/lib/RT/Interface/Email.pm
+++ b/lib/RT/Interface/Email.pm
@@ -130,6 +130,7 @@ sub Gateway {
         %$argsref
     );
 
+    RT->SetCurrentInterface('Email');
     RT->Config->RefreshConfigFromDatabase();
     RT->System->MaybeRebuildLifecycleCache();
 
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index bb5e158516..3dcdb58efb 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -270,6 +270,7 @@ sub WebRemoteUserAutocreateInfo {
 sub HandleRequest {
     my $ARGS = shift;
 
+    RT->SetCurrentInterface('Web');
     if (RT->Config->Get('DevelMode')) {
         require Module::Refresh;
         Module::Refresh->refresh;
@@ -2316,7 +2317,6 @@ sub CreateTicket {
         Date    => $date_now->RFC2822(Timezone => 'user'),
         Body    => $sigless,
         Type    => $ARGS{'ContentType'},
-        Interface => RT::Interface::Web::MobileClient() ? 'Mobile' : 'Web',
     );
 
     my @attachments;
@@ -2698,13 +2698,13 @@ sub MakeMIMEEntity {
         Body                => undef,
         AttachmentFieldName => undef,
         Type                => undef,
-        Interface           => 'API',
+        Interface           => undef,
         @_,
     );
     my $Message = MIME::Entity->build(
         Type    => 'multipart/mixed',
         "Message-Id" => Encode::encode( "UTF-8", RT::Interface::Email::GenMessageId ),
-        "X-RT-Interface" => $args{Interface},
+        "X-RT-Interface" => $args{Interface} || RT->CurrentInterface,
         map { $_ => Encode::encode( "UTF-8", $args{ $_} ) }
             grep defined $args{$_}, qw(Subject From Cc To Date)
     );
diff --git a/lib/RT/Interface/Web/Handler.pm b/lib/RT/Interface/Web/Handler.pm
index dd6fc31801..7b523d7c19 100644
--- a/lib/RT/Interface/Web/Handler.pm
+++ b/lib/RT/Interface/Web/Handler.pm
@@ -202,6 +202,7 @@ sub CleanupRequest {
             unless $INC{'Test/WWW/Mechanize/PSGI.pm'};
 
     RT::ObjectCustomFieldValues::ClearOCFVCache();
+    RT->ResetCurrentInterface;
 }
 
 
diff --git a/lib/RT/REST2/Dispatcher.pm b/lib/RT/REST2/Dispatcher.pm
index fe7f4ef234..32353447b4 100644
--- a/lib/RT/REST2/Dispatcher.pm
+++ b/lib/RT/REST2/Dispatcher.pm
@@ -92,6 +92,7 @@ sub to_psgi_app {
     return sub {
         my $env = shift;
 
+        RT->SetCurrentInterface('REST2');
         RT::ConnectToDatabase();
         my $dispatch = $self->_dispatcher->dispatch($env->{PATH_INFO});
 
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index e59cdc19c9..cc8bb9528f 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -1671,7 +1671,7 @@ sub _RecordNote {
         );
     }
 
-    $args{'MIMEObj'}->head->replace('X-RT-Interface' => 'API')
+    $args{'MIMEObj'}->head->replace('X-RT-Interface' => RT->CurrentInterface)
         unless $args{'MIMEObj'}->head->get('X-RT-Interface');
 
     # convert text parts into utf-8
diff --git a/share/html/REST/1.0/autohandler b/share/html/REST/1.0/autohandler
index fe70b8d0b8..e755943a02 100644
--- a/share/html/REST/1.0/autohandler
+++ b/share/html/REST/1.0/autohandler
@@ -49,6 +49,7 @@
 %#
 <%INIT>
 use RT::Interface::REST;
+RT->SetCurrentInterface('REST');
 $r->content_type('text/plain; charset=utf-8');
 $m->error_format('text');
 $m->call_next();

commit 2d0ea13bfb45b8d02bfdb5080ad699babeb2b1df
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat Nov 20 05:20:45 2021 +0800

    Create CleanupRequest middleware to really cleanup requests for REST2
    
    Previously we added the cleanup functionality to to_psgi_app(initially
    created as an alias of "to_app"), which never gets called. The call of
    response_cb seems not quite right either as it doesn't expect a Plack
    app as the first argument.
    
    This commit wraps the functionality into a middleware and calls the more
    complete version(RT::Interface::Web::Handler::CleanupRequest).

diff --git a/lib/RT/REST2.pm b/lib/RT/REST2.pm
index 1f4c8e4bba..01630500ca 100644
--- a/lib/RT/REST2.pm
+++ b/lib/RT/REST2.pm
@@ -1449,17 +1449,13 @@ handle them appropriately.
 sub to_psgi_app {
     my $self = shift;
     my $res = $self->to_app(@_);
-
-    return Plack::Util::response_cb($res, sub {
-        my $res = shift;
-        $self->CleanupRequest;
-    });
 }
 
 sub to_app {
     my $class = shift;
 
     return builder {
+        enable '+RT::REST2::Middleware::CleanupRequest';
         enable '+RT::REST2::Middleware::ErrorAsJSON';
         enable '+RT::REST2::Middleware::Log';
         enable '+RT::REST2::Middleware::Auth';
@@ -1484,22 +1480,4 @@ sub PSGIWrap {
     };
 }
 
-sub CleanupRequest {
-
-    if ( $RT::Handle && $RT::Handle->TransactionDepth ) {
-        $RT::Handle->ForceRollback;
-        $RT::Logger->crit(
-            "Transaction not committed. Usually indicates a software fault."
-            . "Data loss may have occurred" );
-    }
-
-    # Clean out the ACL cache. the performance impact should be marginal.
-    # Consistency is imprived, too.
-    RT::Principal->InvalidateACLCache();
-    DBIx::SearchBuilder::Record::Cachable->FlushCache
-      if ( RT->Config->Get('WebFlushDbCacheEveryRequest')
-        and UNIVERSAL::can(
-            'DBIx::SearchBuilder::Record::Cachable' => 'FlushCache' ) );
-}
-
 1;
diff --git a/lib/RT/REST2/Middleware/CleanupRequest.pm b/lib/RT/REST2/Middleware/CleanupRequest.pm
new file mode 100644
index 0000000000..52192deb97
--- /dev/null
+++ b/lib/RT/REST2/Middleware/CleanupRequest.pm
@@ -0,0 +1,64 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2021 Best Practical Solutions, LLC
+#                                          <sales at bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
+package RT::REST2::Middleware::CleanupRequest;
+
+use strict;
+use warnings;
+
+use base 'Plack::Middleware';
+
+sub call {
+    my ( $self, $env ) = @_;
+    my $res = $self->app->($env);
+    require RT::Interface::Web::Handler;
+    RT::Interface::Web::Handler->CleanupRequest;
+    return $res;
+}
+
+1;

-----------------------------------------------------------------------


hooks/post-receive
-- 
rt


More information about the rt-commit mailing list