kopia lustrzana https://github.com/halcy/Mastodon.py
add ability to get detailed signup error from create_account
rodzic
f26bf0db1d
commit
853cd82ecb
|
@ -8,6 +8,7 @@ v1.6.3
|
||||||
* Add confirmation email resend API (`email_resend_confirmation`)
|
* Add confirmation email resend API (`email_resend_confirmation`)
|
||||||
* Add account lookup API (`account_lookup`)
|
* Add account lookup API (`account_lookup`)
|
||||||
* Add `policy` param to control notification sources for `push_subscription_set`
|
* Add `policy` param to control notification sources for `push_subscription_set`
|
||||||
|
* Add ability to get detailed signup error to `create_account`
|
||||||
|
|
||||||
v1.6.2
|
v1.6.2
|
||||||
------
|
------
|
||||||
|
|
2
TODO.md
2
TODO.md
|
@ -33,7 +33,7 @@ Refer to mastodon changelog and API docs for details when implementing, add or m
|
||||||
* [x] Add POST /api/v1/emails/confirmations to REST API
|
* [x] Add POST /api/v1/emails/confirmations to REST API
|
||||||
* [x] Add GET /api/v1/accounts/lookup to REST API
|
* [x] Add GET /api/v1/accounts/lookup to REST API
|
||||||
* [x] Add policy param to POST /api/v1/push/subscriptions in REST API
|
* [x] Add policy param to POST /api/v1/push/subscriptions in REST API
|
||||||
* [ ] Add details to error response for POST /api/v1/accounts in REST API
|
* [x] Add details to error response for POST /api/v1/accounts in REST API
|
||||||
|
|
||||||
3.4.2
|
3.4.2
|
||||||
-----
|
-----
|
||||||
|
|
|
@ -605,8 +605,7 @@ class Mastodon:
|
||||||
params['scope'] = " ".join(scopes)
|
params['scope'] = " ".join(scopes)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = self.__api_request(
|
response = self.__api_request('POST', '/oauth/token', params, do_ratelimiting=False)
|
||||||
'POST', '/oauth/token', params, do_ratelimiting=False)
|
|
||||||
self.access_token = response['access_token']
|
self.access_token = response['access_token']
|
||||||
self.__set_refresh_token(response.get('refresh_token'))
|
self.__set_refresh_token(response.get('refresh_token'))
|
||||||
self.__set_token_expired(int(response.get('expires_in', 0)))
|
self.__set_token_expired(int(response.get('expires_in', 0)))
|
||||||
|
@ -658,8 +657,8 @@ class Mastodon:
|
||||||
self.access_token = None
|
self.access_token = None
|
||||||
self.__logged_in_id = None
|
self.__logged_in_id = None
|
||||||
|
|
||||||
@api_version("2.7.0", "2.7.0", "2.7.0")
|
@api_version("2.7.0", "2.7.0", "3.4.0")
|
||||||
def create_account(self, username, password, email, agreement=False, reason=None, locale="en", scopes=__DEFAULT_SCOPES, to_file=None):
|
def create_account(self, username, password, email, agreement=False, reason=None, locale="en", scopes=__DEFAULT_SCOPES, to_file=None, return_detailed_error=False):
|
||||||
"""
|
"""
|
||||||
Creates a new user account with the given username, password and email. "agreement"
|
Creates a new user account with the given username, password and email. "agreement"
|
||||||
must be set to true (after showing the user the instance's user agreement and having
|
must be set to true (after showing the user the instance's user agreement and having
|
||||||
|
@ -674,6 +673,26 @@ class Mastodon:
|
||||||
Returns an access token (just like log_in), which it can also persist to to_file,
|
Returns an access token (just like log_in), which it can also persist to to_file,
|
||||||
and sets it internally so that the user is now logged in. Note that this token
|
and sets it internally so that the user is now logged in. Note that this token
|
||||||
can only be used after the user has confirmed their email.
|
can only be used after the user has confirmed their email.
|
||||||
|
|
||||||
|
By default, the function will throw if the account could not be created. Alternately,
|
||||||
|
when `return_detailed_error` is passed, Mastodon.py will return the detailed error
|
||||||
|
response that the API provides (Starting from version 3.4.0 - not checked here) as an dict with
|
||||||
|
error details as the second return value and the token returned as `None` in case of error.
|
||||||
|
The dict will contain a text `error` values as well as a `details` value which is a dict with
|
||||||
|
one optional key for each potential field (`username`, `password`, `email` and `agreement`),
|
||||||
|
each if present containing a dict with an `error` category and free text `description`.
|
||||||
|
Valid error categories are:
|
||||||
|
|
||||||
|
* ERR_BLOCKED - When e-mail provider is not allowed
|
||||||
|
* ERR_UNREACHABLE - When e-mail address does not resolve to any IP via DNS (MX, A, AAAA)
|
||||||
|
* ERR_TAKEN - When username or e-mail are already taken
|
||||||
|
* ERR_RESERVED - When a username is reserved, e.g. "webmaster" or "admin"
|
||||||
|
* ERR_ACCEPTED - When agreement has not been accepted
|
||||||
|
* ERR_BLANK - When a required attribute is blank
|
||||||
|
* ERR_INVALID - When an attribute is malformed, e.g. wrong characters or invalid e-mail address
|
||||||
|
* ERR_TOO_LONG - When an attribute is over the character limit
|
||||||
|
* ERR_TOO_SHORT - When an attribute is under the character requirement
|
||||||
|
* ERR_INCLUSION - When an attribute is not one of the allowed values, e.g. unsupported locale
|
||||||
"""
|
"""
|
||||||
params = self.__generate_params(locals(), ['to_file', 'scopes'])
|
params = self.__generate_params(locals(), ['to_file', 'scopes'])
|
||||||
params['client_id'] = self.client_id
|
params['client_id'] = self.client_id
|
||||||
|
@ -690,8 +709,7 @@ class Mastodon:
|
||||||
oauth_params['client_secret'] = self.client_secret
|
oauth_params['client_secret'] = self.client_secret
|
||||||
oauth_params['grant_type'] = 'client_credentials'
|
oauth_params['grant_type'] = 'client_credentials'
|
||||||
|
|
||||||
response = self.__api_request(
|
response = self.__api_request('POST', '/oauth/token', oauth_params, do_ratelimiting=False)
|
||||||
'POST', '/oauth/token', oauth_params, do_ratelimiting=False)
|
|
||||||
temp_access_token = response['access_token']
|
temp_access_token = response['access_token']
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MastodonIllegalArgumentError(
|
raise MastodonIllegalArgumentError(
|
||||||
|
@ -699,13 +717,16 @@ class Mastodon:
|
||||||
|
|
||||||
# Step 2: Use that to create a user
|
# Step 2: Use that to create a user
|
||||||
try:
|
try:
|
||||||
response = self.__api_request('POST', '/api/v1/accounts', params, do_ratelimiting=False,
|
response = self.__api_request('POST', '/api/v1/accounts', params, do_ratelimiting=False, access_token_override=temp_access_token, skip_error_check=True)
|
||||||
access_token_override=temp_access_token)
|
if "error" in response:
|
||||||
|
if return_detailed_error:
|
||||||
|
return None, response
|
||||||
|
raise MastodonIllegalArgumentError('Invalid request: %s' % e)
|
||||||
self.access_token = response['access_token']
|
self.access_token = response['access_token']
|
||||||
self.__set_refresh_token(response.get('refresh_token'))
|
self.__set_refresh_token(response.get('refresh_token'))
|
||||||
self.__set_token_expired(int(response.get('expires_in', 0)))
|
self.__set_token_expired(int(response.get('expires_in', 0)))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MastodonIllegalArgumentError('Invalid request: %s' % e)
|
raise MastodonIllegalArgumentError('Invalid request')
|
||||||
|
|
||||||
# Step 3: Check scopes, persist, et cetera
|
# Step 3: Check scopes, persist, et cetera
|
||||||
received_scopes = response["scope"].split(" ")
|
received_scopes = response["scope"].split(" ")
|
||||||
|
@ -714,8 +735,7 @@ class Mastodon:
|
||||||
received_scopes += self.__SCOPE_SETS[scope_set]
|
received_scopes += self.__SCOPE_SETS[scope_set]
|
||||||
|
|
||||||
if not set(scopes) <= set(received_scopes):
|
if not set(scopes) <= set(received_scopes):
|
||||||
raise MastodonAPIError(
|
raise MastodonAPIError('Granted scopes "' + " ".join(received_scopes) + '" do not contain all of the requested scopes "' + " ".join(scopes) + '".')
|
||||||
'Granted scopes "' + " ".join(received_scopes) + '" do not contain all of the requested scopes "' + " ".join(scopes) + '".')
|
|
||||||
|
|
||||||
if to_file is not None:
|
if to_file is not None:
|
||||||
with open(to_file, 'w') as token_file:
|
with open(to_file, 'w') as token_file:
|
||||||
|
@ -724,7 +744,10 @@ class Mastodon:
|
||||||
|
|
||||||
self.__logged_in_id = None
|
self.__logged_in_id = None
|
||||||
|
|
||||||
return response['access_token']
|
if return_detailed_error:
|
||||||
|
return response['access_token'], {}
|
||||||
|
else:
|
||||||
|
return response['access_token']
|
||||||
|
|
||||||
@api_version("3.4.0", "3.4.0", "3.4.0")
|
@api_version("3.4.0", "3.4.0", "3.4.0")
|
||||||
def email_resend_confirmation(self):
|
def email_resend_confirmation(self):
|
||||||
|
@ -2775,7 +2798,7 @@ class Mastodon:
|
||||||
"""
|
"""
|
||||||
if not policy in ['all', 'none', 'follower', 'followed']:
|
if not policy in ['all', 'none', 'follower', 'followed']:
|
||||||
raise MastodonIllegalArgumentError("Valid values for policy are 'all', 'none', 'follower' or 'followed'.")
|
raise MastodonIllegalArgumentError("Valid values for policy are 'all', 'none', 'follower' or 'followed'.")
|
||||||
|
|
||||||
endpoint = Mastodon.__protocolize(endpoint)
|
endpoint = Mastodon.__protocolize(endpoint)
|
||||||
|
|
||||||
push_pubkey_b64 = base64.b64encode(encrypt_params['pubkey'])
|
push_pubkey_b64 = base64.b64encode(encrypt_params['pubkey'])
|
||||||
|
@ -3506,7 +3529,7 @@ class Mastodon:
|
||||||
isotime = isotime[:-2] + ":" + isotime[-2:]
|
isotime = isotime[:-2] + ":" + isotime[-2:]
|
||||||
return isotime
|
return isotime
|
||||||
|
|
||||||
def __api_request(self, method, endpoint, params={}, files={}, headers={}, access_token_override=None, base_url_override=None, do_ratelimiting=True, use_json=False, parse=True, return_response_object=False):
|
def __api_request(self, method, endpoint, params={}, files={}, headers={}, access_token_override=None, base_url_override=None, do_ratelimiting=True, use_json=False, parse=True, return_response_object=False, skip_error_check=False):
|
||||||
"""
|
"""
|
||||||
Internal API request helper.
|
Internal API request helper.
|
||||||
"""
|
"""
|
||||||
|
@ -3657,35 +3680,32 @@ class Mastodon:
|
||||||
time.sleep(to_next)
|
time.sleep(to_next)
|
||||||
request_complete = False
|
request_complete = False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if skip_error_check == False:
|
||||||
|
if response_object.status_code == 404:
|
||||||
|
ex_type = MastodonNotFoundError
|
||||||
|
if not error_msg:
|
||||||
|
error_msg = 'Endpoint not found.'
|
||||||
|
# this is for compatibility with older versions
|
||||||
|
# which raised MastodonAPIError('Endpoint not found.')
|
||||||
|
# on any 404
|
||||||
|
elif response_object.status_code == 401:
|
||||||
|
ex_type = MastodonUnauthorizedError
|
||||||
|
elif response_object.status_code == 500:
|
||||||
|
ex_type = MastodonInternalServerError
|
||||||
|
elif response_object.status_code == 502:
|
||||||
|
ex_type = MastodonBadGatewayError
|
||||||
|
elif response_object.status_code == 503:
|
||||||
|
ex_type = MastodonServiceUnavailableError
|
||||||
|
elif response_object.status_code == 504:
|
||||||
|
ex_type = MastodonGatewayTimeoutError
|
||||||
|
elif response_object.status_code >= 500 and \
|
||||||
|
response_object.status_code <= 511:
|
||||||
|
ex_type = MastodonServerError
|
||||||
|
else:
|
||||||
|
ex_type = MastodonAPIError
|
||||||
|
|
||||||
if response_object.status_code == 404:
|
raise ex_type('Mastodon API returned error', response_object.status_code, response_object.reason, error_msg)
|
||||||
ex_type = MastodonNotFoundError
|
|
||||||
if not error_msg:
|
|
||||||
error_msg = 'Endpoint not found.'
|
|
||||||
# this is for compatibility with older versions
|
|
||||||
# which raised MastodonAPIError('Endpoint not found.')
|
|
||||||
# on any 404
|
|
||||||
elif response_object.status_code == 401:
|
|
||||||
ex_type = MastodonUnauthorizedError
|
|
||||||
elif response_object.status_code == 500:
|
|
||||||
ex_type = MastodonInternalServerError
|
|
||||||
elif response_object.status_code == 502:
|
|
||||||
ex_type = MastodonBadGatewayError
|
|
||||||
elif response_object.status_code == 503:
|
|
||||||
ex_type = MastodonServiceUnavailableError
|
|
||||||
elif response_object.status_code == 504:
|
|
||||||
ex_type = MastodonGatewayTimeoutError
|
|
||||||
elif response_object.status_code >= 500 and \
|
|
||||||
response_object.status_code <= 511:
|
|
||||||
ex_type = MastodonServerError
|
|
||||||
else:
|
|
||||||
ex_type = MastodonAPIError
|
|
||||||
|
|
||||||
raise ex_type(
|
|
||||||
'Mastodon API returned error',
|
|
||||||
response_object.status_code,
|
|
||||||
response_object.reason,
|
|
||||||
error_msg)
|
|
||||||
|
|
||||||
if return_response_object:
|
if return_response_object:
|
||||||
return response_object
|
return response_object
|
||||||
|
|
|
@ -0,0 +1,245 @@
|
||||||
|
interactions:
|
||||||
|
- request:
|
||||||
|
body: client_name=mastodon.py+generated+test+app&scopes=read+write+follow+push&redirect_uris=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob
|
||||||
|
headers:
|
||||||
|
Accept:
|
||||||
|
- '*/*'
|
||||||
|
Accept-Encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
Content-Length:
|
||||||
|
- '122'
|
||||||
|
Content-Type:
|
||||||
|
- application/x-www-form-urlencoded
|
||||||
|
User-Agent:
|
||||||
|
- python-requests/2.28.1
|
||||||
|
method: POST
|
||||||
|
uri: http://localhost:3000/api/v1/apps
|
||||||
|
response:
|
||||||
|
body:
|
||||||
|
string: '{"id":"4","name":"mastodon.py generated test app","website":null,"redirect_uri":"urn:ietf:wg:oauth:2.0:oob","client_id":"OueO_7-PGuI_wJwqr3gJCO3Mfp-CnB7ntLm2BDNgwoE","client_secret":"i74hCQQyscpk-AoXt8gL1lBYLlgsQw7r-vP_cuKWquA","vapid_key":"BFu6DBpfcm8_h8gm3rHUkfaOLg7azvYN_auFI4KcNuh5SLBVMhTkKKvUaLENtA_c6v5Hmrucvh0WwsN1o9NFQRU="}'
|
||||||
|
headers:
|
||||||
|
Cache-Control:
|
||||||
|
- no-store
|
||||||
|
Content-Security-Policy:
|
||||||
|
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
||||||
|
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
||||||
|
style-src ''self'' http://localhost:3000 ''nonce-eWGkzakxkoJqETI+J7AOfA=='';
|
||||||
|
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
||||||
|
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
||||||
|
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
||||||
|
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
||||||
|
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
||||||
|
worker-src ''self'' blob: http://localhost:3000'
|
||||||
|
Content-Type:
|
||||||
|
- application/json; charset=utf-8
|
||||||
|
ETag:
|
||||||
|
- W/"e57c57d0ecbadb4122581beb6057bf7b"
|
||||||
|
Referrer-Policy:
|
||||||
|
- strict-origin-when-cross-origin
|
||||||
|
Transfer-Encoding:
|
||||||
|
- chunked
|
||||||
|
Vary:
|
||||||
|
- Accept, Origin
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
X-Request-Id:
|
||||||
|
- c5d33842-2156-4850-ac91-154f71f72d2e
|
||||||
|
X-Runtime:
|
||||||
|
- '0.017495'
|
||||||
|
X-XSS-Protection:
|
||||||
|
- 1; mode=block
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: OK
|
||||||
|
- request:
|
||||||
|
body: null
|
||||||
|
headers:
|
||||||
|
Accept:
|
||||||
|
- '*/*'
|
||||||
|
Accept-Encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
User-Agent:
|
||||||
|
- mastodonpy
|
||||||
|
method: GET
|
||||||
|
uri: http://localhost:3000/api/v1/instance/
|
||||||
|
response:
|
||||||
|
body:
|
||||||
|
string: '{"uri":"localhost:3000","title":"Mastodon","short_description":"","description":"","email":"","version":"4.0.0rc2","urls":{"streaming_api":"ws://localhost:4000"},"stats":{"user_count":4,"status_count":5,"domain_count":0},"thumbnail":"http://localhost:3000/packs/media/images/preview-6399aebd96ccf025654e2977454f168f.png","languages":["en"],"registrations":true,"approval_required":false,"invites_enabled":true,"configuration":{"accounts":{"max_featured_tags":10},"statuses":{"max_characters":500,"max_media_attachments":4,"characters_reserved_per_url":23},"media_attachments":{"supported_mime_types":["image/jpeg","image/png","image/gif","image/heic","image/heif","image/webp","image/avif","video/webm","video/mp4","video/quicktime","video/ogg","audio/wave","audio/wav","audio/x-wav","audio/x-pn-wave","audio/vnd.wave","audio/ogg","audio/vorbis","audio/mpeg","audio/mp3","audio/webm","audio/flac","audio/aac","audio/m4a","audio/x-m4a","audio/mp4","audio/3gpp","video/x-ms-asf"],"image_size_limit":10485760,"image_matrix_limit":16777216,"video_size_limit":41943040,"video_frame_rate_limit":60,"video_matrix_limit":2304000},"polls":{"max_options":4,"max_characters_per_option":50,"min_expiration":300,"max_expiration":2629746}},"contact_account":null,"rules":[]}'
|
||||||
|
headers:
|
||||||
|
Cache-Control:
|
||||||
|
- max-age=180, public
|
||||||
|
Content-Security-Policy:
|
||||||
|
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
||||||
|
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
||||||
|
style-src ''self'' http://localhost:3000 ''nonce-pTVYgmBqNUhkaog/3BIWrg=='';
|
||||||
|
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
||||||
|
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
||||||
|
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
||||||
|
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
||||||
|
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
||||||
|
worker-src ''self'' blob: http://localhost:3000'
|
||||||
|
Content-Type:
|
||||||
|
- application/json; charset=utf-8
|
||||||
|
Date:
|
||||||
|
- Sat, 19 Nov 2022 00:05:11 GMT
|
||||||
|
ETag:
|
||||||
|
- W/"58e74f5c697f043d86089eae87509b84"
|
||||||
|
Referrer-Policy:
|
||||||
|
- strict-origin-when-cross-origin
|
||||||
|
Transfer-Encoding:
|
||||||
|
- chunked
|
||||||
|
Vary:
|
||||||
|
- Accept, Origin
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
X-Request-Id:
|
||||||
|
- 3f3580e9-a01c-4cb3-a8ff-e933a5b0a878
|
||||||
|
X-Runtime:
|
||||||
|
- '0.038202'
|
||||||
|
X-XSS-Protection:
|
||||||
|
- 1; mode=block
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: OK
|
||||||
|
- request:
|
||||||
|
body: scope=read+write+follow+push&client_id=OueO_7-PGuI_wJwqr3gJCO3Mfp-CnB7ntLm2BDNgwoE&client_secret=i74hCQQyscpk-AoXt8gL1lBYLlgsQw7r-vP_cuKWquA&grant_type=client_credentials
|
||||||
|
headers:
|
||||||
|
Accept:
|
||||||
|
- '*/*'
|
||||||
|
Accept-Encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
Content-Length:
|
||||||
|
- '170'
|
||||||
|
Content-Type:
|
||||||
|
- application/x-www-form-urlencoded
|
||||||
|
User-Agent:
|
||||||
|
- mastodonpy
|
||||||
|
method: POST
|
||||||
|
uri: http://localhost:3000/oauth/token
|
||||||
|
response:
|
||||||
|
body:
|
||||||
|
string: '{"access_token":"dDfMnIWbtYShiuOouwPaH1j8ZzGRdcg39Ns0nV5jXpo","token_type":"Bearer","scope":"read
|
||||||
|
write follow push","created_at":1668816311}'
|
||||||
|
headers:
|
||||||
|
Cache-Control:
|
||||||
|
- no-store
|
||||||
|
Content-Security-Policy:
|
||||||
|
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
||||||
|
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
||||||
|
style-src ''self'' http://localhost:3000 ''nonce-2oP2TTFLzbSaiZa7hgho0w=='';
|
||||||
|
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
||||||
|
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
||||||
|
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
||||||
|
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
||||||
|
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
||||||
|
worker-src ''self'' blob: http://localhost:3000'
|
||||||
|
Content-Type:
|
||||||
|
- application/json; charset=utf-8
|
||||||
|
ETag:
|
||||||
|
- W/"d29d21f6cdf89562d22826c8794a7259"
|
||||||
|
Pragma:
|
||||||
|
- no-cache
|
||||||
|
Referrer-Policy:
|
||||||
|
- strict-origin-when-cross-origin
|
||||||
|
Transfer-Encoding:
|
||||||
|
- chunked
|
||||||
|
Vary:
|
||||||
|
- Accept, Origin
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
X-Request-Id:
|
||||||
|
- 10f9efb8-85eb-4b30-ad16-9656fe53fd44
|
||||||
|
X-Runtime:
|
||||||
|
- '0.022478'
|
||||||
|
X-XSS-Protection:
|
||||||
|
- 1; mode=block
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: OK
|
||||||
|
- request:
|
||||||
|
body: username=coolguy73878&password=&email=email%40localhost73878&locale=en&client_id=OueO_7-PGuI_wJwqr3gJCO3Mfp-CnB7ntLm2BDNgwoE&client_secret=i74hCQQyscpk-AoXt8gL1lBYLlgsQw7r-vP_cuKWquA
|
||||||
|
headers:
|
||||||
|
Accept:
|
||||||
|
- '*/*'
|
||||||
|
Accept-Encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
Authorization:
|
||||||
|
- Bearer dDfMnIWbtYShiuOouwPaH1j8ZzGRdcg39Ns0nV5jXpo
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
Content-Length:
|
||||||
|
- '182'
|
||||||
|
Content-Type:
|
||||||
|
- application/x-www-form-urlencoded
|
||||||
|
User-Agent:
|
||||||
|
- mastodonpy
|
||||||
|
method: POST
|
||||||
|
uri: http://localhost:3000/api/v1/accounts
|
||||||
|
response:
|
||||||
|
body:
|
||||||
|
string: '{"error":"Validation failed: Password can''t be blank, Service agreement
|
||||||
|
must be accepted","details":{"password":[{"error":"ERR_BLANK","description":"can''t
|
||||||
|
be blank"}],"agreement":[{"error":"ERR_ACCEPTED","description":"must be accepted"}]}}'
|
||||||
|
headers:
|
||||||
|
Cache-Control:
|
||||||
|
- no-store
|
||||||
|
Content-Security-Policy:
|
||||||
|
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
||||||
|
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
||||||
|
style-src ''self'' http://localhost:3000 ''nonce-OtVYUk9hlx5v/TcbXUduUA=='';
|
||||||
|
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
||||||
|
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
||||||
|
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
||||||
|
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
||||||
|
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
||||||
|
worker-src ''self'' blob: http://localhost:3000'
|
||||||
|
Content-Type:
|
||||||
|
- application/json; charset=utf-8
|
||||||
|
Referrer-Policy:
|
||||||
|
- strict-origin-when-cross-origin
|
||||||
|
Transfer-Encoding:
|
||||||
|
- chunked
|
||||||
|
Vary:
|
||||||
|
- Accept, Origin
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
X-Request-Id:
|
||||||
|
- 48f3d7ec-0b4f-48ce-bf0c-acbec7479c71
|
||||||
|
X-Runtime:
|
||||||
|
- '0.561200'
|
||||||
|
X-XSS-Protection:
|
||||||
|
- 1; mode=block
|
||||||
|
status:
|
||||||
|
code: 422
|
||||||
|
message: Unprocessable Entity
|
||||||
|
version: 1
|
|
@ -1,122 +0,0 @@
|
||||||
interactions:
|
|
||||||
- request:
|
|
||||||
body: subscription%5Bendpoint%5D=https%3A%2F%2Fexample.com&subscription%5Bkeys%5D%5Bp256dh%5D=BKFO5w6Uf%2B%2F2wo89ovbphk5Zrb0mcAKjZrIyrX66f2IAijRtuXx4yK6J9hR%2FemKnF2DyQcyx7%2F4IGhKHBk0OTEk%3D&subscription%5Bkeys%5D%5Bauth%5D=6T8gVmd01DhQUbejRj%2Bxmg%3D%3D&policy=none&data%5Balerts%5D%5Bfollow%5D=1&data%5Balerts%5D%5Bfavourite%5D=1&data%5Balerts%5D%5Breblog%5D=1&data%5Balerts%5D%5Bmention%5D=1&data%5Balerts%5D%5Bpoll%5D=1&data%5Balerts%5D%5Bfollow_request%5D=1&data%5Balerts%5D%5Bstatus%5D=1
|
|
||||||
headers:
|
|
||||||
Accept:
|
|
||||||
- '*/*'
|
|
||||||
Accept-Encoding:
|
|
||||||
- gzip, deflate
|
|
||||||
Authorization:
|
|
||||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
|
||||||
Connection:
|
|
||||||
- keep-alive
|
|
||||||
Content-Length:
|
|
||||||
- '489'
|
|
||||||
Content-Type:
|
|
||||||
- application/x-www-form-urlencoded
|
|
||||||
User-Agent:
|
|
||||||
- tests/v311
|
|
||||||
method: POST
|
|
||||||
uri: http://localhost:3000/api/v1/push/subscription
|
|
||||||
response:
|
|
||||||
body:
|
|
||||||
string: '{"id":5,"endpoint":"https://example.com","alerts":{"mention":true,"status":true,"reblog":true,"follow":true,"follow_request":true,"favourite":true,"poll":true},"server_key":"BFu6DBpfcm8_h8gm3rHUkfaOLg7azvYN_auFI4KcNuh5SLBVMhTkKKvUaLENtA_c6v5Hmrucvh0WwsN1o9NFQRU="}'
|
|
||||||
headers:
|
|
||||||
Cache-Control:
|
|
||||||
- no-store
|
|
||||||
Content-Security-Policy:
|
|
||||||
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
|
||||||
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
|
||||||
style-src ''self'' http://localhost:3000 ''nonce-bz+9uelNbajqElylgkM2Gg=='';
|
|
||||||
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
|
||||||
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
|
||||||
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
|
||||||
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
|
||||||
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
|
||||||
worker-src ''self'' blob: http://localhost:3000'
|
|
||||||
Content-Type:
|
|
||||||
- application/json; charset=utf-8
|
|
||||||
ETag:
|
|
||||||
- W/"083c3b807a4d145ec452ffd03c768d76"
|
|
||||||
Referrer-Policy:
|
|
||||||
- strict-origin-when-cross-origin
|
|
||||||
Transfer-Encoding:
|
|
||||||
- chunked
|
|
||||||
Vary:
|
|
||||||
- Accept, Origin
|
|
||||||
X-Content-Type-Options:
|
|
||||||
- nosniff
|
|
||||||
X-Download-Options:
|
|
||||||
- noopen
|
|
||||||
X-Frame-Options:
|
|
||||||
- SAMEORIGIN
|
|
||||||
X-Permitted-Cross-Domain-Policies:
|
|
||||||
- none
|
|
||||||
X-Request-Id:
|
|
||||||
- abb4aec7-a93a-4a99-ba4c-5a290bbbf782
|
|
||||||
X-Runtime:
|
|
||||||
- '0.027761'
|
|
||||||
X-XSS-Protection:
|
|
||||||
- 1; mode=block
|
|
||||||
status:
|
|
||||||
code: 200
|
|
||||||
message: OK
|
|
||||||
- request:
|
|
||||||
body: null
|
|
||||||
headers:
|
|
||||||
Accept:
|
|
||||||
- '*/*'
|
|
||||||
Accept-Encoding:
|
|
||||||
- gzip, deflate
|
|
||||||
Authorization:
|
|
||||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
|
||||||
Connection:
|
|
||||||
- keep-alive
|
|
||||||
User-Agent:
|
|
||||||
- tests/v311
|
|
||||||
method: GET
|
|
||||||
uri: http://localhost:3000/api/v1/push/subscription
|
|
||||||
response:
|
|
||||||
body:
|
|
||||||
string: '{"id":5,"endpoint":"https://example.com","alerts":{"mention":true,"status":true,"reblog":true,"follow":true,"follow_request":true,"favourite":true,"poll":true},"server_key":"BFu6DBpfcm8_h8gm3rHUkfaOLg7azvYN_auFI4KcNuh5SLBVMhTkKKvUaLENtA_c6v5Hmrucvh0WwsN1o9NFQRU="}'
|
|
||||||
headers:
|
|
||||||
Cache-Control:
|
|
||||||
- no-store
|
|
||||||
Content-Security-Policy:
|
|
||||||
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
|
||||||
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
|
||||||
style-src ''self'' http://localhost:3000 ''nonce-4kBQ0XWCASsxXi+/Z0W5jA=='';
|
|
||||||
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
|
||||||
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
|
||||||
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
|
||||||
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
|
||||||
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
|
||||||
worker-src ''self'' blob: http://localhost:3000'
|
|
||||||
Content-Type:
|
|
||||||
- application/json; charset=utf-8
|
|
||||||
ETag:
|
|
||||||
- W/"083c3b807a4d145ec452ffd03c768d76"
|
|
||||||
Referrer-Policy:
|
|
||||||
- strict-origin-when-cross-origin
|
|
||||||
Transfer-Encoding:
|
|
||||||
- chunked
|
|
||||||
Vary:
|
|
||||||
- Accept, Origin
|
|
||||||
X-Content-Type-Options:
|
|
||||||
- nosniff
|
|
||||||
X-Download-Options:
|
|
||||||
- noopen
|
|
||||||
X-Frame-Options:
|
|
||||||
- SAMEORIGIN
|
|
||||||
X-Permitted-Cross-Domain-Policies:
|
|
||||||
- none
|
|
||||||
X-Request-Id:
|
|
||||||
- eeb007da-a24b-4e31-b962-30ef0ba3bc16
|
|
||||||
X-Runtime:
|
|
||||||
- '0.008203'
|
|
||||||
X-XSS-Protection:
|
|
||||||
- 1; mode=block
|
|
||||||
status:
|
|
||||||
code: 200
|
|
||||||
message: OK
|
|
||||||
version: 1
|
|
|
@ -70,5 +70,24 @@ def test_app_account_create():
|
||||||
# We can also test resending (marginally)
|
# We can also test resending (marginally)
|
||||||
test_app_api.email_resend_confirmation()
|
test_app_api.email_resend_confirmation()
|
||||||
|
|
||||||
|
@pytest.mark.vcr(match_on=['path'])
|
||||||
|
def test_app_account_create_invalid():
|
||||||
|
suffix = str(time.time()).replace(".", "")[-5:]
|
||||||
|
|
||||||
|
test_app = test_app = Mastodon.create_app(
|
||||||
|
"mastodon.py generated test app",
|
||||||
|
api_base_url="http://localhost:3000/"
|
||||||
|
)
|
||||||
|
|
||||||
|
test_app_api = Mastodon(
|
||||||
|
test_app[0],
|
||||||
|
test_app[1],
|
||||||
|
api_base_url="http://localhost:3000/"
|
||||||
|
)
|
||||||
|
test_token, error = test_app_api.create_account("coolguy" + suffix, "", "email@localhost" + suffix, agreement=False, return_detailed_error=True)
|
||||||
|
assert test_token is None
|
||||||
|
assert "details" in error
|
||||||
|
assert "password" in error.details
|
||||||
|
assert "password" in error.details
|
||||||
|
assert not "username" in error.details
|
||||||
|
|
Ładowanie…
Reference in New Issue