]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Add user interface level (HTTP API/WEBUI)
authorJaroslav Kysela <perex@perex.cz>
Tue, 1 Dec 2015 09:13:38 +0000 (10:13 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 1 Dec 2015 09:13:38 +0000 (10:13 +0100)
src/access.c
src/access.h
src/config.c
src/config.h
src/tvheadend.h
src/webui/comet.c

index 265ef16dcc2af59e8c19534c349f5b6fca8dd615..ba320096bae8b26bc40ae25ac127996e7858f4b6 100644 (file)
@@ -407,7 +407,7 @@ access_dump_a(access_t *a)
   int first;
 
   tvh_strlcatf(buf, sizeof(buf), l,
-    "%s:%s [%c%c%c%c%c%c%c%c%c%c], conn=%u:s%u:r%u%s",
+    "%s:%s [%c%c%c%c%c%c%c%c%c%c], conn=%u:s%u:r%u:l%u%s",
     a->aa_representative ?: "<no-id>",
     a->aa_username ?: "<no-user>",
     a->aa_rights & ACCESS_STREAMING          ? 'S' : ' ',
@@ -423,6 +423,7 @@ access_dump_a(access_t *a)
     a->aa_conn_limit,
     a->aa_conn_limit_streaming,
     a->aa_conn_limit_dvr,
+    a->aa_uilevel,
     a->aa_match ? ", matched" : "");
 
   if (a->aa_profiles) {
@@ -486,7 +487,19 @@ access_dump_a(access_t *a)
  */
 static access_t *access_alloc(void)
 {
-  return calloc(1, sizeof(access_t));
+  access_t *a = calloc(1, sizeof(access_t));
+  a->aa_uilevel = -1;
+  return a;
+}
+
+/*
+ *
+ */
+static access_t *access_full(access_t *a)
+{
+  a->aa_rights = ACCESS_FULL;
+  a->aa_uilevel = UILEVEL_EXPERT;
+  return a;
 }
 
 /*
@@ -513,6 +526,9 @@ access_update(access_t *a, access_entry_t *ae)
     break;
   }
 
+  if(ae->ae_uilevel > a->aa_uilevel)
+    a->aa_uilevel = ae->ae_uilevel;
+
   if(ae->ae_chmin || ae->ae_chmax) {
     uint64_t *p = realloc(a->aa_chrange, (a->aa_chrange_count + 2) * sizeof(uint64_t));
     if (p) {
@@ -592,6 +608,8 @@ access_set_lang_ui(access_t *a)
     if (a->aa_lang)
       a->aa_lang_ui = strdup(a->aa_lang);
   }
+  if (a->aa_uilevel < 0)
+    a->aa_uilevel = config.uilevel;
 }
 
 /**
@@ -611,25 +629,19 @@ access_get(const char *username, const char *password, struct sockaddr *src)
     a->aa_username = strdup(username);
     a->aa_representative = strdup(username);
     if(!passwd_verify2(username, password,
-                       superuser_username, superuser_password)) {
-      a->aa_rights = ACCESS_FULL;
-      return a;
-    }
+                       superuser_username, superuser_password))
+      return access_full(a);
   } else {
     a->aa_representative = malloc(50);
     tcp_get_str_from_ip((struct sockaddr*)src, a->aa_representative, 50);
     if(!passwd_verify2(username, password,
-                       superuser_username, superuser_password)) {
-      a->aa_rights = ACCESS_FULL;
-      return a;
-    }
+                       superuser_username, superuser_password))
+      return access_full(a);
     username = NULL;
   }
 
-  if (access_noacl) {
-    a->aa_rights = ACCESS_FULL;
-    return a;
-  }
+  if (access_noacl)
+    return access_full(a);
 
   TAILQ_FOREACH(ae, &access_entries, ae_link) {
 
@@ -684,25 +696,19 @@ access_get_hashed(const char *username, const uint8_t digest[20],
     a->aa_username = strdup(username);
     a->aa_representative = strdup(username);
     if(!passwd_verify_digest2(username, digest, challenge,
-                              superuser_username, superuser_password)) {
-      a->aa_rights = ACCESS_FULL;
-      return a;
-    }
+                              superuser_username, superuser_password))
+      return access_full(a);
   } else {
     a->aa_representative = malloc(50);
     tcp_get_str_from_ip((struct sockaddr*)src, a->aa_representative, 50);
     if(!passwd_verify_digest2(username, digest, challenge,
-                              superuser_username, superuser_password)) {
-      a->aa_rights = ACCESS_FULL;
-      return a;
-    }
+                              superuser_username, superuser_password))
+      return access_full(a);
     username = NULL;
   }
 
-  if(access_noacl) {
-    a->aa_rights = ACCESS_FULL;
-    return a;
-  }
+  if(access_noacl)
+    return access_full(a);
 
   TAILQ_FOREACH(ae, &access_entries, ae_link) {
 
@@ -750,10 +756,8 @@ access_get_by_username(const char *username)
   a->aa_username = strdup(username);
   a->aa_representative = strdup(username);
 
-  if(access_noacl) {
-    a->aa_rights = ACCESS_FULL;
-    return a;
-  }
+  if(access_noacl)
+    return access_full(a);
 
   if (username[0] == '\0')
     return a;
@@ -786,10 +790,8 @@ access_get_by_addr(struct sockaddr *src)
   a->aa_representative = malloc(50);
   tcp_get_str_from_ip(src, a->aa_representative, 50);
 
-  if(access_noacl) {
-    a->aa_rights = ACCESS_FULL;
-    return a;
-  }
+  if(access_noacl)
+    return access_full(a);
 
   if (access_ip_blocked(src))
     return a;
@@ -1356,6 +1358,18 @@ user_get_userlist ( void *obj, const char *lang )
   return m;
 }
 
+static htsmsg_t *
+uilevel_get_list ( void *o, const char *lang )
+{
+  static const struct strtab tab[] = {
+    { N_("Default"),  UILEVEL_DEFAULT },
+    { N_("Basic"),    UILEVEL_BASIC },
+    { N_("Advanced"), UILEVEL_ADVANCED },
+    { N_("Expert"),   UILEVEL_EXPERT },
+  };
+  return strtab2htsmsg(tab, 1, lang);
+}
+
 const idclass_t access_entry_class = {
   .ic_class      = "access",
   .ic_caption    = N_("Access"),
@@ -1393,6 +1407,14 @@ const idclass_t access_entry_class = {
       .set      = access_entry_class_prefix_set,
       .get      = access_entry_class_prefix_get,
     },
+    {
+      .type     = PT_INT,
+      .id       = "uilevel",
+      .name     = N_("User interface level"),
+      .off      = offsetof(access_entry_t, ae_uilevel),
+      .list     = uilevel_get_list,
+      .opts     = PO_HIDDEN
+    },
     {
       .type     = PT_STR,
       .id       = "lang",
index 9620b196652f27c45eff29a21ae71482497bbc93..67ed47130713cf7bfde81fc168f4579d52699dd5 100644 (file)
@@ -98,6 +98,7 @@ typedef struct access_entry {
 
   int ae_index;
   int ae_enabled;
+  int ae_uilevel;
 
   int ae_streaming;
   int ae_adv_streaming;
@@ -149,6 +150,7 @@ typedef struct access {
   uint32_t  aa_conn_limit_dvr;
   uint32_t  aa_conn_streaming;
   uint32_t  aa_conn_dvr;
+  int       aa_uilevel;
 } access_t;
 
 TAILQ_HEAD(access_ticket_queue, access_ticket);
index 78d2be7093da8d3306ab9c7ff991587b7d538910..ef891cd9c46d15922db1173d83223371e49d0902 100644 (file)
@@ -1897,6 +1897,17 @@ config_class_dscp_list ( void *o, const char *lang )
   return strtab2htsmsg(tab, 1, lang);
 }
 
+static htsmsg_t *
+config_class_uilevel ( void *o, const char *lang )
+{
+  static const struct strtab tab[] = {
+    { N_("Basic"),    UILEVEL_BASIC },
+    { N_("Advanced"), UILEVEL_ADVANCED },
+    { N_("Expert"),   UILEVEL_EXPERT },
+  };
+  return strtab2htsmsg(tab, 1, lang);
+}
+
 const idclass_t config_class = {
   .ic_snode      = &config.idnode,
   .ic_class      = "config",
@@ -1955,6 +1966,14 @@ const idclass_t config_class = {
       .off    = offsetof(config_t, server_name),
       .group  = 1
     },
+    {
+      .type   = PT_INT,
+      .id     = "uilevel",
+      .name   = N_("User interface level"),
+      .off    = offsetof(config_t, uilevel),
+      .list   = config_class_uilevel,
+      .group  = 1
+    },
     {
       .type   = PT_U32,
       .id     = "cookie_expires",
index ebbeddf957ab693efc0c48656d8cc9d41a94cc64..c4f4126e0db87f12c2feaea85e52ee579ffe9ab6 100644 (file)
@@ -30,6 +30,7 @@
 typedef struct config {
   idnode_t idnode;
   uint32_t version;
+  int uilevel;
   char *full_version;
   char *server_name;
   char *language;
index 14f4064407d32718a546c34e5ef38d5834c9fe91..a652069f2838455bb04676ae2baf59e6f0ad6ea5 100644 (file)
@@ -134,6 +134,14 @@ typedef enum {
 } th_commercial_advice_t;
 
 
+/*
+ *
+ */
+#define UILEVEL_DEFAULT  (-1)
+#define UILEVEL_BASIC    0
+#define UILEVEL_ADVANCED 1
+#define UILEVEL_EXPERT   2
+
 /*
  * global timer
  */
index c1b754ff572cdfbe99832f01d0ea2b2540aa70fe..42ec2c2266f7d2c172f27857f751e65fb41f2d50 100644 (file)
@@ -150,9 +150,18 @@ comet_access_update(http_connection_t *hc, comet_mailbox_t *cmb)
   const char *username = hc->hc_access ? (hc->hc_access->aa_username ?: "") : "";
   int64_t bfree, btotal;
   int dvr = !http_access_verify(hc, ACCESS_RECORDER);
+  const char *s;
 
   htsmsg_add_str(m, "notificationClass", "accessUpdate");
 
+  switch (hc->hc_access->aa_uilevel) {
+  case UILEVEL_BASIC:    s = "basic";    break;
+  case UILEVEL_ADVANCED: s = "advanced"; break;
+  case UILEVEL_EXPERT:   s = "expert";   break;
+  default:               s = NULL;       break;
+  }
+  if (s)
+    htsmsg_add_str(m, "uilevel", s);
   if (!access_noacl)
     htsmsg_add_str(m, "username", username);
   if (hc->hc_peer_ipstr)