]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
wizard: hello (login/passwords) page works now
authorJaroslav Kysela <perex@perex.cz>
Wed, 9 Dec 2015 18:42:29 +0000 (19:42 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 9 Dec 2015 18:56:37 +0000 (19:56 +0100)
src/access.c
src/access.h
src/webui/static/app/idnode.js
src/webui/static/app/tvheadend.js
src/webui/static/app/wizard.js
src/wizard.c

index ade3f5a2028ef23403e5a1268e9b9a52dda4779d..8f1696e2a1ccdedd8d04cd172708c0a5720934a0 100644 (file)
@@ -1087,10 +1087,14 @@ access_entry_create(const char *uuid, htsmsg_t *conf)
 /**
  *
  */
-static void
-access_entry_destroy(access_entry_t *ae)
+void
+access_entry_destroy(access_entry_t *ae, int delconf)
 {
   access_ipmask_t *ai;
+  char ubuf[UUID_HEX_SIZE];
+
+  if (delconf)
+    hts_settings_remove("accesscontrol/%s", idnode_uuid_as_str(&ae->ae_id, ubuf));
 
   TAILQ_REMOVE(&access_entries, ae, ae_link);
   idnode_unlink(&ae->ae_id);
@@ -1185,10 +1189,7 @@ static void
 access_entry_class_delete(idnode_t *self)
 {
   access_entry_t *ae = (access_entry_t *)self;
-  char ubuf[UUID_HEX_SIZE];
-
-  hts_settings_remove("accesscontrol/%s", idnode_uuid_as_str(&ae->ae_id, ubuf));
-  access_entry_destroy(ae);
+  access_entry_destroy(ae, 1);
 }
 
 static void
@@ -1602,6 +1603,13 @@ const idclass_t access_entry_class = {
       .name     = N_("Comment"),
       .off      = offsetof(access_entry_t, ae_comment),
     },
+    {
+      .type     = PT_BOOL,
+      .id       = "wizard",
+      .name     = N_("Wizard"),
+      .off      = offsetof(access_entry_t, ae_wizard),
+      .opts     = PO_NOUI
+    },
     {}
   }
 };
@@ -1704,11 +1712,16 @@ passwd_entry_create(const char *uuid, htsmsg_t *conf)
   return pw;
 }
 
-static void
-passwd_entry_destroy(passwd_entry_t *pw)
+void
+passwd_entry_destroy(passwd_entry_t *pw, int delconf)
 {
+  char ubuf[UUID_HEX_SIZE];
+
   if (pw == NULL)
     return;
+
+  if (delconf)
+    hts_settings_remove("passwd/%s", idnode_uuid_as_str(&pw->pw_id, ubuf));
   TAILQ_REMOVE(&passwd_entries, pw, pw_link);
   idnode_unlink(&pw->pw_id);
   free(pw->pw_username);
@@ -1738,10 +1751,7 @@ static void
 passwd_entry_class_delete(idnode_t *self)
 {
   passwd_entry_t *pw = (passwd_entry_t *)self;
-  char ubuf[UUID_HEX_SIZE];
-
-  hts_settings_remove("passwd/%s", idnode_uuid_as_str(&pw->pw_id, ubuf));
-  passwd_entry_destroy(pw);
+  passwd_entry_destroy(pw, 1);
 }
 
 static const char *
@@ -1838,6 +1848,13 @@ const idclass_t passwd_entry_class = {
       .name     = N_("Comment"),
       .off      = offsetof(passwd_entry_t, pw_comment),
     },
+    {
+      .type     = PT_BOOL,
+      .id       = "wizard",
+      .name     = N_("Wizard"),
+      .off      = offsetof(passwd_entry_t, pw_wizard),
+      .opts     = PO_NOUI
+    },
     {}
   }
 };
@@ -2070,11 +2087,11 @@ access_done(void)
 
   pthread_mutex_lock(&global_lock);
   while ((ae = TAILQ_FIRST(&access_entries)) != NULL)
