Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
ACL/all: handle the per user language settings for all operations
  • Loading branch information
perexg committed Jun 29, 2015
1 parent 55efd0f commit 7cfdff0
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 65 deletions.
18 changes: 17 additions & 1 deletion src/access.c
Expand Up @@ -39,6 +39,7 @@
#include "channels.h"
#include "dvr/dvr.h"
#include "tcp.h"
#include "lang_codes.h"

struct access_entry_queue access_entries;
struct access_ticket_queue access_tickets;
Expand Down Expand Up @@ -225,6 +226,21 @@ access_copy(access_t *src)
return dst;
}

/**
*
*/
char *
access_get_lang(access_t *a, const char *lang)
{
if (lang == NULL) {
if (a->aa_lang == NULL)
return NULL;
return strdup(a->aa_lang);
} else {
return lang_code_user(lang);
}
}

/**
*
*/
Expand Down Expand Up @@ -531,7 +547,7 @@ access_update(access_t *a, access_entry_t *ae)
}

if (!a->aa_lang && ae->ae_lang)
a->aa_lang = strdup(ae->ae_lang);
a->aa_lang = lang_code_user(ae->ae_lang);

a->aa_rights |= ae->ae_rights;
}
Expand Down
6 changes: 6 additions & 0 deletions src/access.h
Expand Up @@ -187,6 +187,12 @@ void access_destroy(access_t *a);
*/
access_t *access_copy(access_t *src);

/**
*
*/
char *
access_get_lang(access_t *a, const char *lang);

/**
* Verifies that the given user in combination with the source ip
* complies with the requested mask
Expand Down
24 changes: 23 additions & 1 deletion src/api/api_dvr.c
Expand Up @@ -132,7 +132,8 @@ api_dvr_entry_create
{
dvr_entry_t *de;
dvr_config_t *cfg;
htsmsg_t *conf;
htsmsg_t *conf, *m;
char *s, *lang;
const char *s1;
int res = EPERM;

Expand All @@ -147,10 +148,31 @@ api_dvr_entry_create
htsmsg_set_str(conf, "owner", perm->aa_username ?: "");
htsmsg_set_str(conf, "creator", perm->aa_representative ?: "");

lang = access_get_lang(perm, htsmsg_get_str(conf, "lang"));
if (lang) {
for (s = lang; *s && *s != ','; s++);
*s = '\0';
}

s1 = htsmsg_get_str(conf, "disp_title");
if (s1 && !htsmsg_get_map(conf, "title")) {
m = htsmsg_create_map();
htsmsg_add_str(m, lang, s1);
htsmsg_add_msg(conf, "title", m);
}

s1 = htsmsg_get_str(conf, "disp_subtitle");
if (s1 && !htsmsg_get_map(conf, "subtitle")) {
m = htsmsg_create_map();
htsmsg_add_str(m, lang, s1);
htsmsg_add_msg(conf, "subtitle", m);
}

if ((de = dvr_entry_create(NULL, conf)))
dvr_entry_save(de);

res = 0;
free(lang);
}
pthread_mutex_unlock(&global_lock);

Expand Down
20 changes: 13 additions & 7 deletions src/api/api_epg.c
Expand Up @@ -24,6 +24,7 @@
#include "epg.h"
#include "imagecache.h"
#include "dvr/dvr.h"
#include "lang_codes.h"

static htsmsg_t *
api_epg_get_list ( const char *s )
Expand Down Expand Up @@ -280,17 +281,16 @@ api_epg_grid
{
int i;
epg_query_t eq;
const char *lang, *str;
const char *str;
char *lang;
uint32_t start, limit, end, genre;
int64_t duration_min, duration_max;
htsmsg_field_t *f, *f2;
htsmsg_t *l = NULL, *e, *filter;

memset(&eq, 0, sizeof(eq));

lang = htsmsg_get_str(args, "lang");
if (lang)
eq.lang = strdup(lang);
eq.lang = lang = access_get_lang(perm, htsmsg_get_str(args, "lang"));
str = htsmsg_get_str(args, "title");
if (str)
eq.stitle = strdup(str);
Expand Down Expand Up @@ -471,17 +471,19 @@ api_epg_alternative
uint32_t id, entries = 0;
htsmsg_t *l = htsmsg_create_list();
epg_broadcast_t *e;
const char *lang = htsmsg_get_str(args, "lang");
char *lang;

if (!htsmsg_get_u32(args, "eventId", &id))
return -EINVAL;

/* Main Job */
pthread_mutex_lock(&global_lock);
lang = access_get_lang(perm, htsmsg_get_str(args, "lang"));
e = epg_broadcast_find_by_id(id);
if (e && e->episode)
api_epg_episode_broadcasts(perm, l, lang, e->episode, &entries, e);
pthread_mutex_unlock(&global_lock);
free(lang);

