From: Jaroslav Kysela Date: Wed, 9 Dec 2015 18:42:29 +0000 (+0100) Subject: wizard: hello (login/passwords) page works now X-Git-Tag: v4.2.1~1331 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7b95b156e188dbdab1e729b9b2e74842bce3a358;p=thirdparty%2Ftvheadend.git wizard: hello (login/passwords) page works now --- diff --git a/src/access.c b/src/access.c index ade3f5a20..8f1696e2a 100644 --- a/src/access.c +++ b/src/access.c @@ -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); diff --git a/src/access.h b/src/access.h index bbc300888..a26306103 100644 --- a/src/access.h +++ b/src/access.h @@ -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); /** diff --git a/src/webui/static/app/idnode.js b/src/webui/static/app/idnode.js index 00e46d537..30a639eb6 100644 --- a/src/webui/static/app/idnode.js +++ b/src/webui/static/app/idnode.js @@ -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); diff --git a/src/webui/static/app/tvheadend.js b/src/webui/static/app/tvheadend.js index 865ee36cd..1ea97ef4f 100644 --- a/src/webui/static/app/tvheadend.js +++ b/src/webui/static/app/tvheadend.js @@ -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; + } } /** diff --git a/src/webui/static/app/wizard.js b/src/webui/static/app/wizard.js index 95f693160..0b07f7c1d 100644 --- a/src/webui/static/app/wizard.js +++ b/src/webui/static/app/wizard.js @@ -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; } }); diff --git a/src/wizard.c b/src/wizard.c index 7d0deb071..5dfcfbed8 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -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)