mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 14:03:30 +00:00 
			
		
		
		
	api_docs: Document /remotes/push/e2ee/register endpoint.
				
					
				
			This commit documents the `/remotes/push/e2ee/register` endpoint.
We use auth_email="ZULIP_ORG_ID" and auth_api_key="ZULIP_ORG_KEY"
instead of "BOT_EMAIL_ADDRESS" and "BOT_API_KEY".
(cherry picked from commit f52533795b)
			
			
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							5cd52a2a14
						
					
				
				
					commit
					bb534fbab5
				
			@@ -159,6 +159,7 @@
 | 
				
			|||||||
* [Fetch an API key (development only)](/api/dev-fetch-api-key)
 | 
					* [Fetch an API key (development only)](/api/dev-fetch-api-key)
 | 
				
			||||||
* [Send an E2EE test notification to mobile device(s)](/api/e2ee-test-notify)
 | 
					* [Send an E2EE test notification to mobile device(s)](/api/e2ee-test-notify)
 | 
				
			||||||
* [Register E2EE push device](/api/register-push-device)
 | 
					* [Register E2EE push device](/api/register-push-device)
 | 
				
			||||||
 | 
					* [Register E2EE push device to bouncer](/api/register-remote-push-device)
 | 
				
			||||||
* [Mobile notifications](/api/mobile-notifications)
 | 
					* [Mobile notifications](/api/mobile-notifications)
 | 
				
			||||||
* [Send a test notification to mobile device(s)](/api/test-notify)
 | 
					* [Send a test notification to mobile device(s)](/api/test-notify)
 | 
				
			||||||
