def ensure_calendar_exist(self, workspace: Workspace) -> None: # Note: Cyclic imports from tracim.lib.calendar import CalendarManager from tracim.model.organisational import WorkspaceCalendar calendar_manager = CalendarManager(self._user) try: calendar_manager.enable_calendar_file( calendar_class=WorkspaceCalendar, related_object_id=workspace.workspace_id, raise_=True, ) # If previous calendar file no exist, calendar must be created except FileNotFoundError: self._user.ensure_auth_token() # Ensure database is up-to-date DBSession.flush() transaction.commit() calendar_manager.create_then_remove_fake_event( calendar_class=WorkspaceCalendar, related_object_id=workspace.workspace_id, )
def index(self): from tracim.config.app_cfg import CFG cfg = CFG.get_instance() # TODO BS 20160720: S'assurer d'être identifié ! user = tmpl_context.identity.get('user') dictified_current_user = Context(CTX.CURRENT_USER).toDict(user) fake_api = DictLikeClass( current_user=dictified_current_user, ) user_base_url = CalendarManager.get_user_base_url() workspace_base_url = CalendarManager.get_workspace_base_url() workspace_calendar_urls = CalendarManager\ .get_workspace_readable_calendars_urls_for_user(user) base_href_url = \ re.sub(r"^http[s]?://", '', cfg.RADICALE_CLIENT_BASE_URL_HOST) # Template will use User.auth_token, ensure it's validity user.ensure_auth_token() return DictLikeClass( fake_api=fake_api, user_base_url=user_base_url, workspace_base_url=workspace_base_url, workspace_clendar_urls=workspace_calendar_urls, auth_token=user.auth_token, base_href_url=base_href_url, )
def test_func__rights_read_workspace_calendar__fail__as_unauthorized(self): lawrence = DBSession.query(User).filter( User.email == '*****@*****.**' ).one() workspace = WorkspaceApi(lawrence).create_workspace( 'workspace_1', save_now=False ) workspace.calendar_enabled = True DBSession.flush() workspace_calendar_url = CalendarManager.get_workspace_calendar_url( workspace.workspace_id ) transaction.commit() radicale_base_url = CalendarManager.get_base_url() client = caldav.DAVClient( radicale_base_url, username='******', password='******' ) caldav.Calendar( parent=client, client=client, url=workspace_calendar_url ).events()
def disable_calendar(self, workspace: Workspace) -> None: # Note: Cyclic imports from tracim.lib.calendar import CalendarManager from tracim.model.organisational import WorkspaceCalendar calendar_manager = CalendarManager(self._user) calendar_manager.disable_calendar_file( calendar_class=WorkspaceCalendar, related_object_id=workspace.workspace_id, raise_=False, )
def test_func__event_create__ok__nominal_case(self): lawrence = DBSession.query(User).filter( User.email == '*****@*****.**' ).one() radicale_base_url = CalendarManager.get_base_url() client = caldav.DAVClient( radicale_base_url, username='******', password='******' ) user_calendar_url = CalendarManager.get_user_calendar_url( lawrence.user_id ) user_calendar = caldav.Calendar( parent=client, client=client, url=user_calendar_url ) event_ics = """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Example Corp.//CalDAV Client//EN BEGIN:VEVENT UID:1234567890 DTSTAMP:20100510T182145Z DTSTART:20100512T170000Z DTEND:20100512T180000Z SUMMARY:This is an event LOCATION:Here END:VEVENT END:VCALENDAR """ user_calendar.add_event(event_ics) user_calendar.save() daemons.execute_in_thread('radicale', lambda: transaction.commit()) # TODO - 20160606 - Bastien: lock should be better here ? time.sleep(3) # Wait for be sure transaction commited in daemon transaction.commit() try: event = DBSession.query(Content) \ .filter(Content.label == 'This is an event') \ .filter(Content.owner_id == lawrence.user_id) \ .filter(Content.id == ContentRevisionRO.content_id) \ .one() except NoResultFound: ok_(False, 'Content record should exist for ' '"This is an event" label') eq_(event.properties['location'], 'Here') eq_(event.properties['start'], '2010-05-12 18:00:00+0000') eq_(event.properties['end'], '2010-05-12 17:00:00+0000')
def test_func__rights_read_user_calendar__ok__as_lawrence(self): radicale_base_url = CalendarManager.get_base_url() client = caldav.DAVClient( radicale_base_url, username='******', password='******' ) user = DBSession.query(User).filter( User.email == '*****@*****.**' ).one() user_calendar_url = CalendarManager.get_user_calendar_url(user.user_id) caldav.Calendar( parent=client, client=client, url=user_calendar_url ).events()
def test_func__rights_read_user_calendar__fail__as_john_doe(self): radicale_base_url = CalendarManager.get_base_url() client = caldav.DAVClient( radicale_base_url, username='******', password='******' ) other_user = DBSession.query(User).filter( User.email == '*****@*****.**' ).one() user_calendar_url = CalendarManager.get_user_calendar_url(other_user.user_id) caldav.Calendar( parent=client, client=client, url=user_calendar_url ).events()
def test_func__radicale_auth__fail__as_john_doe(self): radicale_base_url = CalendarManager.get_base_url() client = caldav.DAVClient( radicale_base_url, username='******', password='******' ) client.propfind()
def serialize_api_calendar_workspace(item: User, context: Context): from tracim.lib.calendar import CalendarManager # Cyclic import return DictLikeClass( id=item.user_id, label=item.display_name, description=CalendarManager.get_personal_calendar_description(), type='user', )
def test_func__radicale_auth__ok__as_lawrence(self): radicale_base_url = CalendarManager.get_base_url() client = caldav.DAVClient( radicale_base_url, username='******', password='******' ) client.propfind()
def test_func__radicale_connectivity__ok__nominal_case(self): radicale_base_url = CalendarManager.get_base_url() try: response = requests.get(radicale_base_url) eq_(response.status_code, 401, 'Radicale http response should be ' '401, its {0}' .format(response.status_code)) except ConnectionError as exc: ok_(False, 'Unable to contact radicale on HTTP: {0}'.format(exc))
def execute_created_user_actions(self, created_user: User) -> None: """ Execute actions when user just been created :return: """ # NOTE: Cyclic import from tracim.lib.calendar import CalendarManager from tracim.model.organisational import UserCalendar created_user.ensure_auth_token() # Ensure database is up-to-date DBSession.flush() transaction.commit() calendar_manager = CalendarManager(created_user) calendar_manager.create_then_remove_fake_event( calendar_class=UserCalendar, related_object_id=created_user.user_id )
def index(self): # TODO BS 20160720: S'assurer d'être identifié ! user = tmpl_context.identity.get("user") dictified_current_user = Context(CTX.CURRENT_USER).toDict(user) fake_api = DictLikeClass(current_user=dictified_current_user) user_base_url = CalendarManager.get_user_base_url() workspace_base_url = CalendarManager.get_workspace_base_url() workspace_calendar_urls = CalendarManager.get_workspace_readable_calendars_urls_for_user(user) base_href_url = re.sub(r"^http[s]?://", "", CalendarManager.get_base_url()) # Template will use User.auth_token, ensure it's validity user.ensure_auth_token() return DictLikeClass( fake_api=fake_api, user_base_url=user_base_url, workspace_base_url=workspace_base_url, workspace_clendar_urls=workspace_calendar_urls, auth_token=user.auth_token, base_href_url=base_href_url, )
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)
def calendar_url(self) -> str: # TODO - 20160531 - Bastien: Cyclic import if import in top of file from tracim.lib.calendar import CalendarManager calendar_manager = CalendarManager(None) return calendar_manager.get_workspace_calendar_url(self.workspace_id)
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)
def calendar_url(self) -> str: # TODO - 20160531 - Bastien: Cyclic import if import in top of file from tracim.lib.calendar import CalendarManager calendar_manager = CalendarManager(None) return calendar_manager.get_user_calendar_url(self.user_id)
def test_func__radicale_auth__fail__as_john_doe(self): radicale_base_url = CalendarManager.get_base_url() client = caldav.DAVClient(radicale_base_url, username='******', password='******') client.propfind()
def __init__(self, path: str, principal: bool=False): super().__init__(path, principal) self._replacing = False # See ``replacing`` context manager self._manager = CalendarManager(None)
def test_func__radicale_auth__ok__as_lawrence(self): radicale_base_url = CalendarManager.get_base_url() client = caldav.DAVClient(radicale_base_url, username='******', password='******') client.propfind()