{ "info": { "author": "Hiroaki Yamamoto", "author_email": "hiroaki@hysoftware.net", "bugtrack_url": null, "classifiers": [ "Framework :: Flask", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries", "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# One-Time Password Field for WT-Forms\n\n[![Build Status]][Build Status Link]\n[![Maintainability]][Maintainability Link]\n[![Test Coverage]][Coverage Link]\n\n\n[Build Status]: https://travis-ci.org/hiroaki-yamamoto/WTF-OTP.svg?branch=master\n[Build Status Link]: https://travis-ci.org/hiroaki-yamamoto/WTF-OTP\n[Maintainability]: https://api.codeclimate.com/v1/badges/c03f10d1351fa391e1d2/maintainability\n[Maintainability Link]: https://codeclimate.com/github/hiroaki-yamamoto/WTF-OTP/maintainability\n[Test Coverage]: https://api.codeclimate.com/v1/badges/c03f10d1351fa391e1d2/test_coverage\n[Coverage Link]: https://codeclimate.com/github/hiroaki-yamamoto/WTF-OTP/test_coverage\n\n\n## What This?\n\nThis module has Google's [2 factor authentication fields] for [WT-Forms].\n\n[2 factor authentication fields]: https://github.com/google/google-authenticator\n[WT-Forms]: https://wtforms.readthedocs.org/\n\n## Features\n* Single-Page Application driven secret key generation.\n* **QRCode Generation**\n* Secret field and authentication validator that is based on [WTForms]\n\n[WT-Forms]: https://wtforms.readthedocs.org/\n\n## How to use\n\n### If you want QR Code:\nFirst, write the form to generate secret key and authenticate it:\n\n`form.py`\n```python\n#!/usr/bin/env python\n# coding=utf-8\n\nfrom flask_wtf import Form\nimport wtforms.fields as fld\nimport wtforms.fields.html5 as fld5\nimport wtforms.validators as vld\nfrom wtf_otp import OTPSecretKeyField, OTPCheck\n\nclass UserInfoForm(Form):\n name = fld.StringField()\n email = fld5.EmailField(validators=[\n vld.InputRequired(), vld.Email()\n ])\n password = fld.PasswordField()\n new_password = fld.PasswordField()\n confirm_password = fld.PasswordField(validators=[\n vld.EqualTo(\"new_password\")\n ])\n secret = OTPSecretKeyField(\n qrcode_url=\"/qrcode\", validators=[vld.InputRequired()]\n )\n\nclass LoginForm(Form):\n email = fld5.EmailField(validators=[\n vld.InputRequired(), vld.Email()\n ])\n passwrd = fld.PasswordField(validators=[\n vld.InputRequired()\n ])\n auth = fld.IntegerField(validators=[\n validators=[vld.InputRequired(), OTPCheck()]\n ])\n```\n\nNext, write the app as usual. However, you want to add a new route of which\npath is \"/qrcode\" that generates the qrcode. Fortuantely, the sufficient\nfunction is provided. An instance of `OTPSecretKeyField` provides `qrcode`\nfunction:\n\n```python\nfrom .form import UserInfoForm\n\n# /qrcode is assigned to generate_qrcode.\ndef generate_qrcode(req, res):\n form = UserInfoForm()\n secret = req.args.get(\"secret\")\n if not secret:\n abort(404)\n res.make_response(form.secret.qrcode(\n secret, name=\"Test Example\", issuer_name=\"Test Corp\"\n ))\n resp.mimetype = \"image/svg+xml\"\n```\n\nNote that you can't get the instance by `UserInfoForm.secret`, because\n`UserInfoForm.secret` returns an instance of `UnboundField`.\n\n## If you don't want QRCode\nIf you don't want QRCode, just remove `qrcode_url` from the corresponding\nclasses and remove QRCode generation class.\n\n## More detail\nIf you want more detail, please refer [source code] and [example code].\n\n[source code]: wtf_otp\n[example code]: example\n\n## License (MIT License)\n\nThe MIT License (MIT)\nCopyright (c) 2016- Hiroaki Yamamoto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.", "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/hiroaki-yamamoto/WTF-OTP", "keywords": "WTForms WT-Forms OTP One Time Password", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "WTF-OTP", "package_url": "https://pypi.org/project/WTF-OTP/", "platform": "", "project_url": "https://pypi.org/project/WTF-OTP/", "project_urls": { "Homepage": "https://github.com/hiroaki-yamamoto/WTF-OTP" }, "release_url": "https://pypi.org/project/WTF-OTP/0.6.0/", "requires_dist": null, "requires_python": "", "summary": "One-Time Password for WTForms", "version": "0.6.0" }, "last_serial": 4429781, "releases": { "0.5.0": [], "0.5.1": [ { "comment_text": "", "digests": { "md5": "fb13847d393437dbbfb2ddc758577ce2", "sha256": "ac1801e999226c47b53b8c0e0a08c88acfac30b9185ae78336fafb644806d003" }, "downloads": -1, "filename": "WTF-OTP-0.5.1.tar.gz", "has_sig": false, "md5_digest": "fb13847d393437dbbfb2ddc758577ce2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13126, "upload_time": "2016-07-15T00:13:09", "url": "https://files.pythonhosted.org/packages/5f/0c/993e0554c1560d9d1795f44a82b0235822e41a758687b034ebdd80eada98/WTF-OTP-0.5.1.tar.gz" } ], "0.5.2": [ { "comment_text": "", "digests": { "md5": "0f08fbb4df5b276a215ed046f5cee7ed", "sha256": "668472a18998a9375a25f4dd6e3529ac3dc8ee97c822716ce2128878d4f800df" }, "downloads": -1, "filename": "WTF-OTP-0.5.2.tar.gz", "has_sig": false, "md5_digest": "0f08fbb4df5b276a215ed046f5cee7ed", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13128, "upload_time": "2016-07-15T08:01:42", "url": "https://files.pythonhosted.org/packages/e2/39/9123b7f799891e11c34b512d968773bdf5d1fbc68aa79424d1c7652d94da/WTF-OTP-0.5.2.tar.gz" } ], "0.5.9": [ { "comment_text": "", "digests": { "md5": "24e19aa794b3ac18ec8d98f5112f49ce", "sha256": "17578480317bd8b2afbd61aee3604d65f741d1ea331bf6cc0618b2f7267db47d" }, "downloads": -1, "filename": "WTF-OTP-0.5.9.tar.gz", "has_sig": false, "md5_digest": "24e19aa794b3ac18ec8d98f5112f49ce", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10900, "upload_time": "2018-10-30T02:09:19", "url": "https://files.pythonhosted.org/packages/6e/2b/c4dd483e84a4555be99465c5a3acc8f04d1f2aafacfefec0d99f2d30a643/WTF-OTP-0.5.9.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "768dba0fadb6a1c2be63ce299ba724f9", "sha256": "7ddf8cd3b7948f7a289c069516c129384068afedb7905f23b4d979ed6519fee8" }, "downloads": -1, "filename": "WTF-OTP-0.6.0.tar.gz", "has_sig": false, "md5_digest": "768dba0fadb6a1c2be63ce299ba724f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10900, "upload_time": "2018-10-30T02:12:01", "url": "https://files.pythonhosted.org/packages/ef/b1/015281ab79ee57fcb80f76c69e3a5012953d342bb2134ec99e4d5608741b/WTF-OTP-0.6.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "768dba0fadb6a1c2be63ce299ba724f9", "sha256": "7ddf8cd3b7948f7a289c069516c129384068afedb7905f23b4d979ed6519fee8" }, "downloads": -1, "filename": "WTF-OTP-0.6.0.tar.gz", "has_sig": false, "md5_digest": "768dba0fadb6a1c2be63ce299ba724f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10900, "upload_time": "2018-10-30T02:12:01", "url": "https://files.pythonhosted.org/packages/ef/b1/015281ab79ee57fcb80f76c69e3a5012953d342bb2134ec99e4d5608741b/WTF-OTP-0.6.0.tar.gz" } ] }