fix nkode api; username should be specified at the beginning of the enrollment
This commit is contained in:
@@ -12,26 +12,26 @@ sequenceDiagram
|
||||
Server->>Server: Create Signup Session
|
||||
Note over User,Server: Set nKode
|
||||
Server-->>-Client: signup_session_id, set_keypad, icons
|
||||
Note left of Server: signup_session_id:<br/>51b187b9-c930-4f5d-81da-c11c082f2c64
|
||||
Note left of Server: set_keypad:<br/>Key 0: [ 9 29 3 49 50 25]<br/>Key 1: [27 2 12 22 14 16]<br/>Key 2: [36 47 21 13 23 7]<br/>Key 3: [45 11 30 4 32 43]<br/>Key 4: [18 20 39 40 41 52]<br/>Key 5: [ 0 38 48 31 5 34]<br/>
|
||||
Note left of Server: signup_session_id:<br/>1334d391-3c8a-431a-8186-e91b29d42750
|
||||
Note left of Server: set_keypad:<br/>Key 0: [18 2 39 13 23 16]<br/>Key 1: [36 20 21 49 5 43]<br/>Key 2: [ 0 47 48 4 50 25]<br/>Key 3: [27 38 12 40 32 52]<br/>Key 4: [45 29 3 31 41 34]<br/>Key 5: [ 9 11 30 22 14 7]<br/>
|
||||
Note left of Server: Icons:<br/>[🍎,🍏,🍊,🍋,🍌,🍉<br/>🍇,🍓,🍒,🍑,🥭,🍍<br/>🥥,🥝,🍅,🍆,🥑,🥕<br/>🌽,🥔,🍠,🥐,🥖,🥨<br/>🥯,🥞,🧀,🍖,🍗,🥚<br/>🍔,🍟,🍕,🌭,🥪,🌮<br/>🌯,🍣,🍤,🍙,🍚,🍜<br/>🍲,🍛,🍱,🥟,🍦,🍧<br/>🍨,🍩,🍪,🎂,🍰,🧁]
|
||||
Client->>Client: Order Icons by keypad
|
||||
Client->>User: Display Keypad
|
||||
Note left of Client: Key 0: ['🍑' '🥚' '🍋' '🍩' '🍪' '🥞']<br/>Key 1: ['🍖' '🍊' '🥥' '🥖' '🍅' '🥑']<br/>Key 2: ['🌯' '🍧' '🥐' '🥝' '🥨' '🍓']<br/>Key 3: ['🥟' '🍍' '🍔' '🍌' '🍕' '🍛']<br/>Key 4: ['🌽' '🍠' '🍙' '🍚' '🍜' '🍰']<br/>Key 5: ['🍎' '🍤' '🍨' '🍟' '🍉' '🥪']<br/>
|
||||
Note left of User: User icons: ['🌯' '🍖' '🍰' '🍓']
|
||||
User->>Client: Set Key Selection: [2, 1, 4, 2]
|
||||
Client->>+Server: Set nKode:<br/>51b187b9-c930-4f5d-81da-c11c082f2c64<br/>[2, 1, 4, 2]
|
||||
Note left of Client: Key 0: ['🌽' '🍊' '🍙' '🥝' '🥨' '🥑']<br/>Key 1: ['🌯' '🍠' '🥐' '🍩' '🍉' '🍛']<br/>Key 2: ['🍎' '🍧' '🍨' '🍌' '🍪' '🥞']<br/>Key 3: ['🍖' '🍤' '🥥' '🍚' '🍕' '🍰']<br/>Key 4: ['🥟' '🥚' '🍋' '🍟' '🍜' '🥪']<br/>Key 5: ['🍑' '🍍' '🍔' '🥖' '🍅' '🍓']<br/>
|
||||
Note left of User: User icons: ['🍌' '🍟' '🌽' '🥝']
|
||||
User->>Client: Set Key Selection: [2, 4, 0, 0]
|
||||
Client->>+Server: Set nKode:<br/>1334d391-3c8a-431a-8186-e91b29d42750<br/>[2, 4, 0, 0]
|
||||
Server->>Server: Disperse Set Keypad
|
||||
Note over User,Server: Confirm nKode
|
||||
Server-->>-Client: signup_session_id, confirm_keypad, icons
|
||||
Note left of Server: signup_session_id:<br/>51b187b9-c930-4f5d-81da-c11c082f2c64
|
||||
Note left of Server: confirm_keypad:<br/>Key 0: [27 47 39 4 5 25]<br/>Key 1: [45 20 48 49 14 7]<br/>Key 2: [ 9 38 12 13 32 52]<br/>Key 3: [36 2 30 40 50 34]<br/>Key 4: [18 11 3 31 23 16]<br/>Key 5: [ 0 29 21 22 41 43]<br/>
|
||||
Note left of Server: signup_session_id:<br/>1334d391-3c8a-431a-8186-e91b29d42750
|
||||
Note left of Server: confirm_keypad:<br/>Key 0: [27 47 3 13 14 43]<br/>Key 1: [ 0 29 30 49 23 52]<br/>Key 2: [45 11 39 40 5 25]<br/>Key 3: [ 9 2 21 4 32 34]<br/>Key 4: [18 20 12 31 50 7]<br/>Key 5: [36 38 48 22 41 16]<br/>
|
||||
Client->>Client: Order Icons by keypad
|
||||
Client->>User: Display Keypad
|
||||
Note left of Client: Key 0: ['🍖' '🍧' '🍙' '🍌' '🍉' '🥞']<br/>Key 1: ['🥟' '🍠' '🍨' '🍩' '🍅' '🍓']<br/>Key 2: ['🍑' '🍤' '🥥' '🥝' '🍕' '🍰']<br/>Key 3: ['🌯' '🍊' '🍔' '🍚' '🍪' '🥪']<br/>Key 4: ['🌽' '🍍' '🍋' '🍟' '🥨' '🥑']<br/>Key 5: ['🍎' '🥚' '🥐' '🥖' '🍜' '🍛']<br/>
|
||||
Note left of User: User icons: ['🌯' '🍖' '🍰' '🍓']
|
||||
User->>Client: Key Selection: [3, 0, 2, 1]
|
||||
Client->>+Server: Confirm nKode:<br/>51b187b9-c930-4f5d-81da-c11c082f2c64<br/>[3, 0, 2, 1]
|
||||
Note left of Client: Key 0: ['🍖' '🍧' '🍋' '🥝' '🍅' '🍛']<br/>Key 1: ['🍎' '🥚' '🍔' '🍩' '🥨' '🍰']<br/>Key 2: ['🥟' '🍍' '🍙' '🍚' '🍉' '🥞']<br/>Key 3: ['🍑' '🍊' '🥐' '🍌' '🍕' '🥪']<br/>Key 4: ['🌽' '🍠' '🥥' '🍟' '🍪' '🍓']<br/>Key 5: ['🌯' '🍤' '🍨' '🥖' '🍜' '🥑']<br/>
|
||||
Note left of User: User icons: ['🍌' '🍟' '🌽' '🥝']
|
||||
User->>Client: Key Selection: [3, 4, 4, 0]
|
||||
Client->>+Server: Confirm nKode:<br/>1334d391-3c8a-431a-8186-e91b29d42750<br/>[3, 4, 4, 0]
|
||||
Server->>Server: Create User
|
||||
Server-->>-Client: Success
|
||||
```
|
||||
@@ -10,13 +10,13 @@ sequenceDiagram
|
||||
Note left of User: email: user@example.com
|
||||
User->>Server: Submit Email
|
||||
Server->>Client: login_keypad, icons
|
||||
Note left of Server: Login Keypad:<br/>Key 0: [ 9 1 29 3 49 50 33 25 35]<br/>Key 1: [27 28 2 12 22 14 24 16 17]<br/>Key 2: [36 37 47 21 13 23 42 7 26]<br/>Key 3: [45 19 11 30 4 32 51 43 8]<br/>Key 4: [18 46 20 39 40 41 15 52 44]<br/>Key 5: [ 0 10 38 48 31 5 6 34 53]<br/>
|
||||
Note left of Server: Login Keypad:<br/>Key 0: [18 46 2 39 13 23 6 16 53]<br/>Key 1: [36 28 20 21 49 5 15 43 8]<br/>Key 2: [ 0 10 47 48 4 50 51 25 35]<br/>Key 3: [27 1 38 12 40 32 42 52 17]<br/>Key 4: [45 37 29 3 31 41 24 34 44]<br/>Key 5: [ 9 19 11 30 22 14 33 7 26]<br/>
|
||||
Note left of Server: Icons:<br/>[🍎,🍏,🍊,🍋,🍌,🍉<br/>🍇,🍓,🍒,🍑,🥭,🍍<br/>🥥,🥝,🍅,🍆,🥑,🥕<br/>🌽,🥔,🍠,🥐,🥖,🥨<br/>🥯,🥞,🧀,🍖,🍗,🥚<br/>🍔,🍟,🍕,🌭,🥪,🌮<br/>🌯,🍣,🍤,🍙,🍚,🍜<br/>🍲,🍛,🍱,🥟,🍦,🍧<br/>🍨,🍩,🍪,🎂,🍰,🧁]
|
||||
Client->>Client: Order Icons
|
||||
Client->>User: Display Keypad
|
||||
Note left of Client: Key 0: ['🍑' '🍏' '🥚' '🍋' '🍩' '🍪' '🌭' '🥞' '🌮']<br/>Key 1: ['🍖' '🍗' '🍊' '🥥' '🥖' '🍅' '🥯' '🥑' '🥕']<br/>Key 2: ['🌯' '🍣' '🍧' '🥐' '🥝' '🥨' '🍲' '🍓' '🧀']<br/>Key 3: ['🥟' '🥔' '🍍' '🍔' '🍌' '🍕' '🎂' '🍛' '🍒']<br/>Key 4: ['🌽' '🍦' '🍠' '🍙' '🍚' '🍜' '🍆' '🍰' '🍱']<br/>Key 5: ['🍎' '🥭' '🍤' '🍨' '🍟' '🍉' '🍇' '🥪' '🧁']<br/>
|
||||
Note left of User: User passcode icons: ['🌯' '🍖' '🍰' '🍓']
|
||||
User->>Client: Selected Keys<br/>[2, 1, 4, 2]
|
||||
Client->>Server: Login:<br/>email: user@example.com<br/>selected_keys: [2, 1, 4, 2]
|
||||
Note left of Client: Key 0: ['🌽' '🍦' '🍊' '🍙' '🥝' '🥨' '🍇' '🥑' '🧁']<br/>Key 1: ['🌯' '🍗' '🍠' '🥐' '🍩' '🍉' '🍆' '🍛' '🍒']<br/>Key 2: ['🍎' '🥭' '🍧' '🍨' '🍌' '🍪' '🎂' '🥞' '🌮']<br/>Key 3: ['🍖' '🍏' '🍤' '🥥' '🍚' '🍕' '🍲' '🍰' '🥕']<br/>Key 4: ['🥟' '🍣' '🥚' '🍋' '🍟' '🍜' '🥯' '🥪' '🍱']<br/>Key 5: ['🍑' '🥔' '🍍' '🍔' '🥖' '🍅' '🌭' '🍓' '🧀']<br/>
|
||||
Note left of User: User passcode icons: ['🍌' '🍟' '🌽' '🥝']
|
||||
User->>Client: Selected Keys<br/>[2, 4, 0, 0]
|
||||
Client->>Server: Login:<br/>email: user@example.com<br/>selected_keys: [2, 4, 0, 0]
|
||||
Server-->>Client: Success
|
||||
```
|
||||
@@ -39,20 +39,20 @@ if __name__ == "__main__":
|
||||
props_per_key=9
|
||||
)
|
||||
customer_id = api.create_new_customer(keypad_size, policy)
|
||||
signup_session_id, set_signup_keypad = api.generate_signup_keypad(customer_id)
|
||||
ordered_set_icons = emojis[set_signup_keypad]
|
||||
username = "test_username" + "".join([choice(ascii_lowercase) for _ in range(6)])
|
||||
signup_session_id, set_signup_keypad = api.generate_signup_keypad(customer_id, username)
|
||||
ordered_set_icons = emojis[set_signup_keypad]
|
||||
passcode_len = 4
|
||||
passcode_property_indices = np.random.choice(set_signup_keypad.reshape(-1), size=passcode_len,
|
||||
replace=False).tolist()
|
||||
selected_keys_set = select_keys_with_passcode_values(passcode_property_indices, set_signup_keypad,
|
||||
keypad_size.numb_of_keys)
|
||||
confirm_keypad = api.set_nkode(username, customer_id, selected_keys_set, signup_session_id)
|
||||
confirm_keypad = api.set_nkode(customer_id, selected_keys_set, signup_session_id)
|
||||
selected_keys_confirm = select_keys_with_passcode_values(passcode_property_indices, confirm_keypad,
|
||||
keypad_size.numb_of_keys)
|
||||
ordered_confirm_icons = emojis[confirm_keypad]
|
||||
print(f"Selected Keys\n{selected_keys_confirm}")
|
||||
success = api.confirm_nkode(username, customer_id, selected_keys_confirm, signup_session_id)
|
||||
success = api.confirm_nkode(customer_id, selected_keys_confirm, signup_session_id)
|
||||
context = {
|
||||
"email": "user@example.com",
|
||||
"signup_session_id": signup_session_id,
|
||||
|
||||
0
docs/templates/keypad_dispersion.template.md
vendored
Normal file
0
docs/templates/keypad_dispersion.template.md
vendored
Normal file
0
docs/templates/keypad_shuffle.template.md
vendored
Normal file
0
docs/templates/keypad_shuffle.template.md
vendored
Normal 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,89 +137,21 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": {},
|
||||
"cell_type": "markdown",
|
||||
@@ -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": [
|
||||
210
notebooks/Enrollment_Login_Renewal_Simplified.ipynb
Normal file
210
notebooks/Enrollment_Login_Renewal_Simplified.ipynb
Normal 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
|
||||
}
|
||||
@@ -15,6 +15,9 @@ class NKodeAPI:
|
||||
customers: dict[UUID, Customer] = field(default_factory=dict)
|
||||
signup_sessions: dict[UUID, UserSignupSession] = field(default_factory=dict)
|
||||
|
||||
def get_customer(self, customer_id: UUID) -> Customer:
|
||||
return self.customers[customer_id]
|
||||
|
||||
def create_new_customer(self, keypad_size: KeypadSize, nkode_policy: NKodePolicy) -> UUID:
|
||||
new_customer = Customer.create(
|
||||
cipher=CustomerCipher.create(keypad_size),
|
||||
@@ -23,13 +26,17 @@ class NKodeAPI:
|
||||
self.customers[new_customer.customer_id] = new_customer
|
||||
return new_customer.customer_id
|
||||
|
||||
def generate_signup_keypad(self, customer_id: UUID) -> tuple[UUID, np.ndarray]:
|
||||
def generate_signup_keypad(self, customer_id: UUID, username: str) -> tuple[UUID, np.ndarray]:
|
||||
if customer_id not in self.customers.keys():
|
||||
raise ValueError(f"Customer with ID '{customer_id}' does not exist")
|
||||
customer = self.customers[customer_id]
|
||||
if username in customer.users.keys():
|
||||
raise ValueError(f"Username '{username}' already exists for this customer")
|
||||
customer = self.customers[customer_id]
|
||||
login_keypad = UserKeypad.create(customer.cipher.keypad_size)
|
||||
set_keypad = login_keypad.sign_up_keypad()
|
||||
new_session = UserSignupSession(
|
||||
username=username,
|
||||
session_id=uuid4(),
|
||||
login_keypad=login_keypad,
|
||||
set_keypad=set_keypad.keypad,
|
||||
@@ -41,24 +48,20 @@ class NKodeAPI:
|
||||
|
||||
def set_nkode(
|
||||
self,
|
||||
username: str,
|
||||
customer_id: UUID,
|
||||
key_selection: list[int],
|
||||
session_id: UUID
|
||||
) -> np.ndarray:
|
||||
if customer_id not in self.customers.keys():
|
||||
raise ValueError(f"Customer ID {customer_id} not found")
|
||||
customer = self.customers[customer_id]
|
||||
if username in customer.users.keys():
|
||||
raise ValueError(f"Username '{username}' already exists for this customer")
|
||||
if session_id not in self.signup_sessions.keys():
|
||||
raise ValueError(f"Session ID {session_id} not found")
|
||||
self.signup_sessions[session_id].set_user_nkode(username, key_selection)
|
||||
session = self.signup_sessions[session_id]
|
||||
self.signup_sessions[session_id].set_user_nkode(session.username, key_selection)
|
||||
return self.signup_sessions[session_id].confirm_keypad
|
||||
|
||||
def confirm_nkode(
|
||||
self,
|
||||
username: str,
|
||||
customer_id: UUID,
|
||||
confirm_key_entry: list[int],
|
||||
session_id: UUID
|
||||
@@ -68,8 +71,6 @@ class NKodeAPI:
|
||||
session = self.signup_sessions[session_id]
|
||||
if customer_id != session.customer_id:
|
||||
raise AssertionError(f"Customer ID mismatch: {customer_id} vs {session.customer_id}")
|
||||
if username != session.username:
|
||||
raise AssertionError(f"Username mismatch: {username} vs {session.username}")
|
||||
customer = self.customers[customer_id]
|
||||
passcode = self.signup_sessions[session_id].deduce_passcode(confirm_key_entry)
|
||||
new_user_keys = UserCipher.create(
|
||||
@@ -79,7 +80,7 @@ class NKodeAPI:
|
||||
)
|
||||
enciphered_passcode = new_user_keys.encipher_nkode(passcode, customer.cipher)
|
||||
new_user = User(
|
||||
username=username,
|
||||
username=session.username,
|
||||
enciphered_passcode=enciphered_passcode,
|
||||
cipher=new_user_keys,
|
||||
user_keypad=self.signup_sessions[session_id].login_keypad,
|
||||
|
||||
@@ -11,11 +11,10 @@ class UserSignupSession:
|
||||
customer_id: UUID
|
||||
login_keypad: UserKeypad
|
||||
keypad_size: KeypadSize
|
||||
# TODO: revert back to list[int]
|
||||
username: str
|
||||
set_keypad: Optional[np.ndarray] = None
|
||||
confirm_keypad: Optional[np.ndarray] = None
|
||||
set_key_entry: Optional[np.ndarray] = None
|
||||
username: Optional[str] = None
|
||||
|
||||
def deduce_passcode(self, confirm_key_entry: list[int]) -> list[int]:
|
||||
if not all(0 <= key <= self.keypad_size.numb_of_keys for key in confirm_key_entry):
|
||||
|
||||
@@ -15,20 +15,15 @@ def test_create_new_user_and_renew_keys(nkode_api, keypad_size, passcode_len):
|
||||
username = "test_username"
|
||||
nkode_policy = NKodePolicy() # default policy
|
||||
customer_id = nkode_api.create_new_customer(keypad_size, nkode_policy)
|
||||
session_id, set_keypad = nkode_api.generate_signup_keypad(customer_id)
|
||||
session_id, set_keypad = nkode_api.generate_signup_keypad(customer_id, username)
|
||||
user_passcode = set_keypad[:passcode_len]
|
||||
|
||||
signup_key_selection = lambda keypad: [int(np.where(keypad == prop)[0][0]) // keypad_size.numb_of_keys for prop in user_passcode]
|
||||
set_key_selection = signup_key_selection(set_keypad)
|
||||
|
||||
confirm_keypad = nkode_api.set_nkode(username, customer_id, set_key_selection, session_id)
|
||||
confirm_keypad = nkode_api.set_nkode(customer_id, set_key_selection, session_id)
|
||||
confirm_key_selection = signup_key_selection(confirm_keypad)
|
||||
successful_confirm = nkode_api.confirm_nkode(
|
||||
username,
|
||||
customer_id,
|
||||
confirm_key_selection,
|
||||
session_id
|
||||
)
|
||||
successful_confirm = nkode_api.confirm_nkode(customer_id, confirm_key_selection, session_id)
|
||||
assert successful_confirm
|
||||
|
||||
sign_in_key_selection = lambda keypad: [int(np.where(keypad ==prop)[0][0]) // keypad_size.props_per_key for prop in user_passcode]
|
||||
|
||||
Reference in New Issue
Block a user