[Bps-public-commit] rt-extension-assetsql branch, master, updated. 51cedcf540af8d0569fa1c27fa0792c2e81d1e56

Shawn Moore shawn at bestpractical.com
Thu Jun 16 18:00:43 EDT 2016


The branch, master has been updated
       via  51cedcf540af8d0569fa1c27fa0792c2e81d1e56 (commit)
       via  c48d31379168efe98f00e54f10ef9e2d5b23bbd3 (commit)
      from  22f38cf1ca7a6c7f725d1a9a8403ade2f81d2db5 (commit)

Summary of changes:
 lib/RT/Extension/AssetSQL/Assets.pm     |  56 +++---
 xt/basics.t                             |  50 +++---
 xt/lib/RT/Extension/AssetSQL/Test.pm.in |  41 ++++-
 xt/rights.t                             | 309 ++++++++++++++++++++++++++++++++
 4 files changed, 391 insertions(+), 65 deletions(-)
 create mode 100644 xt/rights.t

- Log -----------------------------------------------------------------
commit c48d31379168efe98f00e54f10ef9e2d5b23bbd3
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Thu Jun 16 21:48:13 2016 +0000

    Fix OwnerGroup by joining watchers for Owner
    
        Unlike for Tickets, the Owner is not denormalized into the Assets table,
        so we must join unconditionally. This removes special cases for Owner.

