Skip to content

Commit 4c5533f

Browse files
committed
* Refactoring
* Added `timezone` CLI command * FAQ & README updated
1 parent bc9836e commit 4c5533f

File tree

10 files changed

+140
-48
lines changed

10 files changed

+140
-48
lines changed

services/cli/cli.c

+17-18
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,24 @@
55
#include "commands/list/list.h"
66
#include "commands/add/add.h"
77
#include "commands/delete/delete.h"
8+
#include "commands/timezone/timezone.h"
89

910
#define TOTP_CLI_COMMAND_NAME "totp"
11+
#define TOTP_CLI_COMMAND_HELP "help"
1012

1113
static void totp_cli_print_unknown_command(FuriString* unknown_command) {
1214
printf("Command \"%s\" is unknown. Use \"help\" command to get list of available commands.", furi_string_get_cstr(unknown_command));
1315
}
1416

1517
static void totp_cli_print_help() {
1618
printf("Usage:\r\n");
17-
printf("totp <command> <arguments>\r\n");
19+
printf(TOTP_CLI_COMMAND_NAME " <command> <arguments>\r\n");
1820
printf("Command list:\r\n");
19-
printf("\thelp - print command usage help\r\n");
20-
printf("\tlist - list all tokens\r\n");
21-
printf("\tdelete <INDEX> [-f] - delete token\r\n");
22-
printf("\t\t<INDEX> - token index in the list\r\n");
23-
printf("\t\t-f - [OPTIONAL] force command to do not ask user for interactive confirmation\r\n");
24-
printf("\tadd <NAME> <SECRET> [-a <ALGO>] [-d <DIGITS>] - add new token\r\n");
25-
printf("\t\t<NAME> - token name\r\n");
26-
printf("\t\t<SECRET> - Base32 token secret\r\n");
27-
printf("\t\t<ALGO> - [OPTIONAL] token hashing algorithm, could be one of: sha1, sha256, sha512; default: sha1\r\n");
28-
printf("\t\t<DIGITS> - [OPTIONAL] number of digits to generate, one of: 6, 8; default: 6\r\n\r\n");
21+
printf("\t" TOTP_CLI_COMMAND_HELP " - print command usage help\r\n\r\n");
22+
totp_cli_command_list_print_help();
23+
totp_cli_command_delete_print_help();
24+
totp_cli_command_add_print_help();
25+
totp_cli_command_timezone_print_help();
2926
}
3027

3128
static void totp_cli_print_unauthenticated() {
@@ -51,14 +48,16 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
5148

5249
args_read_string_and_trim(args, cmd);
5350

54-
if(furi_string_cmp_str(cmd, "help") == 0 || furi_string_empty(cmd)) {
51+
if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_HELP) == 0 || furi_string_empty(cmd)) {
5552
totp_cli_print_help();
56-
} else if(furi_string_cmp_str(cmd, "add") == 0) {
57-
totp_cli_handle_add_command(plugin_state, args);
58-
} else if(furi_string_cmp_str(cmd, "list") == 0) {
59-
totp_cli_handle_list_command(plugin_state);
60-
} else if(furi_string_cmp_str(cmd, "delete") == 0) {
61-
totp_cli_handle_delete_command(plugin_state, args, cli);
53+
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_ADD) == 0) {
54+
totp_cli_command_add_handle(plugin_state, args);
55+
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_LIST) == 0) {
56+
totp_cli_command_list_handle(plugin_state);
57+
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_DELETE) == 0) {
58+
totp_cli_command_delete_handle(plugin_state, args, cli);
59+
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_TIMEZONE) == 0) {
60+
totp_cli_command_timezone_handle(plugin_state, args);
6261
} else {
6362
totp_cli_print_unknown_command(cmd);
6463
}

services/cli/cli_common_helpers.h

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
#pragma once
22

