dst->aa_username = strdup(src->aa_username);
if (src->aa_representative)
dst->aa_representative = strdup(src->aa_representative);
+ if (src->aa_profiles)
+ dst->aa_profiles = htsmsg_copy(src->aa_profiles);
if (src->aa_dvrcfgs)
dst->aa_dvrcfgs = htsmsg_copy(src->aa_dvrcfgs);
if (src->aa_chtags)
return;
free(a->aa_username);
free(a->aa_representative);
+ htsmsg_destroy(a->aa_profiles);
htsmsg_destroy(a->aa_dvrcfgs);
htsmsg_destroy(a->aa_chtags);
free(a);
}
}
+ if(ae->ae_profile && ae->ae_profile->pro_name[0] != '\0') {
+ if (a->aa_profiles == NULL)
+ a->aa_profiles = htsmsg_create_list();
+ htsmsg_add_str(a->aa_profiles, NULL, idnode_uuid_as_str(&ae->ae_profile->pro_id));
+ }
+
if(ae->ae_dvr_config && ae->ae_dvr_config->dvr_config_name[0] != '\0') {
if (a->aa_dvrcfgs == NULL)
a->aa_dvrcfgs = htsmsg_create_list();
TAILQ_REMOVE(&access_entries, ae, ae_link);
idnode_unlink(&ae->ae_id);
+ if (ae->ae_profile)
+ LIST_REMOVE(ae, ae_profile_link);
if (ae->ae_dvr_config)
LIST_REMOVE(ae, ae_dvr_config_link);
if (ae->ae_chtag)
free(ae);
}
+/*
+ *
+ */
+void
+access_destroy_by_profile(profile_t *pro, int delconf)
+{
+ access_entry_t *ae;
+
+ while ((ae = LIST_FIRST(&pro->pro_accesses)) != NULL) {
+ LIST_REMOVE(ae, ae_profile_link);
+ ae->ae_dvr_config = NULL;
+ if (delconf)
+ access_entry_save(ae);
+ }
+}
+
/*
*
*/
while ((ae = LIST_FIRST(&cfg->dvr_accesses)) != NULL) {
LIST_REMOVE(ae, ae_dvr_config_link);
- ae->ae_dvr_config = NULL;
+ ae->ae_profile = profile_find_by_name(NULL, NULL);
if (delconf)
access_entry_save(ae);
}
return &ret;
}
+static int
+access_entry_profile_set(void *o, const void *v)
+{
+ access_entry_t *ae = (access_entry_t *)o;
+ profile_t *pro = v ? profile_find_by_uuid(v) : NULL;
+ if (pro == NULL && ae->ae_profile) {
+ LIST_REMOVE(ae, ae_profile_link);
+ ae->ae_profile = NULL;
+ return 1;
+ } else if (ae->ae_profile != pro) {
+ if (ae->ae_profile)
+ LIST_REMOVE(ae, ae_profile_link);
+ ae->ae_profile = pro;
+ LIST_INSERT_HEAD(&pro->pro_accesses, ae, ae_profile_link);
+ return 1;
+ }
+ return 0;
+}
+
+static const void *
+access_entry_profile_get(void *o)
+{
+ static const char *ret;
+ access_entry_t *ae = (access_entry_t *)o;
+ if (ae->ae_profile)
+ ret = idnode_uuid_as_str(&ae->ae_profile->pro_id);
+ else
+ ret = "";
+ return &ret;
+}
+
const idclass_t access_entry_class = {
.ic_class = "access",
.ic_caption = "Access",
.name = "Advanced Streaming",
.off = offsetof(access_entry_t, ae_adv_streaming),
},
+ {
+ .type = PT_STR,
+ .id = "profile",
+ .name = "Streaming Profile",
+ .set = access_entry_profile_set,
+ .get = access_entry_profile_get,
+ .list = profile_class_get_list,
+ },
{
.type = PT_BOOL,
.id = "dvr",
#include "idnode.h"
#include "htsmsg.h"
+struct profile;
struct dvr_config;
struct channel_tag;
int ae_streaming;
int ae_adv_streaming;
+ struct profile *ae_profile;
+ LIST_ENTRY(access_entry) ae_profile_link;
+
uint32_t ae_conn_limit;
int ae_dvr;
char *aa_username;
char *aa_representative;
uint32_t aa_rights;
+ htsmsg_t *aa_profiles;
htsmsg_t *aa_dvrcfgs;
uint32_t aa_chmin;
uint32_t aa_chmax;
*
*/
void
+access_destroy_by_profile(struct profile *pro, int delconf);
+void
access_destroy_by_dvr_config(struct dvr_config *cfg, int delconf);
void
access_destroy_by_channel_tag(struct channel_tag *ct, int delconf);
}
#endif
-#if ENABLE_LIBAV
+ profile_t *pro;
const char *profile_id = htsmsg_get_str(in, "profile");
- profile_t *pro = NULL;
if (profile_id) {
pro = profile_find_by_uuid(profile_id);
- if (pro == NULL)
- pro = profile_find_by_name(profile_id, "htsp");
+ if (pro)
+ profile_id = pro->pro_name;
}
-
-#else
- profile_t *pro = profile_find_by_name("htsp", NULL);
-#endif
+ pro = profile_find_by_list(htsp->htsp_granted_access->aa_profiles, profile_id, "htsp");
hs->hs_work = profile_work(pro, st, &hs->hs_work_destroy);
if (hs->hs_work) {
return NULL;
}
LIST_INIT(&pro->pro_dvr_configs);
+ LIST_INIT(&pro->pro_accesses);
if (idnode_insert(&pro->pro_id, uuid, pb->clazz, 0)) {
if (uuid)
tvherror("profile", "invalid uuid '%s'", uuid);
TAILQ_REMOVE(&profiles, pro, pro_link);
idnode_unlink(&pro->pro_id);
dvr_config_destroy_by_profile(pro, delconf);
+ access_destroy_by_profile(pro, delconf);
if (pro->pro_free)
pro->pro_free(pro);
free(pro->pro_name);
return profile_default;
TAILQ_FOREACH(pro, &profiles, pro_link) {
- if (!strcmp(pro->pro_name, name))
+ if (pro->pro_enabled && !strcmp(pro->pro_name, name))
return pro;
}
if (alt) {
TAILQ_FOREACH(pro, &profiles, pro_link) {
- if (!strcmp(pro->pro_name, alt))
+ if (pro->pro_enabled && !strcmp(pro->pro_name, alt))
return pro;
}
}
return profile_default;
}
+/*
+ *
+ */
+profile_t *
+profile_find_by_list(htsmsg_t *uuids, const char *name, const char *alt)
+{
+ profile_t *pro, *res = NULL;
+ htsmsg_field_t *f;
+ const char *uuid, *uuid2;
+
+ pro = profile_find_by_name(name, alt);
+ uuid = idnode_uuid_as_str(&pro->pro_id);
+ if (uuids) {
+ HTSMSG_FOREACH(f, uuids) {
+ uuid2 = htsmsg_field_get_str(f) ?: "";
+ if (strcmp(uuid, uuid2) == 0)
+ return res;
+ if (!res) {
+ res = profile_find_by_uuid(uuid2);
+ if (!res->pro_enabled)
+ res = NULL;
+ }
+ }
+ }
+ if (!res)
+ res = profile_find_by_name(NULL, NULL);
+ return res;
+}
+
/*
*
*/
TAILQ_ENTRY(profile) pro_link;
LIST_HEAD(,dvr_config) pro_dvr_configs;
+ LIST_HEAD(,access_entry) pro_accesses;
int pro_enabled;
int pro_shield;
static inline profile_t *profile_find_by_uuid(const char *uuid)
{ return (profile_t*)idnode_find(uuid, &profile_class, NULL); }
profile_t *profile_find_by_name(const char *name, const char *alt);
+profile_t *profile_find_by_list(htsmsg_t *uuids, const char *name, const char *alt);
htsmsg_t * profile_class_get_list(void *o);
tvheadend.acleditor = function(panel, index)
{
- var list = 'enabled,username,password,prefix,streaming,adv_streaming,' +
- 'dvr,dvr_config,webui,admin,conn_limit,channel_min,channel_max,' +
- 'channel_tag,comment';
+ var list = 'enabled,username,password,prefix,' +
+ 'streaming,adv_streaming,profile,' +
+ 'dvr,dvr_config,webui,admin,conn_limit,' +
+ 'channel_min,channel_max,channel_tag,comment';
tvheadend.idnode_grid(panel, {
url: 'api/access/entry',
if(http_access_verify(hc, ACCESS_ADVANCED_STREAMING))
return HTTP_STATUS_UNAUTHORIZED;
- if(!(pro = profile_find_by_name(http_arg_get(&hc->hc_req_args, "profile"), "service")))
+ if(!(pro = profile_find_by_list(hc->hc_access->aa_profiles,
+ http_arg_get(&hc->hc_req_args, "profile"),
+ "service")))
return HTTP_STATUS_NOT_ALLOWED;
if((tcp_id = http_stream_preop(hc)) == NULL)
if (http_access_verify_channel(hc, ACCESS_STREAMING, ch, 1))
return HTTP_STATUS_UNAUTHORIZED;
- if(!(pro = profile_find_by_name(http_arg_get(&hc->hc_req_args, "profile"), "channel")))
+ if(!(pro = profile_find_by_list(hc->hc_access->aa_profiles,
+ http_arg_get(&hc->hc_req_args, "profile"),
+ "channel")))
return HTTP_STATUS_NOT_ALLOWED;
if((tcp_id = http_stream_preop(hc)) == NULL)