Beispiel #1
0
def test_institution():
    client = Client('test_id', 'test_secret')
    response = client.institution(
        to_json(client.institutions())[0]['id']
    )

    assert response.status_code == 200
Beispiel #2
0
def connect(plaid_credentials, bank, bank_credentials):
    client = Client(client_id=plaid_credentials.client_id, secret=plaid_credentials.secret)
    try:
        response = client.connect(bank, {
            'username': bank_credentials.username,
            'password': bank_credentials.password
        })

        data = json.loads(response.content)
        if response.status_code == 200:
            print data
            if "access_token" in data:
                client_access_token = data["access_token"]
                client = Client(client_id=plaid_credentials.client_id, secret=plaid_credentials.secret, access_token=client_access_token)
                response = client.connect_get()
                data = json.loads(response.content)
                with open("tx.json", "w") as f:
                    f.write(json.dumps(data))
        else:
            print "Something went horribly wrong..."
            print data

    except plaid_errors.UnauthorizedError as e:
         # handle this
        print e
Beispiel #3
0
class Plaid:

    def __init__(self, clientId, clientSecret, accessToken=None):
        self.client = Client(client_id=clientId, secret=clientSecret, access_token=accessToken)

    def connect(self, accountType, username, password, email):
        connect = self.client.connect(account_type=accountType, username=username, password=password, email=email)
        if connect.ok:
            json_response = json.loads(connect.content)
            return json_response;

    def answerMFA(self, accountType, mfaAnswer):
        step = self.client.step(account_type=accountType, mfa=mfaAnswer)
        if step.ok:
            transactions = json.loads(step.content)
            return transactions

    def getTransactions(self, options=None):
        transactions = self.client.transactions(options)
        if transactions.ok:
            transactions = json.loads(transactions.content)
            return transactions

    def delete(self):
        self.client.delete_user()
Beispiel #4
0
def tool_bank():
    user = g.user

    client = Client(client_id='test_id', secret='test_secret')
    connect = client.connect(account_type='wells', username='******', password='******', email='*****@*****.**')

    if connect.ok:
        step = client.step(account_type='wells', mfa='tomato')

        if step.ok:
            data = json.loads(step.content)
            transactions = data['transactions']

            spent = {
                'school': 0,
                'essentials': 0,
                'snacks': 0,
                'gas': 0,
                'clothing': 0,
                'recreation': 0
            }
            for t in transactions:
                if t['type']['primary'] in ['place', 'digital']:
                    name = t['name'].lower()
                    amount = t['amount']
                    category = analyze_name(name)
                    spent[category] += amount
            pie = '['
            for cat, val in spent.iteritems():
                pie += '["%s",%d],' % (cat, val)
            pie = pie[:-1]
            pie += ']'
            return render_template('tool/bank.html', pie=pie)

    return render_template_string('Error')
    def import_into_database(self, user, sub_account, access_token):
        # data = PlaidData.getData('wells', "joefarned3", "angela0816", '*****@*****.**')
        client = Client(client_id=self.client_id, secret=self.secret)
        client.set_access_token(access_token)
        connect = client.transactions()
        data = json.loads(connect.content)

        c = MongoClient()
        db = c['pava']

        accounts = db['accounts']
        transactions = db['transactions']

        for account in data['accounts']:
            account['_user_id'] = user.id
            account['_user_account'] = sub_account.id
            if not accounts.find({'_id': account['_id']}).count():
                print accounts.insert(account)
            else:
                accounts.update({'_id': account['_id']}, account)

        for transaction in data['transactions']:
            transaction['_user_id'] = user.id
            if not transactions.find({'_id': transaction['_id']}).count():
                print transactions.insert(transaction)

        return data
Beispiel #6
0
def test_ResourceNotFound_categories_with_suppressed_error():
    Client.config({'suppress_http_errors': True})
    client = Client('test_id', 'test_secret')
    response = client.category('pnc')
    assert response.status_code == 404
    assert (
        to_json(response)['message'] == 'unable to find category'
    )
