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

Support a configurable oauth redirect URL #442

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
107 changes: 107 additions & 0 deletions examples/github_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from flask import Flask
from flask_restx import Api, Resource, fields
from werkzeug.middleware.proxy_fix import ProxyFix
import os

app = Flask(__name__)

app.config["SWAGGER_UI_OAUTH_REDIRECT_URL"] = os.environ.get("SWAGGER_UI_OAUTH_REDIRECT_URL")

app.wsgi_app = ProxyFix(app.wsgi_app)

authorizations = {
'OAuth2': {
'type': 'oauth2',
'flow': 'accessCode',
'authorizationUrl': 'https://github.com/login/oauth/authorize',
'tokenUrl': '/',
'scopes': {
'user:email': 'Read user email addresses'
}
}
}

api = Api(app, version="1.0", title="Todo API", description="A simple TODO API", authorizations=authorizations)

ns = api.namespace("todos", description="TODO operations")

TODOS = {
"todo1": {"task": "build an API"},
"todo2": {"task": "?????"},
"todo3": {"task": "profit!"},
}

todo = api.model(
"Todo", {"task": fields.String(required=True, description="The task details")}
)

listed_todo = api.model(
"ListedTodo",
{
"id": fields.String(required=True, description="The todo ID"),
"todo": fields.Nested(todo, description="The Todo"),
},
)


def abort_if_todo_doesnt_exist(todo_id):
if todo_id not in TODOS:
api.abort(404, "Todo {} doesn't exist".format(todo_id))


parser = api.parser()
parser.add_argument(
"task", type=str, required=True, help="The task details", location="form"
)


@ns.route("/<string:todo_id>")
@api.doc(responses={404: "Todo not found"}, params={"todo_id": "The Todo ID"})
class Todo(Resource):
"""Show a single todo item and lets you delete them"""

@api.doc(description="todo_id should be in {0}".format(", ".join(TODOS.keys())))
@api.marshal_with(todo)
def get(self, todo_id):
"""Fetch a given resource"""
abort_if_todo_doesnt_exist(todo_id)
return TODOS[todo_id]

@api.doc(responses={204: "Todo deleted"})
def delete(self, todo_id):
"""Delete a given resource"""
abort_if_todo_doesnt_exist(todo_id)
del TODOS[todo_id]
return "", 204

@api.doc(parser=parser)
@api.marshal_with(todo)
def put(self, todo_id):
"""Update a given resource"""
args = parser.parse_args()
task = {"task": args["task"]}
TODOS[todo_id] = task
return task


@ns.route("/")
class TodoList(Resource):
"""Shows a list of all todos, and lets you POST to add new tasks"""

@api.marshal_list_with(listed_todo)
def get(self):
"""List all todos"""
return [{"id": id, "todo": todo} for id, todo in TODOS.items()]

@api.doc(parser=parser)
@api.marshal_with(todo, code=201)
def post(self):
"""Create a todo"""
args = parser.parse_args()
todo_id = "todo%d" % (len(TODOS) + 1)
TODOS[todo_id] = {"task": args["task"]}
return TODOS[todo_id], 201


if __name__ == "__main__":
app.run(debug=True)
8 changes: 5 additions & 3 deletions flask_restx/templates/swagger-ui.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@
window.onload = function() {
const ui = window.ui = new SwaggerUIBundle({
url: "{{ specs_url }}",
{% if config.SWAGGER_UI_OAUTH_CLIENT_ID -%}
oauth2RedirectUrl: "{{ url_for('restx_doc.static', filename='oauth2-redirect.html', _external=True) }}",
{%- endif %}
{% if config.SWAGGER_UI_OAUTH_REDIRECT_URL -%}
oauth2RedirectUrl: "{{ config.SWAGGER_UI_OAUTH_REDIRECT_URL }}",
{% else -%}
oauth2RedirectUrl: "{{ url_for('restx_doc.static', filename='oauth2-redirect.html', _external=True) }}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if I'm wrong here, but does this introduce a small behaviour change to previously? By default, config.SWAGGER_UI_OAUTH_CLIENT_ID is not defined and therefore no oauth2RedirectUrl should be set? I think we maybe just need to introduce another if statement? I don't have any OAUTH flows set up to easily test this change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've put back the original check and then nested the new check inside it

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing this.... hold off merging...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK testing done, could you re-review please

{% endif -%}
validatorUrl: "{{ config.SWAGGER_VALIDATOR_URL }}" || null,
dom_id: "#swagger-ui",
presets: [
Expand Down
Loading