3 # $Header: /home/cvs/cvsroot/freeside/rt/bin/Attic/rtadmin,v 1.1 2002-08-12 06:17:07 ivan Exp $
4 # RT is (c) 1996-2001 Jesse Vincent <jesse@fsck.com>
8 use Getopt::Long qw(:config pass_through);
10 use lib "!!RT_LIB_PATH!!";
11 use lib "!!RT_ETC_PATH!!";
13 use RT::Interface::CLI qw(CleanEnv LoadConfig DBConnect
14 GetCurrentUser GetMessageContent);
16 #Clean out all the nasties from the environment
19 #Load etc/config.pm and drop privs
22 #Connect to the database and get RT::SystemUser and RT::Nobody loaded
25 #Drop setgid permissions
26 RT::DropSetGIDPermissions();
28 #Get the current user all loaded
29 my $CurrentUser = GetCurrentUser();
31 unless ($CurrentUser->Id) {
32 print "No RT user found. Please consult your RT administrator.\n";
50 --revoke-right <right>
57 # {{{ help_keyword_sel
58 my $help_keyword_sel = "
61 --modify-keyword-select <name>
63 --ks-keyword <keyword>
68 --disable-keyword-select <name>";
75 --scrip-condition <condition name or id>
76 --scrip-action <action name or id>
77 --scrip-template <template name or id>
87 --delete-template [<id>|<name>]
88 --display-template [<id>|<name>]
91 --modify-template [<id>|<name>]
92 Flags for --create-template and --modify-template
94 --template-description
95 --template-edit-content
104 USAGE: rtadmin --user <userid> [Userflags]
106 rtadmin --queue <queueid> [Queueflags]
107 rtadmin --list-queues
108 rtadmin --group [groupflags]
109 rtadmin --list-groups
110 rtadmin --system [SystemFlags]
111 rtadmin --keyword [keywordflags]
113 User configuration for --user <userid>
133 Auth and external info
134 --externalcontactinfoid
152 --freeformcontactqinfo
155 Group Configuration for --group <groupid>
161 --description <new description>
165 --add-member <userid>
166 --delete-member <userid>
169 Queue Configuration for --queue <queueid>
175 --correspondaddress <email address>
176 --commentaddress <email address>
177 --initialpriority <int>
178 --finalpriority <int>
179 --defaultduein <days>
181 --add-cc <email address>
182 --delete-cc <email address>
183 --add-admincc <email address>
184 --delete-admincc <email address>
198 System configuration for --system
209 Keyword configuration for --keyword <fully qualified name>
211 --create-child <name>
214 --description <new description>
227 my ($user,$group, $queue, $system, $keyword, $listusers,
228 $listgroups, $listqueues, $help);
231 GetOptions ('help|h|usage' => \$help,
233 'queue=s' => \$queue,
234 'group=s' => \$group,
235 'system' => \$system,
236 'keyword=s', => \$keyword,
237 'list-users' => \$listusers,
238 'list-queues' => \$listqueues,
239 'list-groups' => \$listgroups,
244 if ($user) { AdminUser($user) }
245 elsif ($group) { AdminGroup($group) }
246 elsif ($queue) { AdminQueue($queue) }
247 elsif ($system) { AdminSystem($system) }
248 elsif ($keyword) { AdminKeywords($keyword) }
249 elsif ($listusers) { ListUsers() }
250 elsif ($listgroups) { ListGroups() }
251 elsif ($listqueues) { ListQueues() }
252 elsif ($help) { Help()}
254 print "No command found\n";
268 'create', 'disable|delete', 'display',
269 'Name=s', 'Gecos=s', 'Password=s',
270 'EmailAddress=s', 'Privileged=s', 'Comments=s', 'Signature=s',
271 'Organization=s', 'RealName=s', 'NickName=s',
272 'ExternalContactInfoId=s', 'ContactInfoSystem=s',
273 'ExternalAuthId=s', 'AuthSystem=s',
274 'HomePhone=s', 'WorkPhone=s', 'MobilePhone=s', 'PagerPhone=s',
275 'Address1=s', 'Address2=s', 'City=s', 'State=s', 'Zip=s',
276 'Country=s', 'FreeformContactInfo=s');
278 my $user_obj = new RT::User($CurrentUser);
281 #Create the user if we need to
282 if ($args{'create'}) {
284 $user_obj->Create( Name => ($args{'Name'} || $user),
285 Gecos => $args{'Gecos'},
286 Password => $args{'Password'},
287 EmailAddress => $args{'EmailAddress'},
288 Privileged => $args{'Privileged'},
289 Comments => $args{'Comments'},
290 Signature => $args{'Signature'},
291 Organization => $args{'Organization'},
292 RealName => $args{'RealName'},
293 NickName => $args{'NickName'},
294 ExternalContactInfoId => $args{'ExternalContactInfoId'},
295 ContactInfoSystem => $args{'ContactInfoSystem'},
296 ExternalAuthId => $args{'ExternalAuthId'},
297 AuthSystem => $args{'AuthSystem'},
298 HomePhone => $args{'HomePhone'},
299 WorkPhone => $args{'WorkPhone'},
300 MobilePhone => $args{'MobilePhone'},
301 PagerPhone => $args{'PagerPhone'},
302 Address1 => $args{'Address1'},
303 Address2 => $args{'Address2'},
304 City => $args{'City'},
305 State => $args{'State'},
307 FreeformContactInfo => $args{'FreeformContactInfo'}
318 $user_obj->Load($user);
320 unless ($user_obj->id) {
321 print "User '$user' not found\n";
327 #modify the user if we need to
328 my @attributes = ('Name', 'Gecos',
329 'EmailAddress', 'Privileged', 'Comments', 'Signature',
330 'Organization', 'RealName', 'NickName',
331 'ExternalContactInfoId', 'ContactInfoSystem',
332 'ExternalAuthId', 'AuthSystem',
333 'HomePhone', 'WorkPhone', 'MobilePhone', 'PagerPhone',
334 'Address1', 'Address2', 'City', 'State', 'Zip',
335 'Country', 'FreeformContactInfo');
336 foreach my $attrib (@attributes) {
337 if ( (exists ($args{"$attrib"})) and
338 ($user_obj->$attrib() ne $args{"$attrib"})) {
340 my $method = "Set$attrib";
341 my ($val, $msg) = $user_obj->$method($args{"$attrib"});
342 print "User ".$user_obj->Name. " $attrib: $msg\n";
347 if (exists ($args{'Password'})) {
349 ($code, $msg) = $user_obj->SetPassword($args{'Password'});
350 print "User ". $user_obj->Name. ' Password: '. $msg . "\n";
353 #Check if we need to display the user
354 if ($args{'display'}) {
355 foreach my $attrib (@attributes) {
356 next if ($attrib eq 'Password'); #Can't see the password
357 printf("%22.22s %-64s\n",$attrib, ($user_obj->$attrib()||'(undefined)'));
362 #Check if we need to delete the user
363 if ($args{'disable'}) {
364 my ($val, $msg) = $user_obj->SetDisabled(1);
380 'create', 'disable|delete', 'display',
381 'Name=s', 'CorrespondAddress=s', 'Description=s',
382 'CommentAddress=s', 'InitialPriority=n', 'FinalPriority=n',
385 'add-cc=s@', 'add-admincc=s@',
386 'delete-cc=s@', 'delete-admincc=s@',
387 'list-watchers', 'create-template'
391 my $queue_obj = new RT::Queue($CurrentUser);
393 #Create the queue if we need to
394 if ($args{'create'}) {
397 Name => ($args{'Name'} || $queue) ,
398 CorrespondAddress => $args{'CorrespondAddress'},
399 Description => $args{'Description'},
400 CommentAddress => $args{'CommentAddress'},
401 InitialPriority => $args{'InitialPriority'},
402 FinalPriority => $args{'FinalPriority'},
403 DefaultDueIn => $args{'DefaultDueIn'}
410 $queue_obj->Load($queue);
412 unless ($queue_obj->id) {
413 print "Queue '$queue' not found\n";
417 #modify if we need to
418 my @attributes = qw(Name CorrespondAddress Description
419 CommentAddress InitialPriority FinalPriority
422 foreach my $attrib (@attributes) {
423 if ( (exists ($args{"$attrib"})) and
424 ($queue_obj->$attrib() ne $args{"$attrib"})) {
426 my $method = "Set$attrib";
427 my ($val, $msg) = $queue_obj->$method($args{"$attrib"});
428 print "Queue ".$queue_obj->Name. " $attrib: $msg\n";
434 #Check if we need to display the queue
435 if ($args{'display'}) {
436 foreach my $attrib (@attributes) {
437 printf("%22.22s %-64s\n",$attrib, ($queue_obj->$attrib()||'(undefined)'));
442 foreach my $person (@{$args{'add-cc'}}) {
443 my ($val, $msg) = $queue_obj->AddCc(Email => $person);
446 foreach my $person (@{$args{'add-admincc'}}) {
447 my ($val, $msg) = $queue_obj->AddAdminCc(Email => $person);
451 foreach my $person (@{$args{'delete-cc'}}) {
452 my ($val, $msg) = $queue_obj->DeleteCc($person);
455 foreach my $person (@{$args{'delete-admincc'}}) {
456 my ($val, $msg) = $queue_obj->DeleteAdminCc($person);
460 if ($args{'list-watchers'}) {
461 require RT::Watchers;
462 my $watchers = new RT::Watchers($CurrentUser);
463 $watchers->LimitToQueue($queue_obj->id);
464 while (my $watcher = $watchers->Next()) {
465 printf("%10s %-60s\n",
466 $watcher->Type, $watcher->Email );
470 AdminTemplates($queue_obj->Id());
471 AdminScrips($queue_obj->Id());
472 AdminRights($queue_obj->Id());
473 AdminKeywordSelects($queue_obj->Id());
475 #Check if we need to delete the queue
476 if ($args{'disable'}) {
477 my ($val, $msg) = $queue_obj->SetDisabled(1);
492 GetOptions(\%args, 'list-children', 'create-child=s', 'disable|delete', 'Name=s', 'Description=s');
496 my $key_obj = new RT::Keyword($CurrentUser);
499 #If we're dealing with the root of the keyword list
500 if ($keyword eq '/') {
504 my ($val, $msg) = $key_obj->LoadByPath( $keyword );
508 $key_id = $key_obj->Id();
511 if ($args{'create-child'}) {
512 my $child = new RT::Keyword($CurrentUser);
514 my ($val, $msg) = $child->Create( Parent => $key_id,
515 Name => $args{'create-child'},
520 elsif ($args{'list-children'}) {
523 $keywords = $key_obj->Children();
525 #If we didn't actually have a keyword object, we need to create our own Keywords object.
527 $keywords = new RT::Keywords($CurrentUser);
528 $keywords->LimitToParent(0);
531 while (my $key=$keywords->Next) {
533 if ($key->Description) {
534 print " (" . $key->Description .")";
542 #Else we wanna do some modification.
545 #If we didn't load a keyword, get out
546 return(undef) unless ($key_obj->Id);
549 my @attributes = qw( Name Description );
550 foreach my $attrib (@attributes) {
551 if ( (exists ($args{"$attrib"})) and
552 ($key_obj->$attrib() ne $args{"$attrib"})) {
554 my $method = "Set$attrib";
555 my ($val, $msg) = $key_obj->$method($args{"$attrib"});
557 print "Keyword ".$key_obj->Name. " $attrib: $msg\n"; }
560 if ($args{'disable'}) {
561 $key_obj->SetDisabled(1);
570 # {{{ AdminKeywordSelects
572 sub AdminKeywordSelects {
574 # O for queue means global
577 GetOptions(\%args, 'add-keyword-select','disable-keyword-select|delete-keyword-select=s',
578 'modify-keyword-select=s',
579 'keyword-select-Keyword|ks-keyword=s',
580 'keyword-select-Single|ks-single',
581 'keyword-select-Multiple|ks-multiple',
582 'keyword-select-Depth|ks-depth=i',
583 'keyword-select-Name|ks-name=s'
586 # sanitize single vs multiple.
587 if ($args{'keyword-select-Multiple'}) {
588 $args{'keyword-select-Single'} = 0;
591 use RT::KeywordSelect;
592 my $keysel_obj = new RT::KeywordSelect($CurrentUser);
593 if ($args{'add-keyword-select'}) {
595 my ($val, $msg) = $keysel_obj->Create( Keyword => $args{'keyword-select-Keyword'},
596 Depth => $args{'keyword-select-Depth'},
597 Single => $args{'keyword-select-Single'},
598 Name => $args{'keyword-select-Name'},
599 ObjectType => 'Ticket',
600 ObjectField => 'Queue',
601 ObjectValue => $queue);
604 elsif ($args{'modify-keyword-select'}) {
605 $keysel_obj->LoadByName(Name => $args{'modify-keyword-select'},
609 unless ($keysel_obj->Id()) {
610 print "Keyword select not found\n";
613 my @attributes = qw( Name Keyword Single Depth );
614 foreach my $attrib (@attributes) {
615 if ( (exists ($args{"keyword-select-$attrib"})) and
616 ($keysel_obj->$attrib() ne $args{"keyword-select-$attrib"})) {
618 my $method = "Set$attrib";
619 my ($val, $msg) = $keysel_obj->$method($args{"keyword-select-$attrib"});
621 print "Keyword select ".$keysel_obj->Name. " $attrib: $msg\n"; }
628 elsif ($args{'disable-keyword-select'}) {
629 $keysel_obj->LoadByName(Name => $args{'disable-keyword-select'},
632 $keysel_obj->SetDisabled(1);
647 'create', 'delete', 'display',
648 'Name=s', 'Description=s',
650 'add-member=s@', 'delete-member=s@',
656 my $group_obj = new RT::Group($CurrentUser);
658 print "Group not specified.\n";
663 #Create the group if we need to
664 if ($args{'create'}) {
665 my ($val, $msg) = $group_obj->Create( Name => ($args{'Name'} || $group),
666 Description => $args{'Description'} );
669 #otherwise we load it
671 $group_obj->Load($group);
674 #If we have no group object, get the hell out
675 unless ($group_obj->Id) {
676 print "Group not found.\n";
679 if ($args{'delete'}) {
680 my ($val, $msg) = $group_obj->Delete();
687 #modify if we need to
688 my @attributes = qw(Name Description
691 foreach my $attrib (@attributes) {
692 if ( (exists ($args{"$attrib"})) and
693 ($group_obj->$attrib() ne $args{"$attrib"})) {
695 my $method = "Set$attrib";
696 my ($val, $msg) = $group_obj->$method($args{"$attrib"});
697 print "Group ".$group_obj->Name. " $attrib: $msg\n";
702 foreach my $user (@{$args{'add-member'}}) {
703 my ($val, $msg) = $group_obj->AddMember($user);
706 foreach my $user (@{$args{'delete-member'}}) {
707 my ($val, $msg) = $group_obj->DeleteMember($user);
711 if ($args{'list-members'}) {
712 my $members = $group_obj->MembersObj();
713 while (my $member = $members->Next()) {
714 print $member->UserObj->Name() ."\n";
724 print "In AdminSystem\n";
729 AdminKeywordSelects(0);
733 # {{{ sub AdminTemplates
737 #Queue = 0 means 'global';
742 GetOptions(\%args, 'list-templates', 'create-template','modify-template=s',
743 'delete-template=s', 'display-template=s',
744 'template-Name=s', 'template-Description=s',
745 'template-edit-content!');
748 if ($args{'list-templates'}) {
749 print "Templates for $queue\n";
750 require RT::Templates;
751 my $templates = new RT::Templates($CurrentUser);
753 $templates->LimitToQueue($queue);
756 $templates->LimitToGlobal();
758 while (my $template = $templates->Next) {
759 print $template->Id.": ".$template->Name." - " . $template->Description ."\n";
765 require RT::Template;
766 my $template = new RT::Template($CurrentUser);
767 if ($args{'delete-template'}) {
768 $template->Load($args{'delete-template'});
769 unless ($template->id) {
770 print "Couldn't load template";
773 my ($val, $msg) = $template->Delete();
776 elsif ($args{'create-template'}) {
777 #TODO edit the template content
780 my $linesref = GetMessageContent(CurrentUser => $CurrentUser,
783 $content = join("\n", @{$linesref});
786 my ($val, $msg) = $template->Create(Name => $args{'template-Name'},
787 Description => $args{'template-Description'},
792 elsif ($args{'modify-template'}) {
794 $template->Load($args{'modify-template'});
795 unless ($template->Id()) {
796 print "Template not found\n";
799 my @attributes = qw( Name Description );
800 foreach my $attrib (@attributes) {
801 if ( (exists ($args{"template-$attrib"})) and
802 ($template->$attrib() ne $args{"template-$attrib"})) {
804 my $method = "Set$attrib";
805 my $val = $template->$method($args{"template-$attrib"});
809 if ($args{'template-edit-content'}) {
811 my $linesref = GetMessageContent(CurrentUser => $CurrentUser,
812 Content => $template->Content,
815 my $content = join("\n", @{$linesref});
816 my ($val) = $template->SetContent($content);
821 if ($args{'display-template'}) {
822 $template->Load($args{'display-template'});
823 print $template->Name . "\n". $template->Description ."\n". $template->Content."\n";
829 # {{{ sub AdminScrips
833 #Queue = 0 means 'global';
838 GetOptions(\%args, 'list-scrips', 'create-scrip','modify-scrip=s',
839 'scrip-action=s', 'scrip-template=s', 'scrip-condition=s',
844 if ($args{'list-scrips'}) {
845 print "Scrips for $queue\n";
847 my $scrips = new RT::Scrips($CurrentUser);
849 $scrips->LimitToQueue($queue);
852 $scrips->LimitToGlobal();
854 while (my $scrip = $scrips->Next) {
855 print $scrip->Id.": If ".
856 $scrip->ConditionObj->Name." then " .
857 $scrip->ActionObj->Name." with template " .
858 $scrip->TemplateObj->Name."\n";
865 my $scrip = new RT::Scrip($CurrentUser);
866 if ($args{'delete-scrip'}) {
867 $scrip->Load($args{'delete-scrip'});
868 unless ($scrip->id) {
869 print "Couldn't load scrip";
872 my ($val, $msg) = $scrip->Delete();
875 elsif ($args{'create-scrip'}) {
876 my ($val, $msg) = $scrip->Create( ScripAction => $args{'scrip-action'},
877 ScripCondition => $args{'scrip-condition'},
878 Template => $args{'scrip-template'},
887 # {{{ sub AdminRights
891 #Queue = 0 means 'global';
893 my ($scope, $appliesto);
905 'grant-right|add-right|new-right|create-right=s@',
906 'revoke-right|del-right|delete-right=s@',
907 'list-rights', 'userid=s@', 'groupid=s@',
912 if ($args{'list-rights'}) {
914 my $acl = new RT::ACL($CurrentUser);
916 $acl->LimitToQueue($queue);
919 $acl->LimitToSystem();
921 while (my $ace = $acl->Next) {
922 print $ace->RightScope;
924 #Print the queue name if we have it.
925 print " " . $ace->AppliesToObj->Name if (defined $ace->AppliesToObj);
927 print ": ". $ace->PrincipalType . " " .$ace->PrincipalObj->Name .
928 " has right " . $ace->RightName ."\n";
937 # {{{ Build up an array of principals
940 foreach my $group (@{$args{'groupid'}}) {
943 my $princ = new RT::Group($CurrentUser);
944 $princ->Load("$group");
946 $principals[$i]->{'type'} = 'Group';
947 $principals[$i]->{'id'} = $princ->id();
951 print "Could not find group $group\n";
956 foreach my $user (@{$args{'userid'}}) {
957 my $princ = new RT::User($CurrentUser);
958 $princ->Load("$user");
960 $principals[$i]->{'type'} = 'User';
961 $principals[$i]->{'id'} = $princ->id();
965 print "Could not find user $user.\n";
971 foreach my $principal (@principals) {
973 # {{{ Delete rights that need deleting
974 foreach my $right (@{$args{'revoke-right'}}) {
975 my $ace = new RT::ACE($CurrentUser);
976 $RT::Logger->debug("Trying to delete a right: $right \n");
977 my ($val, $msg) = $ace->LoadByValues( RightName => $right,
978 RightScope => $scope,
979 PrincipalType => $principal->{'type'},
980 PrincipalId => $principal->{'id'},
981 RightAppliesTo => $appliesto);
984 print "Right $right not found for" . $principal->{'type'} . " " .
985 $principal->{'id'} . " in scope $scope ($appliesto)\n";
988 my ($delval, $delmsg) =$ace->Delete;
996 # {{{ grant rights that need granting
997 foreach my $right (@{$args{'grant-right'}}) {
998 my $ace = new RT::ACE($CurrentUser);
999 my ($val, $msg) = $ace->Create(RightName => $right,
1000 PrincipalType => $principal->{'type'},
1001 PrincipalId => $principal->{'id'},
1002 RightScope => $scope,
1003 RightAppliesTo => $appliesto);
1018 my $users = new RT::Users($CurrentUser);
1020 while (my $user = $users->Next()) {
1021 printf ("%16s %-16s\n",$user->Name(), $user->EmailAddress());
1026 my $queues = new RT::Queues($CurrentUser);
1028 while (my $queue = $queues->Next()) {
1029 printf ("%16s %-16s\n",$queue->Name(), $queue->Description());
1035 my $groups = new RT::Groups($CurrentUser);
1037 while (my $group = $groups->Next()) {
1038 printf ("%16s %-16s\n",$group->Name(), $group->Description());