Introduction
Introduction Statistics Contact Development Disclaimer Help
Extract auth code to own file, add some tests - toot - Unnamed repository; edit…
Log
Files
Refs
LICENSE
---
commit a50ffe62c33698b9a1bf1211149cdfb1aaeca48e
parent 787e0d28b4cd9d77d7948da80874d17942e9c330
Author: Ivan Habunek <[email protected]>
Date: Sat, 30 Dec 2017 12:52:55 +0100
Extract auth code to own file, add some tests
Diffstat:
tests/test_auth.py | 57 +++++++++++++++++++++++++++++++
tests/utils.py | 4 ++++
toot/auth.py | 101 +++++++++++++++++++++++++++++++
toot/commands.py | 97 +------------------------------
4 files changed, 165 insertions(+), 94 deletions(-)
---
diff --git a/tests/test_auth.py b/tests/test_auth.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+
+from toot import App, User, api, config, auth
+from tests.utils import retval
+
+
+def test_register_app(monkeypatch):
+ app_data = {'id': 100, 'client_id': 'cid', 'client_secret': 'cs'}
+
+ def assert_app(app):
+ assert isinstance(app, App)
+ assert app.instance == "foo.bar"
+ assert app.base_url == "https://foo.bar"
+ assert app.client_id == "cid"
+ assert app.client_secret == "cs"
+
+ monkeypatch.setattr(api, 'create_app', retval(app_data))
+ monkeypatch.setattr(config, 'save_app', assert_app)
+
+ app = auth.register_app("foo.bar")
+ assert_app(app)
+
+
+def test_create_app_from_config(monkeypatch):
+ """When there is saved config, it's returned"""
+ monkeypatch.setattr(config, 'load_app', retval("loaded app"))
+ app = auth.create_app_interactive("bezdomni.net")
+ assert app == 'loaded app'
+
+
+def test_create_app_registered(monkeypatch):
+ """When there is no saved config, a new app is registered"""
+ monkeypatch.setattr(config, 'load_app', retval(None))
+ monkeypatch.setattr(auth, 'register_app', retval("registered app"))
+
+ app = auth.create_app_interactive("bezdomni.net")
+ assert app == 'registered app'
+
+
+def test_create_user(monkeypatch):
+ app = App(4, 5, 6, 7)
+
+ def assert_user(user):
+ assert isinstance(user, User)
+ assert user.instance == app.instance
+ assert user.username == 2
+ assert user.access_token == 3
+
+ monkeypatch.setattr(config, 'save_user', assert_user)
+
+ user = auth.create_user(app, 2, 3)
+
+ assert_user(user)
+
+#
+# TODO: figure out how to mock input so the rest can be tested
+#
diff --git a/tests/utils.py b/tests/utils.py
@@ -10,3 +10,7 @@ class MockResponse:
def json(self):
return self.response_data
+
+
+def retval(val):
+ return lambda *args, **kwargs: val
diff --git a/toot/auth.py b/toot/auth.py
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+
+import webbrowser
+
+from builtins import input
+from getpass import getpass
+
+from toot import api, config, DEFAULT_INSTANCE, User, App, ConsoleError
+from toot.output import print_out
+
+
+def register_app(instance):
+ print_out("Registering application with <green>{}</green>".format(instance…
+
+ try:
+ response = api.create_app(instance)
+ except Exception:
+ raise ConsoleError("Registration failed. Did you enter a valid instanc…
+
+ base_url = 'https://' + instance
+
+ app = App(instance, base_url, response['client_id'], response['client_secr…
+ path = config.save_app(app)
+ print_out("Application tokens saved to: <green>{}</green>\n".format(path))
+
+ return app
+
+
+def create_app_interactive(instance=None):
+ if not instance:
+ print_out("Choose an instance [<green>{}</green>]: ".format(DEFAULT_IN…
+ instance = input()
+ if not instance:
+ instance = DEFAULT_INSTANCE
+
+ return config.load_app(instance) or register_app(instance)
+
+
+def create_user(app, email, access_token):
+ user = User(app.instance, email, access_token)
+ path = config.save_user(user)
+
+ print_out("Access token saved to: <green>{}</green>".format(path))
+
+ return user
+
+
+def login_interactive(app, email=None):
+ print_out("Log in to <green>{}</green>".format(app.instance))
+
+ if email:
+ print_out("Email: <green>{}</green>".format(email))
+
+ while not email:
+ email = input('Email: ')
+
+ password = getpass('Password: ')
+
+ try:
+ print_out("Authenticating...")
+ response = api.login(app, email, password)
+ except api.ApiError:
+ raise ConsoleError("Login failed")
+
+ return create_user(app, email, response['access_token'])
+
+
+BROWSER_LOGIN_EXPLANATION = """
+This authentication method requires you to log into your Mastodon instance
+in your browser, where you will be asked to authorize <yellow>toot</yellow> to…
+your account. When you do, you will be given an <yellow>authorization code</ye…
+which you need to paste here.
+"""
+
+
+def login_browser_interactive(app):
+ url = api.get_browser_login_url(app)
+
+ print_out(BROWSER_LOGIN_EXPLANATION)
+
+ print_out("This is the login URL:")
+ print_out(url)
+ print_out("")
+
+ yesno = input("Open link in default browser? [Y/n]")
+ if not yesno or yesno.lower() == 'y':
+ webbrowser.open(url)
+
+ authorization_code = ""
+ while not authorization_code:
+ authorization_code = input("Authorization code: ")
+
+ print_out("\nRequesting access token...")
+ response = api.request_access_token(app, authorization_code)
+
+ # TODO: user email is not available in this workflow, maybe change the User
+ # to store the username instead? Currently set to "unknown" since it's not
+ # used anywhere.
+ email = "unknown"
+
+ return create_user(app, email, response['access_token'])
diff --git a/toot/commands.py b/toot/commands.py
@@ -1,75 +1,16 @@
# -*- coding: utf-8 -*-
-import webbrowser
-
from bs4 import BeautifulSoup
-from builtins import input
from datetime import datetime
from itertools import zip_longest
-from getpass import getpass
from itertools import chain
from textwrap import TextWrapper
-from toot import api, config, DEFAULT_INSTANCE, User, App, ConsoleError
+from toot import api, config, ConsoleError
+from toot.auth import login_interactive, login_browser_interactive, create_app…
from toot.output import print_out, print_instance, print_account, print_search…
-def register_app(instance):
- print_out("Registering application with <green>{}</green>".format(instance…
-
- try:
- response = api.create_app(instance)
- except:
- raise ConsoleError("Registration failed. Did you enter a valid instanc…
-
- base_url = 'https://' + instance
-
- app = App(instance, base_url, response['client_id'], response['client_secr…
- path = config.save_app(app)
- print_out("Application tokens saved to: <green>{}</green>\n".format(path))
-
- return app
-
-
-def create_app_interactive(instance=None):
- if not instance:
- print_out("Choose an instance [<green>{}</green>]: ".format(DEFAULT_IN…
- instance = input()
- if not instance:
- instance = DEFAULT_INSTANCE
-
- return config.load_app(instance) or register_app(instance)
-
-
-def create_user(app, email, access_token):
- user = User(app.instance, email, access_token)
- path = config.save_user(user)
-
- print_out("Access token saved to: <green>{}</green>".format(path))
-
- return user
-
-
-def login_interactive(app, email=None):
- print_out("Log in to <green>{}</green>".format(app.instance))
-
- if email:
- print_out("Email: <green>{}</green>".format(email))
-
- while not email:
- email = input('Email: ')
-
- password = getpass('Password: ')
-
- try:
- print_out("Authenticating...")
- response = api.login(app, email, password)
- except api.ApiError:
- raise ConsoleError("Login failed")
-
- return create_user(app, email, response['access_token'])
-
-
def _print_timeline(item):
def wrap_text(text, width):
wrapper = TextWrapper(width=width, break_long_words=False, break_on_hy…
@@ -156,41 +97,9 @@ def login(app, user, args):
print_out("<green>✓ Successfully logged in.</green>")
-BROWSER_LOGIN_EXPLANATION = """
-This authentication method requires you to log into your Mastodon instance
-in your browser, where you will be asked to authorize <yellow>toot</yellow> to…
-your account. When you do, you will be given an <yellow>authorization code</ye…
-which you need to paste here.
-"""
-
-
def login_browser(app, user, args):
app = create_app_interactive(instance=args.instance)
- url = api.get_browser_login_url(app)
-
- print_out(BROWSER_LOGIN_EXPLANATION)
-
- print_out("This is the login URL:")
- print_out(url)
- print_out("")
-
- yesno = input("Open link in default browser? [Y/n]")
- if not yesno or yesno.lower() == 'y':
- webbrowser.open(url)
-
- authorization_code = ""
- while not authorization_code:
- authorization_code = input("Authorization code: ")
-
- print_out("\nRequesting access token...")
- response = api.request_access_token(app, authorization_code)
-
- # TODO: user email is not available in this workflow, maybe change the User
- # to store the username instead? Currently set to "unknown" since it's not
- # used anywhere.
- email = "unknown"
-
- create_user(app, email, response['access_token'])
+ login_browser_interactive(app)
print_out()
print_out("<green>✓ Successfully logged in.</green>")
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.