/* Build response */
*resp = htsmsg_create_map();
Expand All @@ -499,13 +501,14 @@ api_epg_related
htsmsg_t *l = htsmsg_create_list();
epg_broadcast_t *e;
epg_episode_t *ep, *ep2;
const char *lang = htsmsg_get_str(args, "lang");
char *lang;

if (!htsmsg_get_u32(args, "eventId", &id))
return -EINVAL;

/* Main Job */
pthread_mutex_lock(&global_lock);
lang = access_get_lang(perm, htsmsg_get_str(args, "lang"));
e = epg_broadcast_find_by_id(id);
ep = e ? e->episode : NULL;
if (ep && ep->brand) {
Expand All @@ -523,6 +526,7 @@ api_epg_related
}
}
pthread_mutex_unlock(&global_lock);
free(lang);

/* Build response */
*resp = htsmsg_create_map();
Expand All @@ -540,7 +544,7 @@ api_epg_load
htsmsg_t *l = htsmsg_create_list(), *ids = NULL, *m;
htsmsg_field_t *f;
epg_broadcast_t *e;
const char *lang = htsmsg_get_str(args, "lang");
char *lang;

if (!(f = htsmsg_field_find(args, "eventId")))
return -EINVAL;
Expand All @@ -550,6 +554,7 @@ api_epg_load

/* Main Job */
pthread_mutex_lock(&global_lock);
lang = access_get_lang(perm, htsmsg_get_str(args, "lang"));
if (ids) {
HTSMSG_FOREACH(f, ids) {
if (htsmsg_field_get_u32(f, &id)) continue;
Expand All @@ -567,6 +572,7 @@ api_epg_load
}
}
pthread_mutex_unlock(&global_lock);
free(lang);

/* Build response */
*resp = htsmsg_create_map();
Expand Down
60 changes: 6 additions & 54 deletions src/dvr/dvr_db.c
Expand Up @@ -44,8 +44,6 @@ static void dvr_entry_destroy(dvr_entry_t *de, int delconf);
static void dvr_timer_expire(void *aux);
static void dvr_timer_start_recording(void *aux);
static void dvr_timer_stop_recording(void *aux);
static int dvr_entry_class_disp_title_set(void *o, const void *v);
static int dvr_entry_class_disp_subtitle_set(void *o, const void *v);

/*
*
Expand Down Expand Up @@ -477,7 +475,6 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf)
dvr_entry_t *de, *de2;
int64_t start, stop;
htsmsg_t *m;
const char *s;

if (conf) {
if (htsmsg_get_s64(conf, "start", &start))
Expand Down Expand Up @@ -510,16 +507,6 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf)
if (m)
de->de_files = htsmsg_copy(m);

/* special case, because PO_NOSAVE, load ignores it */
if (de->de_title == NULL &&
(s = htsmsg_get_str(conf, "disp_title")) != NULL)
dvr_entry_class_disp_title_set(de, s);

/* special case, because PO_NOSAVE, load ignores it */
if (de->de_subtitle == NULL &&
(s = htsmsg_get_str(conf, "disp_subtitle")) != NULL)
dvr_entry_class_disp_subtitle_set(de, s);

de->de_refcnt = 1;

LIST_INSERT_HEAD(&dvrentries, de, de_global_link);
Expand Down Expand Up @@ -1746,64 +1733,30 @@ dvr_entry_class_broadcast_get(void *o)
return &id;
}

static int
dvr_entry_class_disp_title_set(void *o, const void *v)
{
dvr_entry_t *de = (dvr_entry_t *)o;
const char *s = "";
if (v == NULL || *((char *)v) == '\0')
v = "UnknownTitle";
if (de->de_title)
s = lang_str_get(de->de_title, NULL);
if (strcmp(s, v)) {
lang_str_destroy(de->de_title);
de->de_title = lang_str_create();
lang_str_add(de->de_title, v, NULL, 0);
return 1;
}
return 0;
}

static const void *
dvr_entry_class_disp_title_get(void *o)
{
dvr_entry_t *de = (dvr_entry_t *)o;
static const char *s;
const char *lang = de->de_id.in_access ? de->de_id.in_access->aa_lang : NULL;
s = "";
if (de->de_title) {
s = lang_str_get(de->de_title, NULL);
s = lang_str_get(de->de_title, lang);
if (s == NULL)
s = "";
}
return &s;
}

static int
dvr_entry_class_disp_subtitle_set(void *o, const void *v)
{
dvr_entry_t *de = (dvr_entry_t *)o;
const char *s = "";
if (v == NULL || *((char *)v) == '\0')
v = "UnknownSubtitle";
if (de->de_subtitle)
s = lang_str_get(de->de_subtitle, NULL);
if (strcmp(s, v)) {
lang_str_destroy(de->de_subtitle);
de->de_subtitle = lang_str_create();
lang_str_add(de->de_subtitle, v, NULL, 0);
return 1;
}
return 0;
}

