"<HTML><HEAD>\r\n"
"<TITLE>%d %s</TITLE>\r\n"
"</HEAD><BODY>\r\n"
- "<H1>%d %s</H1>\r\n"
- "</BODY></HTML>\r\n",
- error, errtxt, error, errtxt);
+ "<H1>%d %s</H1>\r\n",
+ error, errtxt, error, errtxt);
+
+ if (error == HTTP_STATUS_UNAUTHORIZED)
+ htsbuf_qprintf(&hc->hc_reply, "<P><A HREF=\"/\">Default Login</A></P>");
+
+ htsbuf_qprintf(&hc->hc_reply, "</BODY></HTML>\r\n");
http_send_reply(hc, error, "text/html", NULL, NULL, 0);
}
comet_access_update(http_connection_t *hc, comet_mailbox_t *cmb)
{
htsmsg_t *m = htsmsg_create_map();
+ const char *username = hc->hc_access ? (hc->hc_access->aa_username ?: "") : "";
htsmsg_add_str(m, "notificationClass", "accessUpdate");
- htsmsg_add_u32(m, "dvr", !http_access_verify(hc, ACCESS_RECORDER));
- htsmsg_add_u32(m, "admin", !http_access_verify(hc, ACCESS_ADMIN));
+ htsmsg_add_str(m, "username", username);
+ htsmsg_add_u32(m, "dvr", !http_access_verify(hc, ACCESS_RECORDER));
+ htsmsg_add_u32(m, "admin", !http_access_verify(hc, ACCESS_ADMIN));
if(cmb->cmb_messages == NULL)
cmb->cmb_messages = htsmsg_create_list();
text-shadow: 0 -2px rgba(0, 0, 0, 0.2);
}
+
+.x-tab-strip li.x-tab-login {
+ margin-left: 16px;
+}
+
+.x-tab-strip span.x-tab-strip-login {
+ vertical-align: middle;
+ white-space: nowrap;
+ padding:4px 0px;
+}
+
+.x-tab-strip span.x-tab-strip-login-cmd {
+ vertical-align: middle;
+ cursor:pointer;
+ padding:4px 0;
+ float: right;
+}
+
.x-tree-col {
float: left;
overflow: hidden;
if (!tvheadend.capabilities)
return;
+ tvheadend.rootTabPanel.setLogin(o.username);
+
if (o.dvr == true && tvheadend.dvrpanel == null) {
tvheadend.dvrpanel = tvheadend.dvr();
tvheadend.rootTabPanel.add(tvheadend.dvrpanel);
e.scrollIntoView('systemlog');
};
+/**
+ *
+ */
+tvheadend.RootTabPanel = Ext.extend(Ext.TabPanel, {
+
+ onRender: function(ct, position) {
+ tvheadend.RootTabPanel.superclass.onRender.call(this, ct, position);
+
+ /* Create login components */
+ var before = this.strip.dom.childNodes[this.strip.dom.childNodes.length-1];
+
+ if (!this.loginTpl) {
+ var tt = new Ext.Template(
+ '<li class="x-tab-login" id="{id}">',
+ '<span class="x-tab-strip-login {iconCls}">{text}</span></li>'
+ );
+ tt.disableFormats = true;
+ tt.compile();
+ tvheadend.RootTabPanel.prototype.loginTpl = tt;
+ }
+ var item = new Ext.Component();
+ var p = this.getTemplateArgs(item);
+ var before = this.strip.dom.childNodes[this.strip.dom.childNodes.length-1];
+ item.tabEl = this.loginTpl.insertBefore(before, p);
+ this.loginItem = item;
+
+ if (!this.loginCmdTpl) {
+ var tt = new Ext.Template(
+ '<li class="x-tab-login" id="{id}"><a href="#">',
+ '<span class="x-tab-strip-login-cmd"></span></a></li>'
+ );
+ tt.disableFormats = true;
+ tt.compile();
+ tvheadend.RootTabPanel.prototype.loginCmdTpl = tt;
+ }
+ var item = new Ext.Component();
+ var p = this.getTemplateArgs(item);
+ var el = this.loginCmdTpl.insertBefore(before, p);
+ item.tabEl = Ext.get(el);
+ item.tabEl.select('a').on('click', this.onLoginCmdClicked, this, {preventDefault: true});
+ this.loginCmdItem = item;
+
+ this.on('beforetabchange', function(tp, p) {
+ if (p == this.loginItem || p == this.loginCmdItem)
+ return false;
+ });
+
+ this.setLogin('');
+ },
+
+ getComponent: function(comp) {
+ if (comp === this.loginItem.id || comp == this.loginItem)
+ return this.loginItem;
+ if (comp === this.loginCmdItem.id || comp == this.loginCmdItem)
+ return this.loginCmdItem;
+ return tvheadend.RootTabPanel.superclass.getComponent.call(this, comp);
+ },
+
+ setLogin: function(login) {
+ this.login = login;
+ if (login) {
+ text = 'Logged in as <b>' + login + '</b>';
+ cmd = '(logout)';
+ } else {
+ text = 'No verified access';
+ cmd = '(login)';
+ }
+ var el = this.loginItem.tabEl;
+ var fly = Ext.fly(this.loginItem.tabEl);
+ var t = fly.child('span.x-tab-strip-login', true);
+ Ext.fly(this.loginItem.tabEl).child('span.x-tab-strip-login', true).innerHTML = text;
+ Ext.fly(this.loginCmdItem.tabEl).child('span.x-tab-strip-login-cmd', true).innerHTML = cmd;
+ },
+
+ onLoginCmdClicked: function(e) {
+ window.location.href = this.login ? 'logout' : 'login';
+ }
+
+});
+
/**
*
*/
html: '<div id="header"><h1>Tvheadend Web-Panel</h1></div>'
});
- tvheadend.rootTabPanel = new Ext.TabPanel({
+ tvheadend.rootTabPanel = new tvheadend.RootTabPanel({
region: 'center',
activeTab: 0,
items: [tvheadend.epg()]
return 0;
}
+static int
+page_login(http_connection_t *hc, const char *remain, void *opaque)
+{
+ if (hc->hc_access != NULL &&
+ hc->hc_access->aa_username != NULL &&
+ hc->hc_access->aa_username != '\0') {
+ http_redirect(hc, "/", &hc->hc_req_args);
+ return 0;
+ } else {
+ return HTTP_STATUS_UNAUTHORIZED;
+ }
+}
+
+static int
+page_logout(http_connection_t *hc, const char *remain, void *opaque)
+{
+ if (hc->hc_access == NULL ||
+ hc->hc_access->aa_username == NULL ||
+ hc->hc_access->aa_username == '\0') {
+ http_redirect(hc, "/", &hc->hc_req_args);
+ return 0;
+ } else {
+ return HTTP_STATUS_UNAUTHORIZED;
+ }
+}
+
/**
* Static download of a file from the filesystem
*/
http_path_add("", NULL, page_root2, ACCESS_WEB_INTERFACE);
http_path_add("/", NULL, page_root, ACCESS_WEB_INTERFACE);
+ http_path_add("/login", NULL, page_login, ACCESS_WEB_INTERFACE);
+ http_path_add("/logout", NULL, page_logout, ACCESS_WEB_INTERFACE);
http_path_add_modify("/play", NULL, page_play, ACCESS_WEB_INTERFACE, page_play_path_modify);
http_path_add("/dvrfile", NULL, page_dvrfile, ACCESS_WEB_INTERFACE);