Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Divide API in public and private #4326

Closed
MartinMuzatko opened this issue Mar 14, 2018 · 17 comments
Closed

Divide API in public and private #4326

MartinMuzatko opened this issue Mar 14, 2018 · 17 comments

Comments

@MartinMuzatko
Copy link

Hello.

We try to divide our swagger documentation in two parts. One for our internal documentation and one for consumers.

What is the best way to go about this? We thought about providing two definitions, but maybe there is a YAML flag or whatever to do this. What also works, is that the relevant sections are hidden, before authentication.

Thanks in advance.

Q A
Bug or feature request? Feature request
Which Swagger/OpenAPI version? 2.x
Which Swagger-UI version? 3.3.2
How did you install Swagger-UI? I cloned the repo
Which browser & version? chrome 56
Which operating system? Windows
buildTimestamp:"Sat, 14 Oct 2017 04:42:59 GMT"
gitDirty:true
gitRevision:"gdd0c5227"
machine:"banjo"
version:"3.3.2"
@webron
Copy link
Contributor

webron commented Mar 14, 2018

If you're looking to hide some of the operations, providing it all in one API definition is probably not the way. Even if it's not rendered, users could still get the API definition itself and see the hidden API calls.

@heldersepu
Copy link
Contributor

heldersepu commented Mar 14, 2018

Versioning is the way to go, and your swagger-ui will look like:
http://swagger-net-test-multiapiversions.azurewebsites.net/swagger

@shockey
Copy link
Contributor

shockey commented Mar 14, 2018

As an alternative to the above: the OpenAPI Specification describes a Security filtering concept, in which parts of an OpenAPI document by the server are omitted unless a user provides some sort of authentication: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#security-filtering

@MartinMuzatko
Copy link
Author

Versioning might be an option. I'm using https://github.com/Surnet/swagger-jsdoc to define my swagger definition as comments in the code. So maybe I can use versioning, but I think I may end up splitting it.

@MartinMuzatko
Copy link
Author

MartinMuzatko commented Mar 19, 2018

Right now I'm trying to write a wrapper component plugin, but I'm stuck a little bit.
The plugin should hide the operation block, when not authorized and show otherwise.

Any ideas?
Are there maybe existing plugins? The swagger ecosystem makes it painfully hard to find existing plugins, as there is no effort to list them.

@jake32321
Copy link

@heldersepu working on a project where we'll need to display different docs for different API versions. I saw you have something that might fit the bill of what I'm looking for with the example you posted. Do you have a reference or something I could look at to try and accomplish something similar?

@heldersepu
Copy link
Contributor

@jake32321
Copy link

@heldersepu awesome! Thanks!

@shockey
Copy link
Contributor

shockey commented Mar 27, 2018

The plugin should hide the operation block, when not authorized and show otherwise.

Would you want the operation block to show when any authorization data is set, or do you have an endpoint on your server that you'd like to ping before revealing the documentation?

Also note that this can't be truly secure at the Swagger-UI level, since the user's browser will already have the entire documentation file loaded over the network.

@MartinMuzatko
Copy link
Author

Hey @shockey Thanks for the answer.

Would you want the operation block to show when any authorization data is set

This would be ideal. It doesn't matter, if the definition.json delivers the data. We used to use the documentation only for internal purposes, but now we are giving the documentation to other customers. Right now I had to hide the operation blocks using CSS (although, manually, since there is no indication whether an opblock is secured or not, other than the lock icon)

Security wise, it does not matter. We just want to give away a documentation of operations where we can say, that those are safe to use. They can still go into their devtools of choice and sniff for endpoints and reveal them.
I admit, it maybe is a rare use-case, because you either shield away operations completely with the proper authentication, or you expose everything.

Thanks in advance already for any solution or workaround. Right now - CSS does the job but it is done manually.

@shockey
Copy link
Contributor

shockey commented Mar 28, 2018

@MartinMuzatko, here's a plugin that should achieve what you're looking for:

  const HideOperationsUntilAuthorized = function() {
    return {
      wrapComponents: {
        operation: (Ori, system) => (props) => {
          const isOperationSecured = !!props.operation.get("security").size
          const isOperationAuthorized = props.operation.get("isAuthorized")
          
          if(!isOperationSecured || isOperationAuthorized) {
            return system.React.createElement(Ori, props)
          }
          return null
        }
      }
    }
  }

Let me know if this helps (or not!) 😄

@MartinMuzatko
Copy link
Author

@shockey first of all: thank you a lot for your effort. I very much appreciate it.

This is how the page looks without the script:

image

With the script you suggested, the operation blocks are hidden (but not the section that marks the tag)
With authentication, they are still hidden :/

I still get false for props.operation.get("isAuthorized") after providing the credentials for the correct authentication (Basic). But maybe this is a problem of how I have authentication set up. AFAIK Swagger does not know about credentials and only unlocks/locks based on the securityDefinition defined and the security used in the endpoint documentation.

This is my definition:

securityDefinitions: {
    basicAuth: {
        type: 'basic'
    }
}

This is my endpoint:

/**
 * @swagger
 * /Server:
 *   get:
 *     tags:
 *       - server
 *     description: Returns the Server configuration
 *     produces:
 *       - application/json
 *     responses:
 *       200:
 *         description: 'OK'
 *     security:
 *       - basicAuth
 */

I think I will just go with the CSS option (that also hides the tag) and document our internal API using unit tests.

@shockey
Copy link
Contributor

shockey commented Mar 30, 2018

Hey @MartinMuzatko, here's a video of the plugin in action on my end: http://recordit.co/WY6tsdIJnN

I think the security requirement in your operation is malformed; it should be - basicAuth: [] instead of - basicAuth 😄

@MartinMuzatko
Copy link
Author

Oh cool. I have to try that out. Thank you :)

@shockey
Copy link
Contributor

shockey commented Apr 10, 2018

Closing due to inactivity.

This is simply to keep our issue tracker clean - feel free to comment if there are any further thoughts or concerns, and we'll be happy to reopen this issue.

@shockey shockey closed this as completed Apr 10, 2018
@MartinMuzatko
Copy link
Author

MartinMuzatko commented Apr 11, 2018

Thanks a lot @shockey , it worked out! There is a problem that the tag is not hidden, if all elements of the tag are hidden, but this a problem not only related to this specific use-case with swagger UI. See #3819

@lock
Copy link

lock bot commented Jul 2, 2019

Locking due to inactivity.

This is done to avoid resurrecting old issues and bumping long threads with new, possibly unrelated content.

If you think you're experiencing something similar to what you've found here: please open a new issue, follow the template, and reference this issue in your report.

Thanks!

@lock lock bot locked and limited conversation to collaborators Jul 2, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants