[Rt-commit] rt branch, master, updated. rt-4.2.12-423-g1b895a0

Shawn Moore shawn at bestpractical.com
Fri Oct 30 17:52:41 EDT 2015


The branch, master has been updated
       via  1b895a0ab8a3dc4e51fe554d014589c34526bdd1 (commit)
       via  d4a2fc6ad7e8d051771a58ef182f5de0ef063020 (commit)
       via  62157a3793ab8ea61f1b40aad54c2da70a1add2a (commit)
       via  51853448e413885509a9cffeb92041ac27bb08ef (commit)
       via  b77e1d2dbef3adaebf16f252c36c842c3098f01a (commit)
       via  ffb246cff2ff785825a8a7481c8ceaabb6716a96 (commit)
       via  3a37699db163178a3304ea0d6c3f73935ae5a47a (commit)
       via  706b4185ba7bf7a3757e3ce68d94506c9a1106e2 (commit)
       via  7978fd51d35a37cddff15774975ad72feb0896a7 (commit)
       via  31e49aa345c25cee863a0146b811fc1f03eaeebc (commit)
       via  5dee5422cd89e3c3838fd85a127ae132bfdd162d (commit)
       via  874f61b90d1e868268074424d82164f0d0a7093a (commit)
       via  466dc72e7dd91e89a1c804614413ebfba5c7d81b (commit)
       via  b45d4151f0288d5e0deae19ddfe4968718f2bdc6 (commit)
       via  824c602dbfe4fc726e22192dab460087bb6172fe (commit)
       via  b2d870011ea665f4db92f8e7346fc719415649a9 (commit)
       via  6f0d6467a83a4273bc3f3f76640e5fcf1ad7e661 (commit)
       via  ff898d8f80abaf23ca6d46be7a3e89ad52b1c812 (commit)
       via  c7759ba1f3afb1cebd4975e21241e78c5b2eb0ac (commit)
       via  4b1fd9320d86bd0f960d0940e9dcbf52613c7435 (commit)
       via  71fc832b5a4789a660b88bc47d75850ef04f3e38 (commit)
       via  7cb01e5933dd06b901bc68b939f0a7e97828422f (commit)
       via  f467d55824284d24db9957673dafe44a82d991f1 (commit)
       via  3d5ba26d14ad5b6f01b371512593081aedd9d2e2 (commit)
       via  accaf5b12504ca74d7ac74c3fa85954654f06d8d (commit)
       via  89d776ea37f6803e36bacf82ef48eb43148e7077 (commit)
       via  8b8897b1a2c44191f54ff8904294e9db1c2faa04 (commit)
       via  78cbe3df4e81b124ce71707c38bfcf381c241cdc (commit)
       via  7c59fae30a85d62f31309485c5edef9c4c20a67a (commit)
       via  87d20c2ccfc53e2585649e73a53cb7f424a5b216 (commit)
       via  116841608c9174983c63f187cf10984fdba3fd62 (commit)
       via  5b777ea20c948bc0a4d38524203d74e1d0472669 (commit)
       via  f4a3966036c9f79a722e13588eea6975fdf80550 (commit)
       via  3da168ac6be16ecec5557894356c5ef414c78cf7 (commit)
      from  6aa253f33a0d57f8442b6034ad9296c630d299c4 (commit)