static const void *
dvr_entry_class_disp_subtitle_get(void *o)
{
dvr_entry_t *de = (dvr_entry_t *)o;
static const char *s;
const char *lang = de->de_id.in_access ? de->de_id.in_access->aa_lang : NULL;
s = "";
if (de->de_subtitle) {
s = lang_str_get(de->de_subtitle, NULL);
s = lang_str_get(de->de_subtitle, lang);
if (s == NULL)
s = "";
}
Expand All @@ -1815,9 +1768,10 @@ dvr_entry_class_disp_description_get(void *o)
{
dvr_entry_t *de = (dvr_entry_t *)o;
static const char *s;
const char *lang = de->de_id.in_access ? de->de_id.in_access->aa_lang : NULL;
s = "";
if (de->de_desc) {
s = lang_str_get(de->de_desc, NULL);
s = lang_str_get(de->de_desc, lang);
if (s == NULL)
s = "";
}
Expand Down Expand Up @@ -2084,7 +2038,6 @@ const idclass_t dvr_entry_class = {
.id = "disp_title",
.name = N_("Title"),
.get = dvr_entry_class_disp_title_get,
.set = dvr_entry_class_disp_title_set,
.opts = PO_NOSAVE,
},
{
Expand All @@ -2099,7 +2052,6 @@ const idclass_t dvr_entry_class = {
.id = "disp_subtitle",
.name = N_("Subtitle"),
.get = dvr_entry_class_disp_subtitle_get,
.set = dvr_entry_class_disp_subtitle_set,
.opts = PO_NOSAVE,
},
{
Expand Down
4 changes: 4 additions & 0 deletions src/htsp_server.c
Expand Up @@ -34,6 +34,7 @@
#include "descrambler/caid.h"
#include "notify.h"
#include "htsmsg_json.h"
#include "lang_codes.h"
#if ENABLE_TIMESHIFT
#include "timeshift.h"
#endif
Expand Down Expand Up @@ -2602,6 +2603,9 @@ htsp_authenticate(htsp_connection_t *htsp, htsmsg_t *m)
access_destroy(htsp->htsp_granted_access);
htsp->htsp_granted_access = rights;

if (htsp->htsp_language == NULL && rights->aa_lang)
htsp->htsp_language = strdup(rights->aa_lang);

} else {

tvhlog(LOG_INFO, "htsp", "%s: Identified as user '%s' (unverified)",
Expand Down
26 changes: 26 additions & 0 deletions src/lang_codes.c
Expand Up @@ -696,6 +696,32 @@ const char *lang_code_preferred( void )
return ret;
}

char *lang_code_user( const char *ucode )
{
const char *codes = config_get_language(), *s;
char *ret;

if (!codes)
return ucode ? strdup(ucode) : NULL;
if (!ucode)
return codes ? strdup(codes) : NULL;
ret = malloc(strlen(codes) + strlen(ucode ?: "") + 1);
strcpy(ret, ucode);
while (codes && *codes) {
s = codes;
while (*s && *s != ',')
s++;
if (strncmp(codes, ucode ?: "", s - codes)) {
strcat(ret, ",");
strncat(ret, codes, s - codes);
}
if (*s && *s == ',')
s++;
codes = s;
}
return ret;
}

void lang_code_done( void )
{
lang_code_free(lang_codes_code2b);
Expand Down
1 change: 1 addition & 0 deletions src/lang_codes.h
Expand Up @@ -38,6 +38,7 @@ const char *lang_code_get2 ( const char *code, size_t len );
const lang_code_t *lang_code_get3 ( const char *code );

const char *lang_code_preferred( void );
char *lang_code_user( const char *ucode );

/* Split list of codes as per HTTP Language-Accept spec */
const char **lang_code_split ( const char *codes );
Expand Down
7 changes: 6 additions & 1 deletion src/tvh_locale.c
Expand Up @@ -127,9 +127,14 @@ static void lng_init(struct lng *l)
static struct lng *lng_get(const char *tvh_lang)
{
struct lng *l, ls;
char *s;

if (tvh_lang != NULL && tvh_lang[0] != '\0') {
ls.tvh_lang = tvh_lang;
s = alloca(strlen(tvh_lang) + 1);
ls.tvh_lang = s;
for ( ; *tvh_lang && *tvh_lang != ','; s++, tvh_lang++)
*s = *tvh_lang;
*s = '\0';
l = RB_FIND(&lngs, &ls, link, lng_cmp);
if (l) {
if (!l->msgs_initialized)
Expand Down

0 comments on commit 7cfdff0

Please sign in to comment.