Implement and document first half of admin API

This commit is contained in:
Lorenz Diener 2019-06-22 20:59:53 +02:00
pare a88492bdcf
commit de9155b9f5
S'han modificat 2 arxius amb 226 adicions i 5 eliminacions

Veure arxiu

@ -263,6 +263,8 @@ User dicts
# set up as their moved-to address.
'bot': # Boolean indicating whether this account is automated.
'fields': # List of up to four dicts with free-form 'name' and 'value' profile info.
# For fields with "this is me" type verification, verified_at is set to the
# last verification date (It is None otherwise)
}
mastodon.account_verify_credentials()["source"]
@ -739,6 +741,30 @@ Preference dicts
# content warnings by default
}
Admin account dicts
~~~~~~~~~~~~~~~~~~~
.. _admin account dicts:
.. code-block:: python
{
'id': # The users id,
'username': # The users username, no leading @
'domain': # The users domain
'created_at': # The time of account creation
'email': # For local users, the users e-mail
'ip': # For local users, the users last known IP address
'role': # 'admin', 'moderator' or None
'confirmed': # For local users, False if the user has not confirmed their e-mail, True otherwise
'suspended': # Boolean indicating whether the user has been suspended
'silenced': # Boolean indicating whether the user has been suspended
'disabled': # For local users, boolean indicating whether the user has had their login disabled
'approved': # For local users, False if the user is pending, True otherwise
'locale': # For local users, the locale the user has set,
'invite_request': # If the user requested an invite, the invite request comment of that user. (TODO permanent?)
'invited_by_account_id': # Present if the user was invited by another user and set to the inviting users id.
'account': # The users account, as a standard account dict
}
App registration and user authentication
----------------------------------------
Before you can use the mastodon API, you have to register your
@ -1149,6 +1175,33 @@ All crypto utilities require Mastodon.pys optional "webpush" feature dependencie
.. automethod:: Mastodon.push_subscription_generate_keys
.. automethod:: Mastodon.push_subscription_decrypt_push
Moderation API
--------------
These functions allow you to perform moderation actions on users and generally
process reports using the API. To do this, you need access to the "admin:read" and/or
"admin:write" scopes or their more granular variants (both for the application and the
access token), as well as at least moderator access. Mastodon.py will not request these
by default, as that would be very dangerous.
BIG WARNING: TREAT ANY ACCESS TOKENS THAT HAVE ADMIN CREDENTIALS AS EXTREMELY, MASSIVELY
SENSITIVE DATA AND MAKE EXTRA SURE TO REVOKE THEM AFTER TESTING, NOT LET THEM SIT IN FILES
SOMEWHERE, TRACK WHICH ARE ACTIVE, ET CETERA. ANY EXPOSURE OF SUCH ACCESS TOKENS MEANS YOU
EXPOSE THE PERSONAL DATA OF ALL YOUR USERS TO WHOEVER HAS THESE TOKENS. TREAT THEM WITH
EXTREME CARE.
This is not to say that you should not treat access tokens from admin accounts that do not
have admin: scopes attached with a lot of care, but be extra careful with those that do.
.. automethod:: Mastodon.admin_accounts
.. automethod:: Mastodon.admin_account
.. automethod:: Mastodon.admin_account_enable
.. automethod:: Mastodon.admin_account_approve
.. automethod:: Mastodon.admin_account_reject
.. automethod:: Mastodon.admin_account_unsilence
.. automethod:: Mastodon.admin_account_unsuspend
.. automethod:: Mastodon.admin_account_moderate
Acknowledgements
----------------
Mastodon.py contains work by a large amount of contributors, many of which have

Veure arxiu

