Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#417] Make pgagroal-admin provide JSON output #440

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
Loading