Skip to content

Commit

Permalink
* Refactoring
Browse files Browse the repository at this point in the history
* Added `timezone` CLI command
* FAQ & README updated
  • Loading branch information
akopachov committed Oct 25, 2022
1 parent bc9836e commit 4c5533f
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 48 deletions.
35 changes: 17 additions & 18 deletions services/cli/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,24 @@
#include "commands/list/list.h"
#include "commands/add/add.h"
#include "commands/delete/delete.h"
#include "commands/timezone/timezone.h"

#define TOTP_CLI_COMMAND_NAME "totp"
#define TOTP_CLI_COMMAND_HELP "help"

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

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

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

args_read_string_and_trim(args, cmd);

if(furi_string_cmp_str(cmd, "help") == 0 || furi_string_empty(cmd)) {
if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_HELP) == 0 || furi_string_empty(cmd)) {
totp_cli_print_help();
} else if(furi_string_cmp_str(cmd, "add") == 0) {
totp_cli_handle_add_command(plugin_state, args);
} else if(furi_string_cmp_str(cmd, "list") == 0) {
totp_cli_handle_list_command(plugin_state);
} else if(furi_string_cmp_str(cmd, "delete") == 0) {
totp_cli_handle_delete_command(plugin_state, args, cli);
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_ADD) == 0) {
totp_cli_command_add_handle(plugin_state, args);
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_LIST) == 0) {
totp_cli_command_list_handle(plugin_state);
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_DELETE) == 0) {
totp_cli_command_delete_handle(plugin_state, args, cli);
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_TIMEZONE) == 0) {
totp_cli_command_timezone_handle(plugin_state, args);
} else {
totp_cli_print_unknown_command(cmd);
}
Expand Down
10 changes: 10 additions & 0 deletions services/cli/cli_common_helpers.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
#pragma once

#define TOTP_CLI_ARG(arg) "<" arg ">"
#define TOTP_CLI_OPTIONAL_PARAM(param) "[" param "]"
#define TOTP_CLI_OPTIONAL_PARAM_MARK "[OPTIONAL]"

#define TOTP_CLI_PRINTF(format, ...) \
_Pragma(STRINGIFY(GCC diagnostic push)); \
_Pragma(STRINGIFY(GCC diagnostic ignored "-Wdouble-promotion")); \
printf(format, ##__VA_ARGS__); \
_Pragma(STRINGIFY(GCC diagnostic pop));

void totp_cli_print_invalid_arguments();
33 changes: 24 additions & 9 deletions services/cli/commands/add/add.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
#include "../../cli_common_helpers.h"
#include "../../../../scenes/scene_director.h"

#define TOTP_CLI_COMMAND_ADD_ARG_NAME "NAME"
#define TOTP_CLI_COMMAND_ADD_ARG_SECRET "SECRET"
#define TOTP_CLI_COMMAND_ADD_ARG_ALGO "ALGO"
#define TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX "-a"
#define TOTP_CLI_COMMAND_ADD_ARG_DIGITS "DIGITS"
#define TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "-d"

static bool token_info_set_digits_from_str(TokenInfo* token_info, FuriString* str) {
switch(furi_string_get_char(str, 0)) {
case '6':
Expand Down Expand Up @@ -39,7 +46,15 @@ static bool token_info_set_algo_from_str(TokenInfo* token_info, FuriString* str)
return false;
}

void totp_cli_handle_add_command(PluginState* plugin_state, FuriString* args) {
void totp_cli_command_add_print_help() {
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");
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_NAME) " - token name\r\n");
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_SECRET) " - Base32 token secret\r\n");
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");
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");
}