diff --git a/lib/RT/Extension/AssetSQL/Assets.pm b/lib/RT/Extension/AssetSQL/Assets.pm
index ecf874c..bf20558 100644
--- a/lib/RT/Extension/AssetSQL/Assets.pm
+++ b/lib/RT/Extension/AssetSQL/Assets.pm
@@ -257,7 +257,7 @@ sub CurrentUserCanSee {
 # the idea here is that if the right is set globaly for a role
 # and user plays this role for a catalog directly not a ticket
 # then we have to check in advance
-    if ( my @tmp = grep $_ ne 'Owner' && !ref $roles{ $_ }, keys %roles ) {
+    if ( my @tmp = grep !ref $roles{ $_ }, keys %roles ) {
 
         my $groups = RT::Groups->new( RT->SystemUser );
         $groups->Limit( FIELD => 'Domain', VALUE => 'RT::Catalog-Role', CASESENSITIVE => 0 );
@@ -301,7 +301,6 @@ sub CurrentUserCanSee {
 
     {
         my $join_roles = keys %roles;
-        $join_roles = 0 if $join_roles == 1 && $roles{'Owner'};
         my ($role_group_alias, $cgm_alias);
         if ( $join_roles ) {
             $role_group_alias = $self->_RoleGroupsJoin( New => 1 );
@@ -334,33 +333,23 @@ sub CurrentUserCanSee {
         $ea = 'OR' if $limit_catalogs->( $ea, @direct_catalogs );
         while ( my ($role, $catalogs) = each %roles ) {
             $self->SUPER::_OpenParen('ACL');
-            if ( $role eq 'Owner' ) {
-                $self->Limit(
-                    SUBCLAUSE => 'ACL',
-                    FIELD           => 'Owner',
-                    VALUE           => $id,
-                    ENTRYAGGREGATOR => $ea,
-                );
-            }
-            else {
-                $self->Limit(
-                    SUBCLAUSE       => 'ACL',
-                    ALIAS           => $cgm_alias,
-                    FIELD           => 'MemberId',
-                    OPERATOR        => 'IS NOT',
-                    VALUE           => 'NULL',
-                    QUOTEVALUE      => 0,
-                    ENTRYAGGREGATOR => $ea,
-                );
-                $self->Limit(
-                    SUBCLAUSE       => 'ACL',
-                    ALIAS           => $role_group_alias,
-                    FIELD           => 'Name',
-                    VALUE           => $role,
-                    ENTRYAGGREGATOR => 'AND',
-                    CASESENSITIVE   => 0,
-                );
-            }
+            $self->Limit(
+                SUBCLAUSE       => 'ACL',
+                ALIAS           => $cgm_alias,
+                FIELD           => 'MemberId',
+                OPERATOR        => 'IS NOT',
+                VALUE           => 'NULL',
+                QUOTEVALUE      => 0,
+                ENTRYAGGREGATOR => $ea,
+            );
+            $self->Limit(
+                SUBCLAUSE       => 'ACL',
+                ALIAS           => $role_group_alias,
+                FIELD           => 'Name',
+                VALUE           => $role,
+                ENTRYAGGREGATOR => 'AND',
+                CASESENSITIVE   => 0,
+            );
             $limit_catalogs->( 'AND', @$catalogs ) if ref $catalogs;
             $ea = 'OR' if $ea eq 'AND';
             $self->SUPER::_CloseParen('ACL');
@@ -1028,13 +1017,8 @@ sub _WatcherMembershipLimit {
     my $meta = $FIELD_METADATA{$field};
     my $type = $meta->[1] || '';
 
-    my ($members_alias, $members_column);
-    if ( $type eq 'Owner' ) {
-        ($members_alias, $members_column) = ('main', 'Owner');
-    } else {
-        (undef, undef, $members_alias) = $self->_WatcherJoin( New => 1, Name => $type );
-        $members_column = 'id';
-    }
+    (undef, undef, my $members_alias) = $self->_WatcherJoin( New => 1, Name => $type );
+    my $members_column = 'id';
 
     my $cgm_alias = $self->Join(
         ALIAS1          => $members_alias,
diff --git a/xt/basics.t b/xt/basics.t
index 7c92e16..9e23a36 100644
--- a/xt/basics.t
+++ b/xt/basics.t
@@ -18,6 +18,17 @@ my $shawn = RT::User->new(RT->SystemUser);
 my ($ok, $msg) = $shawn->Create(Name => 'shawn', EmailAddress => 'shawn at bestpractical.com');
 ok($ok, $msg);
 
+my $sysadmins = RT::Group->new( RT->SystemUser );
+($ok, $msg) = $sysadmins->CreateUserDefinedGroup( Name => 'Sysadmins' );
+ok($ok, $msg);
+
+($ok, $msg) = $sysadmins->AddMember($shawn->PrincipalId);
+ok($ok, $msg);
+
+my $memberless = RT::Group->new( RT->SystemUser );
+($ok, $msg) = $memberless->CreateUserDefinedGroup( Name => 'Memberless' );
+ok($ok, $msg);
+
 my $bloc = create_asset(
     Name                       => 'bloc',
     Description                => "Shawn's BPS office media server",
@@ -177,8 +188,16 @@ assetsql "MemberOf = 'asset:$stilgar_id'" => ();
 assetsql "Owner.Name = 'shawn'" => $bloc, $ecaz, $kaitain, $stilgar;
 assetsql "Owner.EmailAddress LIKE 'bestpractical'" => $bloc, $ecaz, $kaitain, $stilgar;
 assetsql "Owner.Name = 'Nobody'" => $morelax;
+assetsql "Owner = '__CurrentUser__'" => ();
+assetsql "Owner != '__CurrentUser__'" => $bloc, $ecaz, $kaitain, $morelax, $stilgar;
+assetsql "OwnerGroup = 'Sysadmins'" => $bloc, $ecaz, $kaitain, $stilgar;
+assetsql "OwnerGroup = 'Memberless'" => ();
 
 assetsql "Contact.Name = 'shawn'" => $bloc, $ecaz, $stilgar;
+assetsql "Contact = '__CurrentUser__'" => ();
+assetsql "Contact != '__CurrentUser__'" => $bloc, $ecaz, $kaitain, $morelax, $stilgar;
+assetsql "ContactGroup = 'Sysadmins'" => $bloc, $ecaz, $stilgar;
+assetsql "ContactGroup = 'Memberless'" => ();
 
 assetsql "CustomField.{Manufacturer} = 'Apple'" => $ecaz, $kaitain, $stilgar;
 assetsql "CF.{Manufacturer} != 'Apple'" => $bloc, $morelax;

commit 51cedcf540af8d0569fa1c27fa0792c2e81d1e56
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Thu Jun 16 22:03:28 2016 +0000

    Tests to make sure AssetSQL doesn't expose inaccessible Assets

diff --git a/xt/basics.t b/xt/basics.t
index 9e23a36..6d3882b 100644
--- a/xt/basics.t
+++ b/xt/basics.t
@@ -41,6 +41,9 @@ my $deleted = create_asset(
     Name                       => 'deleted',
     Description                => "for making sure we don't search deleted",
     Catalog                    => 'Servers',
+    Owner                      => $shawn->PrincipalId,
+    Contact                    => $shawn->PrincipalId,
+    'CustomField-Manufacturer' => 'Dell',
 );
 my $ecaz = create_asset(
     Name                       => 'ecaz',
@@ -108,34 +111,6 @@ my $morelax_id = $morelax->id;
 my $stilgar_id = $stilgar->id;
 my $ticket_id = $ticket->id;
 
-sub assetsql {
-    local $Test::Builder::Level = $Test::Builder::Level + 1;
-
-    my $sql = shift;
-    my @expected = @_;
-
-    my $count = scalar @expected;
-
-    my $assets = RT::Assets->new(RT->SystemUser);
-    $assets->FromSQL($sql);
-    $assets->OrderBy( FIELD => 'Name', ORDER => 'ASC' );
-
-    is($assets->Count, $count, "number of assets from [$sql]");
-    my $i = 0;
-    while (my $asset = $assets->Next) {
-        my $expected = shift @expected;
-        if (!$expected) {
-            fail("got more assets (" . $asset->Name . ") than expected from [$sql]");
-            next;
-        }
-        ++$i;
-        is($asset->Name, $expected->Name, "asset ($i/$count) from [$sql]");
-    }
-    while (my $expected = shift @expected) {
-        fail("got fewer assets than expected (" . $expected->Name . ") from [$sql]");
-    }
-}
-
 assetsql "id = 1" => $bloc;
 assetsql "id != 1" => $ecaz, $kaitain, $morelax, $stilgar;
 assetsql "id = 2" => (); # deleted
diff --git a/xt/lib/RT/Extension/AssetSQL/Test.pm.in b/xt/lib/RT/Extension/AssetSQL/Test.pm.in
index 8fed569..69ce7e5 100644
--- a/xt/lib/RT/Extension/AssetSQL/Test.pm.in
+++ b/xt/lib/RT/Extension/AssetSQL/Test.pm.in
@@ -7,7 +7,7 @@ use lib qw(/opt/rt4/local/lib /opt/rt4/lib);
 package RT::Extension::AssetSQL::Test;
 use base 'RT::Test::Assets';
 
-our @EXPORT = @RT::Test::Assets::EXPORT;
+our @EXPORT = (@RT::Test::Assets::EXPORT, 'assetsql');
 
 sub import {
     my $class = shift;
@@ -26,4 +26,43 @@ sub import {
     __PACKAGE__->export_to_level(1);
 }
 
+sub assetsql {
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+    my $options = shift;
+    my @expected = @_;
+    my $currentuser = RT->SystemUser;
+
+    my $sql;
+    if (ref($options)) {
+        $sql = delete $options->{sql};
+        $currentuser = delete $options->{CurrentUser} if $options->{CurrentUser};
+        die "Unexpected options: " . join ', ', keys %$options if keys %$options;
+    }
+    else {
+        $sql = $options;
+    }
+
+    my $count = scalar @expected;
+
+    my $assets = RT::Assets->new($currentuser);
+    $assets->FromSQL($sql);
+    $assets->OrderBy( FIELD => 'Name', ORDER => 'ASC' );
+
+    Test::More::is($assets->Count, $count, "number of assets from [$sql]");
+    my $i = 0;
+    while (my $asset = $assets->Next) {
+        my $expected = shift @expected;
+        if (!$expected) {
+            Test::More::fail("got more assets (" . $asset->Name . ") than expected from [$sql]");
+            next;
+        }
+        ++$i;
+        Test::More::is($asset->Name, $expected->Name, "asset ($i/$count) from [$sql]");
+    }
+    while (my $expected = shift @expected) {
+        Test::More::fail("got fewer assets than expected (" . $expected->Name . ") from [$sql]");
+    }
+}
+
 1;
diff --git a/xt/rights.t b/xt/rights.t
new file mode 100644
index 0000000..2cc7c28
--- /dev/null
+++ b/xt/rights.t
@@ -0,0 +1,309 @@
+use strict;
+use warnings;
+
+use lib 'xt/lib';
+use RT::Extension::AssetSQL::Test;
+
+my $laptops = create_catalog(Name => 'Laptops');
+my $servers = create_catalog(Name => 'Servers');
+my $keyboards = create_catalog(Name => 'Keyboards');
+
+my $manufacturer = create_cf(Name => 'Manufacturer');
+apply_cfs($manufacturer);
+
+my $blank = create_cf(Name => 'Blank');
+apply_cfs($blank);
+
+my $shawn = RT::User->new(RT->SystemUser);
+my ($ok, $msg) = $shawn->Create(Name => 'shawn', EmailAddress => 'shawn at bestpractical.com');
+ok($ok, $msg);
+
+my $rightsless = RT::User->new(RT->SystemUser);
+($ok, $msg) = $rightsless->Create(Name => 'rightsless', EmailAddress => 'rightsless at bestpractical.com');
+ok($ok, $msg);
+
+my $sysadmins = RT::Group->new( RT->SystemUser );
+($ok, $msg) = $sysadmins->CreateUserDefinedGroup( Name => 'Sysadmins' );
+ok($ok, $msg);
+
+($ok, $msg) = $sysadmins->AddMember($shawn->PrincipalId);
+ok($ok, $msg);
+
+my $memberless = RT::Group->new( RT->SystemUser );
+($ok, $msg) = $memberless->CreateUserDefinedGroup( Name => 'Memberless' );
+ok($ok, $msg);
+
+ok(RT::Test->add_rights({
+    Principal   => 'Privileged',
+    Right       => 'ShowCatalog',
+}), "Granted ShowCatalog");
+
+ok(RT::Test->add_rights({
+    Principal   => 'Owner',
+    Right       => 'ShowAsset',
+}), "Granted ShowAsset");
+
+my $bloc = create_asset(
+    Name                       => 'bloc',
+    Description                => "Shawn's BPS office media server",
+    Catalog                    => 'Servers',
+    Owner                      => $shawn->PrincipalId,
+    Contact                    => $shawn->PrincipalId,
+    'CustomField-Manufacturer' => 'Raspberry Pi',
+);
+my $deleted = create_asset(
+    Name                       => 'deleted',
+    Description                => "for making sure we don't search deleted",
+    Catalog                    => 'Servers',
+    Owner                      => $shawn->PrincipalId,
+    Contact                    => $shawn->PrincipalId,
+    'CustomField-Manufacturer' => 'Dell',
+);
+my $ecaz = create_asset(
+    Name                       => 'ecaz',
+    Description                => "Shawn's BPS laptop",
+    Catalog                    => 'Laptops',
+    Owner                      => $shawn->PrincipalId,
+    Contact                    => $shawn->PrincipalId,
+    'CustomField-Manufacturer' => 'Apple',
+);
+my $kaitain = create_asset(
+    Name                       => 'kaitain',
+    Description                => "unused BPS laptop",
+    Catalog                    => 'Laptops',
+    Owner                      => $shawn->PrincipalId,
+    'CustomField-Manufacturer' => 'Apple',
+);
+my $morelax = create_asset(
+    Name                       => 'morelax',
+    Description                => "BPS in the data center",
+    Catalog                    => 'Servers',
+    'CustomField-Manufacturer' => 'Dell',
+);
+my $stilgar = create_asset(
+    Name                       => 'stilgar',
+    Description                => "English layout",
+    Catalog                    => 'Keyboards',
+    Owner                      => $shawn->PrincipalId,
+    Contact                    => $shawn->PrincipalId,
+    'CustomField-Manufacturer' => 'Apple',
+);
+
+($ok, $msg) = $bloc->SetStatus('stolen');
+ok($ok, $msg);
+
+($ok, $msg) = $deleted->SetStatus('deleted');
+ok($ok, $msg);
+
+($ok, $msg) = $ecaz->SetStatus('in-use');
+ok($ok, $msg);
+
+($ok, $msg) = $kaitain->SetStatus('in-use');
+ok($ok, $msg);
+($ok, $msg) = $kaitain->SetStatus('recycled');
+ok($ok, $msg);
+
+($ok, $msg) = $morelax->SetStatus('in-use');
+ok($ok, $msg);
+
+($ok, $msg) = $ecaz->AddLink(Type => 'RefersTo', Target => $kaitain->URI);
+ok($ok, $msg);
+
+($ok, $msg) = $stilgar->AddLink(Type => 'MemberOf', Target => $ecaz->URI);
+ok($ok, $msg);
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+($ok, $msg) = $ticket->Create(Queue => 'General', Subject => "reboot the server please");
+
+($ok, $msg) = $morelax->AddLink(Type => 'RefersTo', Target => $ticket->URI);
+ok($ok, $msg);
+
+my $bloc_id = $bloc->id;
+my $ecaz_id = $ecaz->id;
+my $kaitain_id = $kaitain->id;
+my $morelax_id = $morelax->id;
+my $stilgar_id = $stilgar->id;
+my $ticket_id = $ticket->id;
+
+my $shawn_cu = RT::CurrentUser->new($shawn);
+my $rightsless_cu = RT::CurrentUser->new($rightsless);
+
+my $assetsql_shawn = sub {
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+    my ($sql, @expected) = @_;
+    assetsql({
+        sql => $sql,
+        CurrentUser => $shawn_cu,
+    }, @expected);
+};
+
+my $assetsql_rightsless = sub {
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+    my ($sql, @expected) = @_;
+    assetsql({
+        sql => $sql,
+        CurrentUser => $rightsless_cu,
+    }, @expected);
+};
+
+$assetsql_shawn->("id = 1" => $bloc);
+$assetsql_shawn->("id != 1" => $ecaz, $kaitain, $stilgar);
+$assetsql_shawn->("id = 2" => ()); # deleted
+$assetsql_shawn->("id = 5" => ()); # morelax
+$assetsql_shawn->("id < 3" => $bloc);
+$assetsql_shawn->("id >= 3" => $ecaz, $kaitain, $stilgar);
+
+$assetsql_shawn->("Name = 'ecaz'" => $ecaz);
+$assetsql_shawn->("Name != 'ecaz'" => $bloc, $kaitain, $stilgar);
+$assetsql_shawn->("Name = 'no match'" => ());
+$assetsql_shawn->("Name != 'no match'" => $bloc, $ecaz, $kaitain, $stilgar);
+
+$assetsql_shawn->("Status = 'new'" => $stilgar);
+$assetsql_shawn->("Status = 'allocated'" => ());
+$assetsql_shawn->("Status = 'in-use'" => $ecaz);
+$assetsql_shawn->("Status = 'recycled'" => $kaitain);
+$assetsql_shawn->("Status = 'stolen'" => $bloc);
+$assetsql_shawn->("Status = 'deleted'" => ());
+
+$assetsql_shawn->("Status = '__Active__'" => $ecaz, $stilgar);
+$assetsql_shawn->("Status != '__Inactive__'" => $ecaz, $stilgar);
+$assetsql_shawn->("Status = '__Inactive__'" => $bloc, $kaitain);
+$assetsql_shawn->("Status != '__Active__'" => $bloc, $kaitain);
+
+$assetsql_shawn->("Catalog = 'Laptops'" => $ecaz, $kaitain);
+$assetsql_shawn->("Catalog = 'Servers'" => $bloc);
+$assetsql_shawn->("Catalog = 'Keyboards'" => $stilgar);
+$assetsql_shawn->("Catalog != 'Servers'" => $ecaz, $kaitain, $stilgar);
+$assetsql_shawn->("Catalog != 'Laptops'" => $bloc, $stilgar);
+$assetsql_shawn->("Catalog != 'Keyboards'" => $bloc, $ecaz, $kaitain);
+
+$assetsql_shawn->("Description LIKE 'data center'" => ());
+$assetsql_shawn->("Description LIKE 'Shawn'" => $bloc, $ecaz);
+$assetsql_shawn->("Description LIKE 'media'" => $bloc);
+$assetsql_shawn->("Description NOT LIKE 'laptop'" => $bloc, $stilgar);
+$assetsql_shawn->("Description LIKE 'deleted'" => ());
+$assetsql_shawn->("Description LIKE 'BPS'" => $bloc, $ecaz, $kaitain);
+
+$assetsql_shawn->("Lifecycle = 'assets'" => $bloc, $ecaz, $kaitain, $stilgar);
+$assetsql_shawn->("Lifecycle != 'assets'" => ());
+$assetsql_shawn->("Lifecycle = 'default'" => ());
+$assetsql_shawn->("Lifecycle != 'default'" => $bloc, $ecaz, $kaitain, $stilgar);
+
+$assetsql_shawn->("Linked IS NOT NULL" => $ecaz, $kaitain, $stilgar);
+$assetsql_shawn->("Linked IS NULL" => $bloc);
+$assetsql_shawn->("RefersTo = 'asset:$kaitain_id'" => $ecaz);
+$assetsql_shawn->("RefersTo = $ticket_id" => ());
+$assetsql_shawn->("HasMember = 'asset:$stilgar_id'" => $ecaz);
+$assetsql_shawn->("MemberOf = 'asset:$stilgar_id'" => ());
+
+$assetsql_shawn->("Owner.Name = 'shawn'" => $bloc, $ecaz, $kaitain, $stilgar);
+$assetsql_shawn->("Owner.EmailAddress LIKE 'bestpractical'" => $bloc, $ecaz, $kaitain, $stilgar);
+$assetsql_shawn->("Owner.Name = 'Nobody'" => ());
+$assetsql_shawn->("Owner = '__CurrentUser__'" => $bloc, $ecaz, $kaitain, $stilgar);
+$assetsql_shawn->("Owner != '__CurrentUser__'" => ());
+$assetsql_shawn->("OwnerGroup = 'Sysadmins'" => $bloc, $ecaz, $kaitain, $stilgar);
+$assetsql_shawn->("OwnerGroup = 'Memberless'" => ());
+
+$assetsql_shawn->("Contact.Name = 'shawn'" => $bloc, $ecaz, $stilgar);
+$assetsql_shawn->("Contact = '__CurrentUser__'" => $bloc, $ecaz, $stilgar);
+$assetsql_shawn->("Contact != '__CurrentUser__'" => $kaitain);
+$assetsql_shawn->("ContactGroup = 'Sysadmins'" => $bloc, $ecaz, $stilgar);
+$assetsql_shawn->("ContactGroup = 'Memberless'" => ());
+
+$assetsql_shawn->("CustomField.{Manufacturer} = 'Apple'" => $ecaz, $kaitain, $stilgar);
+$assetsql_shawn->("CF.{Manufacturer} != 'Apple'" => $bloc);
+$assetsql_shawn->("CustomFieldValue.{Manufacturer} = 'Raspberry Pi'" => $bloc);
+$assetsql_shawn->("CF.{Manufacturer} IS NULL" => ());
+
+$assetsql_shawn->("CF.{Blank} IS NULL" => $bloc, $ecaz, $kaitain, $stilgar);
+$assetsql_shawn->("CF.{Blank} IS NOT NULL" => ());
+
+$assetsql_shawn->("Status = '__Active__' AND Catalog = 'Servers'" => ());
+$assetsql_shawn->("Status = 'in-use' AND Catalog = 'Laptops'" => $ecaz);
+$assetsql_shawn->("Catalog != 'Servers' AND Catalog != 'Laptops'" => $stilgar);
+$assetsql_shawn->("Description LIKE 'BPS' AND Contact.Name IS NULL" => $kaitain);
+$assetsql_shawn->("CF.{Manufacturer} = 'Apple' AND Catalog = 'Laptops'" => $ecaz, $kaitain);
+$assetsql_shawn->("Catalog = 'Servers' AND Linked IS NULL" => $bloc);
+$assetsql_shawn->("Catalog = 'Servers' OR Linked IS NULL" => $bloc);
+$assetsql_shawn->("(Catalog = 'Keyboards' AND CF.{Manufacturer} = 'Apple') OR (Catalog = 'Servers' AND CF.{Manufacturer} = 'Raspberry Pi')" => $bloc, $stilgar);
+
+$assetsql_rightsless->("id = 1");
+$assetsql_rightsless->("id != 1");
+$assetsql_rightsless->("id = 2");
+$assetsql_rightsless->("id < 3");
+$assetsql_rightsless->("id >= 3");
+
+$assetsql_rightsless->("Name = 'ecaz'");
+$assetsql_rightsless->("Name != 'ecaz'");
+$assetsql_rightsless->("Name = 'no match'");
+$assetsql_rightsless->("Name != 'no match'");
+
+$assetsql_rightsless->("Status = 'new'");
+$assetsql_rightsless->("Status = 'allocated'");
+$assetsql_rightsless->("Status = 'in-use'");
+$assetsql_rightsless->("Status = 'recycled'");
+$assetsql_rightsless->("Status = 'stolen'");
+$assetsql_rightsless->("Status = 'deleted'");
+
+$assetsql_rightsless->("Status = '__Active__'");
+$assetsql_rightsless->("Status != '__Inactive__'");
+$assetsql_rightsless->("Status = '__Inactive__'");
+$assetsql_rightsless->("Status != '__Active__'");
+
+$assetsql_rightsless->("Catalog = 'Laptops'");
+$assetsql_rightsless->("Catalog = 'Servers'");
+$assetsql_rightsless->("Catalog = 'Keyboards'");
+$assetsql_rightsless->("Catalog != 'Servers'");
+$assetsql_rightsless->("Catalog != 'Laptops'");
+$assetsql_rightsless->("Catalog != 'Keyboards'");
+
+$assetsql_rightsless->("Description LIKE 'data center'");
+$assetsql_rightsless->("Description LIKE 'Shawn'");
+$assetsql_rightsless->("Description LIKE 'media'");
+$assetsql_rightsless->("Description NOT LIKE 'laptop'");
+$assetsql_rightsless->("Description LIKE 'deleted'");
+$assetsql_rightsless->("Description LIKE 'BPS'");
+
+$assetsql_rightsless->("Lifecycle = 'assets'");
+$assetsql_rightsless->("Lifecycle != 'assets'");
+$assetsql_rightsless->("Lifecycle = 'default'");
+$assetsql_rightsless->("Lifecycle != 'default'");
+
+$assetsql_rightsless->("Linked IS NOT NULL");
+$assetsql_rightsless->("Linked IS NULL");
+$assetsql_rightsless->("RefersTo = 'asset:$kaitain_id'");
+$assetsql_rightsless->("RefersTo = $ticket_id");
+$assetsql_rightsless->("HasMember = 'asset:$stilgar_id'");
+$assetsql_rightsless->("MemberOf = 'asset:$stilgar_id'");
+
+$assetsql_rightsless->("Owner.Name = 'shawn'");
+$assetsql_rightsless->("Owner.EmailAddress LIKE 'bestpractical'");
+$assetsql_rightsless->("Owner.Name = 'Nobody'");
+$assetsql_rightsless->("Owner = '__CurrentUser__'");
+$assetsql_rightsless->("Owner != '__CurrentUser__'");
+$assetsql_rightsless->("OwnerGroup = 'Sysadmins'");
+$assetsql_rightsless->("OwnerGroup = 'Memberless'");
+
+$assetsql_rightsless->("Contact.Name = 'shawn'");
+$assetsql_rightsless->("Contact = '__CurrentUser__'");
+$assetsql_rightsless->("Contact != '__CurrentUser__'");
+$assetsql_rightsless->("ContactGroup = 'Sysadmins'");
+$assetsql_rightsless->("ContactGroup = 'Memberless'");
+
+$assetsql_rightsless->("CustomField.{Manufacturer} = 'Apple'");
+$assetsql_rightsless->("CF.{Manufacturer} != 'Apple'");
+$assetsql_rightsless->("CustomFieldValue.{Manufacturer} = 'Raspberry Pi'");
+$assetsql_rightsless->("CF.{Manufacturer} IS NULL");
+
+$assetsql_rightsless->("CF.{Blank} IS NULL");
+$assetsql_rightsless->("CF.{Blank} IS NOT NULL");
+
+$assetsql_rightsless->("Status = '__Active__' AND Catalog = 'Servers'");
+$assetsql_rightsless->("Status = 'in-use' AND Catalog = 'Laptops'");
+$assetsql_rightsless->("Catalog != 'Servers' AND Catalog != 'Laptops'");
+$assetsql_rightsless->("Description LIKE 'BPS' AND Contact.Name IS NULL");
+$assetsql_rightsless->("CF.{Manufacturer} = 'Apple' AND Catalog = 'Laptops'");
+$assetsql_rightsless->("Catalog = 'Servers' AND Linked IS NULL");
+$assetsql_rightsless->("Catalog = 'Servers' OR Linked IS NULL");
+$assetsql_rightsless->("(Catalog = 'Keyboards' AND CF.{Manufacturer} = 'Apple') OR (Catalog = 'Servers' AND CF.{Manufacturer} = 'Raspberry Pi')");
+

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


More information about the Bps-public-commit mailing list