Skip to content

Commit

Permalink
Issue #25: Authentication cli assistant
Browse files Browse the repository at this point in the history
  • Loading branch information
Nekmo committed Apr 29, 2020
1 parent bdec16f commit 5403845
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 7 deletions.
56 changes: 56 additions & 0 deletions google_keep_tasks/auth.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import json
import os

import click
import gkeepapi
from click import Abort
from gkeepapi.exception import LoginException

from google_keep_tasks.cli import choices_prompt
from google_keep_tasks.exceptions import UnavailableLoginError, LoginError
from google_keep_tasks._compat import JSONDecodeError

Expand Down Expand Up @@ -34,3 +40,53 @@ def get_credentials(self):
if not isinstance(data, dict) or 'username' not in data or 'password' not in data:
raise LoginError('Invalid credentials format file. username and password are required.')
return data['username'], data['password']


class GoogleKeep(object):
def __init__(self):
self.keep = gkeepapi.Keep()
self.auth = GoogleKeepFileAuth()

def login_or_input(self):
auth_changed = False
input_login = False
username = password = None
try:
username, password = self.auth.get_credentials()
except UnavailableLoginError:
click.echo('Welcome to Google Keep. Enter your username and password below. '
'If your account is protected, you need an application password: '
'https://support.google.com/mail/answer/185833')
input_login = True
except LoginError as e:
click.echo('The credentials file is corrupt: {}. Credentials must be re-entered.'.format(e))
input_login = True
while True:
if input_login:
# Request new credentials
auth_changed = True
username, password = self.get_credencials_assistant(username)
try:
self.keep.login(username, password)
except LoginException:
choice = choices_prompt('Authentication failed, what do you want to do?', [
'Enter new credentials',
'retry',
'abort',
], 'e')
if choice == 'e':
input_login = True
elif choice == 'r':
input_login = False
elif choice == 'a':
raise Abort
else:
if auth_changed:
self.auth.save_credentials(username, password)
break

def get_credencials_assistant(self, default_username):
username = click.prompt('Enter your Google username', type=str,
show_default=True, default=default_username)
password = click.prompt('Enter your password', hide_input=True)
return username, password
17 changes: 17 additions & 0 deletions google_keep_tasks/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import click


def choices_prompt(text, choices, default_choice):
choices_descriptions = [' [{}]{}'.format(choice[0].upper() if default_choice == choice[0] else choice[0],
choice[1:])
for choice in choices]
choices_letters = [choice[0].upper() if default_choice == choice[0] else choice[0] for choice in choices]
choice = click.prompt(
'{}\n\n'.format(text) +
'\n'.join(choices_descriptions) +
'\nEnter a choice [{}]'.format('/'.join(choices_letters)),
default=default_choice, show_default=False
)
if not next(iter(filter(lambda x: x == choice.lower(), map(lambda x: x.lower(), choices_letters))), None):
return default_choice
return choice.lower()
11 changes: 4 additions & 7 deletions google_keep_tasks/management.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import gkeepapi
from gkeepapi.exception import LoginException

from google_keep_tasks.auth import get_auth, GoogleKeepFileAuth
from google_keep_tasks.auth import get_auth, GoogleKeepFileAuth, GoogleKeep
from google_keep_tasks.exceptions import LoginError


Expand All @@ -12,12 +12,9 @@
@click.option('--auth', default='auth.txt')
@click.pass_context
def cli(ctx, debug, auth):
keep = gkeepapi.Keep()
try:
keep.login(*GoogleKeepFileAuth().get_credentials())
except LoginException:
raise LoginError
ctx.obj = {'keep': keep}
google_keep = GoogleKeep()
google_keep.login_or_input()
ctx.obj = {'keep': google_keep.keep}


import google_keep_tasks.items
Expand Down

0 comments on commit 5403845

Please sign in to comment.