Skip to content

Commit ebcc079

Browse files
authored
Implemented #137 (#141)
* Implemented #137 *Refactoring
1 parent 06df424 commit ebcc079

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1636
-1594
lines changed

flipperzero-firmware_official_dev

totp/application.fam

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ App(
2828
Lib(
2929
name="base64",
3030
),
31-
Lib(
32-
name="linked_list"
33-
),
3431
Lib(
3532
name="timezone_utils",
3633
),

totp/cli/cli.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
6363
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_AUTOMATION) == 0) {
6464
totp_cli_command_automation_handle(plugin_state, args, cli);
6565
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_RESET) == 0) {
66-
totp_cli_command_reset_handle(cli, cli_context->event_queue);
66+
totp_cli_command_reset_handle(plugin_state, cli, cli_context->event_queue);
6767
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_UPDATE) == 0) {
6868
totp_cli_command_update_handle(plugin_state, args, cli);
6969
} else if(

totp/cli/cli_helpers.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
#include <lib/toolbox/args.h>
44
#include "../types/plugin_event.h"
55

6+
const char* TOTP_CLI_COLOR_ERROR = "91m";
7+
const char* TOTP_CLI_COLOR_WARNING = "93m";
8+
const char* TOTP_CLI_COLOR_SUCCESS = "92m";
9+
const char* TOTP_CLI_COLOR_INFO = "96m";
10+
611
bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli) {
712
if(plugin_state->current_scene == TotpSceneAuthentication) {
813
TOTP_CLI_PRINTF("Pleases enter PIN on your flipper device\r\n");
@@ -13,10 +18,11 @@ bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli) {
1318
furi_delay_ms(100);
1419
}
1520

16-
TOTP_CLI_DELETE_LAST_LINE();
21+
totp_cli_delete_last_line();
1722

1823
if(plugin_state->current_scene == TotpSceneAuthentication || //-V560
1924
plugin_state->current_scene == TotpSceneNone) { //-V560
25+
TOTP_CLI_PRINTF_INFO("Cancelled by user\r\n");
2026
return false;
2127
}
2228
}
@@ -54,7 +60,7 @@ bool totp_cli_read_line(Cli* cli, FuriString* out_str, bool mask_user_input) {
5460
} else if(c == CliSymbolAsciiBackspace || c == CliSymbolAsciiDel) {
5561
size_t out_str_size = furi_string_size(out_str);
5662
if(out_str_size > 0) {
57-
TOTP_CLI_DELETE_LAST_CHAR();
63+
totp_cli_delete_last_char();
5864
furi_string_left(out_str, out_str_size - 1);
5965
}
6066
} else if(c == CliSymbolAsciiCR) {
@@ -83,3 +89,35 @@ void furi_string_secure_free(FuriString* str) {
8389

8490
furi_string_free(str);
8591
}
92+
93+
void totp_cli_print_invalid_arguments() {
94+
TOTP_CLI_PRINTF_ERROR(
95+
"Invalid command arguments. use \"help\" command to get list of available commands");
96+
}
97+
98+
void totp_cli_print_error_updating_config_file() {
99+
TOTP_CLI_PRINTF_ERROR("An error has occurred during updating config file\r\n");
100+
}
101+
102+
void totp_cli_print_error_loading_token_info() {
103+
TOTP_CLI_PRINTF_ERROR("An error has occurred during loading token information\r\n");
104+
}
105+
106+
void totp_cli_print_processing() {
107+
TOTP_CLI_PRINTF("Processing, please wait...\r\n");
108+
}
109+
110+
void totp_cli_delete_last_char() {
111+
TOTP_CLI_PRINTF("\b \b");
112+
fflush(stdout);
113+
}
114+
115+
void totp_cli_delete_current_line() {
116+
TOTP_CLI_PRINTF("\33[2K\r");
117+
fflush(stdout);
118+
}
119+
120+
void totp_cli_delete_last_line() {
121+
TOTP_CLI_PRINTF("\033[A\33[2K\r");
122+
fflush(stdout);
123+
}

totp/cli/cli_helpers.h

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
#define DOCOPT_OPTIONS "[options]"
1515
#define DOCOPT_DEFAULT(val) "[default: " val "]"
1616

17+
extern const char* TOTP_CLI_COLOR_ERROR;
18+
extern const char* TOTP_CLI_COLOR_WARNING;
19+
extern const char* TOTP_CLI_COLOR_SUCCESS;
20+
extern const char* TOTP_CLI_COLOR_INFO;
21+
1722
#define TOTP_CLI_PRINTF(format, ...) printf(format, ##__VA_ARGS__)
1823

1924
#define TOTP_CLI_PRINTF_COLORFUL(color, format, ...) \
@@ -22,11 +27,6 @@
2227
printf("\e[0m"); \
2328
fflush(stdout)
2429

25-
#define TOTP_CLI_COLOR_ERROR "91m"
26-
#define TOTP_CLI_COLOR_WARNING "93m"
27-
#define TOTP_CLI_COLOR_SUCCESS "92m"
28-
#define TOTP_CLI_COLOR_INFO "96m"
29-
3030
#define TOTP_CLI_PRINTF_ERROR(format, ...) \
3131
TOTP_CLI_PRINTF_COLORFUL(TOTP_CLI_COLOR_ERROR, format, ##__VA_ARGS__)
3232
#define TOTP_CLI_PRINTF_WARNING(format, ...) \
@@ -36,24 +36,12 @@
3636
#define TOTP_CLI_PRINTF_INFO(format, ...) \
3737
TOTP_CLI_PRINTF_COLORFUL(TOTP_CLI_COLOR_INFO, format, ##__VA_ARGS__)
3838

39-
#define TOTP_CLI_DELETE_LAST_LINE() \
40-
TOTP_CLI_PRINTF("\033[A\33[2K\r"); \
41-
fflush(stdout)
42-
43-
#define TOTP_CLI_DELETE_CURRENT_LINE() \
44-
TOTP_CLI_PRINTF("\33[2K\r"); \
45-
fflush(stdout)
46-
47-
#define TOTP_CLI_DELETE_LAST_CHAR() \
48-
TOTP_CLI_PRINTF("\b \b"); \
49-
fflush(stdout)
50-
51-
#define TOTP_CLI_PRINT_INVALID_ARGUMENTS() \
52-
TOTP_CLI_PRINTF_ERROR( \
53-
"Invalid command arguments. use \"help\" command to get list of available commands")
39+
#define TOTP_CLI_LOCK_UI(plugin_state) \
40+
Scene __previous_scene = plugin_state->current_scene; \
41+
totp_scene_director_activate_scene(plugin_state, TotpSceneStandby)
5442

55-
#define TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE() \
56-
TOTP_CLI_PRINTF_ERROR("An error has occurred during updating config file\r\n")
43+
#define TOTP_CLI_UNLOCK_UI(plugin_state) \
44+
totp_scene_director_activate_scene(plugin_state, __previous_scene)
5745

5846
/**
5947
* @brief Checks whether user is authenticated and entered correct PIN.
@@ -92,3 +80,38 @@ bool args_read_uint8_and_trim(FuriString* args, uint8_t* value);
9280
* @param str instance to free
9381
*/
9482
void furi_string_secure_free(FuriString* str);
83+
84+
/**
85+
* @brief Deletes last printed line in console
86+
*/
87+
void totp_cli_delete_last_line();
88+
89+
/**
90+
* @brief Deletes current printed line in console
91+
*/
92+
void totp_cli_delete_current_line();
93+
94+
/**
95+
* @brief Deletes last printed char in console
96+
*/
97+
void totp_cli_delete_last_char();
98+
99+
/**
100+
* @brief Prints error message about invalid command arguments
101+
*/
102+
void totp_cli_print_invalid_arguments();
103+
104+
/**
105+
* @brief Prints error message about config file update error
106+
*/
107+
void totp_cli_print_error_updating_config_file();
108+
109+
/**
110+
* @brief Prints error message about config file loading error
111+
*/
112+
void totp_cli_print_error_loading_token_info();
113+
114+
/**
115+
* @brief Prints message to let user knwo that command is processing now
116+
*/
117+
void totp_cli_print_processing();

totp/cli/commands/add/add.c

Lines changed: 86 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,83 @@
11
#include "add.h"
22
#include <stdlib.h>
33
#include <lib/toolbox/args.h>
4-
#include <linked_list.h>
54
#include "../../../types/token_info.h"
65
#include "../../../services/config/config.h"
76
#include "../../../services/convert/convert.h"
87
#include "../../cli_helpers.h"
98
#include "../../../ui/scene_director.h"
109
#include "../../common_command_arguments.h"
1110

11+
struct TotpAddContext {
12+
FuriString* args;
13+
Cli* cli;
14+
uint8_t* iv;
15+
};
16+
17+
enum TotpIteratorUpdateTokenResultsEx {
18+
TotpIteratorUpdateTokenResultInvalidSecret = 1,
19+
TotpIteratorUpdateTokenResultCancelled = 2,
20+
TotpIteratorUpdateTokenResultInvalidArguments = 3
21+
};
22+
23+
static TotpIteratorUpdateTokenResult add_token_handler(TokenInfo* token_info, const void* context) {
24+
const struct TotpAddContext* context_t = context;
25+
26+
// Reading token name
27+
if(!args_read_probably_quoted_string_and_trim(context_t->args, token_info->name)) {
28+
return TotpIteratorUpdateTokenResultInvalidArguments;
29+
}
30+
31+
FuriString* temp_str = furi_string_alloc();
32+
33+
// Read optional arguments
34+
bool mask_user_input = true;
35+
PlainTokenSecretEncoding token_secret_encoding = PLAIN_TOKEN_ENCODING_BASE32;
36+
while(args_read_string_and_trim(context_t->args, temp_str)) {
37+
bool parsed = false;
38+
if(!totp_cli_try_read_algo(token_info, temp_str, context_t->args, &parsed) &&
39+
!totp_cli_try_read_digits(token_info, temp_str, context_t->args, &parsed) &&
40+
!totp_cli_try_read_duration(token_info, temp_str, context_t->args, &parsed) &&
41+
!totp_cli_try_read_unsecure_flag(temp_str, &parsed, &mask_user_input) &&
42+
!totp_cli_try_read_automation_features(token_info, temp_str, context_t->args, &parsed) &&
43+
!totp_cli_try_read_plain_token_secret_encoding(
44+
temp_str, context_t->args, &parsed, &token_secret_encoding)) {
45+
totp_cli_printf_unknown_argument(temp_str);
46+
}
47+
48+
if(!parsed) {
49+
furi_string_free(temp_str);
50+
return TotpIteratorUpdateTokenResultInvalidArguments;
51+
}
52+
}
53+
54+
// Reading token secret
55+
furi_string_reset(temp_str);
56+
TOTP_CLI_PRINTF("Enter token secret and confirm with [ENTER]\r\n");
57+
if(!totp_cli_read_line(context_t->cli, temp_str, mask_user_input)) {
58+
totp_cli_delete_last_line();
59+
furi_string_secure_free(temp_str);
60+
return TotpIteratorUpdateTokenResultCancelled;
61+
}
62+
63+
totp_cli_delete_last_line();
64+
65+
bool secret_set = token_info_set_secret(
66+
token_info,
67+
furi_string_get_cstr(temp_str),
68+
furi_string_size(temp_str),
69+
token_secret_encoding,
70+
context_t->iv);
71+
72+
furi_string_secure_free(temp_str);
73+
74+
if (!secret_set) {
75+
return TotpIteratorUpdateTokenResultInvalidSecret;
76+
}
77+
78+
return TotpIteratorUpdateTokenResultSuccess;
79+
}
80+
1281
void totp_cli_command_add_docopt_commands() {
1382
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_ADD ", " TOTP_CLI_COMMAND_ADD_ALT
1483
", " TOTP_CLI_COMMAND_ADD_ALT2 " Add new token\r\n");
@@ -75,90 +144,30 @@ void totp_cli_command_add_docopt_options() {
75144
}
76145

77146
void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
78-
FuriString* temp_str = furi_string_alloc();
79-
TokenInfo* token_info = token_info_alloc();
80-
81-
// Reading token name
82-
if(!args_read_probably_quoted_string_and_trim(args, temp_str)) {
83-
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
84-
furi_string_free(temp_str);
85-
token_info_free(token_info);
147+
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
86148
return;
87149
}
88150

89-
size_t temp_cstr_len = furi_string_size(temp_str);
90-
token_info->name = malloc(temp_cstr_len + 1);
91-
furi_check(token_info->name != NULL);
92-
strlcpy(token_info->name, furi_string_get_cstr(temp_str), temp_cstr_len + 1);
151+
TokenInfoIteratorContext* iterator_context = totp_config_get_token_iterator_context(plugin_state);
93152

94-
// Read optional arguments
95-
bool mask_user_input = true;
96-
PlainTokenSecretEncoding token_secret_encoding = PLAIN_TOKEN_ENCODING_BASE32;
97-
while(args_read_string_and_trim(args, temp_str)) {
98-
bool parsed = false;
99-
if(!totp_cli_try_read_algo(token_info, temp_str, args, &parsed) &&
100-
!totp_cli_try_read_digits(token_info, temp_str, args, &parsed) &&
101-
!totp_cli_try_read_duration(token_info, temp_str, args, &parsed) &&
102-
!totp_cli_try_read_unsecure_flag(temp_str, &parsed, &mask_user_input) &&
103-
!totp_cli_try_read_automation_features(token_info, temp_str, args, &parsed) &&
104-
!totp_cli_try_read_plain_token_secret_encoding(
105-
temp_str, args, &parsed, &token_secret_encoding)) {
106-
totp_cli_printf_unknown_argument(temp_str);
107-
}
153+
TOTP_CLI_LOCK_UI(plugin_state);
108154

109-
if(!parsed) {
110-
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
111-
furi_string_free(temp_str);
112-
token_info_free(token_info);
113-
return;
114-
}
115-
}
155+
struct TotpAddContext add_context = { .args = args, .cli = cli, .iv = &plugin_state->iv[0] };
156+
TotpIteratorUpdateTokenResult add_result = totp_token_info_iterator_add_new_token(iterator_context, &add_token_handler, &add_context);
116157

117-
// Reading token secret
118-
furi_string_reset(temp_str);
119-
TOTP_CLI_PRINTF("Enter token secret and confirm with [ENTER]\r\n");
120-
if(!totp_cli_read_line(cli, temp_str, mask_user_input) ||
121-
!totp_cli_ensure_authenticated(plugin_state, cli)) {
122-
TOTP_CLI_DELETE_LAST_LINE();
158+
if(add_result == TotpIteratorUpdateTokenResultSuccess) {
159+
TOTP_CLI_PRINTF_SUCCESS(
160+
"Token \"%s\" has been successfully added\r\n",
161+
furi_string_get_cstr(totp_token_info_iterator_get_current_token(iterator_context)->name));
162+
} else if (add_result == TotpIteratorUpdateTokenResultCancelled) {
123163
TOTP_CLI_PRINTF_INFO("Cancelled by user\r\n");
124-
furi_string_secure_free(temp_str);
125-
token_info_free(token_info);
126-
return;
127-
}
128-
129-
TOTP_CLI_DELETE_LAST_LINE();
130-
131-
bool load_generate_token_scene = false;
132-
if(plugin_state->current_scene == TotpSceneGenerateToken) {
133-
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
134-
load_generate_token_scene = true;
135-
}
136-
137-
bool secret_set = token_info_set_secret(
138-
token_info,
139-
furi_string_get_cstr(temp_str),
140-
furi_string_size(temp_str),
141-
token_secret_encoding,
142-
plugin_state->iv);
143-
144-
furi_string_secure_free(temp_str);
145-
146-
if(secret_set) {
147-
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, token_info, furi_check);
148-
plugin_state->tokens_count++;
149-
150-
if(totp_config_file_save_new_token(token_info) == TotpConfigFileUpdateSuccess) {
151-
TOTP_CLI_PRINTF_SUCCESS(
152-
"Token \"%s\" has been successfully added\r\n", token_info->name);
153-
} else {
154-
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
155-
}
156-
} else {
157-
token_info_free(token_info);
164+
} else if (add_result == TotpIteratorUpdateTokenResultInvalidArguments) {
165+
totp_cli_print_invalid_arguments();
166+
} else if (add_result == TotpIteratorUpdateTokenResultInvalidSecret) {
158167
TOTP_CLI_PRINTF_ERROR("Token secret seems to be invalid and can not be parsed\r\n");
168+
} else if (add_result == TotpIteratorUpdateTokenResultFileUpdateFailed) {
169+
totp_cli_print_error_updating_config_file();
159170
}
160171

161-
if(load_generate_token_scene) {
162-
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
163-
}
172+
TOTP_CLI_UNLOCK_UI(plugin_state);
164173
}

0 commit comments

Comments
 (0)