Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ htmlcov/
venv/
.venv/
src/
*.un~
*.un~
*.DS_Store
30 changes: 15 additions & 15 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Firetail
===========
.. _Firetail's Documentation Page: https://pointsecio.readthedocs.org/en/latest/
.. _Firetail's Documentation Page: https://firetail.readthedocs.org/en/latest/
.. _Connexion: https://github.com/spec-first/connexion
.. _Flask: https://flask.pocoo.org/
.. _issues waffle board: https://waffle.io/zalando/connexion
Expand All @@ -22,35 +22,35 @@ Firetail
.. _werkzeug: https://werkzeug.pocoo.org/
.. _Connexion's Documentation Page: https://connexion.readthedocs.org/en/latest/
.. _Crafting effective Microservices in Python: https://jobs.zalando.com/tech/blog/crafting-effective-microservices-in-python/
.. _issues where we are looking for contributions: https://github.com/pointSec-io/pointsecio/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22
.. _issues where we are looking for contributions: https://github.com/FireTail-io/firetail-py-lib/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22
.. _HTTP Methods work in Flask: https://flask.pocoo.org/docs/1.0/quickstart/#http-methods

.. .. image:: https://badges.gitter.im/zalando/connexion.svg
.. :alt: Join the chat at https://gitter.im/zalando/connexion
.. :target: https://gitter.im/zalando/connexion?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge

.. image:: https://github.com/PointSec-io/pointsecio/actions/workflows/pipeline.yml/badge.svg
.. image:: https://github.com/FireTail-io/firetail-py-lib/actions/workflows/pipeline.yml/badge.svg
:alt: Build status
:target: https://github.com/PointSec-io/pointsecio/actions/workflows/pipeline.yml
:target: https://github.com/FireTail-io/firetail-py-lib/actions/workflows/pipeline.yml

.. .. image:: https://coveralls.io/repos/github/zalando/connexion/badge.svg?branch=main
.. :target: https://coveralls.io/github/zalando/connexion?branch=main
.. :alt: Coveralls status

.. image:: https://img.shields.io/pypi/v/pointsecio.svg
:target: https://pypi.python.org/pypi/pointsecio
.. image:: https://img.shields.io/pypi/v/firetail.svg
:target: https://pypi.python.org/pypi/firetail
:alt: Latest Version

.. image:: https://img.shields.io/pypi/status/pointsecio.svg
:target: https://pypi.python.org/pypi/pointsecio
.. image:: https://img.shields.io/pypi/status/firetail.svg
:target: https://pypi.python.org/pypi/firetail
:alt: Development Status

.. image:: https://img.shields.io/pypi/pyversions/pointsecio.svg
:target: https://pypi.python.org/pypi/pointsecio
.. image:: https://img.shields.io/pypi/pyversions/firetail.svg
:target: https://pypi.python.org/pypi/firetail
:alt: Python Versions

.. image:: https://img.shields.io/pypi/l/pointsecio.svg
:target: https://github.com/PointSec-io/pointsecio/blob/main/LICENSE.txt
.. image:: https://img.shields.io/pypi/l/firetail.svg
:target: https://raw.githubusercontent.com/FireTail-io/firetail-py-lib/main/LICENSE.txt
:alt: License

Firetail (fork of Connexion_) is a framework that automagically handles HTTP requests based on `OpenAPI Specification`_
Expand Down Expand Up @@ -582,7 +582,7 @@ Changes

A full changelog is maintained on the `GitHub releases page`_.

.. _GitHub releases page: https://github.com/PointSec-io/pointsecio/releases
.. _GitHub releases page: https://github.com/FireTail-io/firetail-py-lib/releases

Contributing to Firetail/TODOs
================================
Expand All @@ -592,7 +592,7 @@ usual/standard GitHub practices.

Unless you explicitly state otherwise in advance, any non trivial
contribution intentionally submitted for inclusion in this project by you
to the steward of this repository (point security inc) shall be under the
to the steward of this repository (Point Security Inc DBA FireTail (TM)) shall be under the
terms and conditions of Lesser General Public License 2.0 written below, without any
additional copyright information, terms or conditions.

Expand All @@ -604,7 +604,7 @@ TODOs
License
===================

Copyright 2022 point security inc
Copyright 2022 Point Security Inc DBA FireTail (TM)

Licensed under the Lesser General Public License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.txt.

Expand Down
8 changes: 4 additions & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