Summary of changes:
 etc/RT_Config.pm.in                                |   6 +
 etc/acl.Pg                                         |   4 +
 etc/schema.Oracle                                  |  30 +
 etc/schema.Pg                                      |  36 +
 etc/schema.SQLite                                  |  30 +
 etc/schema.mysql                                   |  31 +
 etc/upgrade/{4.1.1 => 4.3.12}/acl.Pg               |   6 +-
 etc/upgrade/4.3.12/schema.Oracle                   |  28 +
 etc/upgrade/4.3.12/schema.Pg                       |  35 +
 etc/upgrade/4.3.12/schema.SQLite                   |  28 +
 etc/upgrade/4.3.12/schema.mysql                    |  29 +
 lib/RT.pm                                          |   3 +
 lib/RT/Action/Notify.pm                            |  86 +++
 lib/RT/CustomRole.pm                               | 728 +++++++++++++++++++++
 lib/RT/{CustomFieldValues.pm => CustomRoles.pm}    | 133 ++--
 lib/RT/Group.pm                                    |  29 +
 lib/RT/Handle.pm                                   |  41 +-
 lib/RT/Interface/Web.pm                            |  62 +-
 lib/RT/{ObjectScrip.pm => ObjectCustomRole.pm}     | 166 +++--
 lib/RT/{ObjectScrips.pm => ObjectCustomRoles.pm}   |  40 +-
 lib/RT/Principal.pm                                |   2 +-
 lib/RT/Queue.pm                                    |  48 +-
 lib/RT/Record/Role/Roles.pm                        | 219 +++++--
 lib/RT/SearchBuilder/Role/Roles.pm                 |   4 +-
 lib/RT/System.pm                                   |  22 +
 lib/RT/Ticket.pm                                   |  84 ++-
 lib/RT/Tickets.pm                                  |  66 +-
 lib/RT/Transaction.pm                              |  20 +-
 sbin/rt-validator.in                               |  16 +
 share/html/Admin/CustomRoles/Modify.html           | 188 ++++++
 .../Admin/{Scrips => CustomRoles}/Objects.html     |  90 +--
 .../{Assets/Catalogs => CustomRoles}/index.html    |  99 +--
 share/html/Admin/Elements/EditQueueWatchers        |   1 -
 share/html/Admin/Elements/EditRights               |   2 +-
 share/html/Admin/Elements/SelectGroups             |   2 +-
 share/html/Admin/Groups/Members.html               |   4 +-
 share/html/Admin/Queues/People.html                |  24 +-
 .../Articles/Article/Elements/SelectSearchPrivacy  |   2 +-
 share/html/Elements/ColumnMap                      |  34 +-
 share/html/Elements/EmailInput                     |  47 +-
 .../{RT__Group => RT__CustomRole}/ColumnMap        |  69 +-
 share/html/Elements/SelectWatcherType              |  14 +-
 share/html/Elements/ShowMemberships                |   4 +-
 .../EditMerge => Elements/SingleUserRoleInput}     |  46 +-
 share/html/Elements/Tabs                           |  27 +-
 share/html/Helpers/Autocomplete/Groups             |   2 +-
 share/html/Helpers/Autocomplete/Users              |   5 +-
 share/html/Search/Build.html                       |   2 +-
 share/html/Search/Bulk.html                        |  26 +
 share/html/Search/Elements/BuildFormatString       |  12 +
 share/html/Search/Elements/EditSort                |   8 +
 share/html/Search/Elements/PickCriteria            |   1 +
 .../Elements/{PickTicketCFs => PickCustomRoles}    |  42 +-
 share/html/Search/Elements/SelectGroup             |   2 +-
 share/html/Search/Elements/SelectPersonType        |  17 +-
 share/html/Ticket/Create.html                      |  27 +
 share/html/Ticket/Elements/AddWatchers             |  34 +-
 share/html/Ticket/Elements/EditBasics              |  36 +-
 share/html/Ticket/Elements/EditPeople              |  35 +-
 share/html/Ticket/Elements/EditWatchers            |   7 +-
 share/html/Ticket/Elements/ShowPeople              |  27 +
 share/html/Ticket/Modify.html                      |   1 +
 share/html/Ticket/ModifyAll.html                   |   2 +-
 share/html/Ticket/Update.html                      |   1 +
 share/static/js/autocomplete.js                    |   8 +
 t/customroles/basic.t                              | 289 ++++++++
 t/customroles/existing-tickets.t                   | 121 ++++
 t/customroles/notify.t                             | 248 +++++++
 t/customroles/rights.t                             | 446 +++++++++++++
 t/customroles/tickets.t                            | 347 ++++++++++
 t/web/ticket_modify_all.t                          |   4 +-
 71 files changed, 3967 insertions(+), 468 deletions(-)
 copy etc/upgrade/{4.1.1 => 4.3.12}/acl.Pg (85%)
 create mode 100644 etc/upgrade/4.3.12/schema.Oracle
 create mode 100644 etc/upgrade/4.3.12/schema.Pg
 create mode 100644 etc/upgrade/4.3.12/schema.SQLite
 create mode 100644 etc/upgrade/4.3.12/schema.mysql
 create mode 100644 lib/RT/CustomRole.pm
 copy lib/RT/{CustomFieldValues.pm => CustomRoles.pm} (53%)
 copy lib/RT/{ObjectScrip.pm => ObjectCustomRole.pm} (62%)
 copy lib/RT/{ObjectScrips.pm => ObjectCustomRoles.pm} (72%)
 create mode 100644 share/html/Admin/CustomRoles/Modify.html
 copy share/html/Admin/{Scrips => CustomRoles}/Objects.html (59%)
 copy share/html/Admin/{Assets/Catalogs => CustomRoles}/index.html (61%)
 copy share/html/Elements/{RT__Group => RT__CustomRole}/ColumnMap (67%)
 copy share/html/{Ticket/Elements/EditMerge => Elements/SingleUserRoleInput} (74%)
 copy share/html/Search/Elements/{PickTicketCFs => PickCustomRoles} (72%)
 create mode 100644 t/customroles/basic.t
 create mode 100644 t/customroles/existing-tickets.t
 create mode 100644 t/customroles/notify.t
 create mode 100644 t/customroles/rights.t
 create mode 100644 t/customroles/tickets.t

- Log -----------------------------------------------------------------
commit 1b895a0ab8a3dc4e51fe554d014589c34526bdd1
Merge: 6aa253f d4a2fc6
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Fri Oct 30 21:49:54 2015 +0000

    Merge branch '4.4/custom-roles'

diff --cc etc/acl.Pg
index 5f2344b,458c52a..6558550
--- a/etc/acl.Pg
+++ b/etc/acl.Pg
@@@ -58,10 -58,10 +58,14 @@@ sub acl 
          ObjectTopics
          objectclasses_id_seq
          ObjectClasses
 +        catalogs_id_seq
 +        Catalogs
 +        assets_id_seq
 +        Assets
+         customroles_id_seq
+         CustomRoles
+         objectcustomroles_id_seq
+         ObjectCustomRoles
      );
  
      my $db_user = RT->Config->Get('DatabaseUser');
diff --cc etc/schema.Oracle
index 8b6767b,59282f7..0a98ab1
--- a/etc/schema.Oracle
+++ b/etc/schema.Oracle
@@@ -483,35 -488,32 +483,65 @@@ Created DATE
  LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL,
  LastUpdated DATE
  );
+ 
 +CREATE SEQUENCE Assets_seq;
 +CREATE TABLE Assets (
 +    id              NUMBER(11,0)    CONSTRAINT Assets_key PRIMARY KEY,
 +    Name            varchar2(255)   DEFAULT '',
 +    Catalog         NUMBER(11,0)    DEFAULT 0 NOT NULL,
 +    Status          varchar2(64)    DEFAULT '',
 +    Description     varchar2(255)   DEFAULT '',
 +    Creator         NUMBER(11,0)    DEFAULT 0 NOT NULL,
 +    Created         DATE,
 +    LastUpdatedBy   NUMBER(11,0)    DEFAULT 0 NOT NULL,
 +    LastUpdated     DATE
 +);
 +
 +CREATE INDEX AssetsName ON Assets (LOWER(Name));
 +CREATE INDEX AssetsStatus ON Assets (Status);
 +CREATE INDEX AssetsCatalog ON Assets (Catalog);
 +
 +CREATE SEQUENCE Catalogs_seq;
 +CREATE TABLE Catalogs (
 +    id              NUMBER(11,0)    CONSTRAINT Catalogs_key PRIMARY KEY,
 +    Name            varchar2(255)   DEFAULT '',
 +    Lifecycle       varchar2(32)    DEFAULT 'assets',
 +    Description     varchar2(255)   DEFAULT '',
 +    Disabled        NUMBER(11,0)    DEFAULT 0 NOT NULL,
 +    Creator         NUMBER(11,0)    DEFAULT 0 NOT NULL,
 +    Created         DATE,
 +    LastUpdatedBy   NUMBER(11,0)    DEFAULT 0 NOT NULL,
 +    LastUpdated     DATE
 +);
 +
 +CREATE INDEX CatalogsName ON Catalogs (LOWER(Name));
 +CREATE INDEX CatalogsDisabled ON Catalogs (Disabled);