Beispiel #7
0
def test_connect_mfa_list():
    client = Client('test_id', 'test_secret')
    # These credentials erroneously still force mfa in the sandbox
    # Should disambiguate by disallowing institution on API level
    # for this particular calling
    response = client.connect('chase', no_mfa_credentials)
    assert response.status_code == 201
    assert to_json(response)['type'] == 'list'
Beispiel #8
0
def test_connect_step_device_phone():
    client = Client('test_id', 'test_secret', access_token='test_chase')
    response = client.connect_step('chase', None, options={
        'send_method': {'type': 'phone'}
    })
    assert response.status_code == 201
    assert to_json(response)['type'] == 'device'
    assert to_json(response)['mfa']['message'] == 'Code sent to xxx-xxx-5309'
Beispiel #9
0
def _get_plaid_client(passphrase, access_token = None):

    f = open('plaid.gpg', 'r')
    plaid_config_data_gpg = f.read()
    f.close()

    crypter_util = crypt.Crypt()
    plaid_config_data = crypter_util.decrypt(plaid_config_data_gpg, passphrase)
    plaid_config = json.loads(plaid_config_data)

    Client.config({
        'url': plaid_config['plaidendpoint']
    })

    return Client(client_id=plaid_config['client'], secret=plaid_config['secret'], access_token=access_token)
Beispiel #10
0
def test_connect():
    with patch('requests.post') as mock_requests_post:
        mock_response = Mock()
        mock_response.content = '{}'
        mock_requests_post.return_value = mock_response

        client = Client('myclientid', 'mysecret')

        account_type = 'bofa'
        username = '******'
        password = '******'
        email = '*****@*****.**'

        response = client.connect(account_type, username, password, email)

        assert mock_response == response
class PlaidData:
	client_id = '54137790d8675800005de8d2'
	secret = 'SKTzUuKXq2ZcxviiwW0fiJ'

	def __init__(self, username, password):
		self.client = Client(client_id=self.client_id, secret=self.secret)
		self.connect = self.client.connect(account_type='wells', username=username, password=password, email='*****@*****.**')

	def getJSONResponse(self):
		json_response = json.loads(self.connect.content)
		import pprint
		pprint.pprint(json_response)
		message = "Your last transaction was @ " + json_response['transactions'][0]['name']
		Messaging.sendMessage(message, "+16508620978") 
Beispiel #12
0
    def exchangeLinkTokenForAccount(self, user, public_token):
        Client.config({
            'url': 'https://tartan.plaid.com'
        })
        print('creating client')
        self.client = Client(client_id=PlaidAPI.client_id,
                             secret=PlaidAPI.secret)
        print('getting response')
        response = self.client.exchange_token(public_token)
        print('response')
        print(response)
        access_token = self.client.access_token
        print("Access token {0}".format(access_token))

        ##create account and store in db
        plaiduser = PlaidUserToken()  # is there a good constructor syntax?
        plaiduser.user = user
        plaiduser.access_token = access_token
        plaiduser.status = 'new'
        plaiduser.status_text = "Created {0}".format(timezone.now())
        plaiduser.save()
        print('saved')
        return plaiduser
Beispiel #13
0
def test_institution_search_without_product():
    client = Client('test_id', 'test_secret')
    response = client.institution_search('wells')
    assert response.status_code == 200
Beispiel #14
0
def test_institution_search_with_bad_product():
    client = Client('test_id', 'test_secret')
    response = client.institution_search('wells fargo', 'bad')
    assert response.status_code == 200
    assert len(to_json(response)) == 0
Beispiel #15
0
def test_institutions():
    client = Client('test_id', 'test_secret')
    response = client.institutions()
    assert response.status_code == 200
Beispiel #16
0
def test_get_connect():
    client = Client('test_id', 'test_secret', access_token='test_bofa')
    response = client.connect_get()
    assert response.status_code == 200
