2
0

add_user 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #!/usr/bin/perl
  2. #
  3. # add_user
  4. #
  5. # Add one or more users to the XML directory
  6. #
  7. #
  8. use strict;
  9. use warnings;
  10. use Getopt::Long;
  11. use Data::Dumper;
  12. ## Useful items
  13. my $path_sep;
  14. my $config_path;
  15. my @dir_elem;
  16. my $user_template = &get_user_template;
  17. my $new_user_count = 0;
  18. ## Command line args
  19. my $users;
  20. my $domain;
  21. my $dirpath;
  22. my $help;
  23. ## Misc items somewhat related to cmd line args
  24. my $start;
  25. my $end;
  26. my $user;
  27. ## Check for Windows vs. *nix
  28. if ( $^O =~ m/^win/i ) {
  29. ## Detected Windows (probably)
  30. $path_sep = "\\"; # single backslash (\)
  31. use File::Spec::Win32;
  32. } else {
  33. $path_sep = '/'; # single slash (/)
  34. use File::Spec;
  35. }
  36. GetOptions(
  37. 'h' => \$help,
  38. 'help' => \$help,
  39. 'domain=s' => \$domain,
  40. 'users=s' => \$users,
  41. 'confpath=s' => \$config_path,
  42. );
  43. if ( $help ) {
  44. usage();
  45. exit(0);
  46. }
  47. if ( ! $domain ) {
  48. $domain='default';
  49. }
  50. ## Validate users if specified on command line
  51. if ( $users ) {
  52. ($start,$end) = split /-/,$users;
  53. if ( ! $start && ! $end ) {
  54. die "Please specify both a start and end range, separated by a hyphen:\n add_user --users=xxxx-yyyy\n";
  55. }
  56. unless ( $start =~ m/[1-9]\d+/ ) {
  57. die "Start of range '$start' is not numeric or is too short\n";
  58. }
  59. unless ( $end =~ m/[1-9]\d+/ ) {
  60. die "End of range '$end' is not numberic or is too short\n";
  61. }
  62. if ( $end <= $start ) {
  63. die "End of range needs to be greater than start of range\n";
  64. }
  65. } else {
  66. ## Look for user id in $ARGV[0]
  67. if ( ! $ARGV[0] ) {
  68. die "You must specify user id as a command line argument to add user, or use the --users option.\n";
  69. }
  70. unless ( $ARGV[0] =~ m/^[1-9]\d+$/ ) {
  71. die "User id must be numeric, be at least 2 digits long, and cannot begin with the digit zero.\n"
  72. }
  73. $user = $ARGV[0];
  74. }
  75. if ( ! $config_path ) {
  76. $config_path = '/usr/local/freeswitch/conf';
  77. }
  78. ## Check to make sure the directories in question exists
  79. unless ( -d $config_path ) {
  80. die "Configuration path '$config_path' does not exist.\n";
  81. }
  82. my $directory_path = $config_path . $path_sep . 'directory';
  83. unless ( -d $directory_path ) {
  84. die "Directory path '$directory_path' does not exist.\n";
  85. }
  86. ## Now check domain pathname and test existence
  87. if ( ! $domain ) {
  88. $domain = 'default';
  89. }
  90. ## Full directory path includes the domain name
  91. my $full_dir_path = $directory_path . $path_sep . $domain;
  92. unless ( -d $full_dir_path ) {
  93. die "Full path to directory and domain '$full_dir_path' does not exist. \n";
  94. }
  95. unless ( -w $full_dir_path ) {
  96. die "This user does not have write access to '$full_dir_path'.\n";
  97. }
  98. print "\n";
  99. ## Regexp assemble items to show user what a PCRE might look like for his new users
  100. my $ra_present;
  101. my $ra_new;
  102. my $ra_all;
  103. eval { require Regexp::Assemble; };
  104. if ( ! $@ ) {
  105. ## If Regexp::Assemble is available flag it for later building regexes
  106. $ra_present = 'true';
  107. $ra_new = Regexp::Assemble->new( # new user regex
  108. reduce => 1,
  109. flags => 0,
  110. );
  111. $ra_all = Regexp::Assemble->new( # all users regex w/ new users thrown in
  112. reduce => 1,
  113. flags => 0,
  114. );
  115. }
  116. ## If we're this far then we can read in the existing users and put them in a hash
  117. ## Later we can check hash to avoid adding duplicate users
  118. my %current_users;
  119. my @CURRENT_USER_FILES = glob($full_dir_path . $path_sep . '*.xml');
  120. foreach ( @CURRENT_USER_FILES ) {
  121. #print "User: $_\n";
  122. open(FILEIN,'<',$_);
  123. while(<FILEIN>) {
  124. next unless m/user id|number-alias/;
  125. m/user id="(\d+)"/;
  126. my $user_id = $1;
  127. if ( ! $user_id ) {
  128. m/alias="(\d+)"/;
  129. $user_id = $1;
  130. }
  131. next unless $user_id;
  132. $current_users{$user_id}++;
  133. if ( $ra_present && $user_id =~ m/^\d+$/ ) {
  134. #print "Adding $user_id to \$re_all...\n";
  135. $ra_all->add($user_id)->anchor_line_begin->anchor_line_end;
  136. }
  137. last;
  138. }
  139. close(FILEIN);
  140. }
  141. #print Dumper(%current_users) . "\n";
  142. if ( $start && $end ) {
  143. ## Add range of users
  144. foreach $user ($start .. $end) {
  145. &add_user($user);
  146. }
  147. } else {
  148. ## Add single user
  149. &add_user($user);
  150. }
  151. print "\nOperation complete. ";
  152. if ( $new_user_count == 0 ) {
  153. print "No users added.\n";
  154. exit(0);
  155. } else {
  156. printf "%d user%s added.\n", $new_user_count, $new_user_count==1 ? "" : "s";
  157. print "Be sure to reloadxml.\n\n";
  158. }
  159. if ( $ra_present ) {
  160. print "Regular expression information:\n\n";
  161. ## Regexp::Assemble adds some stuff we really don't need
  162. ## These lines just make the regexp pattern a bit more readable
  163. my $tmp = $ra_new->as_string;
  164. $tmp =~ s/\?://g;
  165. $tmp =~ s/^\(\?\-xism:\^/^(/;
  166. $tmp =~ s/\$\)$/)\$/;
  167. $tmp =~ s/\\d/[0-9]/g; # [0-9] is sometimes easier to read than \d
  168. print " Sample regex for all new users: " . $tmp . "\n";
  169. $tmp = $ra_all->as_string;
  170. $tmp =~ s/\?://g;
  171. $tmp =~ s/^\(\?\-xism:\^/^(/;
  172. $tmp =~ s/\$\)$/)\$/;
  173. $tmp =~ s/\\d/[0-9]/g; # [0-9] is sometimes easier to read than \d
  174. print "Sample regex for all new AND current users: " . $tmp . "\n\n";
  175. print "In the default configuration you can modify the expression in the condition for 'Local_Extension'.\n";
  176. print ""
  177. } else {
  178. print "If CPAN module Regexp::Assemble were installed this program would be able to suggest a regex for your new users.\n"
  179. }
  180. exit(0);
  181. sub add_user {
  182. my $user_id = shift;
  183. if ( exists( $current_users{$user_id} ) ) {
  184. warn "User id $user_id already exists, skipping...\n";
  185. } else {
  186. my $new_user = $user_template;
  187. $new_user =~ s/__USERID__/$user_id/g;
  188. #print "Adding user id '$user_id' with this XML:\n";
  189. #print $new_user . "\n";
  190. ## Attempt to create the user file
  191. my $user_file_name = $full_dir_path . $path_sep . $user_id . '.xml';
  192. ## Does it already exist?
  193. if ( -f $user_file_name ) {
  194. warn "$user_file_name exists, skipping...\n";
  195. }
  196. my $fh;
  197. open($fh,'>',$user_file_name);
  198. if ( ! $fh ) {
  199. warn "Unable to open '$user_file_name' - $!\n";
  200. warn "Skipping...\n";
  201. next;
  202. }
  203. print $fh $new_user;
  204. close($fh);
  205. print "Added $user_id in file $user_file_name \n";
  206. $new_user_count++;
  207. if ( $ra_present ) {
  208. $ra_new->add($user_id)->anchor_line_begin->anchor_line_end;
  209. $ra_all->add($user_id)->anchor_line_begin->anchor_line_end;
  210. }
  211. }
  212. }
  213. sub get_user_template {
  214. my $templ = <<ENDUSERTEMPLATE;
  215. <include>
  216. <user id="__USERID__">
  217. <params>
  218. <param name="password" value="\$\${default_password}"/>
  219. <param name="vm-password" value="__USERID__"/>
  220. </params>
  221. <variables>
  222. <variable name="toll_allow" value="domestic,international,local"/>
  223. <variable name="accountcode" value="__USERID__"/>
  224. <variable name="user_context" value="default"/>
  225. <variable name="effective_caller_id_name" value="Extension __USERID__"/>
  226. <variable name="effective_caller_id_number" value="__USERID__"/>
  227. <variable name="outbound_caller_id_name" value="\$\${outbound_caller_name}"/>
  228. <variable name="outbound_caller_id_number" value="\$\${outbound_caller_id}"/>
  229. <variable name="callgroup" value="techsupport"/>
  230. </variables>
  231. </user>
  232. </include>
  233. ENDUSERTEMPLATE
  234. return $templ;
  235. }
  236. sub usage {
  237. print <<ENDUSAGE;
  238. FreeSWITCH add user utility
  239. Adds one or more users to the FreeSWITCH directory using XML files.
  240. Syntax:
  241. add_user <user_id> [--domain=<domain_name>] [--confpath=<configuration_path>]
  242. add_user --users=<start_user_id>-<end_user_id> [--domain=<domain_name>] [--confpath=<configuration_path>]
  243. In its simplest form, add_user will simply add the user_id specified at the command line.
  244. By default, users are added to the "default" domain. Use the --domain option to specify
  245. a different domain for the user(s) that are added.
  246. To specify a range of user IDs use the --users option. Separate the beginning and
  247. end of the range with a hyphen (-) character.
  248. By default add_user will look for the XML directory in its default location of
  249. /usr/local/freeswitch/conf/directory. Use the --confpath (configuration path)
  250. option to specify an alternate directory location.
  251. NOTES:
  252. add_user assumes
  253. User IDs must be numeric and cannot begin with zero.
  254. User IDs must be at least two digits long and have no specific length limit.
  255. If a user ID exists it will be skipped.
  256. If a domain specified does not exist no users will be created.
  257. ENDUSAGE
  258. }