def authorized(user, collection, permission): """ :param user: radicale given user id, should be email :param collection: Calendar representation :param permission: 'r' or 'w' :return: True if user can access calendar with asked permission """ if not user: return False current_user = UserApi(None).get_one_by_email(user) manager = CalendarManager(current_user) if manager.is_discovery_path(collection.path): return True try: calendar = manager.find_calendar_with_path(collection.path) except NotFound: return False if permission == CALENDAR_PERMISSION_READ: return calendar.user_can_read(current_user) return calendar.user_can_write(current_user)
class Collection(BaseCollection): """ Radicale use it's own storage system but this override create, update and delete events in our database. """ def __init__(self, path: str, principal: bool=False): super().__init__(path, principal) self._replacing = False # See ``replacing`` context manager self._manager = CalendarManager(None) @contextmanager def replacing(self): """ Radicale filesystem storage make a ``remove`` then an ``append`` to update an item. So to know what we are in update context when ``append`` and ``remove`` functions are called, use this context manager in ``replace`` function. """ try: self._replacing = True yield self finally: self._replacing = False def replace(self, name: str, text: str) -> None: """ Override of parent replace to manage event update action. See ``replacing`` context manager for more informations. :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param text: ICS Event content """ with self.replacing(): super().replace(name, text) self._update_tracim_event(name, text) def remove(self, name: str) -> None: """ :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics """ super().remove(name) if not self._replacing: self._remove_tracim_event(name) def append(self, name: str, text: str) -> None: """ :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param text: ICS Event content """ super().append(name, text) if not self._replacing: self._add_tracim_event(name, text) def _add_tracim_event(self, name: str, text: str) -> Content: """ Create tracim internal Event (Content) with Radicale given data. :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param text: ICS Event content :return: Created Content """ event = self._extract_event(name, text) calendar = self._manager.find_calendar_with_path(self.path) return self._manager.add_event( calendar=calendar, event=event, event_name=name, owner=Auth.current_user ) def _update_tracim_event(self, name: str, text: str) -> Content: """ Update tracim internal Event (Content) with Radicale given data. :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param text: ICS Event content :return: Updated Content """ event = self._extract_event(name, text) calendar = self._manager.find_calendar_with_path(self.path) return self._manager.update_event( calendar=calendar, event=event, event_name=name, current_user=Auth.current_user ) def _remove_tracim_event(self, name: str) -> Content: """ Delete internal tracim Event (Content) with given Event name. :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :return: Deleted Content """ return self._manager.delete_event_with_name(name, Auth.current_user) def _extract_event(self, name: str, text: str) -> iCalendarEvent: """ Return a icalendar.cal.Event construct with given Radicale ICS data. :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param text: ICS Event content :return: ICS Event representation """ radicale_items = self._parse(text, (RadicaleEvent,), name) for item_name in radicale_items: item = radicale_items[item_name] if isinstance(item, RadicaleEvent): return iCalendarEvent.from_ical(item.text)
class Collection(BaseCollection): """ Radicale use it's own storage system but this override create, update and delete events in our database. """ def __init__(self, path: str, principal: bool = False): super().__init__(path, principal) self._replacing = False # See ``replacing`` context manager self._manager = CalendarManager(Auth.current_user) @contextmanager def replacing(self): """ Radicale filesystem storage make a ``remove`` then an ``append`` to update an item. So to know what we are in update context when ``append`` and ``remove`` functions are called, use this context manager in ``replace`` function. """ try: self._replacing = True yield self finally: self._replacing = False def replace(self, name: str, text: str) -> None: """ Override of parent replace to manage event update action. See ``replacing`` context manager for more informations. :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param text: ICS Event content """ with self.replacing(): super().replace(name, text) self._update_tracim_event(name, text) def remove(self, name: str) -> None: """ :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics """ super().remove(name) if not self._replacing: self._remove_tracim_event(name) def append(self, name: str, text: str) -> None: """ :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param text: ICS Event content """ super().append(name, text) if not self._replacing: self._add_tracim_event(name, text) def _add_tracim_event(self, name: str, text: str) -> Content: """ Create tracim internal Event (Content) with Radicale given data. :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param text: ICS Event content :return: Created Content """ event = self._extract_event(name, text) calendar = self._manager.find_calendar_with_path(self.path) return self._manager.add_event(calendar=calendar, event=event, event_name=name, owner=Auth.current_user) def _update_tracim_event(self, name: str, text: str) -> Content: """ Update tracim internal Event (Content) with Radicale given data. :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param text: ICS Event content :return: Updated Content """ event = self._extract_event(name, text) calendar = self._manager.find_calendar_with_path(self.path) return self._manager.update_event(calendar=calendar, event=event, event_name=name, current_user=Auth.current_user) def _remove_tracim_event(self, name: str) -> Content: """ Delete internal tracim Event (Content) with given Event name. :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :return: Deleted Content """ return self._manager.delete_event_with_name(name, Auth.current_user) def _extract_event(self, name: str, text: str) -> iCalendarEvent: """ Return a icalendar.cal.Event construct with given Radicale ICS data. :param name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param text: ICS Event content :return: ICS Event representation """ radicale_items = self._parse(text, (RadicaleEvent, ), name) for item_name in radicale_items: item = radicale_items[item_name] if isinstance(item, RadicaleEvent): return iCalendarEvent.from_ical(item.text)