Beispiel #17
0
def test_unauthorizedError_bad_username():
    client = Client('test_idz', 'test_secret')
    with pytest.raises(UnauthorizedError):
        client.balance()
Beispiel #18
0
def test_auth_mfa():
    client = Client('test_id', 'test_secret')
    response = client.auth('pnc', no_mfa_credentials)
    assert response.status_code == 201
    assert to_json(response)['type'] == 'questions'
Beispiel #19
0
def test_ResourceNotFound_connect():
    client = Client('test_id', 'test_secret')
    with pytest.raises(ResourceNotFoundError):
        client.connect('pnc', no_mfa_credentials)
Beispiel #20
0
def test_connect_mfa_question():
    client = Client('test_id', 'test_secret')
    response = client.connect('bofa', no_mfa_credentials)
    assert response.status_code == 201
    assert to_json(response)['type'] == 'questions'
Beispiel #21
0
def test_connect_no_mfa():
    client = Client('test_id', 'test_secret')
    response = client.connect('amex', no_mfa_credentials)
    assert response.status_code == 200
    assert to_json(response)['access_token'] == 'test_amex'
Beispiel #22
0
def test_auth_step():
    client = Client('test_id', 'test_secret', access_token='test_pnc')
    response = client.auth_step('pnc', 'tomato')
    assert response.status_code == 200
    assert to_json(response)['access_token'] == 'test_pnc'
Beispiel #23
0
def test_ResourceNotFound_categories_with_suppressed_error():
    Client.config({'suppress_http_errors': True})
    client = Client('test_id', 'test_secret')
    response = client.category('pnc')
    assert response.status_code == 404
    assert (to_json(response)['message'] == 'unable to find category')
Beispiel #24
0
def test_ResourceNotFound_categories():
    client = Client('test_id', 'test_secret')
    with pytest.raises(ResourceNotFoundError):
        client.category('pnc')
Beispiel #25
0
def test_ResourceNotFound_connect():
    client = Client('test_id', 'test_secret')
    with pytest.raises(ResourceNotFoundError):
        client.connect('pnc', no_mfa_credentials)
Beispiel #26
0
def test_institution_search_requires_q_or_id():
    client = Client('test_id', 'test_secret')
    with pytest.raises(AssertionError):
        client.institution_search(p='auth')
Beispiel #27
0
def test_unauthorizedError_bad_username():
    client = Client('test_idz', 'test_secret')
    with pytest.raises(UnauthorizedError):
        client.balance()
Beispiel #28
0
def test_auth_delete():
    client = Client('test_id', 'test_secret', access_token='test_chase')
    response = client.auth_delete()
    assert response.status_code == 200
    assert to_json(response)['message'] == 'Successfully removed from system'
Beispiel #29
0
def test_connect_step_question():
    client = Client('test_id', 'test_secret', access_token='test_bofa')
    response = client.connect_step('bofa', 'tomato')
    assert response.status_code == 200
    assert to_json(response)['access_token'] == 'test_bofa'
Beispiel #30
0
def test_unauthorizedError_bad_password():
    client = Client('test_id', 'test_secretz')
    with pytest.raises(UnauthorizedError):
        client.balance()
Beispiel #31
0
def test_connect_no_mfa():
    client = Client('test_id', 'test_secret')
    response = client.connect('amex', no_mfa_credentials)
    assert response.status_code == 200
    assert to_json(response)['access_token'] == 'test_amex'
Beispiel #32
0
def test_connect_step_question_loop():
    client = Client('test_id', 'test_secret', access_token='test_bofa')
    response = client.connect_step('bofa', 'again')
    assert response.status_code == 201
    assert to_json(response)['type'] == 'questions'
Beispiel #33
0
def test_connect_step_question_loop():
    client = Client('test_id', 'test_secret', access_token='test_bofa')
    response = client.connect_step('bofa', 'again')
    assert response.status_code == 201
    assert to_json(response)['type'] == 'questions'