++
+ CREATE SEQUENCE CUSTOMROLES_seq;
+ CREATE TABLE CustomRoles (
+         id              NUMBER(11,0)
+                 CONSTRAINT CustomRoles_Key PRIMARY KEY,
+         Name            VARCHAR2(200),
+         Description     VARCHAR2(255),
+         MaxValues       NUMBER(11,0) DEFAULT 0 NOT NULL,
+         EntryHint       VARCHAR2(255),
+         Creator         NUMBER(11,0) DEFAULT 0 NOT NULL,
+         Created         DATE,
+         LastUpdatedBy   NUMBER(11,0) DEFAULT 0 NOT NULL,
+         LastUpdated     DATE,
+         Disabled        NUMBER(11,0) DEFAULT 0 NOT NULL
+ );
+ 
+ CREATE SEQUENCE OBJECTCUSTOMROLES_seq;
+ CREATE TABLE ObjectCustomRoles (
+         id              NUMBER(11,0)
+                  CONSTRAINT ObjectCustomRoles_Key PRIMARY KEY,
+         CustomRole       NUMBER(11,0)  NOT NULL,
+         ObjectId              NUMBER(11,0)  NOT NULL,
+         SortOrder       NUMBER(11,0) DEFAULT 0 NOT NULL,
+         Creator         NUMBER(11,0) DEFAULT 0 NOT NULL,
+         Created         DATE,
+         LastUpdatedBy   NUMBER(11,0) DEFAULT 0 NOT NULL,
+         LastUpdated     DATE
+ );
+ CREATE UNIQUE INDEX ObjectCustomRoles1 ON ObjectCustomRoles (ObjectId, CustomRole);
diff --cc etc/schema.Pg
index 2020b53,9f9671f..7b6d53c
--- a/etc/schema.Pg
+++ b/etc/schema.Pg
@@@ -715,37 -720,39 +715,73 @@@ LastUpdated TIMESTAMP NULL
  PRIMARY KEY (id)
  );
  
 +CREATE SEQUENCE assets_id_seq;
 +CREATE TABLE Assets (
 +    id                integer                  DEFAULT nextval('assets_id_seq'),
 +    Name              varchar(255)    NOT NULL DEFAULT '',
 +    Catalog           integer         NOT NULL DEFAULT 0,
 +    Status            varchar(64)     NOT NULL DEFAULT '',
 +    Description       varchar(255)    NOT NULL DEFAULT '',
 +    Creator           integer         NOT NULL DEFAULT 0,
 +    Created           timestamp                DEFAULT NULL,
 +    LastUpdatedBy     integer         NOT NULL DEFAULT 0,
 +    LastUpdated       timestamp                DEFAULT NULL,
 +    PRIMARY KEY (id)
 +);
 +
 +CREATE INDEX AssetsName ON Assets (LOWER(Name));
 +CREATE INDEX AssetsStatus ON Assets (Status);
 +CREATE INDEX AssetsCatalog ON Assets (Catalog);
 +
 +CREATE SEQUENCE catalogs_id_seq;
 +CREATE TABLE Catalogs (
 +    id                integer                  DEFAULT nextval('catalogs_id_seq'),
 +    Name              varchar(255)    NOT NULL DEFAULT '',
 +    Lifecycle         varchar(32)     NOT NULL DEFAULT 'assets',
 +    Description       varchar(255)    NOT NULL DEFAULT '',
 +    Disabled          integer         NOT NULL DEFAULT 0,
 +    Creator           integer         NOT NULL DEFAULT 0,
 +    Created           timestamp                DEFAULT NULL,
 +    LastUpdatedBy     integer         NOT NULL DEFAULT 0,
 +    LastUpdated       timestamp                DEFAULT NULL,
 +    PRIMARY KEY (id)
 +);
 +
 +CREATE INDEX CatalogsName ON Catalogs (LOWER(Name));
 +CREATE INDEX CatalogsDisabled ON Catalogs (Disabled);
+ 
+ CREATE SEQUENCE customroles_id_seq;
+ 
+ CREATE TABLE CustomRoles (
+   id INTEGER DEFAULT nextval('customroles_id_seq'),
+   Name varchar(200) NULL  ,
+   Description varchar(255) NULL  ,
+   MaxValues integer NOT NULL DEFAULT 0  ,
+   EntryHint varchar(255) NULL  ,
+ 
+   Creator integer NOT NULL DEFAULT 0  ,
+   Created TIMESTAMP NULL  ,
+   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+   LastUpdated TIMESTAMP NULL  ,
+   Disabled integer NOT NULL DEFAULT 0 ,
+   PRIMARY KEY (id)
+ 
+ );
+ 
+ CREATE SEQUENCE objectcustomroles_id_seq;
+ 
+ CREATE TABLE ObjectCustomRoles (
+   id INTEGER DEFAULT nextval('objectscrips_id_seq'),
+   CustomRole integer NOT NULL,
+   ObjectId integer NOT NULL,
+   SortOrder integer NOT NULL DEFAULT 0  ,
+ 
+   Creator integer NOT NULL DEFAULT 0  ,
+   Created TIMESTAMP NULL  ,
+   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+   LastUpdated TIMESTAMP NULL  ,
+   PRIMARY KEY (id)
+ 
+ );
+ 
+ CREATE UNIQUE INDEX ObjectCustomRoles1 ON ObjectCustomRoles (ObjectId, CustomRole);
diff --cc etc/schema.SQLite
index 2b01716,1d486ec..c2ced74
--- a/etc/schema.SQLite
+++ b/etc/schema.SQLite
@@@ -516,33 -519,32 +516,63 @@@ Created TIMESTAMP NULL
  LastUpdatedBy integer NOT NULL DEFAULT 0,
  LastUpdated TIMESTAMP NULL
  );
