fix nkode api; username should be specified at the beginning of the enrollment

This commit is contained in:
2025-03-24 15:24:53 -05:00
parent 1846dc1065
commit 3a9fadfc03
10 changed files with 281 additions and 199 deletions

View File

@@ -29,15 +29,18 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2025-03-24T09:48:10.442598Z",
"start_time": "2025-03-24T09:48:10.410209Z"
"end_time": "2025-03-24T20:06:28.904351Z",
"start_time": "2025-03-24T20:06:28.864248Z"
}
},
"outputs": [],
"execution_count": 1
"execution_count": 4
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"source": [
"api = NKodeAPI()\n",
"user_icons = np.array([\n",
@@ -48,16 +51,7 @@
" \"🦁\", \"🐻\", \"🐸\", \"🐙\", \"🦄\",\n",
" \"🌟\", \"⚡\", \"🔥\", \"🍕\", \"🎉\"\n",
"])"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2025-03-24T09:48:10.450851Z",
"start_time": "2025-03-24T09:48:10.448737Z"
}
},
"outputs": [],
"execution_count": 2
]
},
{
"metadata": {},
@@ -70,6 +64,7 @@
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": [
"#### Customer Cipher Keys\n",
@@ -78,13 +73,13 @@
"There are two types of Customer Cipher Keys:\n",
"1. property key: Combined with the user property key to get the server-side representation of a users icons.\n",
"2. position key: Combined with the user position key to get the server-side representation the position in each key.\n"
],
"metadata": {
"collapsed": false
}
]
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"source": [
"policy = NKodePolicy(\n",
" max_nkode_len=10,\n",
@@ -107,69 +102,20 @@
"print(f\"Position to Properties Map:\")\n",
"for pos_val, props in position_properties_dict.items():\n",
" print(f\"{pos_val}: {props}\")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2025-03-24T09:48:10.468165Z",
"start_time": "2025-03-24T09:48:10.456820Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Customer Position Key: [ 4136 64524 15410 9988 20496 18918]\n",
"Customer Properties Key:\n",
"[46103 19687 10938 59248 5143 27050]\n",
"[26684 7431 59668 28699 6929 18710]\n",
"[12853 35476 62914 24111 36473 25394]\n",
"[63988 14898 1879 44350 53666 23249]\n",
"[23805 45848 21514 8782 7583 36157]\n",
"Position to Properties Map:\n",
"4136: [46103 26684 12853 63988 23805]\n",
"64524: [19687 7431 35476 14898 45848]\n",
"15410: [10938 59668 62914 1879 21514]\n",
"9988: [59248 28699 24111 44350 8782]\n",
"20496: [ 5143 6929 36473 53666 7583]\n",
"18918: [27050 18710 25394 23249 36157]\n"
]
}
],
"execution_count": 3
]
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-24T09:48:10.593687Z",
"start_time": "2025-03-24T09:48:10.591235Z"
}
},
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"source": [
"user_icon_keypad = user_icons.reshape(-1, keypad_size.props_per_key)\n",
"pos_icons_dict = dict(zip(customer.cipher.position_key, user_icon_keypad.T))\n",
"print(\"Position Value to Icons Map:\")\n",
"for pos_val, icons in pos_icons_dict.items():\n",
" print(f\"{pos_val}: {icons}\")\n"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Position Value to Icons Map:\n",
"4136: ['😀' '🥺' '🤔' '🐱' '🦄']\n",
"64524: ['😂' '😡' '🙃' '🐶' '🌟']\n",
"15410: ['🥳' '😱' '😇' '🦁' '⚡']\n",
"9988: ['😍' '🤯' '🤖' '🐻' '🔥']\n",
"20496: ['🤓' '🥰' '👽' '🐸' '🍕']\n",
"18918: ['😎' '😴' '👾' '🐙' '🎉']\n"
]
}
],
"execution_count": 4
]
},
{
"metadata": {},
@@ -191,88 +137,20 @@
]
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-24T09:48:10.653252Z",
"start_time": "2025-03-24T09:48:10.646267Z"
}
},
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"source": [
"signup_session_id, set_signup_keypad = api.generate_signup_keypad(customer_id)\n",
"username = random_username()\n",
"signup_session_id, set_signup_keypad = api.generate_signup_keypad(customer_id, username)\n",
"display(Markdown(\"\"\"### Icon Keypad\"\"\"))\n",
"keypad_view(user_icons[set_signup_keypad], keypad_size.numb_of_keys)\n",
"display(Markdown(\"\"\"### Index Keypad\"\"\"))\n",
"keypad_view(set_signup_keypad, keypad_size.numb_of_keys)\n",
"display(Markdown(\"\"\"### Customer Properties Keypad\"\"\"))\n",
"keypad_view(customer.cipher.property_key[set_signup_keypad], keypad_size.numb_of_keys)"
],
"outputs": [
{
"data": {
"text/plain": [
"<IPython.core.display.Markdown object>"
],
"text/markdown": "### Icon Keypad"
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Key 0: ['😂' '🥳' '🐻' '🍕' '😎']\n",
"Key 1: ['🐶' '⚡' '🤖' '🥰' '🎉']\n",
"Key 2: ['🌟' '😇' '😍' '🤓' '🐙']\n",
"Key 3: ['😡' '😱' '🔥' '👽' '😴']\n",
"Key 4: ['🙃' '🦁' '🤯' '🐸' '👾']\n"
]
},
{
"data": {
"text/plain": [
"<IPython.core.display.Markdown object>"
],
"text/markdown": "### Index Keypad"
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Key 0: [ 1 2 21 28 5]\n",
"Key 1: [19 26 15 10 29]\n",
"Key 2: [25 14 3 4 23]\n",
"Key 3: [ 7 8 27 16 11]\n",
"Key 4: [13 20 9 22 17]\n"
]
},
{
"data": {
"text/plain": [
"<IPython.core.display.Markdown object>"
],
"text/markdown": "### Customer Properties Keypad"
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Key 0: [19687 10938 44350 7583 27050]\n",
"Key 1: [14898 21514 24111 6929 36157]\n",
"Key 2: [45848 62914 59248 5143 23249]\n",
"Key 3: [ 7431 59668 8782 36473 18710]\n",
"Key 4: [35476 1879 28699 53666 25394]\n"
]
}
],
"execution_count": 5
]
},
{
"metadata": {},
@@ -290,16 +168,6 @@
}
},
"cell_type": "code",
"source": [
"username = random_username()\n",
"passcode_len = 4\n",
"passcode_property_indices = np.random.choice(set_signup_keypad.reshape(-1), size=passcode_len, replace=False).tolist()\n",
"selected_keys_set = select_keys_with_passcode_values(passcode_property_indices, set_signup_keypad, keypad_size.numb_of_keys)\n",
"print(f\"User Passcode Indices: {passcode_property_indices}\")\n",
"print(f\"User Passcode Icons: {user_icons[passcode_property_indices]}\")\n",
"print(f\"User Passcode Server-side properties: {customer.cipher.property_key[passcode_property_indices]}\")\n",
"print(f\"Selected Keys: {selected_keys_set}\")"
],
"outputs": [
{
"name": "stdout",
@@ -312,7 +180,16 @@
]
}
],
"execution_count": 6
"execution_count": 6,
"source": [
"passcode_len = 4\n",
"passcode_property_indices = np.random.choice(set_signup_keypad.reshape(-1), size=passcode_len, replace=False).tolist()\n",
"selected_keys_set = select_keys_with_passcode_values(passcode_property_indices, set_signup_keypad, keypad_size.numb_of_keys)\n",
"print(f\"User Passcode Indices: {passcode_property_indices}\")\n",
"print(f\"User Passcode Icons: {user_icons[passcode_property_indices]}\")\n",
"print(f\"User Passcode Server-side properties: {customer.cipher.property_key[passcode_property_indices]}\")\n",
"print(f\"Selected Keys: {selected_keys_set}\")"
]
},
{
"metadata": {},
@@ -331,11 +208,11 @@
},
"cell_type": "code",
"source": [
"confirm_keypad = api.set_nkode(username, customer_id, selected_keys_set, signup_session_id)\n",
"confirm_keypad = api.set_nkode(customer_id, selected_keys_set, signup_session_id)\n",
"keypad_view(confirm_keypad, keypad_size.numb_of_keys)\n",
"selected_keys_confirm = select_keys_with_passcode_values(passcode_property_indices, confirm_keypad, keypad_size.numb_of_keys)\n",
"print(f\"Selected Keys\\n{selected_keys_confirm}\")\n",
"success = api.confirm_nkode(username, customer_id, selected_keys_confirm, signup_session_id)\n",
"success = api.confirm_nkode(customer_id, selected_keys_confirm, signup_session_id)\n",
"assert success"
],
"outputs": [

View File

@@ -0,0 +1,210 @@
{
"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-24T20:18:04.947152Z",
"start_time": "2025-03-24T20:18:04.916604Z"
}
},
"outputs": [],
"execution_count": 1
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Initialize nKode API"
},
{
"cell_type": "code",
"source": [
"api = NKodeAPI()\n",
"policy = NKodePolicy(\n",
" max_nkode_len=10,\n",
" min_nkode_len=4,\n",
" distinct_positions=0,\n",
" distinct_properties=4,\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-24T20:18:04.960698Z",
"start_time": "2025-03-24T20:18:04.950723Z"
}
},
"outputs": [],
"execution_count": 2
},
{
"metadata": {},
"cell_type": "markdown",
"source": [
"## nKode Enrollment\n",
"Users enroll in three steps:\n"
]
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-24T20:18:04.989029Z",
"start_time": "2025-03-24T20:18:04.986797Z"
}
},
"cell_type": "code",
"source": [
"username = random_username()\n",
"signup_session_id, set_signup_keypad = api.generate_signup_keypad(customer_id, username)"
],
"outputs": [],
"execution_count": 3
},
{
"metadata": {},
"cell_type": "markdown",
"source": [
"### Set nKode\n",
"The client receives `user_icons`, `set_signup_keypad`\n"
]
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-24T20:18:04.997252Z",
"start_time": "2025-03-24T20:18:04.995177Z"
}
},
"cell_type": "code",
"source": [
"passcode_len = 4\n",
"passcode_property_indices = np.random.choice(set_signup_keypad.reshape(-1), size=passcode_len, replace=False).tolist()\n",
"selected_keys_set = select_keys_with_passcode_values(passcode_property_indices, set_signup_keypad, keypad_size.numb_of_keys)"
],
"outputs": [],
"execution_count": 4
},
{
"metadata": {},
"cell_type": "markdown",
"source": [
"### Confirm nKode\n",
"Submit the set key entry to render the confirm keypad."
]
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-24T20:18:05.239384Z",
"start_time": "2025-03-24T20:18:05.002825Z"
}
},
"cell_type": "code",
"source": [
"confirm_keypad = api.set_nkode(username, 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(username, customer_id, selected_keys_confirm, signup_session_id)\n",
"assert success"
],
"outputs": [],
"execution_count": 5
},
{
"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-24T20:18:05.478978Z",
"start_time": "2025-03-24T20:18:05.245767Z"
}
},
"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": 6
},
{
"metadata": {},
"cell_type": "markdown",
"source": [
"## Renew Properties\n",
"1. Renew Customer Properties\n",
"2. Renew User Keys\n",
"3. Refresh User on Login\n",
"\n"
]
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-24T20:18:05.950627Z",
"start_time": "2025-03-24T20:18:05.484941Z"
}
},
"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": 7
}
],
"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
}