From 45d3def574dcb556e1fb4176cf8f92f045ed823b Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Wed, 31 Jul 2019 12:10:04 +0200 Subject: [PATCH] fix "405 Method not allowed" error updating users and retrying on connection failure once --- api/src/Accounts/Univention.php | 3 ++- api/src/Accounts/Univention/Udm.php | 27 +++++++++++++------ .../{UdmCantConnect => UdmCantConnect.php} | 0 3 files changed, 21 insertions(+), 9 deletions(-) rename api/src/Accounts/Univention/{UdmCantConnect => UdmCantConnect.php} (100%) diff --git a/api/src/Accounts/Univention.php b/api/src/Accounts/Univention.php index 9da4c3c16e..7140688bd6 100644 --- a/api/src/Accounts/Univention.php +++ b/api/src/Accounts/Univention.php @@ -89,8 +89,9 @@ class Univention extends Ldap $data['account_dn'] = $udm->createGroup($data); $data['account_id'] = $this->name2id($data['account_lid'], 'account_lid', 'g'); } + // account_lid and password changes need to go through UDM too elseif($data['account_id'] && ($data['old_loginid'] || ($data['old_loginid'] = $this->id2name($data['account_id']))) && - $data['account_lid'] != $data['old_loginid'] && + ($data['account_lid'] != $data['old_loginid'] || !empty($data['account_passwd'])) && ($data['account_dn'] = $this->id2name($data['account_id'], 'account_dn'))) { if ($data['account_type'] !== 'g') diff --git a/api/src/Accounts/Univention/Udm.php b/api/src/Accounts/Univention/Udm.php index 1e4ebe8398..584f9b4244 100644 --- a/api/src/Accounts/Univention/Udm.php +++ b/api/src/Accounts/Univention/Udm.php @@ -86,13 +86,13 @@ class Udm * @param array& $headers =[] on return response headers * @param string $if_match =null etag for If-Match header * @param boolean $return_dn =false return DN of Location header - * @throws Exception on error + * @param int $retry =1 >0 retry on connection-error only * @return array|string decoded JSON or DN for $return_DN === true * @throws UdmCantConnect for connection errors or JSON decoding errors * @throws UdmError for returned JSON error object * @throws UdmMissingLocation for missing Location header with DN ($return_dn === true) */ - protected function call($_path, $_method='GET', array $_payload=[], &$headers=[], $if_match=null, $return_dn=false) + protected function call($_path, $_method='GET', array $_payload=[], &$headers=[], $if_match=null, $return_dn=false, $retry=1) { $curl = curl_init(); @@ -164,18 +164,29 @@ class Udm if (!$response || !($json = json_decode($response, true)) && json_last_error()) { + if ($retry > 0) + { + return $this->call($_path, $_method, $_payload, $headers, $if_match, $return_dn, --$retry); + } $info = curl_getinfo($curl); curl_close($curl); - error_log(__METHOD__."($_path, $_method, ".json_encode($_payload, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).") returned $response, headers=".json_encode($headers, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).", curl_getinfo()=".json_encode($info, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)); + $_path = urldecode($_path); // for nicer error-messages + error_log(__METHOD__."($_path, $_method, ...) returned $response, headers=".json_encode($headers, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).", curl_getinfo()=".json_encode($info, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)); + error_log(__METHOD__."($_path, $_method, ".json_encode($_payload, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).")"); throw new UdmCantConnect("Error contacting Univention UDM REST Api ($_path)".($response ? ': '.json_last_error() : '')); } curl_close($curl); if (!empty($json['error'])) { - error_log(__METHOD__."($_path, $_method, ".json_encode($_payload, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).") returned $response, headers=".json_encode($headers, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)); - throw new UdmError("UDM REST Api ($_path): ".(empty($json['error']['message']) ? $response : $json['error']['message']), $json['error']['code']); + error_log(__METHOD__."($_path, $_method, ...) returned $response, headers=".json_encode($headers, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)); + error_log(__METHOD__."($_path, $_method, ".json_encode($_payload, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).")"); + throw new UdmError("UDM REST Api (".urldecode($_path)."): ".(empty($json['error']['message']) ? $response : $json['error']['message']), $json['error']['code']); + } + if (self::DEBUG) + { + error_log(__METHOD__."($_path, $_method, ...) returned $response, headers=".json_encode($headers, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)); + error_log(__METHOD__."($_path, $_method, ".json_encode($_payload, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).")"); } - if (self::DEBUG) error_log(__METHOD__."($_path, $_method, ".json_encode($_payload, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).") returned $response, headers=".json_encode($headers, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)); if ($return_dn) { @@ -223,7 +234,7 @@ class Udm $payload = $this->user2udm($data, $this->call('users/user/'.urlencode($dn), 'GET', [], $get_headers)); $headers = []; - return $this->call('users/user/', 'PUT', $payload, $headers, $get_headers['etag'], true); + return $this->call('users/user/'.urlencode($dn), 'PUT', $payload, $headers, $get_headers['etag'], true); } /** @@ -313,7 +324,7 @@ class Udm $payload = $this->user2udm($data, $this->call('groups/group/'.urlencode($dn), 'GET', [], $get_headers)); $headers = []; - return $this->call('groups/group/', 'PUT', $payload, $headers, $get_headers['etag'], true); + return $this->call('groups/group/'.urlencode($dn), 'PUT', $payload, $headers, $get_headers['etag'], true); } /** diff --git a/api/src/Accounts/Univention/UdmCantConnect b/api/src/Accounts/Univention/UdmCantConnect.php similarity index 100% rename from api/src/Accounts/Univention/UdmCantConnect rename to api/src/Accounts/Univention/UdmCantConnect.php