]> git.defcon.no Git - hermes/blob - guc-clients/feide2sipuser
5660c5e1b18ff9fbf5644a96e1135c8e25edcf3e
[hermes] / guc-clients / feide2sipuser
1 #!/usr/bin/perl
2 use strict;
3
4 use Getopt::Long;
5 use Net::LDAP;
6 use Net::LDAP::Control::Paged;
7 use Net::LDAP::Constant qw( LDAP_CONTROL_PAGED );
8 use LWP;
9 use JSON;
10 use AppConfig;
11
12 my $api_key;
13
14 my $help;
15 my $username;
16 my $configfile;
17 my $dryrun = 0;
18 my ($g_ua, $session, $api_key, $auth_key, $data, $domain);
19 my ($user, $displayname, $phone, $mail, $sipuser, $linetext);
20
21 my $config = AppConfig->new({ CREATE => 1 });
22
23 $config->define("api_url=s");
24 $config->define("api_keyfile=s");
25 $config->define("feide_server=s");
26 $config->define("feide_login=s");
27 $config->define("feide_passwd=s");
28 $config->define("feide_people=s");
29
30 $config->define("numbers_local_prefix=s");
31 $config->define("numbers_local_series=s");
32 $config->define("numbers_countrycode=s");
33
34 GetOptions(
35 "help" => \$help,
36 "username=s" => \$username,
37 "configfile=s" => \$configfile,
38 "dryrun" => \$dryrun,
39 );
40
41 if (
42 (not $username) ||
43 (( $configfile ) && ( not -f $configfile ))
44 )
45 {
46 $help = 1;
47 }
48
49 $config->file( $configfile );
50
51 if ( ( not $config->api_url ) ||
52 ( not $config->api_keyfile ) ||
53 ( $config->api_keyfile && not -f $config->api_keyfile ) ||
54 ( not $config->feide_server ) ||
55 ( not $config->feide_login ) ||
56 ( not $config->feide_passwd ) ||
57 ( not $config->feide_people ) )
58 {
59 $help = 1;
60 }
61
62 if ( $help ) {
63 print <<END_HELP;
64 Verify that the following options are set:
65 --configfile=s
66 --username=s
67 --dryrun
68
69 Verify the contents of the configuration file.
70 Verify that the key-file exists.
71 END_HELP
72 exit; }
73
74 open KEY, "<" . $config->api_keyfile;
75 chomp( $api_key = <KEY> );
76 close KEY;
77
78 if ( not $username =~ m/\w+/ )
79 { print "Illegal username\n"; exit; }
80
81
82 # Kobler til LDAP-server
83 my $ldap = Net::LDAP->new($config->feide_server, version => 3)
84 or die "Can't connect to LDAP server: " . $config->feide_server . "!\n";
85 my $msg = $ldap->bind (dn => $config->feide_login, password => $config->feide_passwd);
86 if ( $msg->code()) {
87 die ("LDAP error: ", $msg->error_text((), "\n"));
88 }
89
90 $msg = $ldap->search( base => $config->feide_people,
91 scope => "subtree",
92 filter => "(uid=". $username .")",
93 attrs => () );
94 die("Getting information for " . $username . " failed..." ) if ( $msg->count != 1 );
95
96 $user = $msg->entry;
97 $displayname = $user->get_value("displayName");
98 $phone = $user->get_value("telephoneNumber");
99 $mail = $user->get_value("mail");
100 $sipuser = $user->get_value("eduPersonPrincipalName");
101
102 my $short_test = "^" . $config->numbers_local_series;
103 my $long_test = "^" . $config->numbers_local_prefix . $config->numbers_local_series;
104
105 if ( $phone =~ m/$short_test/ )
106 {
107 print "Phone number is in 5-digit local format. Completing E164.\n";
108 $linetext = $config->numbers_local_prefix . $phone;
109 $phone = $config->numbers_countrycode . $config->numbers_local_prefix . $phone;
110 }
111 elsif ( $phone =~ m/$long_test/ )
112 {
113 print "Phone number is in 8-digit local format. Adding CC.\n" ;
114 $linetext = $phone;
115 $phone = $config->numbers_countrycode . $phone;
116 }
117 else
118 {
119 print "Unable to recognize Phone number. Check FEIDE\n";
120 exit;
121 }
122
123 print "Data so far:" . "\n";
124 print " Username: " . $username . "\n";
125 print " Displayname: " . $displayname . "\n";
126 print " Phone: " . $phone . "\n";
127 print " Line-text: " . $linetext . "\n";
128 print " Mail: " . $mail . "\n";
129 print " SIP address: " . $sipuser . "\n";
130
131 $msg = $ldap->unbind;
132 if ( $msg->code()) { die ("LDAP error: ", $msg->error_text((), "\n")); }
133
134 $g_ua = LWP::UserAgent->new;
135 $g_ua->cookie_jar({}); # In-memory jar, look at HTTP::Cookies for persistant
136
137 login_apikey();
138
139
140 $data = exec_apinode("user/available", { "user" => $sipuser });
141 if ( not $data->{'response'} eq 'ok' )
142 {
143 printf("Unable to add user, Hermes response to available query is: %s\n", $data->{'cause'});
144 exit;
145 }
146 undef $data;
147
148 if ( $dryrun ) {
149 print("Dryrun specified. All OK so far, stopping before add.\n");
150 logout();
151 exit;
152 }
153
154 $data = exec_apinode("user/add_local", {
155 "user" => $sipuser,
156 "displayname" => $displayname,
157 "email" => $mail,
158 });
159 if ( not $data->{'response'} eq 'ok' )
160 {
161 printf("Unable to add user, Hermes response to add_local query is: %s\n", $data->{'cause'});
162 exit;
163 }
164 else
165 {
166 printf("Added user, login information:\n");
167 printf("username: %s@%s\nauthid: %s\npassword: %s\n" .
168 "registrar: %s:%d\nproxy: %s:%d\ndisplayname: %s\n" .
169 "email: %s\npermission: %s\n",
170 $data->{'user'}->{'username'},
171 $data->{'user'}->{'domain'},
172 $data->{'user'}->{'authid'},
173 $data->{'user'}->{'password'},
174 $data->{'user'}->{'registrar'},
175 $data->{'user'}->{'r_port'},
176 $data->{'user'}->{'proxy'},
177 $data->{'user'}->{'p_port'},
178 $data->{'user'}->{'displayname'},
179 $data->{'user'}->{'email'},
180 $data->{'user'}->{'permittedcalls'},
181 );
182 $domain = $data->{'user'}->{'domain'},
183 $phone .= "\@" . $domain;
184 }
185 undef $data;
186
187 unless ( $mail eq $sipuser )
188 {
189 $data = exec_apinode("alias/add", {
190 "destination" => $sipuser,
191 "alias" => $mail,
192 });
193 if ( not $data->{'response'} eq 'ok' )
194 {
195 printf("Unable to add alias, Hermes response to add_local query is: %s\n", $data->{'cause'});
196 printf("Attempting to roll back user %s: ", $sipuser);
197 undef $data; $data = exec_apinode("user/remove", { "user" => $sipuser });
198 printf("%s\n", $data->{'response'});
199 exit;
200 }
201 else
202 { printf("alias: %s\n", $mail); }
203 undef $data;
204 }
205
206 $data = exec_apinode("alias/add", {
207 "destination" => $sipuser,
208 "alias" => $phone,
209 });
210 if ( not $data->{'response'} eq 'ok' )
211 {
212 printf("Unable to add E164 number, Hermes response to add_local query is: %s\n", $data->{'cause'});
213 printf("Attempting to roll back user %s: ", $sipuser);
214 exec_apinode("alias/remove", { "alias" => $mail });
215 exec_apinode("user/remove", { "user" => $sipuser });
216 exit;
217 }
218 else
219 { printf("e164: %s\n", $phone); }
220 undef $data;
221
222 $data = exec_apinode("user/update", {
223 "user" => $sipuser,
224 "linetext" => $linetext,
225 });
226 if ( not $data->{'response'} eq 'ok' )
227 {
228 printf("Did not update 'linetext' element.");
229 }
230
231 # During testing:
232 #exec_apinode("alias/remove", { "alias" => $mail });
233 #exec_apinode("alias/remove", { "alias" => $phone });
234 #exec_apinode("user/remove", { "user" => $sipuser });
235
236 logout();
237 ################################################################################################
238 sub exec_apinode($$)
239 {
240 my $node = shift;
241 my $param = shift;
242
243 my ( $response, $data );
244
245 $session = "" if not defined $session;
246 $auth_key = "" if not defined $auth_key;
247 my $url = $config->api_url . "/" . $node;
248
249 $param->{'session'} = $session;
250 $param->{'auth_key'} = $auth_key;
251
252 $response = $g_ua->post( $url, $param );
253 if ( $response->is_success )
254 {
255 if ( $response->content =~ m/\s*{/ )
256 {
257 $data = decode_json( $response->content);
258 }
259 else
260 {
261 $data = $response->content;
262 }
263
264 }
265 return $data;
266 }
267
268 sub login_apikey
269 {
270 my $response = $g_ua->post( $config->api_url . "/auth/login",
271 [ "api_key" => $api_key ] );
272
273 my $data = decode_json( $response->content) if $response->is_success;
274 die("HTTP error") unless $response->is_success;
275
276 if ( $data->{'response'} eq "ok" )
277 {
278 $session = $data->{'session'};
279 $auth_key = $data->{'auth_key'};
280 }
281 else
282 {
283 print "Unable to log in to Hermes API\n";
284 exit;
285 }
286 undef $data; undef $response;
287 }
288
289 sub logout
290 {
291 my $response = $g_ua->post( $config->api_url . "/auth/logout",
292 [ "session" => $session ] );
293 die("HTTP error") unless $response->is_success;
294 undef $session; undef $auth_key;
295 }