"""Logic Tier V2 for User logic.""" from podcast.constants import user as user_constants from podcast.logic import user as user_logic from podcast.models import ad_action as ad_action_model from podcast.models import episode as episode_model from podcast.models import order as order_model from podcast.models import podcast as podcast_model from podcast.models import show_family as show_family_model from podcast.models import user as user_model from podcast.utils.exc import OwsError def show_family_ids_for_current_user(): """Return show families for current user.""" user = user_logic.get_current_user() return [show_family['id'] for show_family in user['show_families']] def current_user_owns_show_family(show_family_id): """Return whether the current user owns show_family.""" show_family = show_family_model.get_show_family_by_id(show_family_id) return show_family['network_id'] in user_logic.network_ids_for_current_user() or \ show_family['id'] in show_family_ids_for_current_user() def current_user_owns_show_family_or_raise(show_family_id): """Raise an error if the current user does not own the show family.""" if not current_user_owns_show_family(show_family_id): raise OwsError.forbidden() def current_user_owns_show_families_or_raise(podcasts): """Raise an error if the current user does not own all the show_families.""" checked_show_family_ids = [] for podcast in podcasts: show_family_id = podcast['show_family_id'] if show_family_id not in checked_show_family_ids: current_user_owns_show_family_or_raise(show_family_id) checked_show_family_ids.append(show_family_id) def podcast_ids_owned_by_current_user(): """Get the podcast ids the user has access to from networks ids and show family ids.""" network_ids = user_logic.network_ids_for_current_user() show_family_ids = show_family_ids_for_current_user() return podcast_model.get_podcast_ids_by_show_family_ids_and_network_ids( show_family_ids, network_ids) def public_and_private_rss_podcasts_owned_by_current_user(): """Get public and private rss podcasts based on user access to networks or show families.""" network_ids = user_logic.network_ids_for_current_user() show_family_ids = show_family_ids_for_current_user() return podcast_model.get_public_and_private_rss_podcasts_by_network_ids_and_show_family_ids( network_ids, show_family_ids) def show_family_ids_owned_by_current_user(): """Get the show family ids the user has access to from networks and user show family access.""" network_ids = user_logic.network_ids_for_current_user() network_level_show_family_ids = show_family_model.get_show_family_ids_by_network_ids(network_ids) show_level_show_family_ids = show_family_ids_for_current_user() return network_level_show_family_ids + show_level_show_family_ids def current_user_owns_episodes_or_raise(episode_ids): """Raise if user does not own all episode ids with access to show families or network.""" if not current_user_owns_episodes(episode_ids): raise OwsError.forbidden() def current_user_owns_episodes(episode_ids): """Check if all episode ids owned by user with access to show families or network.""" episodes = episode_model.get_episodes_by_ids(episode_ids) podcasts_ids = [episode['podcast_id'] for episode in episodes['items']] all_owned_podcast_ids = podcast_ids_owned_by_current_user() return set(podcasts_ids).issubset(set(all_owned_podcast_ids)) def current_user_owns_show_family_ids_or_raise(show_family_ids): """Raise an error if the current user does not own all the show_families by ids.""" checked_show_family_ids = [] for show_family_id in show_family_ids: if show_family_id not in checked_show_family_ids: current_user_owns_show_family_or_raise(show_family_id) checked_show_family_ids.append(show_family_id) def current_user_owns_network_ids_or_raise(network_ids, show_family_level=False): """Raise error if user does not have access to passed in networks.""" all_owned_network_ids = user_logic.network_ids_for_current_user() show_family_ids = show_family_ids_for_current_user() if show_family_level and show_family_ids: show_families = show_family_model.get_show_families(show_family_ids=show_family_ids)['items'] all_owned_network_ids = all_owned_network_ids + [ show_family['network_id'] for show_family in show_families ] if not set(network_ids).issubset(set(all_owned_network_ids)): raise OwsError.forbidden() def current_user_owns_podcast_ids_or_raise(podcast_ids): """Raise if user does not own all podcast ids.""" all_owned_podcast_ids = podcast_ids_owned_by_current_user() if not set(podcast_ids).issubset(set(all_owned_podcast_ids)): raise OwsError.forbidden() def current_user_owns_ad_action(ad_action, current_user=None, is_network_admin=False): """Check that current user has access to ad action.""" order = order_model.get_order_by_megaphone_id(ad_action['order_id']) network_ids = set(order['network_ids']) overlap = set(user_logic.network_ids_for_current_user(current_user)) & network_ids is_network_overlap = len(overlap) > 0 if is_network_overlap: return True elif not is_network_overlap and is_network_admin: return False # Check if user owns episodes at the show family level podcast_ids = set(order['podcast_ids']) owned_podcast_ids = podcast_ids_owned_by_current_user() podcast_overlap = set(owned_podcast_ids) & podcast_ids episode_ids = set(order['episode_ids']) owned_episode_ids = episode_model.get_episode_ids_by_podcast_ids(owned_podcast_ids) episode_overlap = set(owned_episode_ids) & episode_ids return len(podcast_overlap) > 0 or len(episode_overlap) > 0 def current_user_owns_ad_action_or_raise(ad_action, current_user=None, is_network_admin=False): """Check that current user has access to ad action or raise.""" if not current_user_owns_ad_action(ad_action, current_user, is_network_admin): raise OwsError.forbidden() def current_user_has_access_to_ad_action_or_raise(ad_action_id, current_user): """Check that ad action is accessible to users like network admins and producers.""" current_user_role = current_user['role'] is_network_admin = current_user_role == user_constants.NETWORK_ADMIN if not current_user['all_networks']: ad_action = ad_action_model.get_ad_action_no_assets(ad_action_id) current_user_owns_ad_action_or_raise(ad_action, current_user, is_network_admin) def current_user_owns_object(object_type, object_id): """Raise an exception if the current user doesn't have access to object.""" is_authorized = False if object_type == 'network': is_authorized = object_id in user_logic.network_ids_for_current_user() if object_type == 'podcast': podcast = podcast_model.get_podcast_by_id(object_id) is_authorized = current_user_owns_show_family(podcast['show_family_id']) if object_type == 'episode': episode = episode_model.get_episode_by_id(object_id) podcast = podcast_model.get_podcast_by_id(episode['podcast_id']) is_authorized = current_user_owns_show_family(podcast['show_family_id']) if object_type == 'adupload': current_user = user_logic.get_current_user() is_network_admin = current_user['role'] == user_constants.NETWORK_ADMIN ad_action = ad_action_model.get_ad_action_no_assets(object_id) is_authorized = current_user_owns_ad_action(ad_action, current_user, is_network_admin) return {'authorized': is_authorized} def specific_podcast_ids_for_current_user(current_user): """Get the podcast ids the current user has access to at the show family level.""" show_family_ids = [show_family['id'] for show_family in current_user['show_families']] return podcast_model.get_podcast_ids_by_show_family_ids_and_network_ids(show_family_ids) def users_for_order(order_id): """Get users for campaign order id. Returns: dict: containing a dict with users having access to order. """ user_logic.current_user_is_admin_or_raise() order = order_model.get_order_by_megaphone_id(order_id) order_network_ids = set(order['network_ids']) order_podcast_ids = order['podcast_ids'] order_episodes = episode_model.get_episodes_by_ids(order['episode_ids'])['items'] order_podcast_ids += [episode['podcast_id'] for episode in order_episodes] podcasts = podcast_model.get_podcasts_by_ids(order_podcast_ids)['items'] order_show_family_ids = [podcast['show_family_id'] for podcast in podcasts] if user_logic.current_user_is_network_admin(): current_user_network_ids = set(user_logic.network_ids_for_current_user()) current_user_show_family_ids = set(show_family_ids_owned_by_current_user()) order_network_ids = list(order_network_ids & current_user_network_ids) order_show_family_ids = list(set(order_show_family_ids) & current_user_show_family_ids) if len(order_network_ids) == 0 or len(order_show_family_ids) == 0: raise OwsError.forbidden() return user_model.users_for_show_family_and_network_ids( order_show_family_ids, order_network_ids)