-    access_entry_destroy(ae);
+    access_entry_destroy(ae, 0);
   while ((at = TAILQ_FIRST(&access_tickets)) != NULL)
     access_ticket_destroy(at);
   while ((pw = TAILQ_FIRST(&passwd_entries)) != NULL)
-    passwd_entry_destroy(pw);
+    passwd_entry_destroy(pw, 0);
   while ((ib = TAILQ_FIRST(&ipblock_entries)) != NULL)
     ipblock_entry_destroy(ib);
   free((void *)superuser_username);
index bbc30088867e50e54d3bef10c11b49f91c24893e..a26306103c27cbc01cca4083c0c9c8a0d742afb3 100644 (file)
@@ -58,6 +58,7 @@ typedef struct passwd_entry {
   char *pw_password2;
 
   int   pw_enabled;
+  int   pw_wizard;
 
   char *pw_comment;
 } passwd_entry_t;
@@ -97,6 +98,7 @@ typedef struct access_entry {
   char *ae_lang_ui;
 
   int ae_index;
+  int ae_wizard;
   int ae_enabled;
   int ae_uilevel;
   int ae_uilevel_nochange;
@@ -265,6 +267,12 @@ access_get_by_addr(struct sockaddr *src);
 access_entry_t *
 access_entry_create(const char *uuid, htsmsg_t *conf);
 
+/**
+ *
+ */
+void
+access_entry_destroy(access_entry_t *ae, int delconf);
+
 /**
  *
  */
@@ -287,6 +295,8 @@ access_destroy_by_channel_tag(struct channel_tag *ct, int delconf);
 passwd_entry_t *
 passwd_entry_create(const char *uuid, htsmsg_t *conf);
 void
+passwd_entry_destroy(passwd_entry_t *ae, int delconf);
+void
 passwd_entry_save(passwd_entry_t *pw);
 
 /**
index 00e46d5372d5e556c07c2f7903f51a6deadbb3c7..30a639eb6b43407d2508890f8ac6d9d1b507df82 100644 (file)
@@ -1202,6 +1202,11 @@ tvheadend.idnode_editor_win = function(_uilevel, conf)
             conf.win = null;
        }
 
+    if (conf.fullData) {
+       display(conf.fullData, conf, conf.winTitle || _('Edit'));
+       return;
+    }
+
     var params = conf.params || {};
 
     var uuids = null;
@@ -1229,7 +1234,7 @@ tvheadend.idnode_editor_win = function(_uilevel, conf)
             d = d[0];
             if (conf.modifyData)
                 conf.modifyData(conf, d);
-            var title = conf.title;
+            var title = conf.winTitle;
             if (!title) {
                 if (uuids && uuids.length > 1)
                     title = String.format(_('Edit {0} ({1} entries)'),
@@ -1545,8 +1550,10 @@ tvheadend.idnode_grid = function(panel, conf)
             grid.getView().refresh();
     };
 
-    function build(d)
-    {
+    function build(d) {
+        if (grid)
+            return;
+
         if (conf.builder)
             conf.builder(conf);
 
@@ -2483,6 +2490,7 @@ tvheadend.idnode_tree = function(panel, conf)
     function builder() {
         if (tree)
             return;
+
         if (conf.builder)
             conf.builder(conf);
 
index 865ee36cdb323f1fc9af0c3b163185085e0bb2ae..1ea97ef4fae440925f7775d81b95ef2413e9c98d 100644 (file)
@@ -51,14 +51,15 @@ tvheadend.uilevel_match = function(target, current) {
  */
 tvheadend.select_tab = function(id)
 {
-   var i = Ext.getCmp(id);
-   var c = i ? i.ownerCt : null;
-   while (c) {
-      if ('activeTab' in c)
-          c.setActiveTab(i);
-      i = c;
-      c = c.ownerCt;
-   }
+    var i = Ext.getCmp(id);
+    var c = i ? i.ownerCt : null;
+    while (c) {
+        if ('activeTab' in c) {
+            c.setActiveTab(i);
+        }
+        i = c;
+        c = c.ownerCt;
+    }
 }
 
 /**
index 95f693160c9c5317cb844c448e996e9af32f9390..0b07f7c1da256c802f78679a902997c25cedcec9 100644 (file)
@@ -2,6 +2,8 @@
  * Wizard
  */
 
+tvheadend.wizard_delayed_activation = null;
+
 tvheadend.wizard_start = function(page) {
 
     var w = null;
@@ -20,6 +22,8 @@ tvheadend.wizard_start = function(page) {
         tvheadend.wizard = null;
         if (conf.win)
             conf.win.close();
+        tvheadend.wizard_delayed_activation.cancel();
+        tvheadend.wizard_delayed_activation = null;
     }
 
     function getparam(data, prefix) {
@@ -90,10 +94,10 @@ tvheadend.wizard_start = function(page) {
         d = json_decode(d);
         var m = d[0];
         var last = getparam(m, 'page_next_') === null;
-        tvheadend.idnode_editor_win('basic', m, {
+        tvheadend.idnode_editor_win('basic', {
             build: pbuild,
             fullData: m,
-            url: 'api/wizard/' + page,
+            saveURL: 'api/wizard/' + page + '/save',
             winTitle: m.caption,
             iconCls: 'wizard',
             comet: m.events,
@@ -117,10 +121,19 @@ tvheadend.wizard_start = function(page) {
         });
     }
 
+    function activate_tab() {
+        if (page in tabMapping)
+            tvheadend.select_tab(tabMapping[page]);
+    }
+
     tvheadend.wizard = page;
 
-    if (page in tabMapping)
-        tvheadend.select_tab(tabMapping[page]);
+    var delay = 1000;
+    if (tvheadend.wizard_delayed_activation == null) {
+        tvheadend.wizard_delayed_activation = new Ext.util.DelayedTask();
+        delay = 1;
+    }
+    tvheadend.wizard_delayed_activation.delay(1000, activate_tab);
 
     tvheadend.Ajax({
         url: 'api/wizard/' + page + '/load',
@@ -130,6 +143,8 @@ tvheadend.wizard_start = function(page) {
         success: build,
         failure: function(response, options) {
             Ext.MessageBox.alert(_('Unable to obtain wizard page!'), response.statusText);
+            tvheadend.wizard_delayed_activation.cancel();
+            tvheadend.wizard_delayed_activation = null;
         }
     });
 
index 7d0deb0714fcf6a864e35089a757302672bba546..5dfcfbed8f15ae72c8268c3a4e80e4c3507ed847 100644 (file)
@@ -59,6 +59,22 @@ static const void *wizard_description_##page(void *o) \
   return &t; \
 }
 
+#define BASIC_STR_OPS(stru, field) \
+static const void *wizard_get_value_##field(void *o) \
+{ \
+  wizard_page_t *p = o; \
+  stru *w = p->aux; \
+  snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", w->field); \
+  return &prop_sbuf_ptr; \
+} \
+static int wizard_set_value_##field(void *o, const void *v) \
+{ \
+  wizard_page_t *p = o; \
+  stru *w = p->aux; \
+  snprintf(w->field, sizeof(w->field), v); \
+  return 1; \
+}
+
 /*
  *
  */
@@ -86,6 +102,101 @@ static wizard_page_t *page_init(const char *class_name, const char *caption)
  * Hello
  */
 
+typedef struct wizard_hello {
+  char network[256];
+  char admin_username[32];
+  char admin_password[32];
+  char username[32];
+  char password[32];
+} wizard_hello_t;
+
+
+static void hello_save(idnode_t *in)
+{
+  wizard_page_t *p = (wizard_page_t *)in;
+  wizard_hello_t *w = p->aux;
+  access_entry_t *ae, *ae_next;
+  passwd_entry_t *pw, *pw_next;
+  htsmsg_t *conf;
+  const char *s;
+
+  for (ae = TAILQ_FIRST(&access_entries); ae; ae = ae_next) {
+    ae_next = TAILQ_NEXT(ae, ae_link);
+    if (ae->ae_wizard)
+      access_entry_destroy(ae, 1);
+  }
+
+  for (pw = TAILQ_FIRST(&passwd_entries); pw; pw = pw_next) {
+    pw_next = TAILQ_NEXT(pw, pw_link);
+    if (pw->pw_wizard)
+      passwd_entry_destroy(pw, 1);
+  }
+
+  s = w->admin_username[0] ? w->admin_username : "*";
+  conf = htsmsg_create_map();
+  htsmsg_add_bool(conf, "enabled", 1);
+  htsmsg_add_str(conf, "prefix", w->network);
+  htsmsg_add_str(conf, "username", s);
+  htsmsg_add_str(conf, "password", w->admin_password);
+  htsmsg_add_bool(conf, "streaming", 1);
+  htsmsg_add_bool(conf, "adv_streaming", 1);
+  htsmsg_add_bool(conf, "htsp_streaming", 1);
+  htsmsg_add_bool(conf, "dvr", 1);
+  htsmsg_add_bool(conf, "htsp_dvr", 1);
+  htsmsg_add_bool(conf, "webui", 1);
+  htsmsg_add_bool(conf, "admin", 1);
+  ae = access_entry_create(NULL, conf);
+  if (ae) {
+    ae->ae_wizard = 1;
+    access_entry_save(ae);
+  }
+  htsmsg_destroy(conf);
+
+  if (s && s[0] != '*' && w->admin_password[0]) {
+    conf = htsmsg_create_map();
+    htsmsg_add_bool(conf, "enabled", 1);
+    htsmsg_add_str(conf, "username", s);
+    htsmsg_add_str(conf, "password", w->admin_password);
+    pw = passwd_entry_create(NULL, conf);
+    if (pw) {
+      pw->pw_wizard = 1;
+      passwd_entry_save(pw);
+    }
+  }
+
+  if (w->username[0]) {
+    s = w->username && w->username[0] ? w->username : "*";
+    conf = htsmsg_create_map();
+    htsmsg_add_str(conf, "prefix", w->network);
+    htsmsg_add_str(conf, "username", s);
+    htsmsg_add_str(conf, "password", w->password);
+    ae = access_entry_create(NULL, conf);
+    if (ae) {
+      ae->ae_wizard = 1;
+      access_entry_save(ae);
+    }
+    htsmsg_destroy(conf);
+
+    if (s && s[0] != '*' && w->password && w->password[0]) {
+      conf = htsmsg_create_map();
+      htsmsg_add_bool(conf, "enabled", 1);
+      htsmsg_add_str(conf, "username", s);
+      htsmsg_add_str(conf, "password", w->password);
+      pw = passwd_entry_create(NULL, conf);
+      if (pw) {
+        pw->pw_wizard = 1;
+        passwd_entry_save(pw);
+      }
+    }
+  }
+}
+
+BASIC_STR_OPS(wizard_hello_t, network)
+BASIC_STR_OPS(wizard_hello_t, admin_username)
+BASIC_STR_OPS(wizard_hello_t, admin_password)
+BASIC_STR_OPS(wizard_hello_t, username)
+BASIC_STR_OPS(wizard_hello_t, password)
+
 static const void *hello_get_network(void *o)
 {
   strcpy(prop_sbuf, "Test123");
@@ -134,40 +245,40 @@ wizard_page_t *wizard_hello(void)
       .type     = PT_STR,
       .id       = "network",
       .name     = N_("Allowed network"),
-      .get      = hello_get_network,
-      .set      = hello_set_network,
+      .get      = wizard_get_value_network,
+      .set      = wizard_set_value_network,
       .group    = 1
     },
     {
       .type     = PT_STR,
       .id       = "admin_username",
       .name     = N_("Admin username"),
-      .get      = hello_get_network,
-      .set      = hello_set_network,
+      .get      = wizard_get_value_admin_username,
+      .set      = wizard_set_value_admin_username,
       .group    = 2
     },
     {
       .type     = PT_STR,
       .id       = "admin_password",
       .name     = N_("Admin password"),
-      .get      = hello_get_network,
-      .set      = hello_set_network,
+      .get      = wizard_get_value_admin_password,
+      .set      = wizard_set_value_admin_password,
       .group    = 2
     },
     {
       .type     = PT_STR,
       .id       = "username",
       .name     = N_("Username"),
-      .get      = hello_get_network,
-      .set      = hello_set_network,
+      .get      = wizard_get_value_username,
+      .set      = wizard_set_value_username,
       .group    = 3
     },
     {
       .type     = PT_STR,
       .id       = "password",
       .name     = N_("Password"),
-      .get      = hello_get_network,
-      .set      = hello_set_network,
+      .get      = wizard_get_value_password,
+      .set      = wizard_set_value_password,
       .group    = 3
     },
     ICON(),
@@ -179,8 +290,40 @@ wizard_page_t *wizard_hello(void)
     page_init("wizard_hello",
     N_("Welcome - Tvheadend - your TV streaming server and video recorder"));
   idclass_t *ic = (idclass_t *)page->idnode.in_class;
+  wizard_hello_t *w;
+  access_entry_t *ae;
+  passwd_entry_t *pw;
+
   ic->ic_properties = props;
   ic->ic_groups = groups;
+  ic->ic_save = hello_save;
+  page->aux = w = calloc(1, sizeof(wizard_hello_t));
+
+  TAILQ_FOREACH(ae, &access_entries, ae_link) {
+    if (!ae->ae_wizard)
+      continue;
+    if (ae->ae_admin) {
+      htsmsg_t *c = htsmsg_create_map();
+      idnode_save(&ae->ae_id, c);
+      snprintf(w->admin_username, sizeof(w->admin_username), "%s", ae->ae_username);
+      snprintf(w->network, sizeof(w->network), "%s", htsmsg_get_str(c, "prefix") ?: "");
+      htsmsg_destroy(c);
+    } else {
+      snprintf(w->username, sizeof(w->username), "%s", ae->ae_username);
+    }
+  }
+
+  TAILQ_FOREACH(pw, &passwd_entries, pw_link) {
+    if (!pw->pw_wizard || !pw->pw_username)
+      continue;
+    if (w->admin_username[0] &&
+        strcmp(w->admin_username, pw->pw_username) == 0) {
+      snprintf(w->admin_password, sizeof(w->admin_password), "%s", pw->pw_password);
+    } else if (w->username[0] && strcmp(w->username, pw->pw_username) == 0) {
+      snprintf(w->password, sizeof(w->password), "%s", pw->pw_password);
+    }
+  }
+
   return page;
 }
 
@@ -200,7 +343,7 @@ typedef struct wizard_network {
   .id   = "network" STRINGIFY(num), \
   .name = nameval, \
   .get  = network_get_value##num, \
-  .set  = hello_set_network, \
+  .set  = network_set_value##num, \
   .list = network_get_list, \
 }
 
@@ -211,6 +354,13 @@ static const void *network_get_value##num(void *o) \
   wizard_network_t *w = p->aux; \
   snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", w->network_type##num); \
   return &prop_sbuf_ptr; \
+} \
+static int network_set_value##num(void *o, const void *v) \
+{ \
+  wizard_page_t *p = o; \
+  wizard_network_t *w = p->aux; \
+  snprintf(w->network_type##num, sizeof(w->network_type##num), v); \
+  return 1; \
 }
 
 NETWORK_FCN(1)
@@ -219,7 +369,7 @@ NETWORK_FCN(3)
 NETWORK_FCN(4)
 
 DESCRIPTION_FCN(network, N_("\
-Create networks.\
+Create networks. The T means terresterial, C is cable and S is satellite.\
 "))
 
 static htsmsg_t *network_get_list(void *o, const char *lang)