# General information about the project.
project = 'Firetail'
copyright = '2022, point security inc'
copyright = '2022, Point Security Inc DBA FireTail (TM)'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down Expand Up @@ -217,7 +217,7 @@
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'Firetail.tex', 'Firetail Documentation',
'point security inc', 'manual'),
'Point Security Inc DBA FireTail (TM)', 'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
Expand Down Expand Up @@ -247,7 +247,7 @@
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'firetail', 'Firetail Documentation',
['point security inc'], 1)
['Point Security Inc DBA FireTail (TM)'], 1)
]

# If true, show URL addresses after external links.
Expand All @@ -261,7 +261,7 @@
# dir menu entry, description, category)
texinfo_documents = [
('index', 'Firetail', 'Firetail Documentation',
'point security inc', 'Firetail', 'One line description of project.',
'Point Security Inc DBA FireTail (TM)', 'Firetail', 'One line description of project.',
'Miscellaneous'),
]

Expand Down
10 changes: 5 additions & 5 deletions docs/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ You can find a `minimal OAuth example application`_ showing the use of
``x-tokenInfoUrl``, and `another OAuth example`_ showing the use of
``x-tokenInfoFunc`` in Firetail's "examples" folder.

.. _minimal OAuth example application: https://github.com/pointSec-io/pointsecio/tree/main/examples/swagger2/oauth2
.. _another OAuth example: https://github.com/pointSec-io/pointsecio/tree/main/examples/swagger2/oauth2_local_tokeninfo
.. _minimal OAuth example application: https://github.com/FireTail-io/firetail-py-lib/tree/main/examples/swagger2/oauth2
.. _another OAuth example: https://github.com/FireTail-io/firetail-py-lib/tree/main/examples/swagger2/oauth2_local_tokeninfo

Basic Authentication
--------------------
Expand All @@ -62,7 +62,7 @@ parameters: username, password and required_scopes.
You can find a `minimal Basic Auth example application`_ in Firetail's "examples" folder.

.. _oauth scope: https://oauth.net/2/scope/
.. _minimal Basic Auth example application: https://github.com/pointSec-io/pointsecio/tree/main/examples/openapi3/basicauth
.. _minimal Basic Auth example application: https://github.com/FireTail-io/firetail-py-lib/tree/main/examples/openapi3/basicauth

ApiKey Authentication
---------------------
Expand Down Expand Up @@ -134,7 +134,7 @@ parameters to the underlying `werkzeug`_ server.
.. _rfc6750: https://tools.ietf.org/html/rfc6750
.. _rfc6749: https://tools.ietf.org/html/rfc6749
.. _rfc7662: https://tools.ietf.org/html/rfc7662
.. _minimal API Key example application: https://github.com/pointSec-io/pointsecio/blob/main/examples/openapi3/apikey
.. _minimal JWT example application: https://github.com/pointSec-io/pointsecio/tree/main/examples/openapi3/jwt
.. _minimal API Key example application: https://github.com/FireTail-io/firetail-py-lib/blob/main/examples/openapi3/apikey
.. _minimal JWT example application: https://github.com/FireTail-io/firetail-py-lib/tree/main/examples/openapi3/jwt
.. _enabling authentication passthrough in modwsgi: https://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIPassAuthorization.html
.. _modwsgi documentation: https://modwsgi.readthedocs.io/en/develop/index.html
2 changes: 1 addition & 1 deletion examples/openapi3/jwt/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from jose import JWTError, jwt
from werkzeug.exceptions import Unauthorized

JWT_ISSUER = 'io.pointsec.firetail'
JWT_ISSUER = 'io.firetail.firetail'
JWT_SECRET = 'change_this'
JWT_LIFETIME_SECONDS = 600
JWT_ALGORITHM = 'HS256'
Expand Down
2 changes: 1 addition & 1 deletion examples/openapi3/jwt/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Install swagger-ui before firetail.
firetail[swagger-ui]

firetail>=2.2.0
firetail>=1.0.3
python-jose[cryptography]
Flask>=0.10.1
2 changes: 1 addition & 1 deletion examples/openapi3/sqlalchemy/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
firetail>=1.0.97
firetail>=1.0.3
Flask>=0.10.1
SQLAlchemy>=1.0.13
25 changes: 25 additions & 0 deletions examples/swagger2/oauth2/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
==============
OAuth2 Example
==============

This example demonstrates how to implement a resource server with Connexion.
The app will lookup OAuth2 Bearer tokens with the given token info function.

Running:

.. code-block:: bash

$ sudo pip3 install --upgrade connexion # install Connexion from PyPI
$ ./mock_tokeninfo.py & # start mock in background
$ ./app.py

Now open your browser and go to http://localhost:8080/ui/ to see the Swagger UI.

You can use the hardcoded tokens to request the endpoint:

.. code-block:: bash

$ curl http://localhost:8080/secret # missing authentication
$ curl -H 'Authorization: Bearer 123' http://localhost:8080/secret
$ curl -H 'Authorization: Bearer 456' http://localhost:8080/secret

16 changes: 16 additions & 0 deletions examples/swagger2/oauth2/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env python3
"""
Basic example of a resource server
"""

import firetail


def get_secret(user) -> str:
return f"You are: {user}"


if __name__ == "__main__":
app = firetail.FlaskApp(__name__)
app.add_api("app.yaml")
app.run(port=8080)
30 changes: 30 additions & 0 deletions examples/swagger2/oauth2/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
swagger: "2.0"

info:
title: OAuth Example
version: "1.0"

paths:
/secret:
get:
summary: Return secret string
operationId: app.get_secret
responses:
200:
description: secret response
schema:
type: string
security:
# enable authentication and require the "uid" scope for this endpoint
- oauth2: ['uid']

securityDefinitions:
oauth2:
type: oauth2
flow: implicit
authorizationUrl: https://example.com/oauth2/dialog
# the token info URL is hardcoded for our mock_tokeninfo.py script
# you can also pass it as an environment variable TOKENINFO_URL
x-tokenInfoUrl: http://localhost:7979/tokeninfo
scopes:
uid: Unique identifier of the user accessing the service.
30 changes: 30 additions & 0 deletions examples/swagger2/oauth2/mock_tokeninfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env python3
"""
Mock OAuth2 token info
"""

import firetail
from firetail import request

# our hardcoded mock "Bearer" access tokens
TOKENS = {"123": "jdoe", "456": "rms"}


def get_tokeninfo() -> dict:
try:
_, access_token = request.headers["Authorization"].split()
except Exception:
access_token = ""

uid = TOKENS.get(access_token)

if not uid:
return "No such token", 401

return {"uid": uid, "scope": ["uid"]}


if __name__ == "__main__":
app = firetail.FlaskApp(__name__)
app.add_api("mock_tokeninfo.yaml")
app.run(port=7979)
23 changes: 23 additions & 0 deletions examples/swagger2/oauth2/mock_tokeninfo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
swagger: "2.0"

info:
title: Mock OAuth Token Info
version: "1.0"

paths:
/tokeninfo:
get:
summary: OAuth2 token info
operationId: mock_tokeninfo.get_tokeninfo
responses:
200:
description: Token info object
schema:
type: object
properties:
uid:
type: string
scope:
type: array
items:
type: string
24 changes: 24 additions & 0 deletions examples/swagger2/oauth2_local_tokeninfo/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
===============================
OAuth2 Local Validation Example
===============================

This example demonstrates how to implement a resource server with Connexion.
The app will lookup OAuth2 Bearer tokens in a static map.

Running:

.. code-block:: bash

$ sudo pip3 install --upgrade connexion # install Connexion from PyPI
$ ./app.py

Now open your browser and go to http://localhost:8080/ui/ to see the Swagger UI.

You can use the hardcoded tokens to request the endpoint:

.. code-block:: bash

$ curl http://localhost:8080/secret # missing authentication
$ curl -H 'Authorization: Bearer 123' http://localhost:8080/secret
$ curl -H 'Authorization: Bearer 456' http://localhost:8080/secret

26 changes: 26 additions & 0 deletions examples/swagger2/oauth2_local_tokeninfo/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python3
"""
Basic example of a resource server
"""

import firetail

# our hardcoded mock "Bearer" access tokens
TOKENS = {"123": "jdoe", "456": "rms"}


def get_secret(user) -> str:
return f"You are: {user}"


def token_info(access_token) -> dict:
uid = TOKENS.get(access_token)
if not uid:
return None
return {"uid": uid, "scope": ["uid"]}


if __name__ == "__main__":
app = firetail.FlaskApp(__name__)
app.add_api("app.yaml")
app.run(port=8080)
28 changes: 28 additions & 0 deletions examples/swagger2/oauth2_local_tokeninfo/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
swagger: "2.0"

info:
title: OAuth Example
version: "1.0"

paths:
/secret:
get:
summary: Return secret string
operationId: app.get_secret
responses:
200:
description: secret response
schema:
type: string
security:
# enable authentication and require the "uid" scope for this endpoint
- oauth2: ['uid']

securityDefinitions:
oauth2:
type: oauth2
flow: implicit
authorizationUrl: https://example.com/oauth2/dialog
x-tokenInfoFunc: app.token_info
scopes:
uid: Unique identifier of the user accessing the service.
Loading