Beispiel #34
0
import time
import pandas as pd
import numpy as np
from plaid import Client
from datetime import datetime
from google.oauth2 import service_account
from googleapiclient.http import MediaFileUpload
from googleapiclient.discovery import build

DEFAULT_INSTITUTION_ID = 'ins_1'
# Set Plaid API access data and get Client object
client = Client(
    client_id='5ece97fc33df8d00137c4a43',
    secret='c70bb94dccf11c154b80ed8a1c0213',
    public_key='f571792e76a5251f1892b3e5b1bc04',
    environment='sandbox'
)

# For upload files to google
GOOGLE_SCOPES = ['https://www.googleapis.com/auth/drive']
GOOGLE_SERVICE_ACCOUNT_FILE = '../quickstart/python/Quickstart.json'
google_credentials = service_account.Credentials.from_service_account_file(
    GOOGLE_SERVICE_ACCOUNT_FILE, scopes=GOOGLE_SCOPES
)
service = build('drive', 'v3', credentials=google_credentials)


def google_upload(filepath, name):
    folder_id = '1DzhQWufGGqHKcGyZSKkxAa3nvofPPzRF4tInLDW_xyI'
    name = name
    file_path = filepath
Beispiel #35
0
def test_balance():
    client = Client('test_id', 'test_secret', access_token='test_bofa')
    response = client.balance()
    assert response.status_code == 200
Beispiel #36
0
from plaid import Client

from backend.link_token import LinkToken
from general_falcon_webserver import WebApp

client = Client(client_id='5e2e3527dd6924001167e8e8',
                secret='0b89f518880456b6f60020f481b3d7',
                environment='sandbox')

app = WebApp()

app.add_route('link', LinkToken(client))

app.launch_webserver()
Beispiel #37
0
def make_client(client_id, secret, public_key, env="development"):
    return Client(client_id=client_id,
                  secret=secret,
                  public_key=public_key,
                  environment=env)
Beispiel #38
0
from celery import shared_task
from plaid import Client
from .models import Tokens

plaid_client_id = "5da9e9d3470e370016651aa3"
plaid_secret = "1026c23bcd23fccd4f9dabb1f9f172"

client = Client(client_id=plaid_client_id,
                secret=plaid_secret,
                environment='sandbox')


@shared_task
def add(x, y):
    print('sum: ', x + y)
    return x + y


@shared_task
def saveTask(user, access_token):
    item_response = client.Item.get(access_token)
    institution_response = client.Institutions.get_by_id(
        item_response['item']['institution_id'], 'US')

    item_id = item_response['item_id']
    webhook = item_response['webhook']

    token = Tokens.objects.create(user=user,
                                  access_tkn=access_token,
                                  item_id=item_id,
                                  webhook=webhook)
Beispiel #39
0
def test_institution_search_with_multi_tokens():
    client = Client('test_id', 'test_secret')
    response = client.institution_search('wells fargo', 'auth')
    assert response.status_code == 200
    assert to_json(response)[0]['name'] == 'Wells Fargo'
Beispiel #40
0
 def __init__(self):
     self.client = Client(client_id=settings.PLAID_CLIENT_ID,
                          secret=settings.PLAID_SECRET,
                          public_key=settings.PLAID_PUBLIC_KEY,
                          environment=settings.PLAID_ENV)
Beispiel #41
0
def test_auth_mfa():
    client = Client('test_id', 'test_secret')
    response = client.auth('pnc', no_mfa_credentials)
    assert response.status_code == 201
    assert to_json(response)['type'] == 'questions'
Beispiel #42
0
from django.conf import settings
from plaid import Client

plaid_client = Client(
    client_id=settings.PLAID_CLIENT_ID,
    secret=settings.PLAID_SECRET,
    public_key=settings.PLAID_PUBLIC_KEY,
    environment=settings.PLAID_ENVIRONMENT,
)
Beispiel #43
0
def test_institution_search_with_bad_id():
    client = Client('test_id', 'test_secret')
    response = client.institution_search(institution_id='bad')
    assert response.status_code == 200
    assert len(to_json(response)) == 0