void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args) {
FuriString* temp_str = furi_string_alloc();
const char* temp_cstr;

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

temp_cstr = furi_string_get_cstr(temp_str);
if (!token_info_set_secret(token_info, temp_cstr, strlen(temp_cstr), plugin_state->iv)) {
printf("Token secret seems to be invalid and can not be parsed\r\n");
TOTP_CLI_PRINTF("Token secret seems to be invalid and can not be parsed\r\n");
furi_string_free(temp_str);
token_info_free(token_info);
return;
Expand All @@ -76,19 +91,19 @@ void totp_cli_handle_add_command(PluginState* plugin_state, FuriString* args) {
// Read optional arguments
while (args_read_string_and_trim(args, temp_str)) {
bool parsed = false;
if (furi_string_cmpi_str(temp_str, "-a") == 0) {
if (furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX) == 0) {
if (!args_read_string_and_trim(args, temp_str)) {
printf("Missed value for argument \"-a\"\r\n");
TOTP_CLI_PRINTF("Missed value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX "\"\r\n");
} else if (!token_info_set_algo_from_str(token_info, temp_str)) {
printf("\"%s\" is incorrect value for argument \"-a\"\r\n", furi_string_get_cstr(temp_str));
TOTP_CLI_PRINTF("\"%s\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX "\"\r\n", furi_string_get_cstr(temp_str));
} else {
parsed = true;
}
} else if (furi_string_cmpi_str(temp_str, "-d") == 0) {
} else if (furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX) == 0) {
if (!args_read_string_and_trim(args, temp_str)) {
printf("Missed value for argument \"-d\"\r\n");
TOTP_CLI_PRINTF("Missed value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "\"\r\n");
} else if (!token_info_set_digits_from_str(token_info, temp_str)) {
printf("\"%s\" is incorrect value for argument \"-d\"\r\n", furi_string_get_cstr(temp_str));
TOTP_CLI_PRINTF("\"%s\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "\"\r\n", furi_string_get_cstr(temp_str));
} else {
parsed = true;
}
Expand Down Expand Up @@ -121,5 +136,5 @@ void totp_cli_handle_add_command(PluginState* plugin_state, FuriString* args) {

furi_string_free(temp_str);

printf("Token \"%s\" has been successfully added\r\n", token_info->name);
TOTP_CLI_PRINTF("Token \"%s\" has been successfully added\r\n", token_info->name);
}
5 changes: 4 additions & 1 deletion services/cli/commands/add/add.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
#include <cli/cli.h>
#include "../../../../types/plugin_state.h"

void totp_cli_handle_add_command(PluginState* plugin_state, FuriString* args);
#define TOTP_CLI_COMMAND_ADD "add"

void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args);
void totp_cli_command_add_print_help();
31 changes: 20 additions & 11 deletions services/cli/commands/delete/delete.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@
#include "../../cli_common_helpers.h"
#include "../../../../scenes/scene_director.h"

void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args, Cli* cli) {
#define TOTP_CLI_COMMAND_DELETE_ARG_INDEX "INDEX"
#define TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX "-f"

void totp_cli_command_delete_print_help() {
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");
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(TOTP_CLI_COMMAND_DELETE_ARG_INDEX) " - token index in the list\r\n");
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");
}

void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
int token_number;
if (!args_read_int_and_trim(args, &token_number) || token_number <= 0 || token_number > plugin_state->tokens_count) {
totp_cli_print_invalid_arguments();
Expand All @@ -18,10 +27,10 @@ void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args,
FuriString* temp_str = furi_string_alloc();
bool confirm_needed = true;
if (args_read_string_and_trim(args, temp_str)) {
if (furi_string_cmpi_str(temp_str, "-f") == 0) {
if (furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX) == 0) {
confirm_needed = false;
} else {
printf("Unknown argument \"%s\"\r\n", furi_string_get_cstr(temp_str));
TOTP_CLI_PRINTF("Unknown argument \"%s\"\r\n", furi_string_get_cstr(temp_str));
totp_cli_print_invalid_arguments();
furi_string_free(temp_str);
return;
Expand All @@ -35,21 +44,21 @@ void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args,

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

confirmed = user_pick == 'y' || user_pick == 0x0d;
confirmed = user_pick == 'y' || user_pick == CliSymbolAsciiCR;
}

if (confirmed) {
bool activate_generate_token_scene = false;
if (plugin_state->current_scene == TotpSceneGenerateToken) {
if (plugin_state->current_scene != TotpSceneAuthentication) {
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
activate_generate_token_scene = true;
}
Expand All @@ -63,9 +72,9 @@ void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args,
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
}

printf("Token \"%s\" has been successfully deleted\r\n", token_info->name);
TOTP_CLI_PRINTF("Token \"%s\" has been successfully deleted\r\n", token_info->name);
token_info_free(token_info);
} else {
printf("User not confirmed\r\n");
TOTP_CLI_PRINTF("User not confirmed\r\n");
}
}
5 changes: 4 additions & 1 deletion services/cli/commands/delete/delete.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
#include <cli/cli.h>
#include "../../../../types/plugin_state.h"

void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args, Cli* cli);
#define TOTP_CLI_COMMAND_DELETE "delete"

void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
void totp_cli_command_delete_print_help();
19 changes: 12 additions & 7 deletions services/cli/commands/list/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../../../list/list.h"
#include "../../../../types/token_info.h"
#include "../../../config/constants.h"
#include "../../cli_common_helpers.h"

static char* get_algo_as_cstr(TokenHashAlgo algo) {
switch(algo) {
Expand All @@ -29,24 +30,28 @@ static uint8_t get_digits_as_int(TokenDigitsCount digits) {
return 6;
}

void totp_cli_handle_list_command(PluginState* plugin_state) {
void totp_cli_command_list_print_help() {
TOTP_CLI_PRINTF("\t" TOTP_CLI_COMMAND_LIST " - list all tokens\r\n\r\n");
}

void totp_cli_command_list_handle(PluginState* plugin_state) {
if (plugin_state->tokens_list == NULL) {
printf("There are no tokens");
TOTP_CLI_PRINTF("There are no tokens");
return;
}

ListNode* node = plugin_state->tokens_list;

printf("+-----+-----------------------------+--------+--------+\r\n");
printf("| %-*s | %-*s | %-*s | %-s |\r\n", 3, "#", 27, "Name", 6, "Algo", "Digits");
printf("+-----+-----------------------------+--------+--------+\r\n");
TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n");
TOTP_CLI_PRINTF("| %-*s | %-*s | %-*s | %-s |\r\n", 3, "#", 27, "Name", 6, "Algo", "Digits");
TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n");
uint16_t index = 1;
while(node != NULL) {
TokenInfo* token_info = (TokenInfo* )node->data;
token_info_get_digits_count(token_info);
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));
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));
node = node->next;
index++;
}
printf("+-----+-----------------------------+--------+--------+\r\n");
TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n");
}
5 changes: 4 additions & 1 deletion services/cli/commands/list/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@

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

void totp_cli_handle_list_command(PluginState* plugin_state);
#define TOTP_CLI_COMMAND_LIST "list"

void totp_cli_command_list_handle(PluginState* plugin_state);
void totp_cli_command_list_print_help();
36 changes: 36 additions & 0 deletions services/cli/commands/timezone/timezone.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "timezone.h"
#include <lib/toolbox/args.h>
#include "../../../config/config.h"
#include "../../../../scenes/scene_director.h"
#include "../../cli_common_helpers.h"

#define TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE "TIMEZONE"

void totp_cli_command_timezone_print_help() {
TOTP_CLI_PRINTF("\t" TOTP_CLI_COMMAND_TIMEZONE " " TOTP_CLI_OPTIONAL_PARAM(TOTP_CLI_ARG(TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE)) "\r\n");
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");
}

void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* args) {
FuriString* temp_str = furi_string_alloc();
if (args_read_string_and_trim(args, temp_str)) {
float tz = strtof(furi_string_get_cstr(temp_str), NULL);
if (tz >= -12.75f && tz <= 12.75f) {
plugin_state->timezone_offset = tz;
totp_config_file_update_timezone_offset(tz);
TOTP_CLI_PRINTF("Timezone is set to %f\r\n", tz);
if (plugin_state->current_scene == TotpSceneGenerateToken) {
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
} else if (plugin_state->current_scene == TotpSceneAppSettings) {
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
totp_scene_director_activate_scene(plugin_state, TotpSceneAppSettings, NULL);
}
} else {
TOTP_CLI_PRINTF("Invalid timezone offset\r\n");
}
} else {
TOTP_CLI_PRINTF("Current timezone offset is %f\r\n", plugin_state->timezone_offset);
}
furi_string_free(temp_str);
}
9 changes: 9 additions & 0 deletions services/cli/commands/timezone/timezone.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include <cli/cli.h>
#include "../../../../types/plugin_state.h"

#define TOTP_CLI_COMMAND_TIMEZONE "timezone"

void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* args);
void totp_cli_command_timezone_print_help();

0 comments on commit 4c5533f

Please sign in to comment.