File: basic_auth.py

package info (click to toggle)
python-flasgger 0.9.5%2Bdfsg.2-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 13,152 kB
  • sloc: javascript: 6,403; python: 3,665; makefile: 9; sh: 1
file content (118 lines) | stat: -rw-r--r-- 3,079 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
"""
An example that uses HTTP Basic Auth to protect the /apidocs and
/apispec_1.json endpoints.

In this example the login credentials to view the Swagger docs are as follows:

    Username: guest
    Password: secret

Failing to provide the right credentials results in a 401 Unauthorized
response from all the Flasgger endpoints.
"""
from flask import Flask, request, redirect, Response, jsonify
from functools import wraps

from flasgger import Swagger

def requires_basic_auth(f):
    """Decorator to require HTTP Basic Auth for your endpoint."""

    def check_auth(username, password):
        return username == "guest" and password == "secret"

    def authenticate():
        return Response(
            "Authentication required.", 401,
            {"WWW-Authenticate": "Basic realm='Login Required'"},
        )

    @wraps(f)
    def decorated(*args, **kwargs):
        # NOTE: This example will require Basic Auth only when you run the
        # app directly. For unit tests, we can't block it from getting the
        # Swagger specs so we just allow it to go thru without auth.
        # The following two lines of code wouldn't be needed in a normal
        # production environment.
        if __name__ != "__main__":
            return f(*args, **kwargs)

        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            return authenticate()
        return f(*args, **kwargs)

    return decorated

app = Flask(__name__)
app.config["SWAGGER"] = {
    "title": "Swagger Basic Auth App",
    "uiversion": 2,
}
swag = Swagger(app,
    decorators=[ requires_basic_auth ],
    template={
        "swagger": "2.0",
        "info": {
            "title": "Swagger Basic Auth App",
            "version": "1.0",
        },
        "consumes": [
            "application/json",
        ],
        "produces": [
            "application/json",
        ],
    },
)

@app.route("/echo/<name>", methods=["GET", "POST"])
def echo(name):
    """
    Echo back the name and any posted parameters.
    ---
    tags:
      - echo
    parameters:
      - in: path
        name: name
        type: string
        required: true
      - in: body
        name: body
        description: JSON parameters.
        schema:
          properties:
            first_name:
              type: string
              description: First name.
              example: Alice
            last_name:
              type: string
              description: Last name.
              example: Smith
            dob:
              type: string
              format: date
              description: Date of birth.
              example: 1990-01-01
            comment:
              type: string
              description: Something arbitrary.
              example: Hello world
    responses:
      200:
        description: OK.
    """
    data = {
        "url_name": name,
        "json": request.json,
    }
    return jsonify(data)

@app.route("/")
def index():
    return redirect("/apidocs")

if __name__ == "__main__":
    app.run(debug=True)