int first;
snprintf(buf, sizeof(buf),
- "%s:%s [%s%s%s%s%s], conn=%u, chmin=%u, chmax=%u%s",
+ "%s:%s [%s%s%s%s%s], conn=%u, chmin=%llu, chmax=%llu%s",
a->aa_representative ?: "<no-id>",
a->aa_username ?: "<no-user>",
a->aa_rights & ACCESS_STREAMING ? "S" : "",
a->aa_rights & ACCESS_RECORDER ? "R" : "",
a->aa_rights & ACCESS_ADMIN ? "*" : "",
a->aa_conn_limit,
- a->aa_chmin, a->aa_chmax,
+ (long long)a->aa_chmin, (long long)a->aa_chmax,
a->aa_match ? ", matched" : "");
if (a->aa_profiles) {
.off = offsetof(access_entry_t, ae_conn_limit),
},
{
- .type = PT_U32,
+ .type = PT_S64,
+ .intsplit = CHANNEL_SPLIT,
.id = "channel_min",
.name = "Min Channel Num",
.off = offsetof(access_entry_t, ae_chmin),
},
{
- .type = PT_U32,
+ .type = PT_S64,
+ .intsplit = CHANNEL_SPLIT,
.id = "channel_max",
.name = "Max Channel Num",
.off = offsetof(access_entry_t, ae_chmax),
int ae_webui;
int ae_admin;
- uint32_t ae_chmin;
- uint32_t ae_chmax;
+ uint64_t ae_chmin;
+ uint64_t ae_chmax;
struct channel_tag *ae_chtag;
LIST_ENTRY(access_entry) ae_channel_tag_link;
uint32_t aa_rights;
htsmsg_t *aa_profiles;
htsmsg_t *aa_dvrcfgs;
- uint32_t aa_chmin;
- uint32_t aa_chmax;
+ uint64_t aa_chmin;
+ uint64_t aa_chmax;
htsmsg_t *aa_chtags;
int aa_match;
uint32_t aa_conn_limit;
#include "access.h"
#include "api.h"
+static void
+api_channel_key_val(htsmsg_t *dst, const char *key, const char *val)
+{
+ htsmsg_t *e = htsmsg_create_map();
+ htsmsg_add_str(e, "key", key);
+ htsmsg_add_str(e, "val", val ?: "");
+ htsmsg_add_msg(dst, NULL, e);
+}
+
// TODO: this will need converting to an idnode system
static int
api_channel_list
( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
{
channel_t *ch;
- htsmsg_t *l, *e;
+ htsmsg_t *l;
l = htsmsg_create_list();
pthread_mutex_lock(&global_lock);
CHANNEL_FOREACH(ch) {
- e = htsmsg_create_map();
- htsmsg_add_str(e, "key", idnode_uuid_as_str(&ch->ch_id));
- htsmsg_add_str(e, "val", channel_get_name(ch));
- htsmsg_add_msg(l, NULL, e);
+ if (!channel_access(ch, perm, 0)) continue;
+ api_channel_key_val(l, idnode_uuid_as_str(&ch->ch_id), channel_get_name(ch));
}
pthread_mutex_unlock(&global_lock);
*resp = htsmsg_create_map();
channel_t *ch;
CHANNEL_FOREACH(ch)
- idnode_set_add(ins, (idnode_t*)ch, &conf->filter);
+ if (channel_access(ch, perm, 1))
+ idnode_set_add(ins, (idnode_t*)ch, &conf->filter);
}
static int
( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
{
channel_tag_t *ct;
- htsmsg_t *l, *e;
+ htsmsg_t *l;
l = htsmsg_create_list();
- TAILQ_FOREACH(ct, &channel_tags, ct_link) {
- e = htsmsg_create_map();
- htsmsg_add_str(e, "key", idnode_uuid_as_str(&ct->ct_id));
- htsmsg_add_str(e, "val", ct->ct_name);
- htsmsg_add_msg(l, NULL, e);
+ if (perm->aa_chtags) {
+ htsmsg_field_t *f;
+ HTSMSG_FOREACH(f, perm->aa_chtags) {
+ ct = channel_tag_find_by_uuid(htsmsg_field_get_str(f) ?: "");
+ if (ct)
+ api_channel_key_val(l, idnode_uuid_as_str(&ct->ct_id), ct->ct_name);
+ }
+ } else {
+ TAILQ_FOREACH(ct, &channel_tags, ct_link)
+ api_channel_key_val(l, idnode_uuid_as_str(&ct->ct_id), ct->ct_name);
}
*resp = htsmsg_create_map();
htsmsg_add_msg(*resp, "entries", l);
{
channel_tag_t *ct;
- TAILQ_FOREACH(ct, &channel_tags, ct_link)
- idnode_set_add(ins, (idnode_t*)ct, &conf->filter);
+ if (perm->aa_chtags) {
+ htsmsg_field_t *f;
+ HTSMSG_FOREACH(f, perm->aa_chtags) {
+ ct = channel_tag_find_by_uuid(htsmsg_field_get_str(f) ?: "");
+ if (ct)
+ idnode_set_add(ins, (idnode_t*)ct, &conf->filter);
+ }
+ } else {
+ TAILQ_FOREACH(ct, &channel_tags, ct_link)
+ idnode_set_add(ins, (idnode_t*)ct, &conf->filter);
+ }
}
static int
/* Query the EPG */
pthread_mutex_lock(&global_lock);
- epg_query(&eq);
+ epg_query(&eq, perm);
/* Build response */
start = MIN(eq.entries, start);
.ic_get_title = channel_class_get_title,
.ic_delete = channel_class_delete,
.ic_properties = (const property_t[]){
-#if 0
{
.type = PT_BOOL,
.id = "enabled",
.name = "Enabled",
.off = offsetof(channel_t, ch_enabled),
},
-#endif
{
.type = PT_STR,
.id = "name",
if (name == NULL)
return NULL;
CHANNEL_FOREACH(ch)
- if (!strcmp(channel_get_name(ch), name))
+ if (ch->ch_enabled && !strcmp(channel_get_name(ch), name))
break;
return ch;
}
* Check if user can access the channel
*/
int
-channel_access(channel_t *ch, access_t *a, const char *username)
+channel_access(channel_t *ch, access_t *a, int disabled)
{
+ if (!ch)
+ return 0;
+
+ if (!disabled && !ch->ch_enabled)
+ return 0;
+
/* Channel number check */
- if (ch && (a->aa_chmin || a->aa_chmax)) {
- int chnum = channel_get_number(ch);
+ if (a->aa_chmin || a->aa_chmax) {
+ int64_t chnum = channel_get_number(ch);
if (chnum < a->aa_chmin || chnum > a->aa_chmax)
return 0;
}
/* Channel tag check */
- if (ch && a->aa_chtags) {
+ if (a->aa_chtags) {
channel_tag_mapping_t *ctm;
htsmsg_field_t *f;
HTSMSG_FOREACH(f, a->aa_chtags) {
abort();
}
+ /* Defaults */
+ ch->ch_enabled = 1;
+
if (conf) {
ch->ch_load = 1;
idnode_load(&ch->ch_id, conf);
idnode_t ch_id;
RB_ENTRY(channel) ch_link;
-
+
int ch_refcount;
int ch_zombie;
int ch_load;
/* Channel info */
+ int ch_enabled;
char *ch_name; // Note: do not access directly!
int64_t ch_number;
char *ch_icon;
const char * channel_tag_get_icon(channel_tag_t *ct);
-int channel_access(channel_t *ch, struct access *a, const char *username);
+int channel_access(channel_t *ch, struct access *a, int disabled);
int channel_tag_map(channel_t *ch, channel_tag_t *ct);
void channel_tag_unmap(channel_t *ch, channel_tag_t *ct);
dvr_autorec_purge_spawns(dae, 1);
CHANNEL_FOREACH(ch) {
+ if (!ch->ch_enabled) continue;
RB_FOREACH(e, &ch->ch_epg_schedule, sched_link) {
if(autorec_cmp(dae, e))
dvr_entry_create_by_autorec(e, dae);
}
epg_broadcast_t **
-epg_query ( epg_query_t *eq )
+epg_query ( epg_query_t *eq, access_t *perm )
{
channel_t *channel;
channel_tag_t *tag;
/* Single channel */
if (channel && tag == NULL) {
- _eq_add_channel(eq, channel);
+ if (channel_access(channel, perm, 0))
+ _eq_add_channel(eq, channel);
/* Tag based */
} else if (tag) {
channel_tag_mapping_t *ctm;
+ channel_t *ch2;
LIST_FOREACH(ctm, &tag->ct_ctms, ctm_tag_link) {
- if(channel == NULL || ctm->ctm_channel == channel)
- _eq_add_channel(eq, ctm->ctm_channel);
+ ch2 = ctm->ctm_channel;
+ if(ch2 == channel || channel == NULL)
+ if (channel_access(channel, perm, 0))
+ _eq_add_channel(eq, ch2);
}
/* All channels */
} else {
CHANNEL_FOREACH(channel)
- _eq_add_channel(eq, channel);
+ if (channel_access(channel, perm, 0))
+ _eq_add_channel(eq, channel);
}
switch (eq->sort_dir) {
#include <regex.h>
#include "settings.h"
#include "lang_str.h"
+#include "access.h"
/*
* External forward decls
uint32_t allocated;
} epg_query_t;
-epg_broadcast_t **epg_query(epg_query_t *eq);
+epg_broadcast_t **epg_query(epg_query_t *eq, access_t *perm);
void epg_query_free(epg_query_t *eq);
/* ************************************************************************
static inline int
htsp_user_access_channel(htsp_connection_t *htsp, channel_t *ch)
{
- return channel_access(ch, htsp->htsp_granted_access, htsp->htsp_username);
+ return channel_access(ch, htsp->htsp_granted_access, 0);
}
#define HTSP_CHECK_CHANNEL_ACCESS(htsp, ch)\
return htsp_error("User does not have access");
/* Query */
- epg_query(&eq);
+ epg_query(&eq, htsp->htsp_granted_access);
/* Create Reply */
out = htsmsg_create_map();
if (access_verify2(hc->hc_access, mask))
return -1;
- if (channel_access(ch, hc->hc_access, hc->hc_username))
+ if (channel_access(ch, hc->hc_access, 0))
res = 0;
return res;
}
eq.lang = strdup(lang);
//Note: force min/max durations for this interface to 0 and INT_MAX seconds respectively
- epg_query(&eq);
+ epg_query(&eq, hc->hc_access);
c = eq.entries;
CHANNEL_FOREACH(ch) {
- htsbuf_qprintf(hq, "%s (%d)\n", channel_get_name(ch), channel_get_id(ch));
+ htsbuf_qprintf(hq, "%s%s (%d)\n", !ch->ch_enabled ? "[DISABLED] " : "",
+ channel_get_name(ch), channel_get_id(ch));
chnum = channel_get_number(ch);
if (channel_get_minor(chnum))
snprintf(chbuf, sizeof(chbuf), "%u.%u",
profile = profile_validate_name(http_arg_get(&hc->hc_req_args, "profile"));
CHANNEL_FOREACH(ch)
- count++;
+ if (ch->ch_enabled)
+ count++;
chlist = malloc(count * sizeof(channel_t *));
CHANNEL_FOREACH(ch)
- chlist[idx++] = ch;
+ if (ch->ch_enabled)
+ chlist[idx++] = ch;
assert(idx == count);