Skip to content
This repository has been archived by the owner on Mar 18, 2019. It is now read-only.

Provide Hook or Flag for _get_links Behaviour #45

Open
mverteuil opened this issue Jul 20, 2017 · 0 comments
Open

Provide Hook or Flag for _get_links Behaviour #45

mverteuil opened this issue Jul 20, 2017 · 0 comments

Comments

@mverteuil
Copy link

mverteuil commented Jul 20, 2017

There is a bit of cleverness in _get_links that looks for a common prefix and extracts it into tags. This behaviour causes unpredictable results in the encoded schema if a variety of top level items used in different contexts are not displayed to a user based on their permissions.

For example:

User A has access to:

  • /api/vegetables/seedless/ (SeedlessVegetableListCreateAPIView)
  • /api/vegetables/seeded/(SeededVegetableListCreateAPIView)
  • /api/protein/beef (BeefListCreateAPIView)

User B has access to:

  • /api/vegetables/seedless/
  • /api/vegetables/seeded/

The result is that User A's schema will have different operationId values than User B, which means my client code breaks depending on which user is accessing the encoded spec.

The default implementation in SchemaGenerator will cut off the /api prefix which is fine, but the problem stems from the fact that User B does not have access to /api/protein/beef.

This means the resulting operationIds and tags for User A are:

url tags operationId
/api/vegetables/seedless/ vegetables seedless_create
/api/vegetables/seedless/ vegetables seedless_list
/api/vegetables/seeded/ vegetables seeded_create
/api/vegetables/seeded/ vegetables seeded_list
/api/protein/beef/ protein beef_create
/api/protein/beef/ protein beef_list

However User B has:

url tags operationId
/api/vegetables/seedless/ seedless seedless_create
/api/vegetables/seedless/ seedless seedless_list
/api/vegetables/seeded/ seeded seeded_create
/api/vegetables/seeded/ seeded seeded_list

If I try to use the Swagger JS client, due to the variations in the schema, the path changes depending on which user is logged in which is extremely frustrating. This should be configurable by hook or flag, as I'm currently forced to leverage mock.patch to replace openapi_codec.encode._get_links which is horribly fragile and obviously undesired in production code.

For reference, my current solution is to eliminate the section where tags are determined which allows me to route all of my operations through a common operationId, regardless of the level of access the request user has.

def _get_links(document):
    """
    Monkey patch for openapi_codec.encode._get_links

    Implementation removes cleverness in openapi_codec.encode._get_links which tries to reduce
    the size of operation names by removing what it assumes to be redundancies.

    This is not suitable for our case, since the contents of our schemata vary depending on the
    access level of the request user.

    This patch may be applied with a context manager during OpenAPI document rendering.
    """
    # Extract all the links from the first or second level of the document.
    links = []
    for keys, link in get_links_from_document(document):
        operation_id = '_'.join(keys)
        links.append((operation_id, link, []))
    return links
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant