[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Desktop (please complete the following information):**\n - OS: [e.g. iOS]\n\n**Smartphone (please complete the following information):**\n - Device: [e.g. Samsung M30]\n - OS: [e.g. Android 10]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/workflows/python-publish.yml",
    "content": "# This workflow will upload a Python Package using Twine when a release is created\n# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries\n\n# This workflow uses actions that are not certified by GitHub.\n# They are provided by a third-party and are governed by\n# separate terms of service, privacy policy, and support\n# documentation.\n\nname: Upload Python Package\n\non:\n  release:\n    types: [published]\n\npermissions:\n  contents: read\n\njobs:\n  deploy:\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v3\n    - name: Set up Python\n      uses: actions/setup-python@v3\n      with:\n        python-version: '3.x'\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install build\n    - name: Build package\n      run: python -m build\n    - name: Publish package\n      uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29\n      with:\n        user: __token__\n        password: ${{ secrets.PYPI_API_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\npip-wheel-metadata/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n.python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# PEP 582; used by e.g. github.com/David-OConnor/pyflow\n__pypackages__/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n.buildozer\n.vscode\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n"
  },
  {
    "path": ".travis.yml",
    "content": "cache: pip\nmatrix:\n  fast_finish: true\n  include:\n  - name: Black\n    env: RUN=black\n    language: python\n    python: 3.7\n    os: linux\n    dist: bionic\ninstall:\n- pip install pycodestyle\nscript:\n- pycodestyle kivyauth/android/__init__.py\nafter_failure:\n- sleep 10;\n- echo == End ==\ndeploy:\n  skip_existing: true\n  provider: pypi\n  user: __token__\n  password:\n    secure: HDX4vTR4+shTPAc2+SPOE5Z+/5eZkvlX0JtDY+UniEbdSUougWxS1Z+TxWSlQQyL1LE0wB3Wxt1EimBYPDgKu+AiIhSXkjonGvnD4txXTV1qolDOudNzWndu+yPc2AnZi8eWaRGE+s7cJjWVeW7ddCZGfCS2WycSLz3MtGXJfPOz4bB+UhAWc+uAj8VBu72ZeyU8QFRvYgCbeHVAhFcx4U1t6gju601/n3eoylJsUb4Dx/ssCARMplHjW81MvGCX7jbuBadB/mOoo7FdQ42PCzPtDIxeyORR8T6gKcWWga+IWswf8bWau//ry/walbWWqegIam7XeXQK8a1nDMqGGJ0Sn4J5jpJS8wVnmK6Dtw6VALtmPTUd+S7p1pnaDCvEF79zv33qowrVbe4hgHPsX+RWHVs1Vkv2MJ+WtUoDuQizeK7pi+DIpDkHXSZCZRSd2m1pDEz51DjDhKJVJfKmuypIaf2yRtiNpnJgtqfSC9Hk+ErcZW9C311oyFzHIvTlYjlQfepfl3cUImwBoj6FTIUPovLbnn6eXh6k45GltBLG5mOt8nWpFvhHDNf+kcCotyqxTpS46a5p0p4rpsURELSXLsCUely1g1xqEkXLWVeu793qBZweyahiAp9iH+gx+za8xjip5Rty5uUxITuPbv1ITU6nEshQKvbrNfwwALA=\n  distributions: sdist bdist_wheel\n  on:\n    tags: true\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Shashi Ranjan\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.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\"> <img src=\"https://raw.githubusercontent.com/shashi278/social-auth-kivy/master/demo/kivyauth_logo.png\" width=\"30%\" ></img> </p>\n\n\n# KivyAuth\n#### *Integrate Google, Facebook, Github &amp; Twitter login in kivy applications*\n[![build](https://travis-ci.org/shashi278/social-auth-kivy.svg?branch=master)](https://travis-ci.org/github/shashi278/social-auth-kivy/) [![Python 3.6](https://img.shields.io/pypi/pyversions/kivymd)](https://www.python.org/downloads/release/python-360/) [![pypi](https://img.shields.io/pypi/v/kivyauth)](https://pypi.org/project/KivyAuth/) [![license](https://img.shields.io/pypi/l/kivyauth)](https://github.com/shashi278/social-auth-kivy/blob/master/LICENSE) [![format](https://img.shields.io/pypi/format/kivyauth)](https://pypi.org/project/KivyAuth/#modal-close) [![downloads](https://img.shields.io/pypi/dm/kivyauth)](https://pypi.org/project/KivyAuth/) [![code size](https://img.shields.io/github/languages/code-size/shashi278/social-auth-kivy)]() [![repo size](https://img.shields.io/github/repo-size/shashi278/social-auth-kivy)]()\n\n### KivyAuth on Android\n![Demo Gif](https://raw.githubusercontent.com/shashi278/social-auth-kivy/master/demo/demo.gif)\n\n<a href='https://play.google.com/store/apps/details?id=com.watney.glogin' ><img src='https://raw.githubusercontent.com/steverichey/google-play-badge-svg/266d2b2df26f10d3c00b8129a0bd9f6da6b19f00/img/en_get.svg' alt='Get it on Playstore' width=200/> </a>\n\n##\n### KivyAuth on Desktop\n![Desktop_demo_test gif](https://raw.githubusercontent.com/shashi278/social-auth-kivy/cross-platform/demo/kivyauth_desktop_alpha.gif)\n\n\n### Run [demo](demo/) app on desktop:\n * **Make Sure you've created OAuth apps and have their CLIENT_ID and CLIENT_SECRET handy before running demo application**\n * Create an .env file in the app directory with below format:\n  ```properties\n  GOOGLE_CLIENT_ID=<Your-client-id-from-google-cloud-console>\n  GOOGLE_CLIENT_SECRET=<Your-Client-Secret>\n\n  FACEBOOK_CLIENT_ID=<Your-Facebook-Client-id>\n  FACEBOOK_CLIENT_SECRET=<Your-Facebook-Client-secret>\n\n  GITHUB_CLIENT_ID=<Github-Client-id>\n  GITHUB_CLIENT_SECRET=<Github-Client-secret>\n\n  ```\n\n##\n## How to use\n\n### Instruction for using KivyAuth on Desktop:\n* pip install kivyauth==2.3.3\n\n### Note for android:\n  Make sure you go through the [prerequisites](https://github.com/shashi278/social-auth-kivy/blob/master/docs/prerequisites.md)\n  for the login methods you're going to integrate in your application before moving further\n\n#\nThe example below shows integrating google login. Similarly other login methods can also be used.\n\n* Include necessary imports for google login\n```python\nfrom kivyauth.google_auth import initialize_google, login_google, logout_google\n```\n\n* Initialize google login inside your app's build method\n```python\ndef build(self):\n  initialize_google(self.after_login, self.error_listener)\n```\n`after_login` is a function to be called upon successful login with `name`, `email`, and `photo url` of the user. So, create a success listener function which accepts three parameters and perform after-login stuffs(like updating UI, etc.). `error_listener` is called in case of any error and it doesn't accept any argument.\n\n* You can also add auto-login( if the user is already logged in then directly move to after-login stuff) inside app's `on_start` method as below(mention only login providers you are using in your app):\n```python\ndef on_start(self):\n\n    if auto_login(login_providers.google):\n        self.current_provider = login_providers.google\n    elif auto_login(login_providers.facebook):\n        self.current_provider = login_providers.facebook\n    elif auto_login(login_providers.github):\n        self.current_provider = login_providers.github\n    elif auto_login(login_providers.twitter):\n        self.current_provider = login_providers.twitter\n```\n\n* Next, call `login_google()` upon a button click to initiate login process.\n\n* Similarly, to logout, call `logout_google` as\n```python\nlogout_google(self.after_logout)\n```\n`after_logout` is a function to be called after user gets logged out. For example, to update UI.\n\n* Make sure to include `kivyauth` as a requirement in the buildozer.spec file\n```spec\nrequirements = python3,kivy,kivyauth==2.3.3\n```\n\n\n##  \n### TODO:\n  * Support iOS\n\n##\n### Changelog\n#### v2.3.3\n  *  Fixed werkzeug server not shutting down\n\n\n#### v2.3.2\n  *  Fixed crashing when user doesn't have a photo\n\n\n#### v2.3.1 - KivyAuth cross-platform\n  * Kivyauth APIs are now platform-independent\n  * Desktop support for linux, win and possibly mac\n\n\n#### v2.3 - KivyAuth cross-platform\n  * Desktop support added(in alpha)\n  * All android auths are inside `kivyauth.android` while those for desktops are inside `kivyauth.desktop`\n\n\n#### v2.2\n  * Added Auto-login feature\n  * `login_providers` are now inside `kivyauth` rather than `kivyauth.providers`\n\n\n#### v2.0\n  * Individual login providers are moved into respective folders\n  * Fix problem of not being able to use individual login methods\n  * Now it's relatively easier to use the library\n\n### Other\n![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)\n\n**Contributing**: Contributions are more than welcome. Looking for contributions in making it cross-platform(specifically for iOS) and better documentation.\n\n\nFeel free to ping me or raise an issue if you want to talk about this project or Kivy in general.\n"
  },
  {
    "path": "demo/intents.xml",
    "content": "<intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"fb439926446854840\" />\n        </intent-filter>"
  },
  {
    "path": "demo/main.py",
    "content": "import os\nfrom dotenv import load_dotenv\n\nfrom kivy.lang.builder import Builder\nfrom kivy.metrics import dp\nfrom kivy.uix.image import AsyncImage\nfrom kivy.uix.screenmanager import Screen\nfrom kivy.uix.boxlayout import BoxLayout\nfrom kivy import platform\nfrom kivy.clock import Clock\nfrom kivymd.app import MDApp\nfrom kivymd.uix.button import MDRectangleFlatIconButton\nfrom kivymd.uix.snackbar import Snackbar\nfrom kivymd.uix.behaviors.elevation import CommonElevationBehavior\n\nfrom kivyauth.google_auth import initialize_google, login_google, logout_google\nfrom kivyauth.facebook_auth import initialize_fb, login_facebook, logout_facebook\nfrom kivyauth.github_auth import initialize_github, login_github, logout_github\nfrom kivyauth.twitter_auth import initialize_twitter, login_twitter, logout_twitter\nfrom kivyauth.utils import stop_login\nfrom kivyauth.utils import login_providers, auto_login\n\nload_dotenv()\n\nif platform == \"android\":\n    from android.runnable import run_on_ui_thread\n    from jnius import autoclass, cast\n\n    Toast = autoclass(\"android.widget.Toast\")\n    String = autoclass(\"java.lang.String\")\n    CharSequence = autoclass(\"java.lang.CharSequence\")\n    Intent = autoclass(\"android.content.Intent\")\n    Uri = autoclass(\"android.net.Uri\")\n    NewRelic = autoclass(\"com.newrelic.agent.android.NewRelic\")\n    LayoutParams = autoclass(\"android.view.WindowManager$LayoutParams\")\n    AndroidColor = autoclass(\"android.graphics.Color\")\n\n    PythonActivity = autoclass(\"org.kivy.android.PythonActivity\")\n\n    context = PythonActivity.mActivity\n\n    @run_on_ui_thread\n    def show_toast(text):\n        t = Toast.makeText(\n            context, cast(CharSequence, String(text)), Toast.LENGTH_SHORT\n        )\n        t.show()\n\n    @run_on_ui_thread\n    def set_statusbar_color():\n        window = context.getWindow()\n        window.addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)\n        window.setStatusBarColor(AndroidColor.TRANSPARENT)\n\n\nkv = \"\"\"\n#:import Clock kivy.clock.Clock\n#:import platform kivy.platform\nScreenManager:\n    \n    LoginScreen:\n        id: login_screen\n    \n    HomeScreen:\n        id: home_screen\n\n<LoginScreen>:\n    name:\"loginscreen\"\n    BoxLayout:\n        orientation:\"vertical\"\n\n        MDTopAppBar:\n            title: \"KivyAuth Demo\"\n            elevation:9\n            opposite_colos: True\n            left_action_items: [['menu', lambda x: None]]\n            right_action_items: [['source-fork', lambda x: app.send_to_github()]]\n\n        BoxLayout:\n            orientation:\"vertical\"\n\n            Widget:\n                size_hint_y: None\n                height: dp(100)\n\n            LoginButton\n                text: \"Sign In with Google\"\n                icon: \"google\"\n                text_color: 1,1,1,1\n                can_color: 66/255, 133/255, 244/255, 1\n                release_action: app.gl_login\n            \n            LoginButton\n                text: \"Sign In with Facebook\"\n                icon: \"facebook\"\n                text_color: 1,1,1,1\n                can_color: 59/255, 89/255, 152/255, 1\n                release_action: app.fb_login\n            \n            LoginButton\n                text: \"Sign In with Github\"\n                icon: \"github-circle\" if platform == \"android\" else  \"github\"\n                text_color: 1,1,1,1\n                can_color: 33/255, 31/255, 31/255, 1\n                release_action: app.git_login\n            \n            LoginButton\n                text: \"Sign In with Twitter\"\n                icon: \"twitter\"\n                text_color: 1,1,1,1\n                can_color: 8/255, 160/255, 233/255, 1\n                release_action: app.twitter_login\n            \n            Widget:\n                size_hint_y: None\n                height: dp(100)\n\n<LoginButton@AnchorLayout>:\n    text:\"\"\n    icon: \"\"\n    text_color: [0,0,0,1]\n    can_color: 1,1,1,1\n    release_action: print\n    RectangleRaisedIconButton:\n        width: dp(270)\n        height: dp(50)\n        canvas.before:\n            Color:\n                rgba: root.can_color\n            Rectangle:\n                pos: self.pos\n                size: self.size\n        \n\n        elevation: 8\n        icon: root.icon\n        text: root.text\n        font_size: dp(8) if platform == \"android\" else dp(18)\n        text_color: root.text_color\n        on_release:\n            if root.release_action: Clock.schedule_once(root.release_action, 0)\n        \n\n<HomeScreen@Screen>:\n    name:\"homescreen\"\n\n    BoxLayout:\n        id: main_box\n        orientation:\"vertical\"\n\n        MDTopAppBar:\n            id: user_name\n            title: \"\"\n            elevation: 9\n            opposite_colos: True\n            left_action_items: [['menu', lambda x: None]]\n            right_action_items: [['information-outline', lambda x: None]]\n        \n        AnchorLayout:\n            id: user_photo\n\n        BoxLayout:\n            size_hint_y:None\n            height: dp(20)\n            padding: dp(5)\n            \n            MDLabel:\n                id: user_email\n                halign: \"center\"\n                font_style: \"Body1\"\n                text: \"\"\n\n        AnchorLayout:\n            MDRaisedButton:\n                text: \"LOGOUT\"\n                md_bg_color: .9,.9,.9,1\n                theme_text_color: \"Custom\"\n                text_color: 0,0,0,1\n                on_release:\n                    app.logout_()\n\n\n<Content>:\n    orientation: \"vertical\"\n    size_hint_y: None\n    height: \"90dp\"\n\n    AnchorLayout:\n        MDSpinner:\n            size_hint: None, None\n            size: dp(30), dp(30)\n            pos_hint: {'center_x': .5, 'center_y': .5}\n    \n    AnchorLayout:\n        MDLabel:\n            text: \"Logging in...\"\n            halign: \"center\"\n\"\"\"\n\nclass Content(BoxLayout):\n    pass\n\nclass Content(BoxLayout):\n    pass\n\n\nclass LoginScreen(Screen):\n    pass\n\n\nclass RectangleRaisedIconButton(\n    MDRectangleFlatIconButton, CommonElevationBehavior\n):\n    pass\n\n\nclass LoginDemo(MDApp):\n    current_provider = \"\"\n\n    def build(self):\n        initialize_google(\n            self.after_login,\n            self.error_listener,\n            os.getenv(\"GOOGLE_CLIENT_ID\"),\n            os.getenv(\"GOOGLE_CLIENT_SECRET\"),\n        )\n        initialize_fb(\n            self.after_login,\n            self.error_listener,\n            os.getenv(\"FACEBOOK_CLIENT_ID\"),\n            os.getenv(\"FACEBOOK_CLIENT_SECRET\"),\n        )\n        initialize_github(\n            self.after_login,\n            self.error_listener,\n            os.getenv(\"GITHUB_CLIENT_ID\"),\n            os.getenv(\"GITHUB_CLIENT_SECRET\"),\n        )\n\n        if platform == \"android\":\n            set_statusbar_color()\n        tmp = Builder.load_string(kv)\n        if platform != \"android\":\n            from kivymd.uix.dialog import MDDialog\n            from kivymd.uix.button import MDFlatButton\n\n            btn = MDFlatButton(text=\"CANCEL\", text_color=self.theme_cls.primary_color)\n            btn.bind(on_release=lambda *args: (stop_login(), self.dialog.dismiss()))\n            self.dialog = MDDialog(\n                title=\"\",\n                size_hint_x=None,\n                size_hint_y=None,\n                width=\"250dp\",\n                type=\"custom\",\n                auto_dismiss=False,\n                content_cls=Content(),\n                buttons=[btn],\n            )\n        return tmp\n\n    def on_start(self):\n        if platform == \"android\":\n            if auto_login(login_providers.google):\n                self.current_provider = login_providers.google\n            elif auto_login(login_providers.facebook):\n                self.current_provider = login_providers.facebook\n            elif auto_login(login_providers.github):\n                self.current_provider = login_providers.github\n            elif auto_login(login_providers.twitter):\n                self.current_provider = login_providers.twitter\n            primary_clr= [ 108/255, 52/255, 131/255 ]\n            hex_color= '#%02x%02x%02x' % (int(primary_clr[0]*200), int(primary_clr[1]*200), int(primary_clr[2]*200))\n            set_statusbar_color()\n        pass\n\n    def show_login_progress(self):\n        if platform != \"android\":\n            self.dialog.open()\n\n    def hide_login_progress(self):\n        if platform != \"android\":\n            self.dialog.dismiss()\n\n    def fb_login(self, *args):\n        login_facebook()\n        self.current_provider = login_providers.facebook\n        self.show_login_progress()\n\n    def gl_login(self, *args):\n        login_google()\n        self.current_provider = login_providers.google\n        self.show_login_progress()\n\n    def git_login(self, *args):\n        login_github()\n        self.current_provider = login_providers.github\n        self.show_login_progress()\n\n    def twitter_login(self, *args):\n        login_twitter()\n        self.current_provider = login_providers.twitter\n        self.show_login_progress()\n\n    def logout_(self):\n        if self.current_provider == login_providers.google:\n            logout_google(self.after_logout)\n        if self.current_provider == login_providers.facebook:\n            logout_facebook(self.after_logout)\n        if self.current_provider == login_providers.github:\n            logout_github(self.after_logout)\n        if self.current_provider == login_providers.twitter:\n            logout_twitter(self.after_logout)\n\n    def after_login(self, name, email, photo_uri):\n        self.hide_login_progress()\n\n        if platform == \"android\":\n            show_toast(\"Logged in using {}\".format(self.current_provider))\n        else:\n            Snackbar(text=\"Logged in using {}\".format(self.current_provider)).open()\n\n        self.root.current = \"homescreen\"\n        self.update_ui(name, email, photo_uri)\n\n    def after_logout(self):\n        self.update_ui(\"\", \"\", \"\")\n        self.root.current = \"loginscreen\"\n        if platform == \"android\":\n            show_toast(text=\"Logged out from {} login\".format(self.current_provider))\n        else:\n            Snackbar(\n                text=\"Logged out from {} login\".format(self.current_provider)\n            ).open()\n\n    def update_ui(self, name, email, photo_uri):\n        self.root.ids.home_screen.ids.user_photo.add_widget(\n            AsyncImage(\n                source=photo_uri, size_hint=(None, None), height=dp(60), width=dp(60)\n            )\n        )\n        self.root.ids.home_screen.ids.user_name.title = \"Welcome, {}\".format(name)\n        self.root.ids.home_screen.ids.user_email.text = (\n            \"Your Email: {}\".format(email)\n            if email\n            else \"Your Email: Could not fetch email\"\n        )\n\n    def error_listener(self):\n        if platform == \"android\":\n            show_toast(\"Error logging in.\")\n        else:\n            Snackbar(text=\"Error logging in. Check connection or try again.\").show()\n        Clock.schedule_once(lambda *args: self.hide_login_progress())\n\n    def send_to_github(self):\n        if platform == \"android\":\n            intent = Intent()\n            intent.setAction(Intent.ACTION_VIEW)\n            intent.setData(Uri.parse(\"https://github.com/shashi278/social-auth-kivy\"))\n\n            context.startActivity(intent)\n        else:\n            import webbrowser\n            webbrowser.open(\"https://github.com/shashi278/social-auth-kivy\")\n\n\nif __name__ == \"__main__\":\n    LoginDemo().run()\n"
  },
  {
    "path": "docs/integrate-firebase-auth.md",
    "content": "### Integrate Github and Twitter Login in Kivy Applications\n\n#### Firebase has been used to integrate Github and Twitter logins\n\n##### Prerequisites\n* Declare Firebase as a gradle dependency in your `buildozer.spec` file:\n ```spec\n android.gradle_dependencies = com.google.firebase:firebase-auth:19.3.1\n ```\n* For using firebase in kivy applications, we need to tweak few settings internally:\n  * Build your application once, doesn't matter if it crashes\n  * Then find *build.tmpl.gradle* inside *.buildozer/android/platform/build-armeabi-v7a/dists/app-name__armeabi-v7a/templates/* and change gradle plugin version from 3.1.4 to 3.5.2(I've already created a PR for the same in p4a. Hope they merge it) and add google-services plugin as it's required by firebase and apply the plugin:\n  ```java\n  buildscript {\n    repositories {\n       //...\n    }\n    dependencies {\n        //make sure its 3.5.2 here instead of 3.1.4 \n        classpath 'com.android.tools.build:gradle:3.5.2'\n        \n        //google-services plugin, required by firebase\n        classpath 'com.google.gms:google-services:4.3.3'\n    }\n  }\n  \n  //...\n  \n  // At the bottom\n  apply plugin: 'com.google.gms.google-services'\n  ```\n  * Make sure gradle version is set to latest(6.4.1) inside *gradle-wrapper.properties*(It's been updated in develop branch. If you're using master branch of p4a, you may need to update it manually). This file is located at: *.buildozer/android/platform/build-armeabi-v7a/dists/app-name__armeabi-v7a/gradle/wrapper/*\n  \n  * Copy your *google-services.json* inside *.buildozer/android/platform/build-armeabi-v7a/dists/app-name__armeabi-v7a/*. Its required for firebase authentication.\n\n##### Start Integrating\n  * Feel free to look at their [docs](https://firebase.google.com/docs/auth/android/start) for more.\n  * Add few required java classes for firebase authentication\n  ```python\n  #----Firebase classes for Github and Twitter Login----#\n  FirebaseAuth= autoclass('com.google.firebase.auth.FirebaseAuth')\n  FirebaseApp = autoclass('com.google.firebase.FirebaseApp')\n  OAuthProvider = autoclass('com.google.firebase.auth.OAuthProvider')\n  FirebaseUser = autoclass('com.google.firebase.auth.FirebaseUser')\n  ```\n  * We need to implement two java classes to handle success and failure while logging in.\n  ```python\n    class OnSuccessListener(PythonJavaClass):\n      __javainterfaces__=['com/google/android/gms/tasks/OnSuccessListener']\n      __javacontext__= 'app'\n\n      @java_method('(Ljava/lang/Object;)V')\n      def onSuccess(self, result):\n          # User is signed in\n          # You may get user information like name,email, etc. now and perform after-login stuffs.\n          user = FirebaseAuth.getInstance().getCurrentUser()\n\n          # user.getDisplayName()\n          # user.getEmail()\n          # user.getPhotoUrl().toString()\n\n    class OnFailureListener(PythonJavaClass):\n        __javainterfaces__=['com/google/android/gms/tasks/OnFailureListener']\n        __javacontext__= 'app'\n\n        @java_method('(Ljava/lang/Exception;)V')\n        def onFailure(self, e):\n            #handle exception\n  ```\n  \n  * Next, get an instance of `FirebaseAuth` inside `build` method of your app:\n  ```python\n    self.mAuth= FirebaseAuth.getInstance()\n  ```\n  * Finally, add below codes to start login process inside a method to be called when user clicks the login button:\n  ```python\n    provider = OAuthProvider.newBuilder(\"github.com\") # \"twitter.com\" for twitter login\n    pendingResultTask = FirebaseAuth.getPendingAuthResult()\n    if pendingResultTask:\n        #There's something already here! Finish the sign-in for your user.\n        task= pendingResultTask.addOnSuccessListener(OnSuccessListener())\n        task= task.addOnFailureListener(OnFailureListener())\n    else:\n        #There's no pending result so you need to start the sign-in flow.\n\n        task= FirebaseAuth.startActivityForSignInWithProvider(context, provider.build())\n        task= task.addOnSuccessListener(OnSuccessListener())\n        task= task.addOnFailureListener(OnFailureListener())\n  ```\n  \n"
  },
  {
    "path": "docs/integrate-google-facebook-login.md",
    "content": "## Integrate Google and Facebook Login in Kivy Applications\n\n##\n### Google Login:\n\n#### Prerequisite\n * Declare Google Play services as a gradle dependency in your `buildozer.spec` file:\n ```spec\n android.gradle_dependencies = com.google.android.gms:play-services-auth:18.0.0\n ```\n\n#### Start Integrating\n * Feel free to look at their [doc](https://developers.google.com/identity/sign-in/android/sign-in) for more info\n * Add java classes required for google authentication in your `.py` file:\n ```python\n #----Java Classes For Google Login----#\n Gso= autoclass('com.google.android.gms.auth.api.signin.GoogleSignInOptions')\n GsoBuilder= autoclass('com.google.android.gms.auth.api.signin.GoogleSignInOptions$Builder')\n GSignIn= autoclass('com.google.android.gms.auth.api.signin.GoogleSignIn')\n ApiException= autoclass('com.google.android.gms.common.api.ApiException')\n ```\n * Create instance of `GoogleSignInClient` inside `build` method of your kivy App:\n ```python\n gso= GsoBuilder(Gso.DEFAULT_SIGN_IN).requestEmail().build()\n self.mGSignInClient= GSignIn.getClient(context, gso)\n ```\n   Make sure you've,\n ```python\n PythonActivity= autoclass('org.kivy.android.PythonActivity')\n context= PythonActivity.mActivity\n ```\n * After the user signs in, you can get a `GoogleSignInAccount` object for the user in the activity's `onActivityResult` method.\n   For this, we need to bind our function we want to be called when `onActivityResult` gets called during authentication. We can\n   bind our function using bind function from android.activity as:\n   ```python\n   from android.activity import bind as result_bind\n   \n   # inside build method\n   result_bind(on_activity_result=activity_listener_google)\n   ```\n * Create your activity listener function:\n ```python\n def activity_listener_google(request_code, result_code, data):\n    if request_code == RC_SIGN_IN:\n        task= GSignIn.getSignedInAccountFromIntent(data)\n        try:\n            account= task.getResult(ApiException)\n            if account:\n                #user is logged in\n                #Do stuffs you want after a user gets authenticated\n                #eg. update UI, change screen, etc.\n            \n            else:\n                #unable to get account\n\n        except Exception as e:\n            #Error in signing in\n            \n ```\n `RC_SIGN_IN` is just a unique request code used to differentiate among different requests passed to `onActivityResult`. Define it an\n integer constant.\n \n * Finally, start sign in process when user clicks a button. Create a function in your `App` class to be called upon clicking login\n  button and include below codes:\n ```python\n signInIntent= self.mGSignInClient.getSignInIntent()\n context.startActivityForResult(signInIntent, RC_SIGN_IN)\n \n ```\n \n##\n\n### Facebook Login:\n\n#### Prerequisite\n* We'll be creating our own version of facebook login i.e. using python and kivy by following each step from their [doc](https://developers.facebook.com/docs/facebook-login/android/). So, open it in a new tab and follow it along-side.\n\n#### Start Integrating\n* Follow their instructions in step 1 and create an OAuth App. You may skip step 2.\n\n* For step 3, add Facebook-login SDK as a gradle dependency in your `buildozer.spec` file:\n ```spec\n android.gradle_dependencies = com.facebook.android:facebook-login:7.0.0\n ```\n\n* For 4th step,\n  * Add `INTERNET` permission in `buildozer.spec` file\n    ```spec\n    android.permissions = INTERNET\n    ```\n  * Find `android.meta_data` in buildozer.spec file and make it to look like\n    ```spec\n    android.meta_data = com.facebook.sdk.ApplicationId=fb<App-ID-of-your-OAuth-App>\n    ```\n  * Next, find `android.add_activities` in buildozer.spec file and add some activity classes\n    ```spec\n    android.add_activites = com.facebook.FacebookActivity, com.facebook.CustomTabActivity\n    ```\n  * Lastly, create an xml file in the same directory as `main.py`. Name it whatever you like and add this into that xml file\n    ```xml\n    <intent-filter>\n             <action android:name=\"android.intent.action.VIEW\" />\n             <category android:name=\"android.intent.category.DEFAULT\" />\n             <category android:name=\"android.intent.category.BROWSABLE\" />\n         </intent-filter>\n    ```\n    Now add this xml as an intent filter in the spec file\n    ```spec\n    android.manifest.intent_filters = <file-name>.xml\n    ```\n\n* Do as instructed in step 5 and 6\n\n* Skip steps 7 and 8\n\n* For next steps, we'll be implementing few java interfaces in python.\n  \n  * Include few required java classes:\n    ```python\n    #----Java Classes For Facebook Login----#\n    AccessToken= autoclass('com.facebook.AccessToken')\n    CallbackManagerFactory= autoclass('com.facebook.CallbackManager$Factory')\n    FacebookCallback= autoclass('com.facebook.FacebookCallback')\n    FacebookException= autoclass('com.facebook.FacebookException')\n    FacebookSdk= autoclass('com.facebook.FacebookSdk')\n    LoginManager= autoclass('com.facebook.login.LoginManager')\n    GraphRequest= autoclass('com.facebook.GraphRequest')\n    ImageRequest= autoclass('com.facebook.internal.ImageRequest')\n\n    ```\n  * Now, to respond to a login result, you need to register a callback with `LoginManager`. Before that, \n    we need to implement `GraphJSONObjectCallback` class which will be used when login request succeeds and within which\n    we can get user information(like, name, email, etc.)\n    ```python\n    class PythonGraphJSONObjectCallback(PythonJavaClass):\n        __javainterfaces__= ['com/facebook/GraphRequest$GraphJSONObjectCallback']\n        __javacontext__= 'app'\n\n        @java_method('(Lorg/json/JSONObject;Lcom/facebook/GraphResponse;)V')\n        def onCompleted(self, me, response):\n            if response.getError():\n                #handle error\n                \n            else:\n            \n                if AccessToken.isCurrentAccessTokenActive():\n                    access_token= AccessToken.getCurrentAccessToken().getToken()\n                else:\n                    access_token= \"\"\n\n                uri= ImageRequest.getProfilePictureUri(\n                    me.optString(\"id\"),  #user id\n                    100,                 #image height\n                    100,                 #image width\n                    access_token         #access token\n                )\n                \n                # user has been logged in. Get other info\n                # and do after login stuffs(like, updating UI, etc.)\n    ```\n  \n  * Next, we need to implement `FacebookCallback` class which will be registered with `LoginManager`.\n    ```python\n    class PythonFacebookCallback(PythonJavaClass):\n        __javainterfaces__= ['com/facebook/FacebookCallback']\n        __javacontext__= 'app'\n\n        @java_method('(Ljava/lang/Object;)V')\n        def onSuccess(self, result):\n\n            request= GraphRequest.newMeRequest(\n                result.getAccessToken(),\n                PythonGraphJSONObjectCallback()\n            )\n\n            params= Bundle()\n            params.putString(\"fields\", \"last_name,first_name,email\")\n            request.setParameters(params)\n            request.executeAsync()\n\n\n        @java_method('()V')\n        def onCancel(self):\n            #Login has been cancelled\n            \n\n        @java_method('(Lcom/facebook/FacebookException;)V')\n        def onError(self, error):\n            #Error in logging in\n            \n    ```\n  \n  * We then need o initialize Facebook SDK inside App's `build` method:\n    ```python\n    FacebookSdk.sdkInitialize(context.getApplicationContext())\n    ```\n  * And then register the callback with `LoginManager` inside `build` method:\n    ```python\n    mCallbackManager = CallbackManagerFactory.create()\n    mFacebookCallback = PythonFacebookCallback()\n    self.mLoginMgr = LoginManager.getInstance()\n    self.mLoginMgr.registerCallback(mCallbackManager, mFacebookCallback)\n    ```\n  * Finally, in your `onActivityResult` method, call `callbackManager.onActivityResult` to pass the login results to the `LoginManager` via `callbackManager`. For this we just need to add one more line to our `build` method:\n    ```python\n    result_bind(on_activity_result=mCallbackManager.onActivityResult)\n    ```\n    Make sure you've `result_bind` imported:\n    ```python\n    from android.activity import bind as result_bind\n    ```\n  \n  * Finally, perform the actual login with required scopes upon clicking a button. Add below codes inside a function to be called upon a button's pressing/releasing event. \n  ```python\n  self.mLoginMgr.logInWithReadPermissions(\n                cast(autoclass('android.app.Activity'),\n                context), Arrays.asList(\"email\", \"public_profile\")\n                )\n  ```\n    \n"
  },
  {
    "path": "docs/prerequisites.md",
    "content": "### For Google Login\n#\n* Goto https://console.cloud.google.com/\n* While on cloud console, head to `APIs & Services` > `Credentials` > Click on `+ Create Credentials` and select `OAuth client ID`\n* On the following screen select `Android` under `Application Type` field and follow on-screen instructions to fill all the fields and create a client ID for Android.\n* Declare Google Play services as a gradle dependency in your `buildozer.spec` file:\n\n```spec\nandroid.gradle_dependencies = com.google.android.gms:play-services-auth:18.0.0\n```\n\n* Add `INTERNET` permission in `buildozer.spec` file\n    ```spec\n    android.permissions = INTERNET\n    ```\n\n#\n### For Facebook Login\n##\n* You need to follow their [doc](https://developers.facebook.com/docs/facebook-login/android/) along-side. So open it up in a new tab.\n\n* Follow their instruction in step 1 and create an OAuth App. You may skip step 2.\n\n* For step 3, add Facebook-login SDK as a gradle dependency in your `buildozer.spec` file:\n ```spec\n android.gradle_dependencies = com.facebook.android:facebook-login:7.0.0\n ```\n \n* For 4th step,\n  * Add `INTERNET` permission in `buildozer.spec` file\n    ```spec\n    android.permissions = INTERNET\n    ```\n  * Copy your OAuth App ID and find `android.meta_data` in buildozer.spec file and make it to look like\n    ```spec\n    android.meta_data = com.facebook.sdk.ApplicationId=fb<App-ID-of-your-OAuth-App>\n    ```\n  * Next, find `android.add_activities` in buildozer.spec file and add some activity classes\n    ```spec\n    android.add_activites = com.facebook.FacebookActivity, com.facebook.CustomTabActivity\n    ```\n  * Lastly, create an xml file in the same directory as `main.py`. Name it whatever you like and paste below text into that xml file\n    ```xml\n    <intent-filter>\n             <action android:name=\"android.intent.action.VIEW\" />\n             <category android:name=\"android.intent.category.DEFAULT\" />\n             <category android:name=\"android.intent.category.BROWSABLE\" />\n             <data android:scheme=\"fb<App-ID-of-your-OAuth-App>\" />\n    </intent-filter>\n    ```\n    Now add this xml as an intent filter in the spec file\n    ```spec\n    android.manifest.intent_filters = <file-name>.xml\n    ```\n#\n### For Firebase Login\n##\n* Make sure you've created OAuth apps for [Github](https://github.com/settings/applications/new) and/or [Twitter](https://developer.twitter.com/en/apps/create) logins before proceeding further.\n\n* Go to [firebase console](https://console.firebase.google.com) and create a project for your application.\n\n* Once you've created a project, add your android app into the project from the Project Overview screen and follow the on-screen instructions and finally download\nthe `google-services.json` file.\n\n* Declare Firebase as a gradle dependency in your `buildozer.spec` file:\n ```spec\n android.gradle_dependencies = com.google.firebase:firebase-auth:19.3.1\n ```\n \n * Add `INTERNET` permission in `buildozer.spec` file\n    ```spec\n    android.permissions = INTERNET\n    ```\n\n* Next, from your project's console head to the Authentication section and then switch to the Sign-in method tab and enable the sign-in methods you want for your\napp.(For kivyauth you only need to enable Github and Twitter and follow on-screen instructions)\n\n* Now you need to tweak few settings internally:\n  * Build your application once, doesn't matter if it crashes\n  * Then find ***build.tmpl.gradle*** inside *.buildozer/android/platform/python-for-android/pythonforandroid/bootstraps/common/build/templates* and change gradle plugin version\n  from 3.1.4 to 3.5.2 and add google-services plugin as it's required by firebase and apply the plugin:\n      ```java\n      buildscript {\n        repositories {\n           //...\n        }\n        dependencies {\n            //make sure its 3.5.2 here instead of 3.1.4 \n            classpath 'com.android.tools.build:gradle:3.5.2'\n\n            //google-services plugin, required by firebase\n            classpath 'com.google.gms:google-services:4.3.3'\n        }\n      }\n\n      //...\n\n      // At the bottom\n      apply plugin: 'com.google.gms.google-services'\n      ```\n  \n  * Paste your ***google-services.json*** inside *.buildozer/android/platform/python-for-android/pythonforandroid/bootstraps/common/build/*.\n* Re-build your application\n  \n"
  },
  {
    "path": "kivyauth/__init__.py",
    "content": "from kivy.logger import Logger\nfrom kivy.utils import platform\n\n__version__ = \"2.3.3\"\n_log_message = \"KivyAuth:\" + f\" {__version__}\" + f' (installed at \"{__file__}\")'\n\n__all__ = (\"login_providers\", \"auto_login\")\n\nLogger.info(_log_message)\n"
  },
  {
    "path": "kivyauth/android/__init__.py",
    "content": ""
  },
  {
    "path": "kivyauth/android/facebook_auth.py",
    "content": "from android.activity import bind as result_bind\nfrom jnius import PythonJavaClass, autoclass, cast, java_method\nfrom kivy.logger import Logger\n\nCallbackManagerFactory = autoclass(\"com.facebook.CallbackManager$Factory\")\nFacebookSdk = autoclass(\"com.facebook.FacebookSdk\")\nLoginManager = autoclass(\"com.facebook.login.LoginManager\")\nAccessToken = autoclass(\"com.facebook.AccessToken\")\nGraphRequest = autoclass(\"com.facebook.GraphRequest\")\nImageRequest = autoclass(\"com.facebook.internal.ImageRequest\")\n\nBundle = autoclass(\"android.os.Bundle\")\nArrays = autoclass(\"java.util.Arrays\")\n\nPythonActivity = autoclass(\"org.kivy.android.PythonActivity\")\n\ncontext = PythonActivity.mActivity\nmLoginMgr = None\nmList = None\n\n\n__all__ = (\"initialize_fb\", \"login_facebook\", \"logout_facebook\")\n\n\nclass PythonGraphJSONObjectCallback(PythonJavaClass):\n    __javainterfaces__ = [\"com/facebook/GraphRequest$GraphJSONObjectCallback\"]\n    __javacontext__ = \"app\"\n\n    def __init__(self, complete_listener):\n        self.complete_listener = complete_listener\n        super().__init__()\n\n    @java_method(\"(Lorg/json/JSONObject;Lcom/facebook/GraphResponse;)V\")\n    def onCompleted(self, me, response):\n        if response.getError():\n            # handle error\n            Logger.error(\"KivyAuth: Unable to retrieve profile info\")\n\n        else:\n\n            if AccessToken.isCurrentAccessTokenActive():\n                access_token = AccessToken.getCurrentAccessToken().getToken()\n            else:\n                access_token = \"\"\n\n            uri = ImageRequest.getProfilePictureUri(\n                me.optString(\"id\"), 200, 200, access_token\n            )\n\n            Logger.info(\n                \"KivyAuth: Profile info retrieved successfully.\"\n                \" Calling success listener.\"\n            )\n\n            self.complete_listener(\n                me.optString(\"first_name\") + \" \" + me.optString(\"last_name\"),\n                me.optString(\"email\"),\n                uri.toString() if uri else '',\n            )\n\n\nclass PythonFacebookCallback(PythonJavaClass):\n    __javainterfaces__ = [\"com/facebook/FacebookCallback\"]\n    __javacontext__ = \"app\"\n\n    def __init__(self, success_listener, cancel_listener, error_listener):\n        self.success_listener = success_listener\n        self.cancel_listener = cancel_listener\n        self.error_listener = error_listener\n\n    @java_method(\"(Ljava/lang/Object;)V\")\n    def onSuccess(self, result):\n        Logger.info(\"KivyAuth: Login success. Requesting profile info.\")\n\n        request = GraphRequest.newMeRequest(\n            result.getAccessToken(),\n            PythonGraphJSONObjectCallback(self.success_listener),\n        )\n\n        params = Bundle()\n        params.putString(\"fields\", \"last_name,first_name,email\")\n        request.setParameters(params)\n        request.executeAsync()\n\n    @java_method(\"()V\")\n    def onCancel(self):\n        Logger.info(\"KivyAuth: Login Cancelled.\")\n        self.cancel_listener()\n\n    @java_method(\"(Lcom/facebook/FacebookException;)V\")\n    def onError(self, error):\n        Logger.error(\"KivyAuth: Error logging in.\")\n        self.error_listener()\n\n\ndef initialize_fb(success_listener, error_listener, *args, **kwargs):\n    \"\"\"\n    Function to initialize facebook login.\n    Must be called inside `build` method of kivy App before actual login.\n\n    :param: `success_listener` - Function to be called on login success\n    :param: `error_listener` - Function to be called on login error\n    \"\"\"\n    FacebookSdk.sdkInitialize(context.getApplicationContext())\n    mCallbackManager = CallbackManagerFactory.create()\n    mFacebookCallback = PythonFacebookCallback(\n        success_listener, error_listener, error_listener\n    )\n    result_bind(on_activity_result=mCallbackManager.onActivityResult)\n\n    Logger.info(\"KivyAuth: Initialized facebook signin\")\n    global mList\n    mList = [mCallbackManager, mFacebookCallback]\n\n\ndef login_facebook():\n    \"\"\"\n    Function to login using facebook\n    \"\"\"\n    Logger.info(\"KivyAuth: Initiated facebook login\")\n    global mLoginMgr\n    mLoginMgr = LoginManager.getInstance()\n    mLoginMgr.registerCallback(*mList)\n    mLoginMgr.logInWithReadPermissions(\n        cast(autoclass(\"android.app.Activity\"), context),\n        Arrays.asList(\"email\", \"public_profile\"),\n    )\n\n\ndef auto_facebook():\n    \"\"\"\n    Auto login using Facebook. You may call it `on_start`.\n    \"\"\"\n    accessToken = AccessToken.getCurrentAccessToken()\n    if accessToken and not accessToken.isExpired():\n        login_facebook()\n        return True\n\n\ndef logout_facebook(after_logout):\n    \"\"\"\n    Logout from facebook login\n\n    :param: `after_logout` - Function to be called after logging out\n    \"\"\"\n    mLoginMgr.logOut()\n    after_logout()\n    Logger.info(\"KivyAuth: Logged out from facebook login\")\n"
  },
  {
    "path": "kivyauth/android/firebase_auth.py",
    "content": "from android.activity import bind as result_bind\nfrom jnius import PythonJavaClass, autoclass, java_method\nfrom kivy.logger import Logger\n\nFirebaseAuth = autoclass(\"com.google.firebase.auth.FirebaseAuth\")\nOAuthProvider = autoclass(\"com.google.firebase.auth.OAuthProvider\")\n\nPythonActivity = autoclass(\"org.kivy.android.PythonActivity\")\n\ncontext = PythonActivity.mActivity\n\nevent_success_listener = None\nevent_error_listener = None\n\n\nclass OnSuccessListener(PythonJavaClass):\n    __javainterfaces__ = [\"com/google/android/gms/tasks/OnSuccessListener\"]\n    __javacontext__ = \"app\"\n\n    def __init__(self, success_listener):\n        self.success_listener = success_listener\n\n    @java_method(\"(Ljava/lang/Object;)V\")\n    def onSuccess(self, result):\n        # user is signed in\n        Logger.info(\"KivyAuth: Sign in successful using firebase.\")\n        user = FirebaseAuth.getInstance().getCurrentUser()\n\n        _call_success(user)\n\n\nclass OnFailureListener(PythonJavaClass):\n    __javainterfaces__ = [\"com/google/android/gms/tasks/OnFailureListener\"]\n    __javacontext__ = \"app\"\n\n    def __init__(self, error_listener):\n        self.error_listener = error_listener\n\n    @java_method(\"(Ljava/lang/Exception;)V\")\n    def onFailure(self, e):\n        # handle exception\n        Logger.info(\"KivyAuth: Sign in using firebase failed\")\n        self.error_listener()\n\n\ndef _call_success(user):\n    event_success_listener(\n        user.getDisplayName(),\n        user.getEmail(),\n        user.getPhotoUrl().toString() if user.getPhotoUrl() else ''\n    )\n\n\ndef initialize_firebase(success_listener, error_listener):\n    \"\"\"\n    Function to initialize firebase login.\n    Must be called inside `build` method of kivy App before actual login.\n\n    :param: `success_listener` - Function to be called on login success\n    :param: `error_listener` - Function to be called on login error\n    \"\"\"\n    FirebaseAuth.getInstance()\n    Logger.info(\"KivyAuth: Initialized firebase auth\")\n    global event_success_listener\n    event_success_listener = success_listener\n    global event_error_listener\n    event_error_listener = error_listener\n\n\ndef firebase_login(provider):\n    pendingResultTask = FirebaseAuth.getPendingAuthResult()\n    if pendingResultTask:\n        # There's something already here! Finish the sign-in for your user.\n\n        task = pendingResultTask.addOnSuccessListener(\n            OnSuccessListener(event_success_listener)\n        )\n        task = task.addOnFailureListener(OnFailureListener(event_error_listener))\n    else:\n        # There's no pending result so you need to start the sign-in flow.\n\n        task = FirebaseAuth.startActivityForSignInWithProvider(\n            context, provider.build()\n        )\n        task = task.addOnSuccessListener(OnSuccessListener(event_success_listener))\n        task = task.addOnFailureListener(OnFailureListener(event_error_listener))\n\n\ndef firebase_logout(after_logout):\n    Logger.info(\"KivyAuth: Initiated logout using firebase\")\n    FirebaseAuth.getInstance().signOut()\n    after_logout()\n    Logger.info(\"KivyAuth: Logged out from firebase auth\")\n\n\ndef auto_firebase():\n    user = FirebaseAuth.getInstance().getCurrentUser()\n    if user:\n        _call_success(user)\n        return True\n\n\ndef login_github():\n    \"\"\"\n    Function to login using github\n    \"\"\"\n    Logger.info(\"KivyAuth: Initiated github login\")\n    provider = OAuthProvider.newBuilder(\"github.com\")\n    firebase_login(provider)\n\n\ndef login_twitter():\n    \"\"\"\n    Function to login using twitter\n    \"\"\"\n    Logger.info(\"KivyAuth: Initiated twitter login\")\n    provider = OAuthProvider.newBuilder(\"twitter.com\")\n    firebase_login(provider)\n\n\ndef logout_twitter(after_logout):\n    \"\"\"\n    Logout from twitter login\n\n    :param: `after_logout` - Function to be called after logging out\n    \"\"\"\n    firebase_logout(after_logout)\n\n\ndef logout_github(after_logout):\n    \"\"\"\n    Logout from github login\n\n    :param: `after_logout` - Function to be called after logging out\n    \"\"\"\n    firebase_logout(after_logout)\n"
  },
  {
    "path": "kivyauth/android/github_auth.py",
    "content": "from kivy.logger import Logger\nfrom kivyauth.android.firebase_auth import (\n    firebase_login,\n    firebase_logout,\n    initialize_firebase,\n    OAuthProvider,\n    auto_firebase as auto_github,\n)\n\n__all__ = (\"initialize_github\", \"login_github\", \"logout_github\")\n\n\ndef initialize_github(succes_listener, error_listener, *args, **kwargs):\n    initialize_firebase(succes_listener, error_listener)\n\n\ndef login_github():\n    \"\"\"\n    Function to login using github\n    \"\"\"\n    Logger.info(\"KivyAuth: Initiated github login\")\n    provider = OAuthProvider.newBuilder(\"github.com\")\n    firebase_login(provider)\n\n\ndef logout_github(after_logout):\n    \"\"\"\n    Logout from github login\n\n    :param: `after_logout` - Function to be called after logging out\n    \"\"\"\n    firebase_logout(after_logout)\n"
  },
  {
    "path": "kivyauth/android/google_auth.py",
    "content": "from android.activity import bind as result_bind\nfrom jnius import autoclass\nfrom kivy.clock import mainthread\nfrom kivy.logger import Logger\n\nGso = autoclass(\"com.google.android.gms.auth.api.signin.GoogleSignInOptions\")\nGsoBuilder = autoclass(\n    \"com.google.android.gms.auth.api.signin.GoogleSignInOptions$Builder\"\n)\nGSignIn = autoclass(\"com.google.android.gms.auth.api.signin.GoogleSignIn\")\nApiException = autoclass(\"com.google.android.gms.common.api.ApiException\")\nPythonActivity = autoclass(\"org.kivy.android.PythonActivity\")\ncontext = PythonActivity.mActivity\n\nRC_SIGN_IN = 10122\nmGSignInClient = None\nevent_success_listener = None\n\n__all__ = (\"initialize_google\", \"login_google\", \"logout_google\")\n\n\nclass GoogleActivityListener:\n    def __init__(self, success_listener, error_listener):\n        self.success_listener = success_listener\n        self.error_listener = error_listener\n\n    def google_activity_listener(self, request_code, result_code, data):\n        if request_code == RC_SIGN_IN:\n            Logger.info(\"KivyAuth: google_activity_listener called.\")\n            task = GSignIn.getSignedInAccountFromIntent(data)\n            try:\n                account = task.getResult(ApiException)\n                _call_success(account)\n\n            except Exception as e:\n                Logger.info(\"KivyAuth: Error signing in using Google. {}\".format(e))\n                self.error_listener()\n\n\ndef _call_success(account):\n    if account:\n        Logger.info(\"KivyAuth: Google Login success. Calling success listener.\")\n        event_success_listener(\n            account.getDisplayName(),\n            account.getEmail(),\n            account.getPhotoUrl().toString() if account.getPhotoUrl() else '',\n        )\n        return True\n\n\ndef initialize_google(success_listener, error_listener, *args, **kwargs):\n    \"\"\"\n    Function to initialize google login.\n    Must be called inside `build` method of kivy App before actual login.\n\n    :param: `success_listener` - Function to be called on login success\n    :param: `error_listener` - Function to be called on login error\n    \"\"\"\n    global event_success_listener\n    event_success_listener = success_listener\n    gso = GsoBuilder(Gso.DEFAULT_SIGN_IN).requestEmail().build()\n    global mGSignInClient\n    mGSignInClient = GSignIn.getClient(context, gso)\n    gal = GoogleActivityListener(success_listener, error_listener)\n    result_bind(on_activity_result=gal.google_activity_listener)\n\n    Logger.info(\"KivyAuth: Initialized google signin\")\n\n\n# @mainthread\ndef login_google():\n    \"\"\"\n    Function to login using google\n    \"\"\"\n    Logger.info(\"KivyAuth: Initiated google login\")\n    signInIntent = mGSignInClient.getSignInIntent()\n    context.startActivityForResult(signInIntent, RC_SIGN_IN)\n\n\ndef auto_google():\n    \"\"\"\n    Auto login using Google. You may call it `on_start`.\n    \"\"\"\n    account = GSignIn.getLastSignedInAccount(context)\n    return _call_success(account)\n\n\ndef logout_google(after_logout):\n    \"\"\"\n    Logout from google login\n\n    :param: `after_logout` - Function to be called after logging out\n    \"\"\"\n    mGSignInClient.signOut()\n    after_logout()\n    Logger.info(\"KivyAuth: Logged out from google login\")\n"
  },
  {
    "path": "kivyauth/android/twitter_auth.py",
    "content": "from kivy.logger import Logger\nfrom kivyauth.android.firebase_auth import (\n    firebase_login,\n    firebase_logout,\n    initialize_firebase,\n    OAuthProvider,\n    auto_firebase as auto_twitter,\n)\n\n__all__ = (\"initialize_twitter\", \"login_twitter\", \"logout_twitter\")\n\n\ndef initialize_twitter(succes_listener, error_listener, *args, **kwargs):\n    initialize_firebase(succes_listener, error_listener)\n\n\ndef login_twitter():\n    \"\"\"\n    Function to login using twitter\n    \"\"\"\n    Logger.info(\"KivyAuth: Initiated twitter login\")\n    provider = OAuthProvider.newBuilder(\"twitter.com\")\n    firebase_login(provider)\n\n\ndef logout_twitter(after_logout):\n    \"\"\"\n    Logout from twitter login\n\n    :param: `after_logout` - Function to be called after logging out\n    \"\"\"\n    firebase_logout(after_logout)\n"
  },
  {
    "path": "kivyauth/desktop/__init__.py",
    "content": ""
  },
  {
    "path": "kivyauth/desktop/facebook_auth.py",
    "content": "import requests\nfrom oauthlib.oauth2 import WebApplicationClient\nimport json\nimport webbrowser\nimport random\n\nfrom kivyauth.desktop.utils import (\n    request,\n    redirect,\n    is_connected,\n    start_server,\n    app,\n    _close_server_pls,\n    port,\n    stop_login,\n)\nfrom kivy.app import App\nfrom kivy.clock import Clock\n\n# facebook configuration\nFACEBOOK_CLIENT_ID = \"\"\nFACEBOOK_CLIENT_SECRET = \"\"\nfb_authorization_endpoint = \"https://www.facebook.com/v15.0/dialog/oauth?\"\nfb_token_endpoint = \"https://graph.facebook.com/v15.0/oauth/access_token?\"\nfb_userinfo_endpoint = \"https://graph.facebook.com/v15.0/me?\"\n\nclient_facebook = None\n\nevent_success_listener = None\nevent_error_listener = None\n\n__all__ = (\"initialize_fb\", \"login_facebook\", \"logout_facebook\")\n\n\ndef initialize_fb(success_listener, error_listener, client_id=None, client_secret=None):\n    a = App.get_running_app()\n    a.bind(on_stop=lambda *args: _close_server_pls(port))\n\n    global event_success_listener\n    event_success_listener = success_listener\n\n    global event_error_listener\n    event_error_listener = error_listener\n\n    global FACEBOOK_CLIENT_ID\n    FACEBOOK_CLIENT_ID = client_id\n\n    global FACEBOOK_CLIENT_SECRET\n    FACEBOOK_CLIENT_SECRET = client_secret\n\n    global client_facebook\n    client_facebook = WebApplicationClient(FACEBOOK_CLIENT_ID)\n\n\n@app.route(\"/loginFacebook\")\ndef loginFacebook():\n\n    st = \"\".join([random.choice(\"abcdefgh1234567\") for _ in range(10)])\n    ds = \"\".join([random.choice(\"1234567890\") for _ in range(10)])\n\n    request_uri = client_facebook.prepare_request_uri(\n        fb_authorization_endpoint,\n        redirect_uri=request.base_url + \"/callbackFacebook\",\n        scope=[\"email\"],\n        state=\"{st=\" + st + \",ds=\" + ds + \"}\",\n    )\n\n    return redirect(request_uri)\n\n\n@app.route(\"/loginFacebook/callbackFacebook\")\ndef callbackFacebook():\n    code = request.args.get(\"code\")\n\n    # prepare a request to get tokens\n    token_url, headers, body = client_facebook.prepare_token_request(\n        fb_token_endpoint,\n        client_id=FACEBOOK_CLIENT_ID,\n        client_secret=FACEBOOK_CLIENT_SECRET,\n        code=code,\n        redirect_url=request.base_url,\n    )\n\n    # send the request and get the response\n    token_response = requests.post(token_url, headers=headers, data=body)\n\n    # send the request and get the response\n    # app_token_response = requests.get(token_url, headers=headers, data=body)\n\n    headers = {\n        \"Authorization\": token_response.json()[\"access_token\"]\n        + \" \"\n        + token_response.json()[\"token_type\"]\n    }\n\n    request_uri = client_facebook.prepare_request_uri(\n        fb_userinfo_endpoint,\n        fields=[\"id\", \"name\", \"email\", \"picture\"],\n        access_token=token_response.json()[\"access_token\"],\n    )\n\n    # make the request and get the response\n    userinfo_response = requests.get(request_uri, headers=headers, data=None).json()\n    stop_login()\n\n    # parse the information\n    if userinfo_response.get(\"id\"):\n        Clock.schedule_once(lambda *args: event_success_listener(\n            userinfo_response[\"name\"],\n            userinfo_response[\"email\"],\n            userinfo_response[\"picture\"][\"data\"][\"url\"],\n        ), 0)\n\n        return \"<h2>Logged in using Facebook. Return back to the Kivy application</h2>\"\n\n    event_error_listener()\n    return \"User Email not available or not verified\"\n\n\ndef login_facebook():\n    if is_connected():\n        start_server(port)\n        webbrowser.open(\"https://127.0.0.1:{}/loginFacebook\".format(port), 1, False)\n    else:\n        event_error_listener()\n\n\ndef logout_facebook(after_logout):\n    \"\"\"\n    Logout from facebook login\n\n    :param: `after_logout` - Function to be called after logging out\n    \"\"\"\n    after_logout()\n"
  },
  {
    "path": "kivyauth/desktop/github_auth.py",
    "content": "import requests\nfrom oauthlib.oauth2 import WebApplicationClient\nimport json\nimport webbrowser\nimport random\nimport re\n\nfrom kivyauth.desktop.utils import (\n    request,\n    redirect,\n    is_connected,\n    start_server,\n    app,\n    _close_server_pls,\n    port,\n    stop_login,\n)\nfrom kivy.app import App\nfrom kivy.clock import Clock\n\n# github configuration\nGITHUB_CLIENT_ID = \"\"\nGITHUB_CLIENT_SECRET = \"\"\ngit_authorization_endpoint = \"https://github.com/login/oauth/authorize\"\ngit_token_endpoint = \"https://github.com/login/oauth/access_token\"\ngit_userinfo_endpoint = \"https://api.github.com/user\"\n\nclient_github = None\n\nevent_success_listener = None\nevent_error_listener = None\n\n__all__ = (\"initialize_github\", \"login_github\", \"logout_github\")\n\n\ndef initialize_github(\n    success_listener, error_listener, client_id=None, client_secret=None\n):\n    a = App.get_running_app()\n    a.bind(on_stop=lambda *args: _close_server_pls(port))\n\n    global event_success_listener\n    event_success_listener = success_listener\n\n    global event_error_listener\n    event_error_listener = error_listener\n\n    global GITHUB_CLIENT_ID\n    GITHUB_CLIENT_ID = client_id\n\n    global GITHUB_CLIENT_SECRET\n    GITHUB_CLIENT_SECRET = client_secret\n\n    global client_github\n    client_github = WebApplicationClient(GITHUB_CLIENT_ID)\n\n@app.route(\"/loginGithub\")\ndef loginGithub():\n    request_uri = client_github.prepare_request_uri(\n        git_authorization_endpoint,\n        redirect_uri=request.base_url + \"/callbackGithub\",\n        scope=[\"read:user:email\"],\n        state=\"\".join([random.choice(\"abcdefghijklmnopqrstuvwxyz\") for _ in range(20)]),\n    )\n    return redirect(request_uri)\n\n@app.route(\"/loginGithub/callbackGithub\")\ndef callbackGithub():\n    # Get authorization code Github sent back\n    code = request.args.get(\"code\")\n\n    # prepare a request to get tokens\n    token_url, headers, body = client_github.prepare_token_request(\n        git_token_endpoint,\n        client_id=GITHUB_CLIENT_ID,\n        client_secret=GITHUB_CLIENT_SECRET,\n        code=code,\n        redirect_url=request.base_url,\n        state=\"\".join([random.choice(\"abcdefghijklmnopqrstuvwxyz\") for _ in range(20)]),\n    )\n\n    # send the request and get the response\n    token_response = requests.post(token_url, headers=headers, data=body)\n\n    # for some reason, token_response.json() is raising an error. So gotta do it manually\n    token_info = re.search(\n        \"^access_token=(.*)&scope=.*&token_type=(.*)$\", token_response.text\n    )\n\n    headers = {\"Authorization\": token_info.group(2) + \" \" + token_info.group(1)}\n    body = None\n\n    userinfo_response = requests.get(\n        git_userinfo_endpoint, headers=headers, data=body\n    ).json()\n    stop_login()\n\n    # parse the information\n    if userinfo_response.get(\"id\"):\n        Clock.schedule_once(lambda *args: event_success_listener(\n            userinfo_response[\"name\"],\n            userinfo_response[\"email\"],\n            userinfo_response[\"avatar_url\"],\n        ), 0)\n        return \"<h2>Logged in using Github. Return back to the Kivy application</h2>\"\n\n    event_error_listener()\n    return \"User Email not available or not verified\"\n\ndef login_github():\n    if is_connected():\n        start_server(port)\n        webbrowser.open(\"https://127.0.0.1:{}/loginGithub\".format(port), 1, False)\n    else:\n        event_error_listener()\n\ndef logout_github(after_logout):\n    \"\"\"\n    Logout from github login\n\n    :param: `after_logout` - Function to be called after logging out\n    \"\"\"\n    after_logout()\n"
  },
  {
    "path": "kivyauth/desktop/google_auth.py",
    "content": "import requests\nfrom oauthlib.oauth2 import WebApplicationClient\nimport json\nimport webbrowser\n\nfrom kivyauth.desktop.utils import (\n    request,\n    redirect,\n    is_connected,\n    start_server,\n    app,\n    _close_server_pls,\n    port,\n    stop_login,\n)\nfrom kivy.app import App\nfrom kivy.clock import Clock\n\n# google configurations\nGOOGLE_CLIENT_ID = \"\"\nGOOGLE_CLIENT_SECRET = \"\"\nGOOGLE_DISCOVERY_URL = \"https://accounts.google.com/.well-known/openid-configuration\"\n\nclient_google = None\n\nevent_success_listener = None\nevent_error_listener = None\n\n__all__ = (\"initialize_google\", \"login_google\", \"logout_google\")\n\n\ndef get_google_provider_cfg():\n    return requests.get(GOOGLE_DISCOVERY_URL).json()\n\n\ndef initialize_google(\n    success_listener, error_listener, client_id=None, client_secret=None\n):\n    a = App.get_running_app()\n    a.bind(on_stop=lambda *args: _close_server_pls(port))\n\n    global event_success_listener\n    event_success_listener = success_listener\n\n    global event_error_listener\n    event_error_listener = error_listener\n\n    global GOOGLE_CLIENT_ID\n    GOOGLE_CLIENT_ID = client_id\n\n    global GOOGLE_CLIENT_SECRET\n    GOOGLE_CLIENT_SECRET = client_secret\n\n    global client_google\n    client_google = WebApplicationClient(GOOGLE_CLIENT_ID)\n\n@app.route(\"/loginGoogle\")\ndef loginGoogle():\n    # takeout auth endpoint url from google login\n    google_provider_cfg = get_google_provider_cfg()\n\n    authorization_endpoint = google_provider_cfg[\"authorization_endpoint\"]\n    # construct the request uri\n    request_uri = client_google.prepare_request_uri(\n        authorization_endpoint,\n        redirect_uri=request.base_url + \"/callbackGoogle\",\n        scope=[\"openid\", \"email\", \"profile\"],\n    )\n\n    return redirect(request_uri)\n\n@app.route(\"/loginGoogle/callbackGoogle\")\ndef callbackGoogle():\n    # Get authorization code Google sent back\n    code = request.args.get(\"code\")\n\n    # Extract the URL to hit to get tokens\n    # that allows to ask things on behalf of a user\n    google_provider_cfg = get_google_provider_cfg()\n    token_endpoint = google_provider_cfg[\"token_endpoint\"]\n\n    # prepare a request to get tokens\n    token_url, headers, body = client_google.prepare_token_request(\n        token_endpoint,\n        authorization_response=request.url,\n        redirect_url=request.base_url,\n        code=code,\n    )\n\n    # send the request and get the response\n    token_response = requests.post(\n        token_url,\n        headers=headers,\n        data=body,\n        auth=(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET),\n    )\n\n    # parse the token response\n    client_google.parse_request_body_response(json.dumps(token_response.json()))\n\n    # Now we already have necessary tokens\n    # lets ask Google for required informations\n    userinfo_endpoint = google_provider_cfg[\"userinfo_endpoint\"]\n    uri, headers, body = client_google.add_token(userinfo_endpoint)\n\n    userinfo_response = requests.get(uri, headers=headers, data=body).json()\n    stop_login()\n\n    # parse the information\n    if userinfo_response.get(\"email_verified\"):\n        Clock.schedule_once(lambda *args: event_success_listener(\n            userinfo_response[\"name\"],\n            userinfo_response[\"email\"],\n            userinfo_response[\"picture\"],\n        ), 0)\n\n        return \"<h2>Logged in using Google. Return back to the Kivy application</h2>\"\n\n    event_error_listener()\n    return \"User Email not available or not verified\"\n\ndef login_google():\n    if is_connected():\n        start_server(port)\n        webbrowser.open(\"https://127.0.0.1:{}/loginGoogle\".format(port), 1, False)\n\n    else:\n        event_error_listener()\n\ndef logout_google(after_logout):\n    \"\"\"\n    Logout from google login\n\n    :param: `after_logout` - Function to be called after logging out\n    \"\"\"\n    after_logout()\n"
  },
  {
    "path": "kivyauth/desktop/twitter_auth.py",
    "content": "__all__ = (\"initialize_twitter\", \"login_twitter\", \"logout_twitter\")\n\n\ndef initialize_twitter(\n    success_listener, error_listener, client_id=None, client_secret=None\n):\n    raise NotImplementedError\n\n\ndef login_twitter():\n    raise NotImplementedError\n\n\ndef logout_twitter():\n    raise NotImplementedError\n\n# # twitter configuration\n# TWITTER_CLIENT_ID = \"\"\n# TWITTER_CLIENT_SECRET = \"\"\n# tw_authorization_endpoint = \"https://api.twitter.com/oauth/authorize\"\n# tw_token_endpoint = \"https://api.twitter.com/oauth/access_token\"\n# tw_userinfo_endpoint = \"https://api.twitter.com/user\"\n# tw_request_token_endpoint = \"https://api.twitter.com/oauth/request_token\"\n\n# @app.route(\"/loginTwitter\")\n# def loginTwitter():\n\n#     # construct the request uri\n#     # request_uri = client_twitter.prepare_request_uri(\n#     #     tw_authorization_endpoint,\n#     #     redirect_uri=request.base_url + \"/callbackTwitter\",\n#     # )\n#     # return redirect(request_uri)\n\n#     resp = requests.post(\n#         tw_request_token_endpoint,\n#         {\n#             \"oauth_callback\": \"https%3A%2F%2F127.0.0.1%3A9004%2FloginTwitter%2FcallbackTwitter\"\n#         },\n#     )\n#     return resp.json()\n\n\n# @app.route(\"/loginTwitter/callbackTwitter\")\n# def callbackTwitter():\n#     code = request.args.get(\"code\")\n\n#     token_url, headers, body = client_twitter.prepare_token_request(\n#         tw_token_endpoint,\n#         client_id=TWITTER_CLIENT_ID,\n#         client_secret=TWITTER_CLIENT_SECRET,\n#         code=code,\n#         redirect_url=request.base_url,\n#     )\n\n#     # send the request and get the response\n#     token_response = requests.post(token_url, headers=headers, data=body)\n\n#     # for some reason, token_response.json() is raising an error. So gotta do it manually\n#     token_info = re.search(\n#         \"^access_token=(.*)&scope=.*&token_type=(.*)$\", token_response.text\n#     )\n#     uri = tw_userinfo_endpoint\n#     headers = {\"Authorization\": token_info.group(2) + \" \" + token_info.group(1)}\n#     body = None\n\n#     global userinfo_response\n#     userinfo_response = requests.get(uri, headers=headers, data=body).json()\n\n#     # parse the information\n#     if userinfo_response.get(\"id\"):\n#         close_server()\n#         print(get_userinfo())\n#         print(get_userinfo())\n#         # return update_database(\n#         #     tmp[\"id\"], tmp[\"email\"], tmp[\"picture\"][\"data\"][\"url\"], tmp[\"name\"]\n#         # )\n#         return \"Success using twitter. Return to the app\"\n#     return \"User Email not available or not verified\", 400\n\n\n# if __name__ == \"__main__\":\n\n#     if is_connected():\n#         port = 9004\n#         start_server(port)\n\n#         webbrowser.open(\"https://127.0.0.1:{}/loginGoogle\".format(port), 1, False)\n\n#     else:\n#         print(\"Could not connect. Check connection and try again\")\n"
  },
  {
    "path": "kivyauth/desktop/utils.py",
    "content": "from flask import Flask, request, redirect\nimport requests\nimport os\nimport threading\nimport socket\nimport random\n\napp = Flask(\"Local Server: KivyAuth Login\")\napp.secret_key = os.urandom(26)\n\nPATH = os.path.dirname(__file__)\n\nport = 9004\nran_num = random.randint(1111, 9999)\n\n\ndef _start_server(*args):\n    try:\n        app.run(host=\"127.0.0.1\", port=port, ssl_context='adhoc')\n    except OSError as e:\n        print(e)\n\ndef start_server(port):\n    thread = threading.Thread(target=_start_server)\n\n    thread.start()\n\n\n@app.route(\"/kill{}\".format(ran_num))\ndef close_server(*args, **kwargs):\n    func = request.environ.get(\"werkzeug.server.shutdown\")\n    if func is None:\n        raise RuntimeError(\"Not running with the Werkzeug Server\")\n    func()\n\n    return \"\"\n\ndef stop_login(*args):\n    _close_server_pls(port)\n\ndef _close_server_pls(port, *args):\n    try:\n        requests.get(\"https://127.0.0.1:{}/kill{}\".format(port, ran_num), verify=False)\n    except requests.exceptions.ConnectionError:\n        pass\n\ndef is_connected():\n    try:\n        socket.create_connection((\"www.google.com\", 80))\n        return True\n    except OSError:\n        pass\n    return False\n"
  },
  {
    "path": "kivyauth/facebook_auth.py",
    "content": "from kivy.utils import platform\n\nif platform == \"android\":\n    from kivyauth.android.facebook_auth import (\n        initialize_fb,\n        login_facebook,\n        logout_facebook,\n    )\n\nelif platform != \"ios\":\n    from kivyauth.desktop.facebook_auth import (\n        initialize_fb,\n        login_facebook,\n        logout_facebook,\n    )\n"
  },
  {
    "path": "kivyauth/github_auth.py",
    "content": "from kivy.utils import platform\n\nif platform == \"android\":\n    from kivyauth.android.github_auth import (\n        initialize_github,\n        login_github,\n        logout_github,\n    )\n\nelif platform != \"ios\":\n    from kivyauth.desktop.github_auth import (\n        initialize_github,\n        login_github,\n        logout_github,\n    )\n"
  },
  {
    "path": "kivyauth/google_auth.py",
    "content": "from kivy.utils import platform\n\nif platform == \"android\":\n    from kivyauth.android.google_auth import (\n        initialize_google,\n        login_google,\n        logout_google,\n    )\n\nelif platform != \"ios\":\n    from kivyauth.desktop.google_auth import (\n        initialize_google,\n        login_google,\n        logout_google,\n    )\n"
  },
  {
    "path": "kivyauth/twitter_auth.py",
    "content": "from kivy.utils import platform\n\nif platform == \"android\":\n    from kivyauth.android.twitter_auth import (\n        initialize_twitter,\n        login_twitter,\n        logout_twitter,\n    )\n\nelif platform != \"ios\":\n    from kivyauth.desktop.twitter_auth import (\n        initialize_twitter,\n        login_twitter,\n        logout_twitter,\n    )\n"
  },
  {
    "path": "kivyauth/utils.py",
    "content": "from kivy.utils import platform\n\nif platform == \"android\":\n\n    def stop_login(*args):\n        pass\n\n\nelif platform != \"ios\":\n    from kivyauth.desktop.utils import stop_login\n\n\nclass LoginProviders:\n    google = \"google\"\n    facebook = \"facebook\"\n    github = \"github\"\n    twitter = \"twitter\"\n\n\nlogin_providers = LoginProviders()\n\n\ndef auto_login(provider):\n    \"\"\"\n    Auto login using a given provider. You may call it `on_start`.\n\n    :param: `provider` is one of `kivyauth.login_providers`\n    \"\"\"\n    if platform == \"android\":\n        if provider == login_providers.google:\n            from kivyauth.android.google_auth import auto_google\n\n            return auto_google()\n\n        if provider == login_providers.facebook:\n            from kivyauth.android.facebook_auth import auto_facebook\n\n            return auto_facebook()\n\n        if provider == login_providers.github:\n            from kivyauth.android.github_auth import auto_github\n\n            return auto_github()\n\n        if provider == login_providers.twitter:\n            from kivyauth.android.twitter_auth import auto_twitter\n\n            return auto_twitter()\n\n    else:\n        raise NotImplementedError(\"Not yet availabe for desktop\")\n"
  },
  {
    "path": "setup.py",
    "content": "from setuptools import setup\nimport os, re\n\nwith open(\"README.md\", \"r\") as fh:\n    long_description = fh.read()\n\n\ndef is_android():\n    if \"ANDROID_BOOTLOGO\" in os.environ:\n        return True\n    return False\n\n\ndef get_version() -> str:\n    \"\"\"Get __version__ from __init__.py file.\"\"\"\n    version_file = os.path.join(os.path.dirname(__file__), \"kivyauth\", \"__init__.py\")\n    version_file_data = open(version_file, \"rt\", encoding=\"utf-8\").read()\n    version_regex = r\"(?<=^__version__ = ['\\\"])[^'\\\"]+(?=['\\\"]$)\"\n    try:\n        version = re.findall(version_regex, version_file_data, re.M)[0]\n        return version\n    except IndexError:\n        raise ValueError(f\"Unable to find version string in {version_file}.\")\n\n\nsetup(\n    name=\"KivyAuth\",\n    version=get_version(),\n    packages=[\"kivyauth\"],\n    package_data={\"kivyauth\": [\"*.py\", \"desktop/*\", \"android/*\"],},\n    # metadata to display on PyPI\n    author=\"Shashi Ranjan\",\n    author_email=\"shashiranjankv@gmail.com\",\n    description=\"Integrate Google, Facebook, Github & Twitter login in kivy applications \",\n    long_description=long_description,\n    long_description_content_type=\"text/markdown\",\n    keywords=\"social-login google-login facebook-login firebase-auth kivy-application kivy python\",\n    url=\"https://github.com/shashi278/social-auth-kivy\",\n    classifiers=[\n        \"Programming Language :: Python :: 3\",\n        \"License :: OSI Approved :: MIT License\",\n        \"Operating System :: Android\",\n        \"Operating System :: Microsoft :: Windows\",\n        \"Operating System :: OS Independent\"\n    ],\n    install_requires=[\"kivy>=2.0.0\", \"oauthlib\", \"werkzeug==2.0.3\", \"flask==2.0.3\", \"requests\"]\n    if not is_android()\n    else [],\n    python_requires=\">=3.6\",\n)\n"
  }
]