3+
#define TOTP_CLI_ARG(arg) "<" arg ">"
4+
#define TOTP_CLI_OPTIONAL_PARAM(param) "[" param "]"
5+
#define TOTP_CLI_OPTIONAL_PARAM_MARK "[OPTIONAL]"
6+
7+
#define TOTP_CLI_PRINTF(format, ...) \
8+
_Pragma(STRINGIFY(GCC diagnostic push)); \
9+
_Pragma(STRINGIFY(GCC diagnostic ignored "-Wdouble-promotion")); \
10+
printf(format, ##__VA_ARGS__); \
11+
_Pragma(STRINGIFY(GCC diagnostic pop));
12+
313
void totp_cli_print_invalid_arguments();

services/cli/commands/add/add.c

+24-9
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77
#include "../../cli_common_helpers.h"
88
#include "../../../../scenes/scene_director.h"
99

10+
#define TOTP_CLI_COMMAND_ADD_ARG_NAME "NAME"
11+
#define TOTP_CLI_COMMAND_ADD_ARG_SECRET "SECRET"
12+
#define TOTP_CLI_COMMAND_ADD_ARG_ALGO "ALGO"
13+
#define TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX "-a"
14+
#define TOTP_CLI_COMMAND_ADD_ARG_DIGITS "DIGITS"
15+
#define TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "-d"
16+
1017
static bool token_info_set_digits_from_str(TokenInfo* token_info, FuriString* str) {
1118
switch(furi_string_get_char(str, 0)) {
1219
case '6':
@@ -39,7 +46,15 @@ static bool token_info_set_algo_from_str(TokenInfo* token_info, FuriString* str)
3946
return false;
4047
}
4148

42-
void totp_cli_handle_add_command(PluginState* plugin_state, FuriString* args) {
49+
void totp_cli_command_add_print_help() {
50+
TOTP_CLI_PRINTF("\t" TOTP_CLI_COMMAND_ADD " " TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_NAME) " " TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_SECRET) " " TOTP_CLI_OPTIONAL_PARAM(TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX " " TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_ALGO)) " " TOTP_CLI_OPTIONAL_PARAM(TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX " " TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_DIGITS)) " - add new token\r\n");
51+
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_NAME) " - token name\r\n");
52+
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_SECRET) " - Base32 token secret\r\n");
53+
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_ALGO) " - " TOTP_CLI_OPTIONAL_PARAM_MARK " token hashing algorithm, could be one of: sha1, sha256, sha512; default: sha1\r\n");
54+
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_DIGITS) " - " TOTP_CLI_OPTIONAL_PARAM_MARK " number of digits to generate, one of: 6, 8; default: 6\r\n\r\n");
55+
}
56+
57+
void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args) {
4358
FuriString* temp_str = furi_string_alloc();
4459
const char* temp_cstr;
4560

@@ -67,7 +82,7 @@ void totp_cli_handle_add_command(PluginState* plugin_state, FuriString* args) {
6782

6883
temp_cstr = furi_string_get_cstr(temp_str);
6984
if (!token_info_set_secret(token_info, temp_cstr, strlen(temp_cstr), plugin_state->iv)) {
70-
printf("Token secret seems to be invalid and can not be parsed\r\n");
85+
TOTP_CLI_PRINTF("Token secret seems to be invalid and can not be parsed\r\n");
7186
furi_string_free(temp_str);
7287
token_info_free(token_info);
7388
return;
@@ -76,19 +91,19 @@ void totp_cli_handle_add_command(PluginState* plugin_state, FuriString* args) {
7691
// Read optional arguments
7792
while (args_read_string_and_trim(args, temp_str)) {
7893
bool parsed = false;
79-
if (furi_string_cmpi_str(temp_str, "-a") == 0) {
94+
if (furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX) == 0) {
8095
if (!args_read_string_and_trim(args, temp_str)) {
81-
printf("Missed value for argument \"-a\"\r\n");
96+
TOTP_CLI_PRINTF("Missed value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX "\"\r\n");
8297
} else if (!token_info_set_algo_from_str(token_info, temp_str)) {
83-
printf("\"%s\" is incorrect value for argument \"-a\"\r\n", furi_string_get_cstr(temp_str));
98+
TOTP_CLI_PRINTF("\"%s\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX "\"\r\n", furi_string_get_cstr(temp_str));
8499
} else {
85100
parsed = true;
86101
}
87-
} else if (furi_string_cmpi_str(temp_str, "-d") == 0) {
102+
} else if (furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX) == 0) {
88103
if (!args_read_string_and_trim(args, temp_str)) {
89-
printf("Missed value for argument \"-d\"\r\n");
104+
TOTP_CLI_PRINTF("Missed value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "\"\r\n");
90105
} else if (!token_info_set_digits_from_str(token_info, temp_str)) {
91-
printf("\"%s\" is incorrect value for argument \"-d\"\r\n", furi_string_get_cstr(temp_str));
106+
TOTP_CLI_PRINTF("\"%s\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "\"\r\n", furi_string_get_cstr(temp_str));
92107
} else {
93108
parsed = true;
94109
}
@@ -121,5 +136,5 @@ void totp_cli_handle_add_command(PluginState* plugin_state, FuriString* args) {
121136

122137
furi_string_free(temp_str);
123138

124-
printf("Token \"%s\" has been successfully added\r\n", token_info->name);
139+
TOTP_CLI_PRINTF("Token \"%s\" has been successfully added\r\n", token_info->name);
125140
}

services/cli/commands/add/add.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@
33
#include <cli/cli.h>
44
#include "../../../../types/plugin_state.h"
55

6-
void totp_cli_handle_add_command(PluginState* plugin_state, FuriString* args);
6+
#define TOTP_CLI_COMMAND_ADD "add"
7+
8+
void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args);
9+
void totp_cli_command_add_print_help();

services/cli/commands/delete/delete.c

+20-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,16 @@
88
#include "../../cli_common_helpers.h"
99
#include "../../../../scenes/scene_director.h"
1010

11-
void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args, Cli* cli) {
11+
#define TOTP_CLI_COMMAND_DELETE_ARG_INDEX "INDEX"
12+
#define TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX "-f"
13+
14+
void totp_cli_command_delete_print_help() {
15+
TOTP_CLI_PRINTF("\t" TOTP_CLI_COMMAND_DELETE " " TOTP_CLI_ARG(TOTP_CLI_COMMAND_DELETE_ARG_INDEX) " " TOTP_CLI_OPTIONAL_PARAM(TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX) " - delete token\r\n");
16+
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(TOTP_CLI_COMMAND_DELETE_ARG_INDEX) " - token index in the list\r\n");
17+
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX " - " TOTP_CLI_OPTIONAL_PARAM_MARK " force command to do not ask user for interactive confirmation\r\n\r\n");
18+
}
19+
20+
void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
1221
int token_number;
1322
if (!args_read_int_and_trim(args, &token_number) || token_number <= 0 || token_number > plugin_state->tokens_count) {
1423
totp_cli_print_invalid_arguments();
@@ -18,10 +27,10 @@ void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args,
1827
FuriString* temp_str = furi_string_alloc();
1928
bool confirm_needed = true;
2029
if (args_read_string_and_trim(args, temp_str)) {
21-
if (furi_string_cmpi_str(temp_str, "-f") == 0) {
30+
if (furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX) == 0) {
2231
confirm_needed = false;
2332
} else {
24-
printf("Unknown argument \"%s\"\r\n", furi_string_get_cstr(temp_str));
33+
TOTP_CLI_PRINTF("Unknown argument \"%s\"\r\n", furi_string_get_cstr(temp_str));
2534
totp_cli_print_invalid_arguments();
2635
furi_string_free(temp_str);
2736
return;
@@ -35,21 +44,21 @@ void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args,
3544

3645
bool confirmed = !confirm_needed;
3746
if (confirm_needed) {
38-
printf("WARNING!\r\n");
39-
printf("Token \"%s\" will be permanently deleted without ability to recover it.\r\n", token_info->name);
40-
printf("Confirm? [y/n]\r\n");
47+
TOTP_CLI_PRINTF("WARNING!\r\n");
48+
TOTP_CLI_PRINTF("TOKEN \"%s\" WILL BE PERMANENTLY DELETED WITHOUT ABILITY TO RECOVER IT.\r\n", token_info->name);
49+
TOTP_CLI_PRINTF("Confirm? [y/n]\r\n");
4150
fflush(stdout);
4251
char user_pick;
4352
do {
4453
user_pick = tolower(cli_getc(cli));
45-
} while (user_pick != 'y' && user_pick != 'n' && user_pick != 0x0d);
54+
} while (user_pick != 'y' && user_pick != 'n' && user_pick != CliSymbolAsciiCR);
4655

47-
confirmed = user_pick == 'y' || user_pick == 0x0d;
56+
confirmed = user_pick == 'y' || user_pick == CliSymbolAsciiCR;
4857
}
4958

5059
if (confirmed) {
5160
bool activate_generate_token_scene = false;
52-
if (plugin_state->current_scene == TotpSceneGenerateToken) {
61+
if (plugin_state->current_scene != TotpSceneAuthentication) {
5362
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
5463
activate_generate_token_scene = true;
5564
}
@@ -63,9 +72,9 @@ void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args,
6372
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
6473
}
6574

66-
printf("Token \"%s\" has been successfully deleted\r\n", token_info->name);
75+
TOTP_CLI_PRINTF("Token \"%s\" has been successfully deleted\r\n", token_info->name);
6776
token_info_free(token_info);
6877
} else {
69-
printf("User not confirmed\r\n");
78+
TOTP_CLI_PRINTF("User not confirmed\r\n");
7079
}
7180
}

services/cli/commands/delete/delete.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@
33
#include <cli/cli.h>
44
#include "../../../../types/plugin_state.h"
55

6-
void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args, Cli* cli);
6+
#define TOTP_CLI_COMMAND_DELETE "delete"
7+
8+
void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
9+
void totp_cli_command_delete_print_help();

services/cli/commands/list/list.c

+12-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "../../../list/list.h"
55
#include "../../../../types/token_info.h"
66
#include "../../../config/constants.h"
7+
#include "../../cli_common_helpers.h"
78

89
static char* get_algo_as_cstr(TokenHashAlgo algo) {
910
switch(algo) {
@@ -29,24 +30,28 @@ static uint8_t get_digits_as_int(TokenDigitsCount digits) {
2930
return 6;
3031
}
3132

32-
void totp_cli_handle_list_command(PluginState* plugin_state) {
33+
void totp_cli_command_list_print_help() {
34+
TOTP_CLI_PRINTF("\t" TOTP_CLI_COMMAND_LIST " - list all tokens\r\n\r\n");
35+
}
36+
37+
void totp_cli_command_list_handle(PluginState* plugin_state) {
3338
if (plugin_state->tokens_list == NULL) {
34-
printf("There are no tokens");
39+
TOTP_CLI_PRINTF("There are no tokens");
3540
return;
3641
}
3742

3843
ListNode* node = plugin_state->tokens_list;
3944

40-
printf("+-----+-----------------------------+--------+--------+\r\n");
41-
printf("| %-*s | %-*s | %-*s | %-s |\r\n", 3, "#", 27, "Name", 6, "Algo", "Digits");
42-
printf("+-----+-----------------------------+--------+--------+\r\n");
45+
TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n");
46+
TOTP_CLI_PRINTF("| %-*s | %-*s | %-*s | %-s |\r\n", 3, "#", 27, "Name", 6, "Algo", "Digits");
47+
TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n");
4348
uint16_t index = 1;
4449
while(node != NULL) {
4550
TokenInfo* token_info = (TokenInfo* )node->data;
4651
token_info_get_digits_count(token_info);
47-
printf("| %-3" PRIu16 " | %-27.27s | %-6s | %-6" PRIu8 " |\r\n", index, token_info->name, get_algo_as_cstr(token_info->algo), get_digits_as_int(token_info->digits));
52+
TOTP_CLI_PRINTF("| %-3" PRIu16 " | %-27.27s | %-6s | %-6" PRIu8 " |\r\n", index, token_info->name, get_algo_as_cstr(token_info->algo), get_digits_as_int(token_info->digits));
4853
node = node->next;
4954
index++;
5055
}
51-
printf("+-----+-----------------------------+--------+--------+\r\n");
56+
TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n");
5257
}

services/cli/commands/list/list.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22

33
#include "../../../../types/plugin_state.h"
44

5-
void totp_cli_handle_list_command(PluginState* plugin_state);
5+
#define TOTP_CLI_COMMAND_LIST "list"
6+
7+
void totp_cli_command_list_handle(PluginState* plugin_state);
8+
void totp_cli_command_list_print_help();
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include "timezone.h"
2+
#include <lib/toolbox/args.h>
3+
#include "../../../config/config.h"
4+
#include "../../../../scenes/scene_director.h"
5+
#include "../../cli_common_helpers.h"
6+
7+
#define TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE "TIMEZONE"
8+
9+
void totp_cli_command_timezone_print_help() {
10+
TOTP_CLI_PRINTF("\t" TOTP_CLI_COMMAND_TIMEZONE " " TOTP_CLI_OPTIONAL_PARAM(TOTP_CLI_ARG(TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE)) "\r\n");
11+
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE) " - " TOTP_CLI_OPTIONAL_PARAM_MARK " timezone offset in hours to be set, if not provided then current timezone offset will be printed\r\n\r\n");
12+
}
13+
14+
void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* args) {
15+
FuriString* temp_str = furi_string_alloc();
16+
if (args_read_string_and_trim(args, temp_str)) {
17+
float tz = strtof(furi_string_get_cstr(temp_str), NULL);
18+
if (tz >= -12.75f && tz <= 12.75f) {
19+
plugin_state->timezone_offset = tz;
20+
totp_config_file_update_timezone_offset(tz);
21+
TOTP_CLI_PRINTF("Timezone is set to %f\r\n", tz);
22+
if (plugin_state->current_scene == TotpSceneGenerateToken) {
23+
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
24+
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
25+
} else if (plugin_state->current_scene == TotpSceneAppSettings) {
26+
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
27+
totp_scene_director_activate_scene(plugin_state, TotpSceneAppSettings, NULL);
28+
}
29+
} else {
30+
TOTP_CLI_PRINTF("Invalid timezone offset\r\n");
31+
}
32+
} else {
33+
TOTP_CLI_PRINTF("Current timezone offset is %f\r\n", plugin_state->timezone_offset);
34+
}
35+
furi_string_free(temp_str);
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
#include <cli/cli.h>
4+
#include "../../../../types/plugin_state.h"
5+
6+
#define TOTP_CLI_COMMAND_TIMEZONE "timezone"
7+
8+
void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* args);
9+
void totp_cli_command_timezone_print_help();

0 commit comments

Comments
 (0)