mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +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)
 | 
			
		||||
* [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 to bouncer](/api/register-remote-push-device)
 | 
			
		||||
* [Mobile notifications](/api/mobile-notifications)
 | 
			
		||||
* [Send a test notification to mobile device(s)](/api/test-notify)
 | 
			
		||||
* [Add an APNs device token](/api/add-apns-token)
 | 
			
		||||
 
 | 
			
		||||
@@ -319,8 +319,9 @@ def generate_curl_example(
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    if authentication_required:
 | 
			
		||||
        auth_email = DEFAULT_AUTH_EMAIL
 | 
			
		||||
        auth_api_key = DEFAULT_AUTH_API_KEY
 | 
			
		||||
        is_zilencer_endpoint = endpoint.startswith("/remotes/")
 | 
			
		||||
        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}"))
 | 
			
		||||
 | 
			
		||||
    for parameter in parameters:
 | 
			
		||||
 
 | 
			
		||||
@@ -26,9 +26,10 @@ from zerver.openapi.openapi import get_endpoint_from_operationid
 | 
			
		||||
 | 
			
		||||
UNTESTED_GENERATED_CURL_EXAMPLES = {
 | 
			
		||||
    # 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",
 | 
			
		||||
    "test-notify",
 | 
			
		||||
    "register-remote-push-device",
 | 
			
		||||
    # Having a message for a specific user available to test this endpoint
 | 
			
		||||
    # is tricky for testing.
 | 
			
		||||
    "delete-reminder",
 | 
			
		||||
 
 | 
			
		||||
@@ -12788,6 +12788,133 @@ paths:
 | 
			
		||||
                      }
 | 
			
		||||
                    description: |
 | 
			
		||||
                      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:
 | 
			
		||||
    post:
 | 
			
		||||
      operationId: update-user-topic
 | 
			
		||||
 
 | 
			
		||||
@@ -263,7 +263,6 @@ class OpenAPIArgumentsTest(ZulipTestCase):
 | 
			
		||||
        "/jwt/fetch_api_key",
 | 
			
		||||
        #### Bouncer endpoints
 | 
			
		||||
        # Higher priority to document
 | 
			
		||||
        "/remotes/push/e2ee/register",
 | 
			
		||||
        "/remotes/push/e2ee/notify",
 | 
			
		||||
        # Lower priority to document
 | 
			
		||||
        "/remotes/server/register",
 | 
			
		||||
 
 | 
			
		||||
@@ -43,9 +43,15 @@ class DocumentationArticle:
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
    if is_zilencer_endpoint:
 | 
			
		||||
        context["api_url"] = settings.ZULIP_SERVICES_URL + "/api"
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    subdomain = get_subdomain(request)
 | 
			
		||||
    if subdomain != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN or not settings.ROOT_DOMAIN_LANDING_PAGE:
 | 
			
		||||
        display_subdomain = subdomain
 | 
			
		||||
@@ -226,6 +232,7 @@ class MarkdownDirectoryView(ApiURLView):
 | 
			
		||||
        # The following is a somewhat hacky approach to extract titles from articles.
 | 
			
		||||
        endpoint_name = None
 | 
			
		||||
        endpoint_method = None
 | 
			
		||||
        is_zilencer_endpoint = False
 | 
			
		||||
        if os.path.exists(article_absolute_path):
 | 
			
		||||
            with open(article_absolute_path) as article_file:
 | 
			
		||||
                first_line = article_file.readlines()[0]
 | 
			
		||||
@@ -237,6 +244,7 @@ class MarkdownDirectoryView(ApiURLView):
 | 
			
		||||
                assert endpoint_name is not None
 | 
			
		||||
                assert endpoint_method is not None
 | 
			
		||||
                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:
 | 
			
		||||
                api_operation = context["PAGE_METADATA_URL"].split("/api/")[1]
 | 
			
		||||
                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
 | 
			
		||||
        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
 | 
			
		||||
        context["api_url_context"] = api_url_context
 | 
			
		||||
        if endpoint_name and endpoint_method:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user