﻿# The example shows how to print accounts of safe box in SecureAnyBox
#   in this example, helper method find_safe_box_by_name is used to get safe box id 
#   for a given safe box name ('test box')

# SABClient methods used:
#
# login(self, username, password, domain='system', access_code=None)
# logout(self)
# find_safe_box_by_name(self, box_name, parent_box_id=None)
# get_record_list(self, safe_box_id)
# get_record(self, record_id)

import sys
import json
import sabclient

# If the logged-on user requests a second factor, SABClient calls the second factor callback 
#   to retrieve the six-digit code
def get_second_factor():
  print('** SECOND FACTOR AUTHENTICATION **')
  print()
  s = input("Enter 6-digit code from your authenticator application: ") 
  return s

# The class Switcher serves in Python as a replacement for the switch/case construct
class Switcher(object):

    # print_record prints out concrete fields by type of record
    # record types are account, account-sec, cert, ccard and file
    #   replace() function converts hyphen character "-" to underscore one "_" (enabled in Python identifiers)
    def print_record(self, record_template, rec):
        method_name = 'print_' + record_template.replace('-', '_', 1)
        method = getattr(self, method_name, lambda: 'Invalid')
        print()  # records separating an empty line
        return method(rec)

    # print_common_record_fields prints out common fields of all records
    def print_common_record_fields(self, rec):
        print('  Name:        ', rec.get("name", ''))
        print('  Description: ', rec.get("description", ''))
        print('  Tags:        ', rec.get("tags"))
        print('  Note:         "' + rec.get("note", '') + '"')
        return

    # print_account prints out fields of the account
    def print_account(self, rec):
        print('account:        (', rec["id"], ')')
        self.print_common_record_fields(rec)

        print('  Site:        ', rec.get("site", ''))
        print('  Address:     ', rec.get("serverAddress", ''))
        print('  Login:       ', rec.get("loginName", ''))

        return True

    # print_account_sec prints out fields of the secure account
    def print_account_sec(self, rec):
        print('sec account:    (', rec["id"], ')')
        self.print_common_record_fields(rec)

        print('  Site:        ', rec.get("site", ''))

        attributes = rec.get("attributes", {})
        print('  Address:     ', attributes.get("sec-serverAddress", ''))
        print('  Login:       ', attributes.get("sec-loginName", ''))
        print('  Secret Note:  "' + attributes.get("sec-note", '') + '"')

        return True

    # print_account prints out fields of the certificate
    def print_cert(self, rec):
        print('certificate:    (', rec["id"], ')')
        self.print_common_record_fields(rec)

        attributes = rec.get("attributes", {})
        print('  Alias:       ', attributes.get("alias", ''))
        print('  Certificate: ', attributes.get("file", ''))
        print('  Cert pswd:   ', attributes.get("filePassword", ''))
        print('  Secret Note:  "' + attributes.get("sec-note", '') + '"')

        return True

    # print_account prints out fields of the credit card
    def print_ccard(self, rec):
        print('credit card     (', rec["id"], ')')
        self.print_common_record_fields(rec)

        attributes = rec.get("attributes", {})
        print('  Number:      ', attributes.get("number", ''))
        print('  Expiration:  ', attributes.get("expiration", ''))
        print('  Cvv:         ', attributes.get("cvv", ''))
        print('  Pin:         ', attributes.get("pin", ''))
        print('  Secret Note:  "' + attributes.get("sec-note", '') + '"')

        return True

    # print_account prints out fields of the file record
    def print_file(self, rec):
        print('file:           (', rec["id"], ')')
        self.print_common_record_fields(rec)

        attributes = rec.get("attributes", {})
        print('  File:        ', attributes.get("file", ''))
        print('  Secret Note:  "' + attributes.get("sec-note", '') + '"')

        return True

################################## main ######################################################

# first we need to create SecureAnyBox (SAB) client for given SAB server address (including base path);
# the callback applies when the second factor is required to sign in
sab = sabclient.SABClient('http://127.0.0.1:8843/secureanybox/', callback=get_second_factor)

# Then we need to authenticate the user.
# Don't use admin account, create account with minimum access rights, only to the required safe box
result = sab.login('serviceuser', 'password', access_code='123456', domain='test')

if result:
    switch = Switcher()

    # to list records, we need to know an id of parent safe box we can get a safe box id from URL in SecureAnyBox
    # web interface (e.g in https://172.22.14.2/sab/static/safe-search.page?s#$groupbrowse$/group/893 the 893 is a
    # safe box id)

    # or we can find the safe box by name (internally SABClient will list safe boxes and find one with name matching
    # safe_box_name or return None if no such safe box was found)
    safe_box_name = 'test box'
    safe_box = sab.find_safe_box_by_name(safe_box_name);

    if safe_box is None:
        print('safe box ' + safe_box_name + ' was not found.')
        exit(1)  # quit with non-zero exit code so that calling script can test if this script failed or not

    # get_record_list returns a list of records in a box containing common record fields
    record_list = sab.get_record_list(safe_box['id'])

    for rec in record_list:
        # get_record returns a record with all appropriate fields
        record = sab.get_record(rec["id"])
        switch.print_record(record["template"], record)

# when not needed anymore, you can logout the client, which will destroy session cookies and the client can no
# longer be used to work with SAB server
sab.logout