* [Add an APNs device token](/api/add-apns-token)
 | 
					* [Add an APNs device token](/api/add-apns-token)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -319,8 +319,9 @@ def generate_curl_example(
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if authentication_required:
 | 
					    if authentication_required:
 | 
				
			||||||
        auth_email = DEFAULT_AUTH_EMAIL
 | 
					        is_zilencer_endpoint = endpoint.startswith("/remotes/")
 | 
				
			||||||
        auth_api_key = DEFAULT_AUTH_API_KEY
 | 
					        auth_email = "ZULIP_ORG_ID" if is_zilencer_endpoint else DEFAULT_AUTH_EMAIL
 | 
				
			||||||
 | 
					        auth_api_key = "ZULIP_ORG_KEY" if is_zilencer_endpoint else DEFAULT_AUTH_API_KEY
 | 
				
			||||||
        lines.append("    -u " + shlex.quote(f"{auth_email}:{auth_api_key}"))
 | 
					        lines.append("    -u " + shlex.quote(f"{auth_email}:{auth_api_key}"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for parameter in parameters:
 | 
					    for parameter in parameters:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,9 +26,10 @@ from zerver.openapi.openapi import get_endpoint_from_operationid
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
UNTESTED_GENERATED_CURL_EXAMPLES = {
 | 
					UNTESTED_GENERATED_CURL_EXAMPLES = {
 | 
				
			||||||
    # Would need push notification bouncer set up to test the
 | 
					    # Would need push notification bouncer set up to test the
 | 
				
			||||||
    # generated curl example for the following two endpoints.
 | 
					    # generated curl example for the following three endpoints.
 | 
				
			||||||
    "e2ee-test-notify",
 | 
					    "e2ee-test-notify",
 | 
				
			||||||
    "test-notify",
 | 
					    "test-notify",
 | 
				
			||||||
 | 
					    "register-remote-push-device",
 | 
				
			||||||
    # Having a message for a specific user available to test this endpoint
 | 
					    # Having a message for a specific user available to test this endpoint
 | 
				
			||||||
    # is tricky for testing.
 | 
					    # is tricky for testing.
 | 
				
			||||||
    "delete-reminder",
 | 
					    "delete-reminder",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12788,6 +12788,133 @@ paths:
 | 
				
			|||||||
                      }
 | 
					                      }
 | 
				
			||||||
                    description: |
 | 
					                    description: |
 | 
				
			||||||
                      Error when the server is not configured to use push notification service:
 | 
					                      Error when the server is not configured to use push notification service:
 | 
				
			||||||
 | 
					  /remotes/push/e2ee/register:
 | 
				
			||||||
 | 
					    post:
 | 
				
			||||||
 | 
					      operationId: register-remote-push-device
 | 
				
			||||||
 | 
					      summary: Register E2EE push device to bouncer
 | 
				
			||||||
 | 
					      tags: ["mobile"]
 | 
				
			||||||
 | 
					      description: |
 | 
				
			||||||
 | 
					        Register a push device to bouncer to receive end-to-end encrypted
 | 
				
			||||||
 | 
					        mobile push notifications.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Self-hosted servers use this endpoint to asynchronously register
 | 
				
			||||||
 | 
					        a push device to the bouncer server after receiving a request from
 | 
				
			||||||
 | 
					        the mobile client to [register E2EE push device](/api/register-push-device).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        It is not meant to be used by mobile clients directly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        **Changes**: New in Zulip 11.0 (feature level 406).
 | 
				
			||||||
 | 
					      requestBody:
 | 
				
			||||||
 | 
					        required: true
 | 
				
			||||||
 | 
					        content:
 | 
				
			||||||
 | 
					          application/x-www-form-urlencoded:
 | 
				
			||||||
 | 
					            schema:
 | 
				
			||||||
 | 
					              type: object
 | 
				
			||||||
 | 
					              properties:
 | 
				
			||||||
 | 
					                realm_uuid:
 | 
				
			||||||
 | 
					                  description: |
 | 
				
			||||||
 | 
					                    The UUID of the realm to which the push device
 | 
				
			||||||
 | 
					                    being registered belongs.
 | 
				
			||||||
 | 
					                  type: string
 | 
				
			||||||
 | 
					                  example: "realm-uuid"
 | 
				
			||||||
 | 
					                push_account_id:
 | 
				
			||||||
 | 
					                  description: |
 | 
				
			||||||
 | 
					                    The `push_account_id` value provided by the mobile client
 | 
				
			||||||
 | 
					                    to [register E2EE push device](/api/register-push-device).
 | 
				
			||||||
 | 
					                  type: integer
 | 
				
			||||||
 | 
					                  example: 2408
 | 
				
			||||||
 | 
					                encrypted_push_registration:
 | 
				
			||||||
 | 
					                  description: |
 | 
				
			||||||
 | 
					                    The `encrypted_push_registration` value provided by the mobile client
 | 
				
			||||||
 | 
					                    to [register E2EE push device](/api/register-push-device).
 | 
				
			||||||
 | 
					                  type: string
 | 
				
			||||||
 | 
					                  example: "encrypted-push-registration-data"
 | 
				
			||||||
 | 
					                bouncer_public_key:
 | 
				
			||||||
 | 
					                  description: |
 | 
				
			||||||
 | 
					                    The `bouncer_public_key` value provided by the mobile client
 | 
				
			||||||
 | 
					                    to [register E2EE push device](/api/register-push-device).
 | 
				
			||||||
 | 
					                  type: string
 | 
				
			||||||
 | 
					                  example: "bouncer-public-key"
 | 
				
			||||||
 | 
					              required:
 | 
				
			||||||
 | 
					                - realm_uuid
 | 
				
			||||||
 | 
					                - push_account_id
 | 
				
			||||||
 | 
					                - encrypted_push_registration
 | 
				
			||||||
 | 
					                - bouncer_public_key
 | 
				
			||||||
 | 
					      responses:
 | 
				
			||||||
 | 
					        "200":
 | 
				
			||||||
 | 
					          description: Success
 | 
				
			||||||
 | 
					          content:
 | 
				
			||||||
 | 
					            application/json:
 | 
				
			||||||
 | 
					              schema:
 | 
				
			||||||
 | 
					                allOf:
 | 
				
			||||||
 | 
					                  - $ref: "#/components/schemas/JsonSuccessBase"
 | 
				
			||||||
 | 
					                  - required:
 | 
				
			||||||
 | 
					                      - device_id
 | 
				
			||||||
 | 
					                    additionalProperties: false
 | 
				
			||||||
 | 
					                    properties:
 | 
				
			||||||
 | 
					                      result: {}
 | 
				
			||||||
 | 
					                      msg: {}
 | 
				
			||||||
 | 
					                      ignored_parameters_unsupported: {}
 | 
				
			||||||
 | 
					                      device_id:
 | 
				
			||||||
 | 
					                        type: integer
 | 
				
			||||||
 | 
					                        description: |
 | 
				
			||||||
 | 
					                          Unique identifier assigned by the bouncer for the registration.
 | 
				
			||||||
 | 
					                        example: 2408
 | 
				
			||||||
 | 
					                    example: {"device_id": 2408, "msg": "", "result": "success"}
 | 
				
			||||||
 | 
					        "400":
 | 
				
			||||||
 | 
					          description: Bad request.
 | 
				
			||||||
 | 
					          content:
 | 
				
			||||||
 | 
					            application/json:
 | 
				
			||||||
 | 
					              schema:
 | 
				
			||||||
 | 
					                oneOf:
 | 
				
			||||||
 | 
					                  - allOf:
 | 
				
			||||||
 | 
					                      - $ref: "#/components/schemas/CodedError"
 | 
				
			||||||
 | 
					                      - example:
 | 
				
			||||||
 | 
					                          {
 | 
				
			||||||
 | 
					                            "code": "INVALID_BOUNCER_PUBLIC_KEY",
 | 
				
			||||||
 | 
					                            "msg": "Invalid bouncer_public_key",
 | 
				
			||||||
 | 
					                            "result": "error",
 | 
				
			||||||
 | 
					                          }
 | 
				
			||||||
 | 
					                        description: |
 | 
				
			||||||
 | 
					                          An example JSON response for when the given `bouncer_public_key` is invalid:
 | 
				
			||||||
 | 
					                  - allOf:
 | 
				
			||||||
 | 
					                      - $ref: "#/components/schemas/CodedError"
 | 
				
			||||||
 | 
					                      - example:
 | 
				
			||||||
 | 
					                          {
 | 
				
			||||||
 | 
					                            "code": "REQUEST_EXPIRED",
 | 
				
			||||||
 | 
					                            "msg": "Request expired",
 | 
				
			||||||
 | 
					                            "result": "error",
 | 
				
			||||||
 | 
					                          }
 | 
				
			||||||
 | 
					                        description: |
 | 
				
			||||||
 | 
					                          An example JSON response for when the given `encrypted_push_registration` is stale:
 | 
				
			||||||
 | 
					                  - allOf:
 | 
				
			||||||
 | 
					                      - $ref: "#/components/schemas/CodedError"
 | 
				
			||||||
 | 
					                      - example:
 | 
				
			||||||
 | 
					                          {
 | 
				
			||||||
 | 
					                            "code": "BAD_REQUEST",
 | 
				
			||||||
 | 
					                            "msg": "Invalid encrypted_push_registration",
 | 
				
			||||||
 | 
					                            "result": "error",
 | 
				
			||||||
 | 
					                          }
 | 
				
			||||||
 | 
					                        description: |
 | 
				
			||||||
 | 
					                          An example JSON response for when either the bouncer fails to decrypt
 | 
				
			||||||
 | 
					                          the given `encrypted_push_registration` or the decrypted data is invalid:
 | 
				
			||||||
 | 
					        "403":
 | 
				
			||||||
 | 
					          description: |
 | 
				
			||||||
 | 
					            Forbidden.
 | 
				
			||||||
 | 
					          content:
 | 
				
			||||||
 | 
					            application/json:
 | 
				
			||||||
 | 
					              schema:
 | 
				
			||||||
 | 
					                allOf:
 | 
				
			||||||
 | 
					                  - $ref: "#/components/schemas/CodedError"
 | 
				
			||||||
 | 
					                  - example:
 | 
				
			||||||
 | 
					                      {
 | 
				
			||||||
 | 
					                        "code": "MISSING_REMOTE_REALM",
 | 
				
			||||||
 | 
					                        "msg": "Organization not registered",
 | 
				
			||||||
 | 
					                        "result": "error",
 | 
				
			||||||
 | 
					                      }
 | 
				
			||||||
 | 
					                    description: |
 | 
				
			||||||
 | 
					                      An example JSON response for when no realm is registered for
 | 
				
			||||||
 | 
					                      the authenticated server on the bouncer for the given `realm_uuid`:
 | 
				
			||||||
  /user_topics:
 | 
					  /user_topics:
 | 
				
			||||||
    post:
 | 
					    post:
 | 
				
			||||||
      operationId: update-user-topic
 | 
					      operationId: update-user-topic
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -263,7 +263,6 @@ class OpenAPIArgumentsTest(ZulipTestCase):
 | 
				
			|||||||
        "/jwt/fetch_api_key",
 | 
					        "/jwt/fetch_api_key",
 | 
				
			||||||
        #### Bouncer endpoints
 | 
					        #### Bouncer endpoints
 | 
				
			||||||
        # Higher priority to document
 | 
					        # Higher priority to document
 | 
				
			||||||
        "/remotes/push/e2ee/register",
 | 
					 | 
				
			||||||
        "/remotes/push/e2ee/notify",
 | 
					        "/remotes/push/e2ee/notify",
 | 
				
			||||||
        # Lower priority to document
 | 
					        # Lower priority to document
 | 
				
			||||||
        "/remotes/server/register",
 | 
					        "/remotes/server/register",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,9 +43,15 @@ class DocumentationArticle:
 | 
				
			|||||||
    endpoint_method: str | None
 | 
					    endpoint_method: str | None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def add_api_url_context(context: dict[str, Any], request: HttpRequest) -> None:
 | 
					def add_api_url_context(
 | 
				
			||||||
 | 
					    context: dict[str, Any], request: HttpRequest, is_zilencer_endpoint: bool = False
 | 
				
			||||||
 | 
					) -> None:
 | 
				
			||||||
    context.update(zulip_default_context(request))
 | 
					    context.update(zulip_default_context(request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if is_zilencer_endpoint:
 | 
				
			||||||
 | 
					        context["api_url"] = settings.ZULIP_SERVICES_URL + "/api"
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    subdomain = get_subdomain(request)
 | 
					    subdomain = get_subdomain(request)
 | 
				
			||||||
    if subdomain != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN or not settings.ROOT_DOMAIN_LANDING_PAGE:
 | 
					    if subdomain != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN or not settings.ROOT_DOMAIN_LANDING_PAGE:
 | 
				
			||||||
        display_subdomain = subdomain
 | 
					        display_subdomain = subdomain
 | 
				
			||||||
@@ -226,6 +232,7 @@ class MarkdownDirectoryView(ApiURLView):
 | 
				
			|||||||
        # The following is a somewhat hacky approach to extract titles from articles.
 | 
					        # The following is a somewhat hacky approach to extract titles from articles.
 | 
				
			||||||
        endpoint_name = None
 | 
					        endpoint_name = None
 | 
				
			||||||
        endpoint_method = None
 | 
					        endpoint_method = None
 | 
				
			||||||
 | 
					        is_zilencer_endpoint = False
 | 
				
			||||||
        if os.path.exists(article_absolute_path):
 | 
					        if os.path.exists(article_absolute_path):
 | 
				
			||||||
            with open(article_absolute_path) as article_file:
 | 
					            with open(article_absolute_path) as article_file:
 | 
				
			||||||
                first_line = article_file.readlines()[0]
 | 
					                first_line = article_file.readlines()[0]
 | 
				
			||||||
@@ -237,6 +244,7 @@ class MarkdownDirectoryView(ApiURLView):
 | 
				
			|||||||
                assert endpoint_name is not None
 | 
					                assert endpoint_name is not None
 | 
				
			||||||
                assert endpoint_method is not None
 | 
					                assert endpoint_method is not None
 | 
				
			||||||
                article_title = get_openapi_summary(endpoint_name, endpoint_method)
 | 
					                article_title = get_openapi_summary(endpoint_name, endpoint_method)
 | 
				
			||||||
 | 
					                is_zilencer_endpoint = endpoint_name.startswith("/remotes/")
 | 
				
			||||||
            elif self.api_doc_view and "{generate_api_header(" in first_line:
 | 
					            elif self.api_doc_view and "{generate_api_header(" in first_line:
 | 
				
			||||||
                api_operation = context["PAGE_METADATA_URL"].split("/api/")[1]
 | 
					                api_operation = context["PAGE_METADATA_URL"].split("/api/")[1]
 | 
				
			||||||
                endpoint_name, endpoint_method = get_endpoint_from_operationid(api_operation)
 | 
					                endpoint_name, endpoint_method = get_endpoint_from_operationid(api_operation)
 | 
				
			||||||
@@ -268,7 +276,7 @@ class MarkdownDirectoryView(ApiURLView):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # An "article" might require the api_url_context to be rendered
 | 
					        # An "article" might require the api_url_context to be rendered
 | 
				
			||||||
        api_url_context: dict[str, Any] = {}
 | 
					        api_url_context: dict[str, Any] = {}
 | 
				
			||||||
        add_api_url_context(api_url_context, self.request)
 | 
					        add_api_url_context(api_url_context, self.request, is_zilencer_endpoint)
 | 
				
			||||||
        api_url_context["run_content_validators"] = True
 | 
					        api_url_context["run_content_validators"] = True
 | 
				
			||||||
        context["api_url_context"] = api_url_context
 | 
					        context["api_url_context"] = api_url_context
 | 
				
			||||||
        if endpoint_name and endpoint_method:
 | 
					        if endpoint_name and endpoint_method:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user