+ 
 +CREATE TABLE Assets (
 +    id                INTEGER PRIMARY KEY,
 +    Name              varchar(255)    NOT NULL DEFAULT '',
 +    Catalog           int(11)         NOT NULL DEFAULT 0,
 +    Status            varchar(64)     NOT NULL DEFAULT '',
 +    Description       varchar(255)    NOT NULL DEFAULT '',
 +    Creator           int(11)         NOT NULL DEFAULT 0,
 +    Created           timestamp                DEFAULT NULL,
 +    LastUpdatedBy     int(11)         NOT NULL DEFAULT 0,
 +    LastUpdated       timestamp                DEFAULT NULL
 +);
 +
 +CREATE INDEX AssetsName on Assets (Name);
 +CREATE INDEX AssetsStatus ON Assets (Status);
 +CREATE INDEX AssetsCatalog ON Assets (Catalog);
 +
 +CREATE TABLE Catalogs (
 +    id                INTEGER PRIMARY KEY,
 +    Name              varchar(255)    NOT NULL DEFAULT '',
 +    Lifecycle         varchar(32)     NOT NULL DEFAULT 'assets',
 +    Description       varchar(255)    NOT NULL DEFAULT '',
 +    Disabled          int2            NOT NULL DEFAULT 0,
 +    Creator           int(11)         NOT NULL DEFAULT 0,
 +    Created           timestamp                DEFAULT NULL,
 +    LastUpdatedBy     int(11)         NOT NULL DEFAULT 0,
 +    LastUpdated       timestamp                DEFAULT NULL
 +);
 +
 +CREATE INDEX CatalogsName on Catalogs (Name);
 +CREATE INDEX CatalogsDisabled ON Catalogs (Disabled);
++
+ CREATE TABLE CustomRoles (
+   id INTEGER NOT NULL  ,
+   Name varchar(200) collate NOCASE NULL  ,
+   Description varchar(255) collate NOCASE NULL  ,
+   MaxValues integer,
+   EntryHint varchar(255) collate NOCASE NULL  ,
+ 
+   Creator integer NOT NULL DEFAULT 0  ,
+   Created DATETIME NULL  ,
+   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+   LastUpdated DATETIME NULL  ,
+   Disabled int2 NOT NULL DEFAULT 0 ,
+   PRIMARY KEY (id)
+ ) ;
+ 
+ CREATE TABLE ObjectCustomRoles (
+   id INTEGER NOT NULL  ,
+   CustomRole int NOT NULL  ,
+   ObjectId integer NOT NULL,
+   SortOrder integer NOT NULL DEFAULT 0  ,
+ 
+   Creator integer NOT NULL DEFAULT 0  ,
+   Created DATETIME NULL  ,
+   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+   LastUpdated DATETIME NULL  ,
+   PRIMARY KEY (id)
+ );
+ CREATE UNIQUE INDEX ObjectCustomRoles1 ON ObjectCustomRoles (ObjectId, CustomRole);
diff --cc etc/schema.mysql
index 477f99c,9323efb..6ebe75f
--- a/etc/schema.mysql
+++ b/etc/schema.mysql
@@@ -503,35 -509,33 +503,66 @@@ CREATE TABLE ObjectClasses 
    LastUpdated datetime default NULL,
    PRIMARY KEY  (id)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+ 
 +CREATE TABLE Assets (
 +    id                int(11)         NOT NULL AUTO_INCREMENT,
 +    Name              varchar(255)    NOT NULL DEFAULT '',
 +    Catalog           int(11)         NOT NULL DEFAULT 0,
 +    Status            varchar(64)     NOT NULL DEFAULT '',
 +    Description       varchar(255)    NOT NULL DEFAULT '',
 +    Creator           int(11)         NOT NULL DEFAULT 0,
 +    Created           datetime                 DEFAULT NULL,
 +    LastUpdatedBy     int(11)         NOT NULL DEFAULT 0,
 +    LastUpdated       datetime                 DEFAULT NULL,
 +    PRIMARY KEY (id)
 +) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 +
 +CREATE INDEX AssetsName ON Assets (Name);
 +CREATE INDEX AssetsStatus ON Assets (Status);
 +CREATE INDEX AssetsCatalog ON Assets (Catalog);
 +
 +CREATE TABLE Catalogs (
 +    id                int(11)         NOT NULL AUTO_INCREMENT,
 +    Name              varchar(255)    NOT NULL DEFAULT '',
 +    Lifecycle         varchar(32)     NOT NULL DEFAULT 'assets',
 +    Description       varchar(255)    NOT NULL DEFAULT '',
 +    Disabled          int2            NOT NULL DEFAULT 0,
 +    Creator           int(11)         NOT NULL DEFAULT 0,
 +    Created           datetime                 DEFAULT NULL,
 +    LastUpdatedBy     int(11)         NOT NULL DEFAULT 0,
 +    LastUpdated       datetime                 DEFAULT NULL,
 +    PRIMARY KEY (id)
 +) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 +
 +CREATE INDEX CatalogsName ON Catalogs (Name);
 +CREATE INDEX CatalogsDisabled ON Catalogs (Disabled);
