Skip to content

Commit 6cd59a3

Browse files
committed
Allow noninteractive WsCli SDK usage. Do not send empty body params.
1 parent e49cf61 commit 6cd59a3

2 files changed

Lines changed: 102 additions & 49 deletions

File tree

wscli-php-sdk/src/WsCli.php

Lines changed: 92 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,33 @@ private function checkArgs($required = [])
9393
return $error;
9494
}
9595

96+
private function getPassword()
97+
{
98+
if (array_key_exists('password', $this->opts) &&
99+
strlen((string)$this->opts['password']) < 20) {
100+
$this->log->error("Password length shorter than 20");
101+
if (array_key_exists('noninteractive', $this->opts) &&
102+
$this->opts['noninteractive']) {
103+
return 1;
104+
}
105+
}
106+
if (!array_key_exists('password', $this->opts)) {
107+
$this->log->error("Password not specified!");
108+
if (array_key_exists('noninteractive', $this->opts) &&
109+
$this->opts['noninteractive']) {
110+
return 1;
111+
}
112+
$this->opts['password'] = '';
113+
while (strlen((string)$this->opts['password']) < 20) {
114+
$this->opts['password'] = readline("Give password (at least 20 chars, upper/lower letters and special chars): ");
115+
}
116+
}
117+
if (!$this->getEncryptedPassword()) {
118+
$this->log->error("Could not get encrypted password.");
119+
$error = 1;
120+
}
121+
}
122+
96123
private function handleAccount($api, $cmd, $fromApi, $fromCmd)
97124
{
98125
$error = $this->checkArgs(['email', 'mode']);
@@ -121,7 +148,12 @@ private function handleAccount($api, $cmd, $fromApi, $fromCmd)
121148
$this->log->debug(print_r($resp, true));
122149
return $resp;
123150
case "verifyEmail":
124-
while (strlen($this->opts['code']) != 6) {
151+
while (strlen((string)$this->opts['code']) != 6) {
152+
$this->log->error("Code not long enough: " . $this->opts['code'] . ".");
153+
if (array_key_exists('noninteractive', $this->opts) &&
154+
$this->opts['noninteractive']) {
155+
return 1;
156+
}
125157
$this->opts['code'] = readline("Give EMail verification code: ");
126158
}
127159
if ($error) {
@@ -137,11 +169,17 @@ private function handleAccount($api, $cmd, $fromApi, $fromCmd)
137169
$this->log->debug("Callbacking to " . $fromApi . "->" . $fromCmd);
138170
$this->opts['<cmd>'] = $fromCmd;
139171
$this->opts['<api>'] = $fromApi;
172+
$this->opts['code'] = '';
140173
return $this->__call($cmd, [$api]);
141174
}
142175
return $resp;
143176
case "verifyPhone":
144177
while (strlen((string)$this->opts['code']) != 6) {
178+
$this->log->error("Code not long enough: " . $this->opts['code'] . ".");
179+
if (array_key_exists('noninteractive', $this->opts) &&
180+
$this->opts['noninteractive']) {
181+
return 1;
182+
}
145183
$this->opts['code'] = readline("Give phone registration code: ");
146184
}
147185
if ($error) {
@@ -166,31 +204,34 @@ private function handleAccount($api, $cmd, $fromApi, $fromCmd)
166204
}
167205
if (!$this->getChallenge()) {
168206
$this->log->error("Could not get challenge.");
169-
$error = 1;
207+
return 1;
170208
}
171-
if (!array_key_exists('password', $this->opts)) {
172-
$this->opts['password'] = '';
173-
while (strlen((string)$this->opts['password']) < 20) {
174-
$this->opts['password'] = readline("Give password (at least 20 chars, upper/lower letters and special chars): ");
209+
if (!array_key_exists('code', $this->opts)) {
210+
$resp = $this->${"api"}->initPasswordReset(
211+
$this->opts['email'],
212+
$this->opts['mode']
213+
);
214+
if ($resp['response_code'] != "00") {
215+
$this->log->error("Failed to init password reset");
216+
$this->log->error(print_r($resp, true));
217+
return $resp;
218+
}
219+
if (array_key_exists('noninteractive', $this->opts) &&
220+
$this->opts['noninteractive']) {
221+
return $resp;
175222
}
176223
}
177-
if (!$this->getEncryptedPassword()) {
178-
$this->log->error("Could not get encrypted password.");
179-
$error = 1;
224+
if ($this->getPassword()) {
225+
return 1;
180226
}
181-
if ($error) {
182-
return $error;
183-
}
184-
$resp = $this->${"api"}->initPasswordReset(
185-
$this->opts['email'],
186-
$this->opts['mode']
187-
);
188-
if ($resp['response_code'] != "00") {
189-
$this->log->error("Failed to init password reset");
190-
$this->log->error(print_r($resp, true));
191-
return $resp;
227+
if (!array_key_exists('code', $this->opts)) {
228+
$this->log->error("Code not specified");
229+
if (array_key_exists('noninteractive', $this->opts) &&
230+
$this->opts['noninteractive']) {
231+
return 1;
232+
}
233+
$this->opts['code'] = readline("Give password reset SMS code: ");
192234
}
193-
$this->opts['code'] = readline("Give password reset SMS code: ");
194235
$resp = $this->${"api"}->passwordReset(
195236
$this->getBodyParams(),
196237
$this->opts['email'],
@@ -226,6 +267,15 @@ private function handleSession($api, $cmd)
226267
return $resp;
227268
case "loginMFA":
228269
case "login":
270+
if (array_key_exists('code', $this->opts)) {
271+
if (strlen((string)$this->opts['code']) == 6) {
272+
$cmd = "loginMFA";
273+
}
274+
if (strlen((string)$this->opts['code']) != 6) {
275+
$this->log->error("Provided code is not long enough: " . $this->opts['code'] . ".");
276+
return 1;
277+
}
278+
}
229279
if (array_key_exists('idtoken', $this->opts) &&
230280
strlen($this->opts['idtoken']) > 0 &&
231281
array_key_exists('mode', $this->opts) &&
@@ -241,17 +291,7 @@ private function handleSession($api, $cmd)
241291
$this->log->error("Could not get challenge.");
242292
$error = 1;
243293
}
244-
if ($error) {
245-
return $error;
246-
}
247-
if (!array_key_exists('password', $this->opts)) {
248-
$this->opts['password'] = '';
249-
while (strlen((string)$this->opts['password']) < 20) {
250-
$this->opts['password'] = readline("Give password (at least 20 chars, upper/lower letters and special chars): ");
251-
}
252-
}
253-
if (!$this->getEncryptedPassword()) {
254-
$this->log->error("Could not get encrypted password.");
294+
if ($this->getPassword()) {
255295
$error = 1;
256296
}
257297
if ($error) {
@@ -264,7 +304,9 @@ private function handleSession($api, $cmd)
264304
);
265305
$this->opts['code'] = ''; // Reset code if any
266306
$this->log->debug(print_r($resp, true));
267-
if ($resp['response_code'] == "00") {
307+
if ($resp['response_code'] == "00" &&
308+
(!array_key_exists('noninteractive', $this->opts) ||
309+
!$this->opts['noninteractive'])) {
268310
if (strstr($resp['response_text'], "Verify phone number")) {
269311
$this->opts['<api>'] = "account";
270312
$this->opts['<cmd>'] = "verifyPhone";
@@ -284,17 +326,18 @@ private function handleSession($api, $cmd)
284326
$this->opts['<cmd>'] = "verifyEmail";
285327
return $this->__call("login", [$api]);
286328
}
287-
if ($resp['response_text'] == "Login OK") {
288-
$this->updateConfig("idtoken: " . $resp['id_token']);
289-
$exp = date("Y-m-d H:i:s", time()+$resp['expires_in']-10);
290-
$this->log->debug("idtokenexpiry: " . $exp);
291-
if ($exp === false) {
292-
$this->log->error("Could not form idtoken expiry date. Setting to +3300s");
293-
$exp = time() + 3300;
294-
}
295-
$this->updateConfig("idtokenexpiry: \"" . $exp . "\"");
296-
$this->updateConfig("idtokenmode: \"" . $this->opts['mode'] . "\"");
329+
}
330+
if ($resp['response_code'] == "00" &&
331+
$resp['response_text'] == "Login OK") {
332+
$this->updateConfig("idtoken: " . $resp['id_token']);
333+
$exp = date("Y-m-d H:i:s", time()+$resp['expires_in']-10);
334+
$this->log->debug("idtokenexpiry: " . $exp);
335+
if ($exp === false) {
336+
$this->log->error("Could not form idtoken expiry date. Setting to +3300s");
337+
$exp = time() + 3300;
297338
}
339+
$this->updateConfig("idtokenexpiry: \"" . $exp . "\"");
340+
$this->updateConfig("idtokenmode: \"" . $this->opts['mode'] . "\"");
298341
}
299342
return $resp;
300343
default:
@@ -683,6 +726,12 @@ private function getBodyParams()
683726
$bodyParams['AccessToken'] = $this->opts['accesstoken'];
684727
unset($bodyParams['accesstoken']);
685728
}
729+
$apiKey = $bodyParams['ApiKey'];
730+
$bodyParams = array_filter($bodyParams);
731+
if ($apiKey == "0") {
732+
// array_filter() filters out keys with value "0"
733+
$bodyParams['ApiKey'] = "0";
734+
}
686735
$bodyParams = json_encode($bodyParams);
687736
$this->log->debug("body params: " . print_r($bodyParams, true));
688737
return $bodyParams;

wscli-php/src/wscli.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@
2525
wscli (-v | --version)
2626
wscli --update
2727
wscli --rollback
28-
wscli account verifyEmail [-c CONF] [-e EMAIL] [-m MODE] [--code=<code>]
29-
wscli account verifyPhone [-c CONF] [-e EMAIL] [-m MODE] [--phone=<phone>]
30-
wscli account passwordReset [-c CONF] [-e EMAIL] [-m MODE]
28+
wscli account verifyEmail [-c CONF] [-e EMAIL] [-m MODE] [--code=<code>] [--noninteractive] [--accesstoken=<token>]
29+
wscli account verifyPhone [-c CONF] [-e EMAIL] [-m MODE] [--phone=<phone>] [--code=<code>] [--noninteractive]
30+
wscli account passwordReset [-c CONF] [-e EMAIL] [-m MODE] [--noninteractive]
3131
wscli account register [-c CONF] [-e EMAIL] [-m MODE] [-a APIKEY] [--name=<name>] [--company=<company>]
32-
[--password=<password>] [--phone=<phone>]
32+
[--password=<password>] [--phone=<phone>] [--noninteractive]
3333
wscli session logout [-c CONF] [-a APIKEY] [-i IDTOKEN]
3434
wscli session login [-c CONF] [-e EMAIL] [-m MODE] [--password=<password>]
35-
[--environment=<environment>]
35+
[--environment=<environment>] [--code=<mfacode>] [--session=<session>] [--noninteractive]
3636
wscli files listFiles [-c CONF] [-a APIKEY] [-i IDTOKEN] [-b BANK] [--filetype=<filetype>] [--filestatus=<filestatus>]
3737
wscli files downloadFile [-c CONF] [-a APIKEY] [-i IDTOKEN] [-b BANK] [--filetype=<filetype>] [--filereference=<fileref>]
3838
wscli files deleteFile [-c CONF] [-a APIKEY] [-i IDTOKEN] [-b BANK] [--filetype=<filetype>] [--filereference=<fileref>]
@@ -58,22 +58,26 @@
5858
-v, --version Show version
5959
--update Update wscli to latest version
6060
--rollback Rollback wscli to previous version, after an update
61+
--noninteractive SDK will NOT interactively ask, e.g for password and MFA
6162
-c FILE, --config=FILE YAML configuration file containing all required parameters in 'settings' block
6263
-a APIKEY, --apikey=APIKEY Integrator's API Key
63-
-i IDTOKEN, --idtoken=IDTOKEN Session authorization token received from successful login
64+
-i IDTOKEN, --idtoken=IDTOKEN Identity carrying authorization token received from successful login
6465
-b BANK, --bank=BANK Target bank, e.g. nordea
6566
-e EMAIL, --email=EMAIL Account user's email
6667
-m MODE, --mode=MODE admin or data account
6768
--name=<name> Account users's name
6869
--phone=<phone> Account user's phone number with country code, e.g. +358401234567
6970
--company=<company> Account user's company
7071
--password=<password> Account user's password for <mode> account
72+
--accesstoken=<token> When email is not verified, login returns access token that must be passed to emailVerify
73+
--session=<session> Session token, when e.g. SMS MFA is requested during login
7174
--environment=<env> Environment, test or production
7275
--filetype=<filetype> Bank's file type
7376
--filestatus=<filestatus> Bank's file status, e.g. ALL
7477
--filecontents=<filecontents> Upload file contents
7578
--filereference=<filereference> Bank's file reference from listFiles entry
7679
--extemail=<extemail> Link extemail to this account for certificates sharing
80+
--code=<code> SMS MFA code or email verification code
7781
--pincode=<pincode> PIN code for WS certificate enrollment
7882
--wstargetid=<wstargetid> Use wstargetid in certificate enrollment
7983
--wsuserid=<wsuserid> Use wsuserid in certificate enrollment

0 commit comments

Comments
 (0)