@ -167,11 +167,20 @@ class Mastodon:
'write:blocks',
'write:follows',
'write:mutes',
]
],
'admin:read': [
'admin:read:accounts',
'admin:read:reports',
],
'admin:write': [
'admin:write:accounts',
'admin:write:reports',
],
}
__VALID_SCOPES = ['read', 'write', 'follow', 'push'] + __SCOPE_SETS['read'] + __SCOPE_SETS['write']
__VALID_SCOPES = ['read', 'write', 'follow', 'push', 'admin:read', 'admin:write'] + \
__SCOPE_SETS['read'] + __SCOPE_SETS['write'] + __SCOPE_SETS['admin:read'] + __SCOPE_SETS['admin:write']
__SUPPORTED_MASTODON_VERSION = "2.8.4"
__SUPPORTED_MASTODON_VERSION = "2.9.2"
# Dict versions
__DICT_VERSION_APPLICATION = "2.7.2"
@ -593,7 +602,7 @@ class Mastodon:
Activity is returned for 12 weeks going back from the current week.
Returns a list `activity dicts`_.
Returns a list of `activity dicts`_.
"""
return self.__api_request('GET', '/api/v1/instance/activity')
@ -2318,7 +2327,166 @@ class Mastodon:
"""
self.__api_request('DELETE', '/api/v1/push/subscription')
###
# Moderation API
###
@api_version("2.9.1", "2.9.1", "2.9.1")
def admin_accounts(self, remote=False, by_domain=None, status='active', username=None, display_name=None, email=None, ip=None, staff_only=False, max_id=None, min_id=None, since_id=None, limit=None):
"""
Fetches a list of accounts that match given criteria. By default, local accounts are returned.
Set `remote` to True to get remote accounts, otherwise local accounts are returned (default: local accounts)
Set `by_domain` to a domain to get only accounts from that domain.
Set `status` to one of "active", "pending", "disabled", "silenced" or "suspended" to get only accounts with that moderation status (default: active)
Set `username` to a string to get only accounts whose username contains this string.
Set `display_name` to a string to get only accounts whose display name contains this string.
Set `email` to an email to get only accounts with that email (this only works on local accounts).
Set `ip` to an ip (as a string, standard v4/v6 notation) to get only accounts whose last active ip is that ip (this only works on local accounts).
Set `staff_only` to True to only get staff accounts (this only works on local accounts).
Note that setting the boolean parameters to False does not mean "give me users to which this does not apply" but
instead means "I do not care if users have this attribute".
Returns a list of `admin account dicts`_.
"""
if max_id != None:
max_id = self.__unpack_id(max_id)
if min_id != None:
min_id = self.__unpack_id(min_id)
if since_id != None:
since_id = self.__unpack_id(since_id)
params = self.__generate_params(locals(), ['remote', 'status', 'staff_only'])
if remote == True:
params["remote"] = True
mod_statuses = ["active", "pending", "disabled", "silenced", "suspended"]
if not status in mod_statuses:
raise ValueError("Invalid moderation status requested.")
if staff_only == True:
params["staff"] = True
for mod_status in mod_statuses:
if status == mod_status:
params[status] = True
return self.__api_request('GET', '/api/v1/admin/accounts', params)
def admin_account(self, id):
"""
Fetches a single `admin account dict`_ for the user with the given id.
Returns that dict.
"""
id = self.__unpack_id(id)
return self.__api_request('GET', '/api/v1/admin/accounts/{0}'.format(id))
def admin_account_enable(self, id):
"""
Reenables login for a local account for which login has been disabled.
Returns the updated `admin account dict`_.
"""
id = self.__unpack_id(id)
return self.__api_request('POST', '/api/v1/admin/accounts/{0}/enable'.format(id))
def admin_account_approve(self, id):
"""
Approves a pending account.
Returns the updated `admin account dict`_.
"""
id = self.__unpack_id(id)
return self.__api_request('POST', '/api/v1/admin/accounts/{0}/approve'.format(id))
def admin_account_reject(self, id):
"""
Rejects and deletes a pending account.
Returns the updated `admin account dict`_ for the account that is now gone.
"""
id = self.__unpack_id(id)
return self.__api_request('POST', '/api/v1/admin/accounts/{0}/reject'.format(id))
def admin_account_unsilence(self, id):
"""
Unsilences an account.
Returns the updated `admin account dict`_.
"""
id = self.__unpack_id(id)
return self.__api_request('POST', '/api/v1/admin/accounts/{0}/unsilence'.format(id))
def admin_account_unsuspend(self, id):
"""
Unsuspends an account.
Returns the updated `admin account dict`_.
"""
id = self.__unpack_id(id)
return self.__api_request('POST', '/api/v1/admin/accounts/{0}/unsuspend'.format(id))
def admin_account_moderate(self, id, action=None, report_id=None, warning_preset_id=None, text=None, send_email_notification=True):
"""
Perform a moderation action on an account.
Valid actions are:
* "disable" - for a local user, disable login.
* "silence" - hide the users posts from all public timelines.
* "suspend" - irreversibly delete all the users posts, past and future.
If no action is specified, the user is only issued a warning.
Specify the id of a report as `report_id` to close the report with this moderation action as the resolution.
Specify `warning_preset_id` to use a warning preset as the notification text to the user, or `text` to specify text directly.
If both are specified, they are concatenated (preset first). Note that there is currently no API to retrieve or create
warning presets.
Set `send_email_notification` to False to not send the user an e-mail notification informing them of the moderation action.
"""
if action is None:
action = "none"
if send_email_notification == False:
send_email_notification = None
id = self.__unpack_id(id)
if not report_id is None:
report_id = self.__unpack_id(report_id)
params = self.__generate_params(locals(), ['id', 'action'])
params["type"] = action
self.__api_request('POST', '/api/v1/admin/accounts/{0}/action'.format(id), params)
def admin_reports(self, resolved, account_id, target_account_id):
pass
#GET /api/v1/admin/reports Get reports, with params resolved, account_id, target_account_id
def admin_report(self, id):
pass
#GET /api/v1/admin/reports/:id Get a specific report
def admin_report_assign(self, id):
pass
#POST /api/v1/admin/reports/:id/assign_to_self Assign report to self
def admin_report_unassign(self, id):
pass
#POST /api/v1/admin/reports/:id/unassign Unassign report from self
def admin_report_reopen(self, id):
pass
#POST /api/v1/admin/reports/:id/reopen Re-open report
def admin_report_resolve(self, id):
pass
#POST /api/v1/admin/reports/:id/resolve Close report
###
# Push subscription crypto utilities
###