++
+ CREATE TABLE CustomRoles (
+   id INTEGER NOT NULL  AUTO_INCREMENT,
+   Name varchar(200) NULL  ,
+   Description varchar(255) NULL  ,
+   MaxValues integer,
+   EntryHint varchar(255) NULL  ,
+ 
+   Creator integer NOT NULL DEFAULT 0  ,
+   Created DATETIME NULL  ,
+   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+   LastUpdated DATETIME NULL  ,
+   Disabled int2 NOT NULL DEFAULT 0 ,
+   PRIMARY KEY (id)
+ ) ENGINE=InnoDB CHARACTER SET utf8;
+ 
+ CREATE TABLE ObjectCustomRoles (
+   id INTEGER NOT NULL  AUTO_INCREMENT,
+   CustomRole integer NOT NULL  ,
+   ObjectId integer NOT NULL,
+   SortOrder integer NOT NULL DEFAULT 0  ,
+ 
+   Creator integer NOT NULL DEFAULT 0  ,
+   Created DATETIME NULL  ,
+   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+   LastUpdated DATETIME NULL  ,
+   PRIMARY KEY (id)
+ ) ENGINE=InnoDB CHARACTER SET utf8;
+ 
+ CREATE UNIQUE INDEX ObjectCustomRoles1 ON ObjectCustomRoles (ObjectId, CustomRole);
diff --cc etc/upgrade/4.3.12/acl.Pg
index 0000000,820f7de..820f7de
mode 000000,100644..100644
--- a/etc/upgrade/4.3.12/acl.Pg
+++ b/etc/upgrade/4.3.12/acl.Pg
diff --cc etc/upgrade/4.3.12/schema.Oracle
index 0000000,f138d6e..f138d6e
mode 000000,100644..100644
--- a/etc/upgrade/4.3.12/schema.Oracle
+++ b/etc/upgrade/4.3.12/schema.Oracle
diff --cc etc/upgrade/4.3.12/schema.Pg
index 0000000,5e02ba4..5e02ba4
mode 000000,100644..100644
--- a/etc/upgrade/4.3.12/schema.Pg
+++ b/etc/upgrade/4.3.12/schema.Pg
diff --cc etc/upgrade/4.3.12/schema.SQLite
index 0000000,6a47e4d..6a47e4d
mode 000000,100644..100644
--- a/etc/upgrade/4.3.12/schema.SQLite
+++ b/etc/upgrade/4.3.12/schema.SQLite
diff --cc etc/upgrade/4.3.12/schema.mysql
index 0000000,427b66c..427b66c
mode 000000,100644..100644
--- a/etc/upgrade/4.3.12/schema.mysql
+++ b/etc/upgrade/4.3.12/schema.mysql
diff --cc lib/RT/Handle.pm
index 6956b22,434ac68..f849e46
--- a/lib/RT/Handle.pm
+++ b/lib/RT/Handle.pm
@@@ -848,11 -829,10 +848,12 @@@ sub InsertData 
  
      # Slurp in stuff to insert from the datafile. Possible things to go in here:-
      our (@Groups, @Users, @Members, @ACL, @Queues, @Classes, @ScripActions, @ScripConditions,
-            @Templates, @CustomFields, @Scrips, @Attributes, @Initial, @Final,
 -           @Templates, @CustomFields, @CustomRoles, @Scrips, @Attributes, @Initial, @Final);
++           @Templates, @CustomFields, @CustomRoles, @Scrips, @Attributes, @Initial, @Final,
 +           @Catalogs, @Assets);
      local (@Groups, @Users, @Members, @ACL, @Queues, @Classes, @ScripActions, @ScripConditions,
-            @Templates, @CustomFields, @Scrips, @Attributes, @Initial, @Final,
 -           @Templates, @CustomFields, @CustomRoles, @Scrips, @Attributes, @Initial, @Final);
++           @Templates, @CustomFields, @CustomRoles, @Scrips, @Attributes, @Initial, @Final,
 +           @Catalogs, @Assets);
+ 
      local $@;
      $RT::Logger->debug("Going to load '$datafile' data file");
      eval { require $datafile }
diff --cc lib/RT/Queue.pm
index 7d85ccd,0f50fde..83e2b3b
--- a/lib/RT/Queue.pm
+++ b/lib/RT/Queue.pm
@@@ -466,6 -467,60 +467,23 @@@ sub TicketTransactionCustomFields 
      return ($cfs);
  }
  
+ =head2 CustomRoles
+ 
+ Returns an L<RT::CustomRoles> object containing all queue-specific roles.
+ 
+ =cut
+ 
+ sub CustomRoles {
+     my $self = shift;
+ 
+     my $roles = RT::CustomRoles->new( $self->CurrentUser );
+     if ( $self->CurrentUserHasRight('SeeQueue') ) {
+         $roles->LimitToObjectId( $self->Id );
+         $roles->ApplySortOrder;
+     }
+     return ($roles);
+ }
+ 
 -
 -
 -=head2 AllRoleGroupTypes
 -
 -B<DEPRECATED> and will be removed in a future release. Use L</Roles>
 -instead.
 -
 -Returns a list of the names of the various role group types for Queues,
 -including roles used only for ACLs like Requestor and Owner. If you don't want
 -them, see L</ManageableRoleGroupTypes>.
 -
 -=cut
 -
 -sub AllRoleGroupTypes {
 -    RT->Deprecated(
 -        Remove => "4.4",
 -        Instead => "RT::Queue->Roles",
 -    );
 -    shift->Roles;
 -}
 -
 -=head2 IsRoleGroupType
 -
 -B<DEPRECATED> and will be removed in a future release. Use L</HasRole> instead.
 -
 -Returns whether the passed-in type is a role group type.
 -
 -=cut
 -
 -sub IsRoleGroupType {
 -    RT->Deprecated(
 -        Remove => "4.4",
 -        Instead => "RT::Queue->HasRole",
 -    );
 -    shift->HasRole(@_);
 -}
 -
  =head2 ManageableRoleGroupTypes
  
  Returns a list of the names of the various role group types for Queues,