Beispiel #44
0
import time
import pandas as pd
import numpy as np
from plaid import Client
from datetime import datetime
from google.oauth2 import service_account
from googleapiclient.http import MediaFileUpload
from googleapiclient.discovery import build

DEFAULT_INSTITUTION_ID = 'ins_1'
# Set Plaid API access data and get Client object
client = Client(client_id='5ecba3951aa68500131ccd7a',
                secret='4b79ae100459ab86833f5aedb9caf7',
                public_key='19586b0d0ac976669c9f0abf56ddf7',
                environment='sandbox')

# For upload files to google
GOOGLE_SCOPES = ['https://www.googleapis.com/auth/drive']
GOOGLE_SERVICE_ACCOUNT_FILE = '../service_account.json'
google_credentials = service_account.Credentials.from_service_account_file(
    GOOGLE_SERVICE_ACCOUNT_FILE, scopes=GOOGLE_SCOPES)
service = build('drive', 'v3', credentials=google_credentials)


def google_upload(filepath, name):
    folder_id = '1UscZpDhizXJsJQoHUy6JjRS4o-DhBOtH'
    name = name
    file_path = filepath
    file_metadata = {
        'name': name,
        'mimeType': 'application/vnd.google-apps.spreadsheet',
Beispiel #45
0
def test_UnauthorizedError_bad_token():
    client = Client('test_id', 'test_secret', 'test_zoba')
    with pytest.raises(UnauthorizedError):
        client.balance()
Beispiel #46
0
class PlaidAccess():
    def __init__(self,
                 client_id=None,
                 secret=None,
                 account_id=None,
                 access_token=None):
        if client_id and secret:
            self.client_id = client_id
            self.secret = secret
        else:
            self.client_id, self.secret = cm.get_plaid_config()
        self.client = Client(client_id=self.client_id, secret=self.secret)
        # if access_token: self.acceess_token = access_token
        # if account_id: self.account_id = account_id

    def get_transactions(self,
                         access_token,
                         account_id,
                         start_date=None,
                         end_date=None):
        """Get transaction for a given account for the given dates"""
        self.client.access_token = access_token
        options = {}
        options["account"] = account_id
        # options["pending"] = True
        #get all transaction up to and including today
        options['lte'] = datetime.date.today().strftime('%Y-%m-%d')
        self.connect_response = self.client.connect_get(options).json()
        return self.connect_response['transactions']

    def add_account(self, nickname):
        try:
            self._get_available_institutions()
        except Exception as e:
            raise Exception(
                "There was a problem obtaining a list of institutions. Try again later."
            ) from e

        selected_institution = self._get_institution()
        if selected_institution is None:
            print("Quitting, no account added", file=sys.stdout)
            sys.exit(0)
        self.active_institution = self.available_institutions[
            selected_institution][1]
        self.account_type = self.active_institution["type"]
        un, pwd, pin = self._get_needed_creds()
        # self.client.client_id = "test_id"
        # self.client.secret = "test_secret"
        # un = "plaid_test"
        # pwd = "plaid_good"
        login = {'username': un, 'password': pwd}
        if pin: login['pin'] = pin
        try:
            self.connect_response = self.client.connect(
                self.account_type, login)
        except plaid_errors.PlaidError as e:
            print(e.message)
            return
        else:
            cont = True
            try:
                while not self._check_status():
                    cont = self._process_mfa(self.connect_response.json())
                    if not cont: break
            except plaid_errors.PlaidError as e:
                print(
                    "The following error has occurred, no account added:\n{}".
                    format(e.message),
                    file=sys.stderr)
                sys.exit(1)
            else:
                if not cont:
                    print("Quitting, no account added", file=sys.stderr)
                    sys.exit(1)

                accts = self.connect_response.json()['accounts']
                if not self._present_accounts(accts):
                    print("Quitting, no account added", file=sys.stderr)
                    sys.exit(1)

                self._save_account_section(nickname)

    def _save_account_section(self, nickname):
        acct_section = OrderedDict()
        acct_section[nickname] = OrderedDict()
        section = acct_section[nickname]
        section['access_token'] = self.client.access_token
        section['account'] = self.selected_account['_id']
        a = prompt(
            "What account is used for posting transactions [{}]: ".format(
                cm.CONFIG_DEFAULTS.posting_account))
        if a:
            section['posting_account'] = a
        else:
            section['posting_account'] = cm.CONFIG_DEFAULTS.posting_account

        a = prompt(
            "What currency does this account use for posting transactions [{}]: "
            .format(cm.CONFIG_DEFAULTS.currency))
        if a:
            section['currency'] = a
        else:
            section['currency'] = cm.CONFIG_DEFAULTS.currency

        a = self._present_file_options(nickname, 'mapping',
                                       cm.FILE_DEFAULTS.mapping_file)
        if a:
            section['mapping_file'] = a

        a = self._present_file_options(nickname, 'journal',
                                       cm.FILE_DEFAULTS.journal_file)
        if a:
            section['journal_file'] = a

        a = self._present_file_options(nickname, 'accounts',
                                       cm.FILE_DEFAULTS.accounts_file)
        if a:
            section['accounts_file'] = a

        a = self._present_file_options(nickname, 'template',
                                       cm.FILE_DEFAULTS.template_file)
        if a:
            section['template_file'] = a

        cm.write_section(acct_section)

    def _present_file_options(self, nickname, file_type, default_file):
        a = prompt(
            "Create a separate {} file configuration setting for this account [Y/n]: "
            .format(file_type),
            validator=YesNoValidator()).lower()
        if not bool(a) or a.startswith("y"):
            cont = True
            while cont:
                path = prompt(
                    "Enter the path for the {} file used for this account [{}]: "
                    .format(file_type, default_file),
                    completer=PATH_COMPLETER)
                if path:
                    path = os.path.expanduser(path)
                    file_exists = os.path.isfile(path)
                    if not file_exists:
                        create = prompt(
                            "{} does not exist. Do you want to create it? [Y/n]: "
                            .format(path),
                            validator=YesNoValidator()).lower()
                        if not bool(create) or create.startswith("y"):
                            if not os.path.exists(path):
                                cm._create_directory_tree(path)
                            cm._create_directory_tree(path)
                            cm.touch(path)
                            cont = False
                        else:
                            cont = True
                    else:
                        cont = False
                else:  #use default
                    create = prompt(
                        "{} does not exist. Do you want to create it? [Y/n]: ".
                        format(default_file),
                        validator=YesNoValidator()).lower()
                    if not bool(create) or create.startswith("y"):
                        if not os.path.exists(default_file):
                            cm._create_directory_tree(default_file)
                        cm.touch(default_file)
                        path = default_file
                        cont = False
                    else:
                        cont = True
                if cont:
                    print("Invalid path {}. Please enter a valid path.".format(
                        path))
                else:
                    cont = False

            if not path:
                path = cm.get_custom_file_path(nickname,
                                               file_type,
                                               create_file=True)
            return path
        elif a.startswith("n"):
            return None

    def _process_mfa(self, data):
        type = data['type']
        mfa = data['mfa']
        if type == 'questions':
            return self._present_question([q['question'] for q in mfa])
        elif type == 'list':
            return self._present_list(mfa)
        elif type == 'selection':
            return self._present_selection(mfa)
        else:
            raise Exception("Unknown mfa type from Plaid")

    def _present_question(self, question):
        clear_screen()
        print(question[0])
        answer = prompt("Answer: ",
                        validator=NullValidator(
                            message="You must enter your answer",
                            allow_quit=True))
        if answer.lower() == "q": return False  #we have abandoned ship
        self.connect_response = self.client.connect_step(
            self.account_type, answer)
        return True

    def _present_accounts(self, data):
        clear_screen()
        accounts = list(enumerate(data, start=1))
        message = ["Which account do you want to add:\n"]
        for i, d in accounts:
            a = {}
            a['choice'] = str(i)
            a['name'] = d['meta']['name']
            a['type'] = d['subtype'] if 'subtype' in d else d['type']
            message.append("{choice:<2}. {name:<40}  {type}\n".format(**a))

        message.append("\nEnter your selection: ")
        answer = prompt(
            "".join(message),
            validator=NumberValidator(
                message="Enter the NUMBER of the account you want to add",
                allow_quit=True,
                max_number=len(accounts)))
        if answer.lower() == "q": return False  #we have abandoned ship
        self.selected_account = accounts[int(answer) - 1][1]
        return True

    def _present_list(self, data):
        clear_screen()
        devices = list(enumerate(data, start=1))
        message = ["Where do you want to send the verification code:\n"]
        for i, d in devices:
            message.append("{:<4}{}\n".format(i, d["mask"]))
        message.append("\nEnter your selection: ")
        answer = prompt(
            "".join(message),
            validator=NumberValidator(
                message=
                "Enter the NUMBER where you want to send verification code",
                allow_quit=True,
                max_number=len(devices)))
        if answer.lower() == "q": return False  #we have abandoned ship
        dev = devices[int(answer) - 1][1]
        print("Code will be sent to: {}".format(dev["mask"]))
        self.connect_response = self.client.connect_step(
            self.account_type,
            None,
            options={'send_method': {
                'type': dev['type']
            }})
        code = prompt("Enter the code you received: ",
                      validator=NumberValidator())
        self.connect_response = self.client.connect_step(
            self.account_type, code)
        return True

    def _present_selection(self, data):
        """
        Could not test: needs implementation
        """
        clear_screen()
        raise NotImplementedError(
            "MFA selections are not yet implemented, sorry.")

    def _get_needed_creds(self):
        credentials = self.active_institution["credentials"]
        clear_screen()
        print("Enter the required credentials for {}\n".format(
            self.active_institution["name"]))
        user_prompt = "Username ({}): ".format(credentials["username"])
        pass_prompt = "Password ({}): ".format(credentials["password"])
        pin = None
        username = prompt(
            user_prompt,
            validator=NullValidator(message="Please enter your username"))
        password = prompt(
            pass_prompt,
            is_password=True,
            validator=NullValidator(message="You must enter your password"))
        if "pin" in credentials:
            pin = prompt(
                "PIN: ",
                validator=NumLengthValidator(
                    message="Pin must be at least {} characters long"))
            if not bool(pin) or pin.lower() == "q":
                pin = None  #make sure we have something
        return username, password, pin

    def _get_available_institutions(self):
        # limit to just those institutions that have connect abilities,
        # as that is the service we will be using to get transactions
        institutions = self.client.institutions().json()
        self.available_institutions = list(
            enumerate([i for i in institutions if 'connect' in i['products']],
                      start=1))

    def _get_institution(self):
        accounts = []
        total_institutions = len(self.available_institutions)
        for account in self.available_institutions:
            num, info = account
            accounts.append("{num:<4}{inst}".format(num=num,
                                                    inst=info['name']))

        institution_prompt = textwrap.dedent(
            """What bank is this account going to be for? \n{}\n\nEnter Number [q to quit]:"""
            .format('\n'.join(accounts)))

        clear_screen()

        res = prompt(institution_prompt,
                     validator=NumberValidator(
                         message="You must enter the chosen number",
                         allow_quit=True,
                         max_number=total_institutions))
        if res.isdigit():
            choice = int(res) - 1
        elif res.lower() == "q":
            choice = None

        return choice

    def _check_status(self):
        status = self.connect_response.status_code
        if status == 200:
            # good, user connected
            return True
        elif status == 201:
            # MFA required
            return False
        else:
            return False
Beispiel #47
0
def test_unauthorizedError_bad_password():
    client = Client('test_id', 'test_secretz')
    with pytest.raises(UnauthorizedError):
        client.balance()
Beispiel #48
0
    class Meta:
        order_by = ('username', )


# the user model specifies its fields (or columns) declaratively, like django
"""class Credentials(BaseModel):
    name = CharField(unique=True)
    id = CharField()
    secret = CharField()

    class Meta:
        order_by = ('name',)"""

database.create_table(User, safe=True)

Client.config({'url': 'https://tartan.plaid.com'})
#ident = Person.get(Person.name == 'Grandma L.')
#print(ident)
id = "57b4e70c66710877408d0855"  # obtain id and secret from db, same for all queries
secret = "d416705651d48d87e080e966c80421"
"""ident = Credentials(name = 'main', id = id, secret = secret)
ident.save()
ident = Credentials.get(Credentials.name == 'main')
print(ident)"""
client = Client(client_id=id, secret=secret)
account_type = 'chase'


def answer_mfa(data, client):
    if data['type'] == 'questions':
        # Ask your user for the answer to the question[s].
Beispiel #49
0
def test_ResourceNotFound_categories():
    client = Client('test_id', 'test_secret')
    with pytest.raises(ResourceNotFoundError):
        client.category('pnc')
Beispiel #50
0
def test_institution():
    client = Client('test_id', 'test_secret')
    response = client.institution(to_json(client.institutions())[0]['id'])

    assert response.status_code == 200
Beispiel #51
0
def test_auth_step():
    client = Client('test_id', 'test_secret', access_token='test_pnc')
    response = client.auth_step('pnc', 'tomato')
    assert response.status_code == 200
    assert to_json(response)['access_token'] == 'test_pnc'
Beispiel #52
0
def test_connect_update():
    client = Client('test_id', 'test_secret', access_token='test_amex')
    response = client.connect_update(no_mfa_credentials)
    assert response.status_code == 200
Beispiel #53
0
def test_auth_update():
    client = Client('test_id', 'test_secret', access_token='test_amex')
    response = client.auth_update(no_mfa_credentials)
    assert response.status_code == 200
Beispiel #54
0
def test_connect_step_update():
    client = Client('test_id', 'test_secret', access_token='test_bofa')
    response = client.connect_update_step('bofa', 'tomato')
    assert response.status_code == 200
Beispiel #55
0
def test_connect_mfa_question():
    client = Client('test_id', 'test_secret')
    response = client.connect('bofa', no_mfa_credentials)
    assert response.status_code == 201
    assert to_json(response)['type'] == 'questions'
Beispiel #56
0
def test_upgrade():
    client = Client('test_id', 'test_secret', access_token='test_bofa')
    response = client.upgrade('info')
    assert response.status_code == 200
    assert 'info' in to_json(response).keys()
Beispiel #57
0
def test_connect_step_question():
    client = Client('test_id', 'test_secret', access_token='test_bofa')
    response = client.connect_step('bofa', 'tomato')
    assert response.status_code == 200
    assert to_json(response)['access_token'] == 'test_bofa'
Beispiel #58
0
def test_exchange():
    client = Client('test_id', 'test_secret')
    response = client.exchange_token('test,chase,connected')
    assert response.status_code == 200
    assert to_json(response)['access_token'] == 'test_chase'
    assert client.access_token == 'test_chase'
Beispiel #59
0
def test_connect_delete():
    client = Client('test_id', 'test_secret', access_token='test_chase')
    response = client.connect_delete()
    assert response.status_code == 200
    assert to_json(response)['message'] == 'Successfully removed from system'
Beispiel #60
0
def test_UnauthorizedError_bad_token():
    client = Client('test_id', 'test_secret', 'test_zoba')
    with pytest.raises(UnauthorizedError):
        client.balance()