New ejabberd API endpoint (check_account) and added api_request helper
This commit is contained in:
pare
79e7f6fc4a
commit
7170f6592d
S'han modificat 3 arxius amb 159 adicions i 23 eliminacions
|
@ -255,6 +255,7 @@ class Akkomabot:
|
|||
self.node_users_str = self.__get_parameter("node_users_str", lang_file_path)
|
||||
self.uptime_str = self.__get_parameter("uptime_str", lang_file_path)
|
||||
self.processes_str = self.__get_parameter("processes_str", lang_file_path)
|
||||
self.account_exists_str = self.__get_parameter("account_exists_str", lang_file_path)
|
||||
|
||||
@staticmethod
|
||||
def __modify_file(self, file_name, pattern,value=""):
|
||||
|
|
143
ejabberdapi.py
143
ejabberdapi.py
|
@ -58,16 +58,34 @@ class Ejabberd:
|
|||
|
||||
return password
|
||||
|
||||
def check_account(self, username, host):
|
||||
|
||||
data = {'user':username,
|
||||
'host':self.__local_vhost,
|
||||
}
|
||||
|
||||
endpoint = self.__api_base_url + '/api/check_account?'
|
||||
|
||||
response = self.__api_request(endpoint, data)
|
||||
|
||||
account_exists = True if response.json() == 0 else False
|
||||
|
||||
return account_exists
|
||||
|
||||
def register(self, username, host, user_password):
|
||||
|
||||
account_exists = self.account_exists(username, host)
|
||||
|
||||
if not account_exists:
|
||||
|
||||
data = {'user':username,
|
||||
'host':self.__local_vhost,
|
||||
'password':user_password,
|
||||
}
|
||||
|
||||
API_ENDPOINT = self.__api_base_url + '/api/register?'
|
||||
endpoint = self.__api_base_url + '/api/register?'
|
||||
|
||||
response = requests.post(url = API_ENDPOINT, json = data, auth=(self.__admin_account, self.__admin_pass))
|
||||
response = self.__api_request(endpoint, data)
|
||||
|
||||
is_registered = response.ok
|
||||
|
||||
|
@ -79,6 +97,12 @@ class Ejabberd:
|
|||
|
||||
response_text = f"{response.json()['status']}: {response.json()['message']}"
|
||||
|
||||
else:
|
||||
|
||||
is_registered = False
|
||||
|
||||
response_text = f"el compte {username}@{host} ja existeix!"
|
||||
|
||||
return (is_registered, response_text)
|
||||
|
||||
def unregister(self, username, host):
|
||||
|
@ -97,9 +121,9 @@ class Ejabberd:
|
|||
'host':self.__local_vhost,
|
||||
}
|
||||
|
||||
API_ENDPOINT = self.__api_base_url + '/api/unregister?'
|
||||
endpoint = self.__api_base_url + '/api/unregister?'
|
||||
|
||||
response = requests.post(url = API_ENDPOINT, json = data, auth=(self.__admin_account, self.__admin_pass))
|
||||
response = self.__api_request(endpoint, data)
|
||||
|
||||
is_unregistered = response.ok
|
||||
|
||||
|
@ -119,9 +143,9 @@ class Ejabberd:
|
|||
"name": name
|
||||
}
|
||||
|
||||
API_ENDPOINT = self.__api_base_url + '/api/stats?'
|
||||
endpoint = self.__api_base_url + '/api/stats?'
|
||||
|
||||
response = requests.post(url = API_ENDPOINT, json = data, auth=(self.__admin_account, self.__admin_pass))
|
||||
response = self.__api_request(endpoint, data)
|
||||
|
||||
result = response.json()['stat']
|
||||
|
||||
|
@ -136,14 +160,73 @@ class Ejabberd:
|
|||
data = {
|
||||
}
|
||||
|
||||
API_ENDPOINT = self.__api_base_url + '/api/status?'
|
||||
endpoint = self.__api_base_url + '/api/status?'
|
||||
|
||||
response = requests.post(url = API_ENDPOINT, json = data, auth=(self.__admin_account, self.__admin_pass))
|
||||
response = self.__api_request(endpoint, data)
|
||||
|
||||
result = response.json()
|
||||
|
||||
return result
|
||||
|
||||
def __api_request(self, endpoint, data):
|
||||
|
||||
try:
|
||||
|
||||
response = requests.post(url = endpoint, json = data, auth=(self._Ejabberd__admin_account, self._Ejabberd__admin_pass))
|
||||
|
||||
except Exception as e:
|
||||
|
||||
raise EjabberdNetworkError(f"Could not complete request: {e}")
|
||||
|
||||
if response is None:
|
||||
|
||||
raise EjabberdIllegalArgumentError("Illegal request.")
|
||||
|
||||
if not response.ok:
|
||||
|
||||
try:
|
||||
if isinstance(response, dict) and 'error' in response:
|
||||
error_msg = response['error']
|
||||
elif isinstance(response, str):
|
||||
error_msg = response
|
||||
else:
|
||||
error_msg = None
|
||||
except ValueError:
|
||||
error_msg = None
|
||||
|
||||
if response.status_code == 404:
|
||||
ex_type = EjabberdNotFoundError
|
||||
if not error_msg:
|
||||
error_msg = 'Endpoint not found.'
|
||||
# this is for compatibility with older versions
|
||||
# which raised EjabberdAPIError('Endpoint not found.')
|
||||
# on any 404
|
||||
elif response.status_code == 401:
|
||||
ex_type = EjabberdUnauthorizedError
|
||||
elif response.status_code == 500:
|
||||
ex_type = EjabberdInternalServerError
|
||||
elif response.status_code == 502:
|
||||
ex_type = EjabberdBadGatewayError
|
||||
elif response.status_code == 503:
|
||||
ex_type = EjabberdServiceUnavailableError
|
||||
elif response.status_code == 504:
|
||||
ex_type = EjabberdGatewayTimeoutError
|
||||
elif response.status_code >= 500 and \
|
||||
response.status_code <= 511:
|
||||
ex_type = EjabberdServerError
|
||||
else:
|
||||
ex_type = EjabberdAPIError
|
||||
|
||||
raise ex_type(
|
||||
'Ejabberd API returned error',
|
||||
response.status_code,
|
||||
response.reason,
|
||||
error_msg)
|
||||
|
||||
else:
|
||||
|
||||
return response
|
||||
|
||||
@staticmethod
|
||||
def __check_setup(self):
|
||||
|
||||
|
@ -197,3 +280,47 @@ class Ejabberd:
|
|||
if isinstance(json_object, dict):
|
||||
return AttribAccessDict(json_object)
|
||||
return json_object
|
||||
##
|
||||
# Exceptions
|
||||
##
|
||||
class EjabberdError(Exception):
|
||||
"""Base class for Mastodon.py exceptions"""
|
||||
|
||||
class EjabberdIOError(IOError, EjabberdError):
|
||||
"""Base class for Mastodon.py I/O errors"""
|
||||
|
||||
class EjabberdNetworkError(EjabberdIOError):
|
||||
"""Raised when network communication with the server fails"""
|
||||
pass
|
||||
class EjabberdAPIError(EjabberdError):
|
||||
"""Raised when the mastodon API generates a response that cannot be handled"""
|
||||
pass
|
||||
class EjabberdServerError(EjabberdAPIError):
|
||||
"""Raised if the Server is malconfigured and returns a 5xx error code"""
|
||||
pass
|
||||
class EjabberdInternalServerError(EjabberdServerError):
|
||||
"""Raised if the Server returns a 500 error"""
|
||||
pass
|
||||
|
||||
class EjabberdBadGatewayError(EjabberdServerError):
|
||||
"""Raised if the Server returns a 502 error"""
|
||||
pass
|
||||
|
||||
class EjabberdServiceUnavailableError(EjabberdServerError):
|
||||
"""Raised if the Server returns a 503 error"""
|
||||
pass
|
||||
|
||||
class EjabberdGatewayTimeoutError(EjabberdServerError):
|
||||
"""Raised if the Server returns a 504 error"""
|
||||
pass
|
||||
class EjabberdNotFoundError(EjabberdAPIError):
|
||||
"""Raised when the ejabberd API returns a 404 Not Found error"""
|
||||
pass
|
||||
|
||||
class EjabberdUnauthorizedError(EjabberdAPIError):
|
||||
"""Raised when the ejabberd API returns a 401 Unauthorized error
|
||||
|
||||
This happens when an OAuth token is invalid or has been revoked,
|
||||
or when trying to access an endpoint that can't be used without
|
||||
authentication without providing credentials."""
|
||||
pass
|
||||
|
|
12
xmpp.py
12
xmpp.py
|
@ -13,9 +13,9 @@ if __name__ == '__main__':
|
|||
|
||||
notifications = bot.akkoma.notifications()
|
||||
|
||||
except:
|
||||
except bot.akkoma.AkkomaNetworkError as net_error:
|
||||
|
||||
pass
|
||||
sys.exit(net_error)
|
||||
|
||||
for notif in notifications:
|
||||
|
||||
|
@ -33,6 +33,10 @@ if __name__ == '__main__':
|
|||
|
||||
if mention.question == bot.register_str:
|
||||
|
||||
account_exists = ejabberd.check_account(mention.acct, bot.akkoma_hostname)
|
||||
|
||||
if not account_exists:
|
||||
|
||||
password = ejabberd.generate_pass()
|
||||
|
||||
is_registered, text = ejabberd.register(mention.acct, bot.akkoma_hostname, password)
|
||||
|
@ -49,6 +53,10 @@ if __name__ == '__main__':
|
|||
|
||||
bot.akkoma.status_post(f'@{mention.acct}, {text}', in_reply_to_id=mention.status_id, visibility='direct')
|
||||
|
||||
else:
|
||||
|
||||
bot.akkoma.status_post(f'@{mention.acct}, {bot.account_exists_str}', in_reply_to_id=mention.status_id, visibility='direct')
|
||||
|
||||
elif mention.question == bot.unregister_str:
|
||||
|
||||
is_unregistered, is_admin = ejabberd.unregister(mention.acct, bot.akkoma_hostname)
|
||||
|
|
Loading…
Referencia en una nova incidència