diff --cc t/customroles/basic.t
index 0000000,76599fe..d703eee
mode 000000,100644..100644
--- a/t/customroles/basic.t
+++ b/t/customroles/basic.t
@@@ -1,0 -1,289 +1,289 @@@
+ use strict;
+ use warnings;
+ 
+ use RT::Test tests => undef;
+ 
+ my $general = RT::Test->load_or_create_queue( Name => 'General' );
+ my $inbox = RT::Test->load_or_create_queue( Name => 'Inbox' );
+ my $specs = RT::Test->load_or_create_queue( Name => 'Specs' );
+ my $development = RT::Test->load_or_create_queue( Name => 'Development' );
+ 
+ diag 'testing no roles yet' if $ENV{'TEST_VERBOSE'};
+ {
+     my $roles = RT::CustomRoles->new(RT->SystemUser);
+     $roles->UnLimit;
+     is($roles->Count, 0, 'no roles created yet');
+ 
 -    is_deeply([sort RT::System->Roles], ['AdminCc', 'Cc', 'Owner', 'Requestor'], 'System->Roles');
++    is_deeply([sort RT::System->Roles], ['AdminCc', 'Cc', 'Contact', 'HeldBy', 'Owner', 'Requestor'], 'System->Roles');
+     is_deeply([sort RT::Queue->Roles], ['AdminCc', 'Cc', 'Owner', 'Requestor'], 'Queue->Roles');
+     is_deeply([sort $general->Roles], ['AdminCc', 'Cc', 'Owner', 'Requestor'], 'General->Roles');
+     is_deeply([sort RT::Ticket->Roles], ['AdminCc', 'Cc', 'Owner', 'Requestor'], 'Ticket->Roles');
+     is_deeply([sort RT::Queue->ManageableRoleGroupTypes], ['AdminCc', 'Cc'], 'Queue->ManageableRoleTypes');
+     is_deeply([sort $general->ManageableRoleGroupTypes], ['AdminCc', 'Cc'], 'General->ManageableRoleTypes');
+ }
+ 
+ diag 'create a single-member role' if $ENV{'TEST_VERBOSE'};
+ my $engineer;
+ {
+     $engineer = RT::CustomRole->new(RT->SystemUser);
+     my ($ok, $msg) = $engineer->Create(
+         Name      => 'Engineer-' . $$,
+         MaxValues => 1,
+     );
+     ok($ok, "created role: $msg");
+ 
+     is($engineer->Name, 'Engineer-' . $$, 'role name');
+     is($engineer->MaxValues, 1, 'role is single member');
+     ok($engineer->SingleValue, 'role is single member');
+     ok(!$engineer->UnlimitedValues, 'role is single member');
+     ok(!$engineer->IsAddedToAny, 'role is not applied to any queues yet');
+     ok(RT::Queue->Role('RT::CustomRole-1')->{Single}, 'role is single member');
+ 
 -    is_deeply([sort RT::System->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'Requestor'], 'System->Roles');
++    is_deeply([sort RT::System->Roles], ['AdminCc', 'Cc', 'Contact', 'HeldBy', 'Owner', 'RT::CustomRole-1', 'Requestor'], 'System->Roles');
+     is_deeply([sort RT::Queue->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'Requestor'], 'Queue->Roles');
+     is_deeply([sort $general->Roles], ['AdminCc', 'Cc', 'Owner', 'Requestor'], 'General->Roles');
+     is_deeply([sort RT::Ticket->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'Requestor'], 'Ticket->Roles');
+     is_deeply([sort RT::Queue->ManageableRoleGroupTypes], ['AdminCc', 'Cc'], 'Queue->ManageableRoleTypes');
+     is_deeply([sort $general->ManageableRoleGroupTypes], ['AdminCc', 'Cc'], 'General->ManageableRoleTypes');
+ }
+ 
+ diag 'create a multi-member role' if $ENV{'TEST_VERBOSE'};
+ my $sales;
+ {
+     $sales = RT::CustomRole->new(RT->SystemUser);
+     my ($ok, $msg) = $sales->Create(
+         Name      => 'Sales-' . $$,
+         MaxValues => 0,
+     );
+     ok($ok, "created role: $msg");
+ 
+     is($sales->Name, 'Sales-' . $$, 'role name');
+     is($sales->MaxValues, 0, 'role is multi member');
+     ok(!$sales->SingleValue, 'role is multi member');
+     ok($sales->UnlimitedValues, 'role is multi member');
+     ok(!$sales->IsAddedToAny, 'role is not applied to any queues yet');
+     ok(!RT::Queue->Role('RT::CustomRole-2')->{Single}, 'role is multi member');
+ 
 -    is_deeply([sort RT::System->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor'], 'System->Roles');
++    is_deeply([sort RT::System->Roles], ['AdminCc', 'Cc', 'Contact', 'HeldBy', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor'], 'System->Roles');
+     is_deeply([sort RT::Queue->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor'], 'Queue->Roles');
+     is_deeply([sort $general->Roles], ['AdminCc', 'Cc', 'Owner', 'Requestor'], 'General->Roles');
+     is_deeply([sort RT::Ticket->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor'], 'Ticket->Roles');
+     is_deeply([sort RT::Queue->ManageableRoleGroupTypes], ['AdminCc', 'Cc', 'RT::CustomRole-2'], 'Queue->ManageableRoleTypes');
+     is_deeply([sort $general->ManageableRoleGroupTypes], ['AdminCc', 'Cc'], 'General->ManageableRoleTypes');
+ }
+ 
+ diag 'collection methods' if $ENV{'TEST_VERBOSE'};
+ {
+     my $roles = RT::CustomRoles->new(RT->SystemUser);
+     $roles->UnLimit;
+     $roles->OrderBy(
+         FIELD => 'id',
+         ORDER => 'Asc',
+     );
+ 
+     is($roles->Count, 2, 'two roles');
+     is($roles->Next->Name, 'Engineer-' . $$, 'first role');
+     is($roles->Next->Name, 'Sales-' . $$, 'second role');
+ 
+     my $single = RT::CustomRoles->new(RT->SystemUser);
+     $single->LimitToSingleValue;
+     is($single->Count, 1, 'one single-value role');
+     is($single->Next->Name, 'Engineer-' . $$, 'single role');
+ 
+     my $multi = RT::CustomRoles->new(RT->SystemUser);
+     $multi->LimitToMultipleValue;
+     is($multi->Count, 1, 'one multi-value role');
+     is($multi->Next->Name, 'Sales-' . $$, 'single role');
+ }
+ 
+ diag 'roles not added to any queues yet' if $ENV{'TEST_VERBOSE'};
+ {
+     for my $queue ($general, $inbox, $specs, $development) {
+         my $roles = RT::CustomRoles->new(RT->SystemUser);
+         $roles->LimitToObjectId($queue->Id);
+         is($roles->Count, 0, 'no roles yet for ' . $queue->Name);
+ 
+         my $qroles = $queue->CustomRoles;
+         is($qroles->Count, 0, 'no roles yet from ' . $queue->Name);
+ 
+         ok(!$sales->IsAdded($queue->Id), 'Sales is not added to ' . $queue->Name);
+         ok(!$engineer->IsAdded($queue->Id), 'Engineer is not added to ' . $queue->Name);
+     }
+ }
+ 
+ diag 'add roles to queues' if $ENV{'TEST_VERBOSE'};
+ {
+     my ($ok, $msg) = $sales->AddToObject($inbox->id);
+     ok($ok, "added Sales to Inbox: $msg");
+ 
+     ($ok, $msg) = $sales->AddToObject($specs->id);
+     ok($ok, "added Sales to Specs: $msg");
+ 
+     ($ok, $msg) = $engineer->AddToObject($specs->id);
+     ok($ok, "added Engineer to Specs: $msg");
+ 
+     ($ok, $msg) = $engineer->AddToObject($development->id);
+     ok($ok, "added Engineer to Development: $msg");
+ }
+ 
+ diag 'roles now added to queues' if $ENV{'TEST_VERBOSE'};
+ {
 -    is_deeply([sort RT::System->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor'], 'System->Roles');
++    is_deeply([sort RT::System->Roles], ['AdminCc', 'Cc', 'Contact', 'HeldBy', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor'], 'System->Roles');
+     is_deeply([sort RT::Queue->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor'], 'Queue->Roles');
+     is_deeply([sort RT::Ticket->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor'], 'Ticket->Roles');
+     is_deeply([sort RT::Queue->ManageableRoleGroupTypes], ['AdminCc', 'Cc', 'RT::CustomRole-2'], 'Queue->ManageableRoleTypes');
+ 
+     # General
+     {
+         my $roles = RT::CustomRoles->new(RT->SystemUser);
+         $roles->LimitToObjectId($general->Id);
+         is($roles->Count, 0, 'no roles for General');
+ 
+         my $qroles = $general->CustomRoles;
+         is($qroles->Count, 0, 'no roles from General');
+ 
+         ok(!$sales->IsAdded($general->Id), 'Sales is not added to General');
+         ok(!$engineer->IsAdded($general->Id), 'Engineer is not added to General');
+ 
+         is_deeply([sort $general->Roles], ['AdminCc', 'Cc', 'Owner', 'Requestor'], 'General->Roles');
+         is_deeply([sort $general->ManageableRoleGroupTypes], ['AdminCc', 'Cc'], 'General->ManageableRoleTypes');
+         is_deeply([grep { $general->IsManageableRoleGroupType($_) } 'AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor', 'Nonexistent'], ['AdminCc', 'Cc'], 'General IsManageableRoleGroupType');
+     }
+ 
+     # Inbox
+     {
+         my $roles = RT::CustomRoles->new(RT->SystemUser);
+         $roles->LimitToObjectId($inbox->Id);
+         is($roles->Count, 1, 'one role for Inbox');
+         is($roles->Next->Name, 'Sales-' . $$, 'and the one role is Sales');
+ 
+         my $qroles = $inbox->CustomRoles;
+         is($qroles->Count, 1, 'one role from Inbox');
+         is($qroles->Next->Name, 'Sales-' . $$, 'and the one role is Sales');
+ 
+         ok($sales->IsAdded($inbox->Id), 'Sales is added to Inbox');
+         ok(!$engineer->IsAdded($inbox->Id), 'Engineer is not added to Inbox');
+ 
+         is_deeply([sort $inbox->Roles], ['AdminCc', 'Cc', 'Owner', $sales->GroupType, 'Requestor'], 'Inbox->Roles');
+         is_deeply([sort $inbox->ManageableRoleGroupTypes], ['AdminCc', 'Cc', $sales->GroupType], 'Inbox->ManageableRoleTypes');
+         is_deeply([grep { $inbox->IsManageableRoleGroupType($_) } 'AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor', 'Nonexistent'], ['AdminCc', 'Cc', 'RT::CustomRole-2'], 'Inbox IsManageableRoleGroupType');
+     }
+ 
+     # Specs
+     {
+         my $roles = RT::CustomRoles->new(RT->SystemUser);
+         $roles->LimitToObjectId($specs->Id);
+         $roles->OrderBy(
+             FIELD => 'id',
+             ORDER => 'Asc',
+         );
+         is($roles->Count, 2, 'two roles for Specs');
+         is($roles->Next->Name, 'Engineer-' . $$, 'and the first role is Engineer');
+         is($roles->Next->Name, 'Sales-' . $$, 'and the second role is Sales');
+ 
+         my $qroles = $specs->CustomRoles;
+         $qroles->OrderBy(
+             FIELD => 'id',
+             ORDER => 'Asc',
+         );
+         is($qroles->Count, 2, 'two roles from Specs');
+         is($qroles->Next->Name, 'Engineer-' . $$, 'and the first role is Engineer');
+         is($qroles->Next->Name, 'Sales-' . $$, 'and the second role is Sales');
+ 
+         ok($sales->IsAdded($specs->Id), 'Sales is added to Specs');
+         ok($engineer->IsAdded($specs->Id), 'Engineer is added to Specs');
+ 
+         is_deeply([sort $specs->Roles], ['AdminCc', 'Cc', 'Owner', $engineer->GroupType, $sales->GroupType, 'Requestor'], 'Specs->Roles');
+         is_deeply([sort $specs->ManageableRoleGroupTypes], ['AdminCc', 'Cc', $sales->GroupType], 'Specs->ManageableRoleTypes');
+         is_deeply([grep { $specs->IsManageableRoleGroupType($_) } 'AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor', 'Nonexistent'], ['AdminCc', 'Cc', 'RT::CustomRole-2'], 'Specs IsManageableRoleGroupType');
+     }
+ 
+     # Development
+     {
+         my $roles = RT::CustomRoles->new(RT->SystemUser);
+         $roles->LimitToObjectId($development->Id);
+         is($roles->Count, 1, 'one role for Development');
+         is($roles->Next->Name, 'Engineer-' . $$, 'and the one role is sales');
+ 
+         my $qroles = $development->CustomRoles;
+         is($qroles->Count, 1, 'one role from Development');
+         is($qroles->Next->Name, 'Engineer-' . $$, 'and the one role is sales');
+ 
+         ok(!$sales->IsAdded($development->Id), 'Sales is not added to Development');
+         ok($engineer->IsAdded($development->Id), 'Engineer is added to Development');
+ 
+         is_deeply([sort $development->Roles], ['AdminCc', 'Cc', 'Owner', $engineer->GroupType, 'Requestor'], 'Development->Roles');
+         is_deeply([sort $development->ManageableRoleGroupTypes], ['AdminCc', 'Cc'], 'Development->ManageableRoleTypes');
+         is_deeply([grep { $development->IsManageableRoleGroupType($_) } 'AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'Requestor', 'Nonexistent'], ['AdminCc', 'Cc'], 'Development IsManageableRoleGroupType');
+     }
+ }
+ 
+ diag 'role names' if $ENV{'TEST_VERBOSE'};
+ {
+     my ($ok, $msg) = $engineer->SetName('Programmer-' . $$);
+     ok($ok, "SetName: $msg");
+     is($engineer->Name, 'Programmer-' . $$, 'new name');
+ 
+     # should be okay
+     ($ok, $msg) = $engineer->SetName('Programmer-' . $$);
+     ok($ok || $msg =~ /already the current value/ , "SetName: $msg");
+     is($engineer->Name, 'Programmer-' . $$, 'new name');
+ 
+     my $playground = RT::CustomRole->new(RT->SystemUser);
+     ($ok, $msg) = $playground->Create(Name => 'Playground-' . $$, MaxValues => 1);
+     ok($ok, "playground role: $msg");
+ 
+     for my $name (
+         'Programmer-' . $$,
+         'proGRAMMER-' . $$,
+         'Cc',
+         'CC',
+         'AdminCc',
+         'ADMIN CC',
+         'Requestor',
+         'requestors',
+         'Owner',
+         'OWNer',
+     ) {
+         # creating a role with that name should fail
+         my $new = RT::CustomRole->new(RT->SystemUser);
+         ($ok, $msg) = $new->Create(Name => $name, MaxValues => 1);
+         ok(!$ok, "creating a role with duplicate name $name should fail: $msg");
+ 
+         # updating an existing role with the dupe name should fail too
+         ($ok, $msg) = $playground->SetName($name);
+         ok(!$ok, "updating an existing role with duplicate name $name should fail: $msg");
+         is($playground->Name, 'Playground-' . $$, 'name stayed the same');
+     }
+ 
+     # make sure we didn't create any new roles
+     my $roles = RT::CustomRoles->new(RT->SystemUser);
+     $roles->UnLimit;
+     is($roles->Count, 3, 'three roles (original two plus playground)');
+ 
 -    is_deeply([sort RT::System->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'RT::CustomRole-3', 'Requestor'], 'No new System->Roles');
++    is_deeply([sort RT::System->Roles], ['AdminCc', 'Cc', 'Contact', 'HeldBy', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'RT::CustomRole-3', 'Requestor'], 'No new System->Roles');
+     is_deeply([sort RT::Queue->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'RT::CustomRole-3', 'Requestor'], 'No new Queue->Roles');
+     is_deeply([sort RT::Ticket->Roles], ['AdminCc', 'Cc', 'Owner', 'RT::CustomRole-1', 'RT::CustomRole-2', 'RT::CustomRole-3', 'Requestor'], 'No new Ticket->Roles');
+     is_deeply([sort RT::Queue->ManageableRoleGroupTypes], ['AdminCc', 'Cc', 'RT::CustomRole-2'], 'No new Queue->ManageableRoleGroupTypes');
+ }
+ 
+ diag 'load by name and id' if $ENV{'TEST_VERBOSE'};
+ {
+     my $role = RT::CustomRole->new(RT->SystemUser);
+     $role->Load($engineer->id);
+     is($role->Name, 'Programmer-' . $$, 'load by id');
+ 
+     $role = RT::CustomRole->new(RT->SystemUser);
+     $role->Load('Sales-' . $$);
+     is($role->id, $sales->id, 'load by name');
+ }
+ 
+ diag 'LabelForRole' if $ENV{'TEST_VERBOSE'};
+ {
+     is($inbox->LabelForRole($sales->GroupType), 'Sales-' . $$, 'Inbox label for Sales');
+     is($specs->LabelForRole($sales->GroupType), 'Sales-' . $$, 'Specs label for Sales');
+     is($specs->LabelForRole($engineer->GroupType), 'Programmer-' . $$, 'Specs label for Engineer');
+     is($development->LabelForRole($engineer->GroupType), 'Programmer-' . $$, 'Development label for Engineer');
+ }
+ 
+ done_testing;

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


More information about the rt-commit mailing list