{ "cells": [ { "cell_type": "code", "source": [ "import sys\n", "import os\n", "sys.path.append(os.path.abspath('..')) # Adds the parent directory to path\n", "from src.nkode_api import NKodeAPI\n", "from src.models import NKodePolicy, KeypadSize\n", "from src.utils import select_keys_with_passcode_values\n", "from secrets import choice\n", "from string import ascii_lowercase\n", "import numpy as np\n", "\n", "def random_username() -> str:\n", " return \"test_username\" + \"\".join([choice(ascii_lowercase) for _ in range(6)])\n" ], "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2025-03-28T15:06:18.878127Z", "start_time": "2025-03-28T15:06:18.874618Z" } }, "outputs": [], "execution_count": 30 }, { "metadata": {}, "cell_type": "markdown", "source": [ "## Initialize nKode API and Create Customer\n", "#### nKode Customer\n", "An nKode customer is business has employees (users). An nKode API can service many customers each with their own users.\n", "Each customer specifies a keypad size and a nkode policy.\n", "The keypad can't be dispersable (`numb_of_keys < properties_per_key`)" ] }, { "cell_type": "code", "source": [ "api = NKodeAPI()\n", "policy = NKodePolicy(\n", " max_nkode_len=10,\n", " min_nkode_len=4,\n", " distinct_positions=0, # complexity\n", " distinct_properties=4, # disparity\n", ")\n", "keypad_size = KeypadSize(\n", " numb_of_keys = 5,\n", " props_per_key = 6\n", ")\n", "customer_id = api.create_new_customer(keypad_size, policy)\n", "customer = api.get_customer(customer_id)" ], "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2025-03-28T15:06:18.896461Z", "start_time": "2025-03-28T15:06:18.891125Z" } }, "outputs": [], "execution_count": 31 }, { "metadata": {}, "cell_type": "markdown", "source": [ "## nKode Enrollment\n", "Users enroll in three steps:\n", "1. Create Signup Session\n", "2. Set nKode\n", "3. Confirm nKode\n", "\n", "#### Create Signup Session\n", "A user, associate with customer (or business), specifies a username and receives a signup_session_id and set_keypad. The keypad is a index array. It tells the client how to sort the user's icons." ] }, { "metadata": { "ExecuteTime": { "end_time": "2025-03-28T15:06:18.914254Z", "start_time": "2025-03-28T15:06:18.911798Z" } }, "cell_type": "code", "source": [ "username = random_username()\n", "signup_session_id, set_keypad = api.generate_signup_keypad(customer_id, username)" ], "outputs": [], "execution_count": 32 }, { "metadata": {}, "cell_type": "markdown", "source": [ "### Set nKode\n", "The client receives `user_icons`, `set_signup_keypad`\n" ] }, { "metadata": { "ExecuteTime": { "end_time": "2025-03-28T15:06:18.931791Z", "start_time": "2025-03-28T15:06:18.929028Z" } }, "cell_type": "code", "source": [ "passcode_len = 4\n", "passcode_property_indices = np.random.choice(set_keypad.reshape(-1), size=passcode_len, replace=False).tolist()\n", "selected_keys_set = select_keys_with_passcode_values(passcode_property_indices, set_keypad, keypad_size.numb_of_keys)" ], "outputs": [], "execution_count": 33 }, { "metadata": {}, "cell_type": "markdown", "source": [ "### Confirm nKode\n", "The user enter then submits their key entry. The server returns the confirm_keypad, another index array and dispersion of the set_keypad." ] }, { "metadata": { "ExecuteTime": { "end_time": "2025-03-28T15:06:19.247638Z", "start_time": "2025-03-28T15:06:18.938601Z" } }, "cell_type": "code", "source": [ "confirm_keypad = api.set_nkode(customer_id, selected_keys_set, signup_session_id)\n", "selected_keys_confirm = select_keys_with_passcode_values(passcode_property_indices, confirm_keypad, keypad_size.numb_of_keys)\n", "success = api.confirm_nkode(customer_id, selected_keys_confirm, signup_session_id)\n", "assert success" ], "outputs": [], "execution_count": 34 }, { "metadata": {}, "cell_type": "markdown", "source": [ "### User Login\n", "1. Get login keypad\n", "2. Select keys with passcode icons (in our case, passcode property indices)\n" ] }, { "metadata": { "ExecuteTime": { "end_time": "2025-03-28T15:06:19.559753Z", "start_time": "2025-03-28T15:06:19.254675Z" } }, "cell_type": "code", "source": [ "login_keypad = api.get_login_keypad(username, customer_id)\n", "selected_keys_login = select_keys_with_passcode_values(passcode_property_indices, login_keypad, keypad_size.props_per_key)\n", "success = api.login(customer_id, username, selected_keys_login)\n", "assert success" ], "outputs": [], "execution_count": 35 }, { "metadata": {}, "cell_type": "markdown", "source": [ "## Renew Properties\n", "Replace server-side ciphers keys and nkode hash with new values.\n", "1. Renew Customer Properties\n", "2. Renew User Keys\n", "3. Refresh User on Login" ] }, { "metadata": { "ExecuteTime": { "end_time": "2025-03-28T15:06:20.181548Z", "start_time": "2025-03-28T15:06:19.568067Z" } }, "cell_type": "code", "source": [ "api.renew_keys(customer_id) # Steps 1 and 2\n", "login_keypad = api.get_login_keypad(username, customer_id)\n", "selected_keys_login = select_keys_with_passcode_values(passcode_property_indices, login_keypad, keypad_size.props_per_key)\n", "success = api.login(customer_id, username, selected_keys_login) # Step 3\n", "assert success" ], "outputs": [], "execution_count": 36 }, { "metadata": { "ExecuteTime": { "end_time": "2025-03-28T15:06:20.500050Z", "start_time": "2025-03-28T15:06:20.194912Z" } }, "cell_type": "code", "source": [ "login_keypad = api.get_login_keypad(username, customer_id)\n", "selected_keys_login = select_keys_with_passcode_values(passcode_property_indices, login_keypad, keypad_size.props_per_key)\n", "success = api.login(customer_id, username, selected_keys_login)\n", "assert success" ], "outputs": [], "execution_count": 37 } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 0 }