{ "info": { "author": "Omar Ryhan", "author_email": "omarryhan@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "

\n \"Logo\"\n

\n \"Build\n \"Software\n \"Code\n \"Downloads\"\n \"Monthly\n

\n

\n\n# Flask-Stateless-Auth\n\nA lightweight no-batteries-included stateless authentication extension for Flask.\n\n## Features\n\n- Flask-Stateless-Auth assists with stateless authentication in case a Flask developer decides to:\n - Authenticate statelessly without the use of sessions.\n - Not to issue signed tokens e.g.(JWT), instead issue tokens that are to be validated against a db or a datastore of sorts.\n \n- Flask-Stateless-Auth stores a current_stateless_user variable in the request context upon authentication using the `token_required` decorator\n\n- Developer is free to implement their own authorization scheme, However:\n - A typical `header_name` is 'Authorization'\n - A typical `auth_type` is 'Bearer'\n - A typical `token` is a random b64 encoded string.\n - A typical `token_type` is: an access or refresh token\n\n- 2 Signals provided:\n 1. `user-authorized`\n 2. `user-unauthorized`\n\n## Setup \u2699\ufe0f\n\n $ pip install flask-stateless-auth\n\n## Quick Start \n\n```python 3.7\n# initializations\nstateless_auth_manager = StatelessAuthManager()\napp = Flask(__name__.split('.')[0])\n\n# configs\nclass Config:\n #TOKEN_TYPE = 'Bearer' # Default\n #TOKEN_HEADER = 'Authorization'# Default\n #ADD_CONTEXT_PROCESSOR = True # Default\n #DEFAULT_TOKEN_TYPE = 'access' # Default\n\n# models\nclass User(UserMixin):\n def __init__(self, id, username):\n self.id = id\n self.username = username\n\nclass Token(TokenMixin):\n def __init__(self, user_id, access_token, refresh_token):\n self.user_id = user_id\n self.access_token = access_token\n self.refresh_token = refresh_token \n\n# db\nusers = [\n User(1, 'first_user'),\n User(2, 'second_user')\n]\n\ntokens = [\n Token(1, 'first_user_access_token', 'first_user_refresh_token'),\n Token(2, 'second_user_access_token', 'second_user_refresh_token')\n]\n\n# First loader\n@stateless_auth_manager.token_loader\ndef token_by(token, token_type, auth_type):\n''' where `token` is the token loaded from the header '''\n try:\n for token in tokens:\n if token_type == 'access'\n if token.access_token == token:\n return token\n elif token_type == 'refresh':\n if token.refresh_token == token:\n return token\n raise StatelessAuthError(msg='{} Invalid token'.format(token.type), code=401, type_='Token')\n except StatelessAuthError:\n raise\n except Exception as e:\n log.critical(e)\n raise StatelessAuthError(msg='internal server error', code=500, type_='Server')\n\n# Second loader\n@stateless_auth_manager.user_loader\ndef user_by_token(token):\n''' where `token` is the token model loaded from the token table '''\n try:\n for user in users:\n if user.id == token.id: return user\n except Exception as e:\n log.critical(e)\n raise StatelessAuthError(msg='internal server error', code=500, type_='Server')\n log.critical('token: {} belongs to a user: {} but user wasn't found'.format(token.id, user.id))\n raise StatelessAuthError(msg='internal server error', code=500, type_='Server')\n\n# Error handler\n@app.errorhandler(StatelessAuthError)\ndef handle_stateless_auth_error(error):\n return jsonify({'error': error.full_msg}), error.code\n\n@app.route('/secret', methods=['GET'])\n@token_required(token_type='access', auth_type='Bearer') #access by default\ndef secret():\n data = {'secret': 'Stateless auth is awesome :O'}\n return jsonify(data), 200\n\n@app.route('/whoami', methods=['GET'])\n@token_required\ndef whoami():\n data = {'my_username': current_stateless_user.username}\n return jsonify(data), 200\n\nif __name__ == '__main__':\n app.config.from_object(Config())\n stateless_auth_manager.init_app(app)\n app.run()\n```\n\n- For a more practical example, check out: `tests/app_example.py` and `tests/test_app.py`.\n\n## Important Remarks:\n\n1. Flask-Stateless-Auth enforces the use of the following authorization format:\n - `{\"header_name\": \"auth_type\" + \" \" + \"token\"}`\n\n2. Flask-Stateless-Auth needs 2 callbacks in order to function properly:\n\n 1. `token_loader`: Should load a token from your models given, a `token`, `token_type`, and `auth_type`\n 2. `user_loader`: Should load a user from your models given token(token loaded from `token_loader`)\n\n3. Flask-Stateless-Auth also needs a StatlessAuthError error handler. The handler will receive an error with the following attributes:\n\n - `error.code`: suggested status code\n - `error.msg`: message\n - `error.type`: Error type ('token', 'request', 'scope')\n - `error.full_msg`: Error msg + type\n - The developer can then decide how to handle each error seperately by controlling the info they would want to give out to the api client.\n\n4. It is recommended that you raise a StatelessAuthError in case a token or a user cannot be loaded. However, you can still return `None` and FlaskStatelessAuth will return a generic error message and code.\n\n5. Your token model must have an `is_expired()` method that takes a request's `auth_type` (e.g. 'bearer') and `token_type` (e.g. 'access' or 'refresh') and returns a boolean.\n\n6. Your user model must have an `is_active` property that returns a boolean.\n\n7. If you don't want to implement point `5.` and `6.` then you can simply make your token and user models inherit from the `TokenMixin` and `UserMixin` mixins respecitvely.\n\n## Testing\n\n $ tox\n\n## API\n\n- StatelessAuthManager\n- StatelessAuthError\n- current_stateless_user\n- token_required()\n- TokenMixin\n- UserMixin\n\n## Contact \ud83d\udce7\n\nI currently work as a freelance software devloper. Like my work and got a gig for me?\n\nWant to hire me fulltime? Send me an email @ omarryhan@gmail.com\n\n## Buy me a coffee \u2615\n\n**Bitcoin:** 3NmywNKr1Lzo8gyNXFUnzvboziACpEa31z\n\n**Ethereum:** 0x1E1400C31Cd813685FE0f6D29E0F91c1Da4675aE\n\n**Bitcoin Cash:** qqzn7rsav6hr3zqcp4829s48hvsvjat4zq7j42wkxd\n\n**Litecoin:** MB5M3cE3jE4E8NwGCWoFjLvGqjDqPyyEJp\n\n**Paypal:** https://paypal.me/omarryhan", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/omarryhan/flask-stateless-auth", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "flask-stateless-auth", "package_url": "https://pypi.org/project/flask-stateless-auth/", "platform": "", "project_url": "https://pypi.org/project/flask-stateless-auth/", "project_urls": { "Homepage": "https://github.com/omarryhan/flask-stateless-auth" }, "release_url": "https://pypi.org/project/flask-stateless-auth/0.0.17/", "requires_dist": null, "requires_python": "", "summary": "Flask stateless authentication with secrets", "version": "0.0.17" }, "last_serial": 5362604, "releases": { "0.0.10": [ { "comment_text": "", "digests": { "md5": "ef060b1f8a8b64723ab3a9d28df044df", "sha256": "ef01f62234815bace2992c4e0b407f95ec8b6f76dd7b187b016dec4a41447b23" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.10.tar.gz", "has_sig": false, "md5_digest": "ef060b1f8a8b64723ab3a9d28df044df", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5021, "upload_time": "2018-09-13T09:36:48", "url": "https://files.pythonhosted.org/packages/86/76/1be9ebf5d671f26b0b5d4712dbfa8c5760d65ad91ef30a64e5df1ced5438/flask-stateless-auth-0.0.10.tar.gz" } ], "0.0.11": [ { "comment_text": "", "digests": { "md5": "27ba776f4e847d9d56b7d958aaa2041c", "sha256": "1d78ec380cf7b229eefbfc1c7b3913a8fb4b136762160433fc5d54a1adf0aa80" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.11.tar.gz", "has_sig": false, "md5_digest": "27ba776f4e847d9d56b7d958aaa2041c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5049, "upload_time": "2018-09-15T13:47:44", "url": "https://files.pythonhosted.org/packages/64/21/5441bf7ebaa59929e6822556e6355c0fbaef341bf23d54d90db244376d27/flask-stateless-auth-0.0.11.tar.gz" } ], "0.0.12": [ { "comment_text": "", "digests": { "md5": "59bab2e31ef5c1a7c132b460e36b92dd", "sha256": "d444d6d235e744346dca51b19e00ff8ba63dff6064adbf604e9c52442ba10b1e" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.12.tar.gz", "has_sig": false, "md5_digest": "59bab2e31ef5c1a7c132b460e36b92dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5132, "upload_time": "2018-09-16T07:20:13", "url": "https://files.pythonhosted.org/packages/f3/7e/31eefbc6ee2e1a39094117eb3196ab196667ced5fb724ab6c9beb4a1b61d/flask-stateless-auth-0.0.12.tar.gz" } ], "0.0.13": [ { "comment_text": "", "digests": { "md5": "0c94d3bd83a13ffd2404289c10eccf0e", "sha256": "c0eb17dfa0fcef285fd7ce0dc25f4a608979aab9f221041290307a63717df76a" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.13.tar.gz", "has_sig": false, "md5_digest": "0c94d3bd83a13ffd2404289c10eccf0e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5190, "upload_time": "2018-09-16T07:31:58", "url": "https://files.pythonhosted.org/packages/01/d8/88a61209178da601767ea11072175b72c0d06aa07b8190c238066d082c55/flask-stateless-auth-0.0.13.tar.gz" } ], "0.0.14": [ { "comment_text": "", "digests": { "md5": "2b6604f0210f5559e8cfa1c9100489d2", "sha256": "91cb4ab481dc1f15601f9194c3cd36d5e62174a1f9557fec0992617a7a1374b4" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.14.tar.gz", "has_sig": false, "md5_digest": "2b6604f0210f5559e8cfa1c9100489d2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5153, "upload_time": "2018-09-17T20:13:55", "url": "https://files.pythonhosted.org/packages/c9/7f/294a92c58d2de33e60997ecfb1d49b680a620c49bf6d1d0623131ebc7fc1/flask-stateless-auth-0.0.14.tar.gz" } ], "0.0.15": [ { "comment_text": "", "digests": { "md5": "3832c31162d05caf029ec3186f883051", "sha256": "fb26d1e81918c837798f3f717c6d8d5b7b537e440774de20b4a7fa088f650d2c" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.15.tar.gz", "has_sig": false, "md5_digest": "3832c31162d05caf029ec3186f883051", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9896, "upload_time": "2018-09-23T15:39:32", "url": "https://files.pythonhosted.org/packages/0c/39/bca14d2635b2a7d1a247e5eb7d1279378b165ef8fa009ca10eedc13355a3/flask-stateless-auth-0.0.15.tar.gz" } ], "0.0.16": [ { "comment_text": "", "digests": { "md5": "9f98421347fdc5097ef89df2c25e1a71", "sha256": "72164eb8cb7fb6b04f7ea9bdfb41aec15329023e44178a01d8aa8875ff135951" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.16.tar.gz", "has_sig": false, "md5_digest": "9f98421347fdc5097ef89df2c25e1a71", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10066, "upload_time": "2018-09-27T10:25:18", "url": "https://files.pythonhosted.org/packages/fd/df/22d1b4d2c4ee05aec341720cf72ed094f06377614db2ef5f91f3c05eac7a/flask-stateless-auth-0.0.16.tar.gz" } ], "0.0.17": [ { "comment_text": "", "digests": { "md5": "9bd267c0f3c8ffa873bf12a810d47554", "sha256": "c9be6aba83e3b0cc8ff50e2c51fb7e8174396f0903e1404e3145c704267f89b0" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.17.tar.gz", "has_sig": false, "md5_digest": "9bd267c0f3c8ffa873bf12a810d47554", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9150, "upload_time": "2019-06-05T13:52:19", "url": "https://files.pythonhosted.org/packages/d8/f5/5e14780ec7bdb4398c46ec9c5f0e4a8774b748518bcba61198c727f1b659/flask-stateless-auth-0.0.17.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "fcffb25680a670b6a6a5b60a0848394c", "sha256": "2abcff13919bb719106387ec934808c7d8c60977cba85609a8b73e178cc7df08" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.3.tar.gz", "has_sig": false, "md5_digest": "fcffb25680a670b6a6a5b60a0848394c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8118, "upload_time": "2018-09-04T12:08:06", "url": "https://files.pythonhosted.org/packages/25/5b/bbaf7ccdced2bcfc30dcc4b6a48f38b1e0481ff389529a931ae21e01e857/flask-stateless-auth-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "995cb8852f29eb78ae741349b47e458d", "sha256": "f3d8faefd23a2cd707da3733119e84c2b5605addd1ff1a7f5f2dc6fab3070cb0" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.4.tar.gz", "has_sig": false, "md5_digest": "995cb8852f29eb78ae741349b47e458d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5155, "upload_time": "2018-09-04T12:57:25", "url": "https://files.pythonhosted.org/packages/33/93/90fa9d09b6c4d8a63a9d44cb412974879d40bd966589f87832e5503693f6/flask-stateless-auth-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "322d0feea4b5d9d94dd1b29ad3da1112", "sha256": "4782fc79f4309cc50864abb742f7217dbc804a8c6ec4076985c25a840f472d24" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.5.tar.gz", "has_sig": false, "md5_digest": "322d0feea4b5d9d94dd1b29ad3da1112", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4858, "upload_time": "2018-09-04T16:54:53", "url": "https://files.pythonhosted.org/packages/18/c3/9b876f2bf9bdb21839c716b21acf8d0a899dfe697dbbcc0cc3cfd4c7595d/flask-stateless-auth-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "cda14c8f6486829aba7bc9056e340e6a", "sha256": "0201c7b75be95cc57d0fd9128a7c5ce423d9f0461f365d84a33bc0db490620e8" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.6.tar.gz", "has_sig": false, "md5_digest": "cda14c8f6486829aba7bc9056e340e6a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4908, "upload_time": "2018-09-04T17:50:50", "url": "https://files.pythonhosted.org/packages/cc/2c/cfede972b1083d4bb6bb43bfd8fd33ac8a9936c9efad4fdbd0979714a95b/flask-stateless-auth-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "d1f36a0b3cc1403114cfcdf3c312c0fb", "sha256": "c64dd15d7d44f01ca3fbffe9793a423c24756a855e34aff6e9e738702061335f" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.7.tar.gz", "has_sig": false, "md5_digest": "d1f36a0b3cc1403114cfcdf3c312c0fb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4893, "upload_time": "2018-09-04T18:42:08", "url": "https://files.pythonhosted.org/packages/cb/3a/b198df16f234aa95cfcf66f293d97c7be695e8d26c535b828700173301ff/flask-stateless-auth-0.0.7.tar.gz" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "6c43d568bfd4ba6313c0469618dfe67c", "sha256": "e1ebf56dd700732841f9c8d27e877c9a794db82bd1edcf9f1a745e77c7e20a1f" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.8.tar.gz", "has_sig": false, "md5_digest": "6c43d568bfd4ba6313c0469618dfe67c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5004, "upload_time": "2018-09-09T10:38:52", "url": "https://files.pythonhosted.org/packages/7e/04/615c68d40c7c844c53726e3d665260affe51e3b843d69ab7843f0a85696e/flask-stateless-auth-0.0.8.tar.gz" } ], "0.0.9": [ { "comment_text": "", "digests": { "md5": "652439afd4cc74dc67955584d76245c3", "sha256": "247f05825ac8f373c312ac6d7c93315c962ed0065ba65255caae9ac795c6284d" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.9.tar.gz", "has_sig": false, "md5_digest": "652439afd4cc74dc67955584d76245c3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4997, "upload_time": "2018-09-10T18:41:40", "url": "https://files.pythonhosted.org/packages/d2/ee/2b9db48dd2525af3ebe365e7477e60da5dd623f7374097757dbc05c264a3/flask-stateless-auth-0.0.9.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "9bd267c0f3c8ffa873bf12a810d47554", "sha256": "c9be6aba83e3b0cc8ff50e2c51fb7e8174396f0903e1404e3145c704267f89b0" }, "downloads": -1, "filename": "flask-stateless-auth-0.0.17.tar.gz", "has_sig": false, "md5_digest": "9bd267c0f3c8ffa873bf12a810d47554", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9150, "upload_time": "2019-06-05T13:52:19", "url": "https://files.pythonhosted.org/packages/d8/f5/5e14780ec7bdb4398c46ec9c5f0e4a8774b748518bcba61198c727f1b659/flask-stateless-auth-0.0.17.tar.gz" } ] }