Skip to content

Commit

Permalink
[#417] Make pgagroal-admin provide JSON output
Browse files Browse the repository at this point in the history
  • Loading branch information
T1t4m1un committed Apr 19, 2024
1 parent 5dd618b commit 4d78972
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 8 deletions.
11 changes: 11 additions & 0 deletions doc/ADMIN.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Available options are the following ones:
-P, --password PASSWORD Set the password for the user
-g, --generate Generate a password
-l, --length Password length
-F, --format text|json Set the output format
-V, --version Display version information
-?, --help Display help
Expand Down Expand Up @@ -60,6 +61,16 @@ The `master-key` command allows the definition of a password to protect the vaul
that is the "container" for users' credentials.


## JSON Output Format

It is possible to obtain the output of a command in a JSON format by specyfing the `-F` (`--format`) option on the command line.
Supported output formats are:
- `text` (the default)
- `json`

For more details, see the corresponding section in the CLI documentation.


## Deprecated commands

The following commands have been deprecated and will be removed
Expand Down
1 change: 1 addition & 0 deletions doc/GETTING_STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ Options:
-P, --password PASSWORD Set the password for the user
-g, --generate Generate a password
-l, --length Password length
-F, --format text|json Set the output format
-V, --version Display version information
-?, --help Display help
Expand Down
100 changes: 92 additions & 8 deletions src/admin.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include <logging.h>
#include <security.h>
#include <utils.h>
#include <json.h>
#include <management.h>

/* system */
#include <ctype.h>
Expand All @@ -56,7 +58,7 @@ static int master_key(char* password, bool generate_pwd, int pwd_length);
static int add_user(char* users_path, char* username, char* password, bool generate_pwd, int pwd_length);
static int update_user(char* users_path, char* username, char* password, bool generate_pwd, int pwd_length);
static int remove_user(char* users_path, char* username);
static int list_users(char* users_path);
static int list_users(char* users_path, char output_format);

const struct pgagroal_command command_table[] =
{
Expand Down Expand Up @@ -170,6 +172,7 @@ usage(void)
printf(" -P, --password PASSWORD Set the password for the user\n");
printf(" -g, --generate Generate a password\n");
printf(" -l, --length Password length\n");
printf(" -F, --format text|json Set the output format\n");
printf(" -V, --version Display version information\n");
printf(" -?, --help Display help\n");
printf("\n");
Expand All @@ -193,6 +196,7 @@ main(int argc, char** argv)
char* password = NULL;
char* file_path = NULL;
bool generate_pwd = false;
char output_format = COMMAND_OUTPUT_FORMAT_TEXT;
int pwd_length = DEFAULT_PASSWORD_LENGTH;
int option_index = 0;
size_t command_count = sizeof(command_table) / sizeof(struct pgagroal_command);
Expand All @@ -207,11 +211,12 @@ main(int argc, char** argv)
{"file", required_argument, 0, 'f'},
{"generate", no_argument, 0, 'g'},
{"length", required_argument, 0, 'l'},
{"format", required_argument, 0, 'F' },
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, '?'}
};

c = getopt_long(argc, argv, "gV?f:U:P:l:",
c = getopt_long(argc, argv, "gV?f:U:P:l:F:",
long_options, &option_index);

if (c == -1)
Expand All @@ -236,6 +241,16 @@ main(int argc, char** argv)
case 'l':
pwd_length = atoi(optarg);
break;
case 'F':
if (!strncmp(optarg, "json", MISC_LENGTH))
{
output_format = COMMAND_OUTPUT_FORMAT_JSON;
}
else
{
output_format = COMMAND_OUTPUT_FORMAT_TEXT;
}
break;
case 'V':
version();
break;
Expand Down Expand Up @@ -303,7 +318,7 @@ main(int argc, char** argv)
else if (parsed.cmd->action == ACTION_LIST_USERS)
{

if (list_users(file_path))
if (list_users(file_path, output_format))
{
errx(1, "Error for <user ls>");
}
Expand Down Expand Up @@ -938,23 +953,70 @@ remove_user(char* users_path, char* username)
}

static int
list_users(char* users_path)
list_users(char* users_path, char output_format)
{
FILE* users_file = NULL;
char line[MISC_LENGTH];
char* ptr = NULL;
cJSON *json = NULL;
cJSON *user_list = NULL;

users_file = fopen(users_path, "r");
if (!users_file)
{
goto error;
}

/* List */
while (fgets(line, sizeof(line), users_file))
if (output_format == COMMAND_OUTPUT_FORMAT_JSON)
{
ptr = strtok(line, ":");
printf("%s\n", ptr);
/* JSON format output */
int user_count = 0;
json = pgagroal_json_create_new_command_object("user ls", true, "pgagroal-admin");
user_list = cJSON_CreateArray();

if (user_list == NULL)
{
goto error;
}

while (fgets(line, sizeof(line), users_file))
{
ptr = strtok(line, ":");
cJSON *user_name = cJSON_CreateString(ptr);
if (user_name == NULL)
{
goto error;
}

user_count++;
cJSON_AddItemToArray(user_list, user_name);
}

cJSON *command = cJSON_GetObjectItemCaseSensitive(json, "command");
if (command == NULL)
{
goto error;
}

cJSON *output = cJSON_GetObjectItemCaseSensitive(command, JSON_TAG_COMMAND_OUTPUT);
if (output == NULL)
{
goto error;
}

cJSON_AddNumberToObject(output, "count", user_count);
cJSON_AddItemToObject(output, "list", user_list);

pgagroal_json_print_and_free_json_object(json);
}
else
{
/* Text format output */
while (fgets(line, sizeof(line), users_file))
{
ptr = strtok(line, ":");
printf("%s\n", ptr);
}
}

fclose(users_file);
Expand All @@ -968,5 +1030,27 @@ list_users(char* users_path)
fclose(users_file);
}

if (json)
{
do
{
cJSON *command = cJSON_GetObjectItemCaseSensitive(json, "command");
if (command == NULL)
{
break;
}

cJSON *error = cJSON_GetObjectItemCaseSensitive(json, JSON_TAG_COMMAND_ERROR);
if (error == NULL)
{
break;
}

cJSON_SetIntValue(error, 1);
} while(0);

pgagroal_json_print_and_free_json_object(json);
}

return 1;
}

0 comments on commit 4d78972

Please sign in to comment.