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