Skip to content

Latest commit

 

History

History
182 lines (133 loc) · 6.08 KB

item-creation.md

File metadata and controls

182 lines (133 loc) · 6.08 KB

PYONEPASSWORD ITEM CREATION

Description

This document describes the process of item creation using pyonpassword, as well as several relevant classes.

Basic item creation

In the simplest case, use a convenience method on a signed-in OP object. Currently there is one for creating login items, but more will be added over time. Use op.login_item_create().

from pyonepassword import OP
from pyonepassword.api.object_types import OPLoginItem

def main():
    # see README.md for sign-in process
    op: OP = do_signin()

    title = "Example Login Item"
    username = "test_username"
    great_password = "really-great-password"

    login_url = "https://website.example"

    new_item: OPLoginItem = op.login_item_create(title,
                                                 username,
                                                 url=login_url,
                                                 password=great_password,
                                                 vault="Test Data")

You can also have a password generated by providing a password recipe, rather than a password. This involves the OPPasswordRecipe class.

from pyonepassword import OP
from pyonepassword.api.constants import LETTERS_DIGITS_SYMBOLS_20
from pyonepassword.api.object_types import OPLoginItem, OPPasswordRecipe


def main():
    # see README.md for sign-in process
    op: OP = do_signin()

    title = "Example Login Item"
    username = "test_username"
    login_url = "https://website.example"

    # Explicitly specify a recipe
    # in this case, a 40-character alphabetic-only password
    recipe = OPPasswordRecipe(length=40, digits=False, symbols=False)
    # ... or use one of the predefined constants (pyonepassword.api.constants)
    # 20-character letters/digits/symbols password
    recipe = LETTERS_DIGITS_SYMBOLS_20

    new_item: OPLoginItem = op.login_item_create(title,
                                                 username,
                                                 url=login_url,
                                                 # If 'password' is a recipe rather than a string
                                                 # the '--generate-password=<recipe>' CLI option will be used
                                                 # to auto-generate a password for this login item
                                                 password=recipe,
                                                 vault="Test Data")

Advanced Item Creation

If you want more control over the new item, such as adding custom fields or sections, you can create an item template object, and pass that object to the more generic op.item_create().

from pyonepassword import OP
from pyonepassword.api.constants import LETTERS_DIGITS_SYMBOLS_20
from pyonepassword.api.object_types import (
    OPLoginItem,
    OPLoginItemTemplate,
    OPNewSection,
    OPNewStringField
)



def main():
    # see README.md for sign-in process

    username = "test_username"
    title = "Test Login Item"
    login_url = "https://website.example"

    section_label = "Example Section"
    field_label = "Example Field"
    field_value = "Exampe field text."
    # Section ID will be randomly generated if not provided
    new_section = OPNewSection(section_label)

    # Field ID will be randomly generated if not provided
    # If section is provided, this field will be part of that section
    new_field = OPNewStringField(field_label, field_value, section=new_section)

    # add custom field and section to the new login item template
    item_template = OPLoginItemTemplate(title, username, url=login_url,
                                   sections=[new_section], fields=[new_field])

    op: OP = do_signin()

    # NOTE: only password recipes, not literal password strings are supported via item_create()
    #       however, a password string can be provided to OPLoginItemTemplate()
    recipe = LETTERS_DIGITS_SYMBOLS_20

    # Use generic 'item_create()' API to pass in an item template object
    # NOTE: item_create() will raise an exception if a password recipe is provided
    # for item types that don't support passwords
    new_item: OPLoginItem = op.item_create(item_template, password_recipe=recipe)
    return new_item

Login item with a TOTP field

If you need to create a new login item that includes TOTP code generator, you can use the OPNewTOTPField, plus optionally the OPNewTOTPUri class:

import base64
import secrets

from pyonepassword import OP
from pyonepassword.api.constants import LETTERS_DIGITS_SYMBOLS_20
from pyonepassword.api.object_types import (
    OPLoginItem,
    OPLoginItemTemplate,
    OPNewTOTPField,
    OPNewTOTPUri,
    OPPasswordRecipe,
    OPTOTPField
)


def totp_secret():
    # Normally the website/service provides this, but
    # we generate one for our example
    secret = secrets.token_bytes(10)
    secret = base64.b32encode(secret).decode()
    secret = secret.rstrip("=")
    return secret


def build_totp_uri():
    issuer = "Example Website"
    account_name = "newuser@website"
    secret = totp_secret()

    # If website/service provides fully-formed URI string
    new_totp_uri = "otpauth://totp/Example%20Website:newuser%40website?secret=EPW4UE4E7IKC2QMB&issuer=Example%20Website"

    # or for more sanity checking & proper encoding, create a OPNewTOTPUri object
    new_totp_uri = OPNewTOTPUri(
        secret, account_name=account_name, issuer=issuer)

    return new_totp_uri


def main():
    username = "test_username"
    title = "New Login with TOT"

    op = OP()
    recipe = OPPasswordRecipe(length=40, digits=False, symbols=False)
    # or...
    recipe = LETTERS_DIGITS_SYMBOLS_20

    new_totp_uri = build_totp_uri()
    totp_field_label = "One-time Password"
    totp_field = OPNewTOTPField(totp_field_label, new_totp_uri)

    new_item_template = OPLoginItemTemplate(title, username, fields=[totp_field])

    new_item: OPLoginItem = op.item_create(
        new_item_template, password_recipe=recipe, vault="Test Data")

    totp_field: OPTOTPField = new_item.first_field_by_label(totp_field_label)
    totp_code = totp_field.totp
    print(f"{totp_code}")