Skip to content

Commit

Permalink
Changed argument handling to use Glib::OptionGroup, since Gio::Applic…
Browse files Browse the repository at this point in the history
…ation cannot handle numeric arguments. Level of detail can be finely controlled. Locked status is also printed.
  • Loading branch information
Daniel K. O. (dkosmari) committed Apr 16, 2024
1 parent c949025 commit 455c471
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 67 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,26 @@ keyring](https://specifications.freedesktop.org/secret-service/latest/) using
Usage
-----

With no arguments, all unlocked collections and items are shown, without secrets:
With no arguments, all unlocked collections and items are shown, without attributes or
secrets:

lssecrets

To show secrets, use the argument `--secrets`:
To show item attributes, use the argument `--detail=3`:

lssecrets --secrets
lssecrets --detail=3

To show item attributes and secrets, use the argument `--detail=4`:

lssecrets --detail=4

If there are collections or items locked, use the option `--unlock` to unlock everything:

lssecrets --unlock

Both options can be combined, to unlock and show the secrets:

lssecrets --secrets --unlock
lssecrets --detail=4 --unlock


Dependencies
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

AC_PREREQ([2.71])
AC_INIT([lssecrets],
[1.0],
[1.1],
[https://github.com/dkosmari/lssecrets/issues],
[lssecrets],
[https://github.com/dkosmari/lssecrets])
Expand Down
143 changes: 81 additions & 62 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,22 @@


using std::cout;
using std::clog;
using std::cerr;
using std::endl;

using namespace std::literals;


#if HAVE_GLIBMM_2_68
#define AF_NON_UNIQUE Gio::Application::Flags::NON_UNIQUE
#define OEF_IN_MAIN Glib::OptionEntry::Flags::IN_MAIN
#else
#define AF_NON_UNIQUE Gio::ApplicationFlags::APPLICATION_NON_UNIQUE
#define OEF_IN_MAIN Glib::OptionEntry::Flags::FLAG_IN_MAIN
#endif


template<typename T>
class GObjectWrapper {
T* ptr = nullptr;
Expand Down Expand Up @@ -295,77 +305,71 @@ throw_error(GError* raw_err)
struct App : Gio::Application {


bool show_secrets = false;
bool do_unlock = false;
enum Detail : int {
Service = 0,
Collections = 1,
Items = 2,
Attributes = 3,
Secrets = 4
};


int detail = Detail::Items;
bool unlock_flag = false;
bool version_flag = false;

Glib::OptionGroup main_group{"", ""};
Glib::OptionEntry detail_opt;
Glib::OptionEntry unlock_opt;
Glib::OptionEntry version_opt;

std::optional<GObjectWrapper<SecretService>> service;


App() :
Gio::Application{"lssecrets.dkosmari.github.com"}
Gio::Application{"lssecrets.dkosmari.github.com", AF_NON_UNIQUE}
{
set_option_context_summary("Show keyring secrets using libsecret.");
set_option_context_description(PACKAGE_NAME " <" PACKAGE_URL ">\n"
"Bug reports <" PACKAGE_BUGREPORT ">\n");


add_main_option_entry(
#if HAVE_GLIBMM_2_68
OptionType::BOOL,
#else
OptionType::OPTION_TYPE_BOOL,
#endif
"secrets",
's',
"Show secret values.");
add_main_option_entry(
#if HAVE_GLIBMM_2_68
OptionType::BOOL,
#else
OptionType::OPTION_TYPE_BOOL,
#endif
"unlock",
'u',
"Unlock secrets.");

add_main_option_entry(
#if HAVE_GLIBMM_2_68
OptionType::BOOL,
#else
OptionType::OPTION_TYPE_BOOL,
#endif
"version",
'v',
"Print version number and exit.");

signal_handle_local_options().connect(sigc::mem_fun(*this, &App::handle_local_options),
true);
}



int
handle_local_options(const Glib::RefPtr<Glib::VariantDict>& options)
{
if (options->contains("version")) {
cout << PACKAGE_STRING << endl;
return 0;
}

if (options->contains("secrets"))
show_secrets = true;

if (options->contains("unlock"))
do_unlock = true;

return -1; // means "continue processing options"
detail_opt.set_flags(OEF_IN_MAIN);
detail_opt.set_long_name("detail");
detail_opt.set_short_name('d');
detail_opt.set_description("Set detail of detail, where N is:\n"
" 0 = service\n"
" 1 = collections\n"
" 2 = items (default)\n"
" 3 = attributes\n"
" 4 = secrets");
detail_opt.set_arg_description("N");
main_group.add_entry(detail_opt, detail);

unlock_opt.set_flags(OEF_IN_MAIN);
unlock_opt.set_long_name("unlock");
unlock_opt.set_short_name('u');
unlock_opt.set_description("Unlock secrets.");
main_group.add_entry(unlock_opt, unlock_flag);

version_opt.set_flags(OEF_IN_MAIN);
version_opt.set_long_name("version");
version_opt.set_short_name('v');
version_opt.set_description("Print version number and exit.");
main_group.add_entry(version_opt, version_flag);

add_option_group(main_group);
}


void
on_activate()
override
{
if (version_flag) {
cout << PACKAGE_STRING << endl;
return;
}

try {
print();
}
Expand All @@ -383,7 +387,7 @@ struct App : Gio::Application {

GError* service_error = nullptr;
int flags = SECRET_SERVICE_LOAD_COLLECTIONS;
if (show_secrets)
if (detail >= Detail::Secrets)
flags |= SECRET_SERVICE_OPEN_SESSION;

service = take(secret_service_get_sync(SecretServiceFlags(flags),
Expand All @@ -398,7 +402,6 @@ struct App : Gio::Application {
<< g_dbus_proxy_get_object_path(*service)
<< '\n';


// check known aliases
const std::vector<std::string> known_aliases{
"default", "login", "session"
Expand Down Expand Up @@ -427,6 +430,9 @@ struct App : Gio::Application {

cout << '\n';

if (detail < Detail::Collections)
return;

auto collections = to_vector<SecretCollection>(secret_service_get_collections(*service));
for (auto& col : collections) {
print(col, reverse_aliases, " ");
Expand Down Expand Up @@ -475,15 +481,19 @@ struct App : Gio::Application {
<< timestamp_to_string(modified).value()
<< '\n';

bool locked = secret_collection_get_locked(col);
if (locked && do_unlock) {
if (unlock_flag && secret_collection_get_locked(col)) {
auto error = unlock(col);
if (error)
cout << indent << " Error: " << error->what() << endl;
}
bool locked = secret_collection_get_locked(col);
cout << indent << " Locked: " << locked << '\n';

cout << '\n';

if (detail < Detail::Items)
return;

auto items = to_vector<SecretItem>(secret_collection_get_items(col));
for (auto& item : items) {
print(item, indent + " ");
Expand Down Expand Up @@ -522,6 +532,9 @@ struct App : Gio::Application {
<< timestamp_to_string(modified).value()
<< '\n';

if (detail < Detail::Attributes)
return;

auto attributes = to_map(secret_item_get_attributes(item));
if (!attributes.empty()) {
static const std::string attrib_indent = indent + " ";
Expand All @@ -536,16 +549,22 @@ struct App : Gio::Application {
}
}

bool locked = secret_item_get_locked(item);
if (locked && do_unlock) {
auto print_locked = [&item, indent] {
bool locked = secret_item_get_locked(item);
cout << indent << " Locked: " << locked << '\n';
};

if (unlock_flag && secret_item_get_locked(item)) {
auto error = unlock(item);
print_locked();
if (error) {
cout << indent << " Error: " << error->what() << endl;
return;
}
}
} else
print_locked();

if (!show_secrets)
if (detail < Detail::Secrets)
return;

GError* error = nullptr;
Expand Down

0 comments on commit 455c471

Please sign in to comment.