]> mj.ucw.cz Git - subauth.git/commitdiff
Listing of zones
authorMartin Mares <mj@ucw.cz>
Wed, 19 Jul 2017 19:05:01 +0000 (21:05 +0200)
committerMartin Mares <mj@ucw.cz>
Wed, 19 Jul 2017 19:05:01 +0000 (21:05 +0200)
client/subauth.c
server/cmd.c
server/subauthd.c
server/subauthd.h

index dc28cd0b015e7614f8ca37e9e800ee690f17c63e..30dd28cdd1a047b1ccd8f5317ab35cd2a4ea8eae 100644 (file)
@@ -36,19 +36,22 @@ static void set_string(struct json_node *n, const char *key, const char *val)
   json_object_set(n, key, json_new_string(js, val));
 }
 
-static struct json_node *get_child(struct json_node *obj, const char *key, bool mandatory, uint type)
+static struct json_node *get_child(struct json_node *obj, const char *key, uint type)
 {
   struct json_node *n = json_object_get(obj, key);
-  if (!n)
-    {
-      if (mandatory)
-       die("Malformed reply: missing %s", key);
-    }
-  else if (n->type != type)
+  if (n && n->type != type)
     die("Malformed reply: %s has wrong type", key);
   return n;
 }
 
+static struct json_node *need_child(struct json_node *obj, const char *key, uint type)
+{
+  struct json_node *n = get_child(obj, key, type);
+  if (!n)
+    die("Malformed reply: missing %s", key);
+  return n;
+}
+
 static void op_new(const char *op)
 {
   js = json_new();
@@ -108,7 +111,7 @@ static void op_run(void)
 
   if (rp->type != JSON_OBJECT)
     die("Malformed reply: Top-level node is not an object");
-  struct json_node *err = get_child(rp, "error", 1, JSON_STRING);
+  struct json_node *err = need_child(rp, "error", JSON_STRING);
   if (strcmp(err->string, ""))
     {
       fprintf(stderr, "Error: %s\n", err->string);
@@ -124,10 +127,32 @@ static void cmd_set_passwd(void)
 
 static void cmd_list(void)
 {
-  op_new("list");
+  op_new("list-accts");
   op_run();
 }
 
+static void cmd_zones(void)
+{
+  op_new("list-zones");
+  op_run();
+
+  struct json_node **jzs = need_child(rp, "zones", JSON_ARRAY)->elements;
+  printf("%-16s %6s %6s  %s\n", "Zone", "Passwd", "Tokens", "Description");
+  for (uint i=0; i < GARY_SIZE(jzs); i++)
+    {
+      struct json_node *jz = jzs[i];
+      struct json_node *jname = need_child(jz, "name", JSON_STRING);
+      struct json_node *jdesc = get_child(jz, "desc", JSON_STRING);
+      struct json_node *jpass = get_child(jz, "allow-passwd", JSON_NUMBER);
+      struct json_node *jtokens = get_child(jz, "allow-tokens", JSON_NUMBER);
+      printf("%-16s %6s %6d  %s\n",
+       jname->string,
+       (jpass && jpass->number ? "yes" : "-"),
+       (jtokens ? (uint) jtokens->number : 0),
+       (jdesc ? jdesc->string : "(no description)"));
+    }
+}
+
 static void cmd_raw(void)
 {
   op_new("");
@@ -142,6 +167,7 @@ static void cmd_raw(void)
 enum command {
   CMD_SET_PASSWD,
   CMD_LIST,
+  CMD_ZONES,
   CMD_RAW,
   CMD_MAX
 };
@@ -149,6 +175,7 @@ enum command {
 void (* const command_handlers[CMD_MAX])(void) = {
   [CMD_SET_PASSWD] = cmd_set_passwd,
   [CMD_LIST] = cmd_list,
+  [CMD_ZONES] = cmd_zones,
   [CMD_RAW] = cmd_raw,
 };
 
@@ -169,6 +196,7 @@ static const struct opt_section options = {
     OPT_HELP("Commands:"),
     OPT_SWITCH(0, "passwd", command, CMD_SET_PASSWD, OPT_SINGLE, "\tSet password"),
     OPT_SWITCH(0, "list", command, CMD_LIST, OPT_SINGLE, "\tList tokens for all zones"),
+    OPT_SWITCH(0, "zones", command, CMD_ZONES, OPT_SINGLE, "\tList all known zones"),
     OPT_SWITCH(0, "raw", command, CMD_RAW, OPT_SINGLE, "\tSend raw JSON command to the daemon"),
     OPT_HELP(""),
     OPT_HELP("Command options:"),
index 180f421332073820d5fa0fedc1761897e262a3a1..4b10368cc8efad80649e27ffbfa32f19a7d6a280 100644 (file)
 
 #include "subauthd.h"
 
+static void set_string(struct client *c, struct json_node *n, const char *key, const char *val)
+{
+  if (val)
+    json_object_set(n, key, json_new_string(c->json, val));
+}
+
+static void set_uint(struct client *c, struct json_node *n, const char *key, uint val)
+{
+  json_object_set(n, key, json_new_number(c->json, val));
+}
+
 static void NONRET cmd_error(struct client *c, const char *err, ...)
 {
   va_list args;
   char msg[1024];
   va_start(args, err);
   vsnprintf(msg, sizeof(msg), err, args);
-  json_object_set(c->reply, "error", json_new_string(c->json, msg));
+  set_string(c, c->reply, "error", msg);
   trans_throw("adhoc", NULL, "Error caught");
   va_end(args);
 }
 
 static void cmd_ok(struct client *c)
 {
-  json_object_set(c->reply, "error", json_new_string_ref(c->json, ""));
+  set_string(c, c->reply, "error", "");
 }
 
 const char *get_string(struct json_node *n, const char *key)
@@ -237,7 +248,7 @@ static void cmd_create_token(struct client *c)
 
   struct auth_token *at = auth_create_token(aa);
   char *tok = auth_set_token_generated(at, get_string(c->request, "comment"));
-  json_object_set(c->reply, "token", json_new_string(c->json, tok));
+  set_string(c, c->reply, "token", tok);
   xfree(tok);
 
   msg(L_INFO, "Created token: login=<%s> zone=<%s> id=<%s>", aa->user->login, aa->zone->name, at->ident);
@@ -310,7 +321,7 @@ static void cmd_login(struct client *c)
   cmd_ok(c);
 }
 
-static void cmd_list(struct client *c)
+static void cmd_list_accts(struct client *c)
 {
   const char *login = cmd_need_target_login(c);
 
@@ -319,7 +330,7 @@ static void cmd_list(struct client *c)
     cmd_error(c, "No such user");
 
   struct json_context *js = c->json;
-  json_object_set(c->reply, "login", json_new_string(js, au->login));
+  set_string(c, c->reply, "login", au->login);
   struct json_node *jas = json_new_array(js);
   json_object_set(c->reply, "accounts", jas);
 
@@ -327,7 +338,7 @@ static void cmd_list(struct client *c)
     {
       struct json_node *ja = json_new_object(js);
       json_array_append(jas, ja);
-      json_object_set(ja, "zone", json_new_string(js, aa->zone->name));
+      set_string(c, ja, "zone", aa->zone->name);
 
       struct json_node *jts = json_new_array(js);
       json_object_set(ja, "tokens", jts);
@@ -344,19 +355,37 @@ static void cmd_list(struct client *c)
            case TOKEN_GENERATED:       type = "token"; break;
            default:                    type = "unknown"; break;
            }
-         json_object_set(jt, "type", json_new_string(js, type));
+         set_string(c, jt, "type", type);
 
-         if (at->ident)
-           json_object_set(jt, "ident", json_new_string(js, at->ident));
-         if (at->comment)
-           json_object_set(jt, "comment", json_new_string(js, at->comment));
-         json_object_set(jt, "lastmod", json_new_number(js, at->last_modified));
+         set_string(c, jt, "ident", at->ident);
+         set_string(c, jt, "comment", at->comment);
+         set_uint(c, jt, "lastmod", at->last_modified);
        }
     }
 
   cmd_ok(c);
 }
 
+static void cmd_list_zones(struct client *c)
+{
+  struct json_context *js = c->json;
+
+  struct json_node *jzs = json_new_array(js);
+  json_object_set(c->reply, "zones", jzs);
+
+  CLIST_FOR_EACH(struct auth_zone *, az, zone_list)
+    {
+      struct json_node *jz = json_new_object(js);
+      json_array_append(jzs, jz);
+      set_string(c, jz, "name", az->name);
+      set_string(c, jz, "desc", az->desc);
+      set_uint(c, jz, "allow-passwd", az->allow_passwd);
+      set_uint(c, jz, "allow-tokens", az->allow_tokens);
+    }
+
+  cmd_ok(c);
+}
+
 struct command {
   const char *cmd;
   void (*handler)(struct client *c);
@@ -369,7 +398,8 @@ static const struct command command_table[] = {
   { "create-token",    cmd_create_token },
   { "set-passwd",      cmd_set_passwd },
   { "login",           cmd_login },
-  { "list",            cmd_list },
+  { "list-accts",      cmd_list_accts },
+  { "list-zones",      cmd_list_zones },
 };
 
 void cmd_dispatch(struct client *c)
@@ -379,7 +409,7 @@ void cmd_dispatch(struct client *c)
 
   if (rq->type != JSON_OBJECT || !(cmd = get_string(rq, "cmd")))
     {
-      json_object_set(c->reply, "error", json_new_string_ref(c->json, "Malformed request"));
+      set_string(c, c->reply, "error", "Malformed request");
       return;
     }
 
@@ -392,7 +422,7 @@ void cmd_dispatch(struct client *c)
       }
   if (!command)
     {
-      json_object_set(c->reply, "error", json_new_string_ref(c->json, "No such command"));
+      set_string(c, c->reply, "error", "No such command");
       return;
     }
 
index c8bff033dbf20d6a1a9a4566f7618b7c69b3f7b8..38b8c29d016468bf4ce9041a8396cbd3778bbe99 100644 (file)
@@ -289,6 +289,7 @@ static struct cf_section zone_config = {
   CF_COMMIT(zone_commit),
   CF_ITEMS {
     CF_STRING("Name", PTR_TO(struct auth_zone, name)),
+    CF_STRING("Description", PTR_TO(struct auth_zone, desc)),
     CF_UINT("AutoCreateAcct", PTR_TO(struct auth_zone, auto_create_acct)),
     CF_UINT("AllowPasswd", PTR_TO(struct auth_zone, allow_passwd)),
     CF_UINT("AllowTokens", PTR_TO(struct auth_zone, allow_tokens)),
index 30fd01657d8f44fcba2e4be4a83f371621e2926b..7148bfd145bbf4a7d0a43e5f07a2e951f58f385c 100644 (file)
@@ -49,6 +49,7 @@ struct json_node *get_object(struct json_node *n, const char *key);
 struct auth_zone {
   cnode n;
   char *name;
+  char *desc;
   uint auto_create_acct;
   uint allow_passwd;
   uint allow_tokens;