Trees | Indices | Help |
---|
|
1 # -*- Mode: Python; test-case-name: flumotion.test.test_icalbouncer -*- 2 # vi:si:et:sw=4:sts=4:ts=4 3 4 # Flumotion - a streaming media server 5 # Copyright (C) 2004,2005,2006,2007,2008,2009 Fluendo, S.L. 6 # Copyright (C) 2010,2011 Flumotion Services, S.A. 7 # All rights reserved. 8 # 9 # This file may be distributed and/or modified under the terms of 10 # the GNU Lesser General Public License version 2.1 as published by 11 # the Free Software Foundation. 12 # This file is distributed without any warranty; without even the implied 13 # warranty of merchantability or fitness for a particular purpose. 14 # See "LICENSE.LGPL" in the source distribution for more information. 15 # 16 # Headers in this file shall remain intact. 17 18 """ 19 A bouncer that only lets in during an event scheduled with an ical file. 20 """ 21 22 from datetime import datetime, timedelta 23 24 from twisted.internet import defer 25 26 from flumotion.common import keycards, messages, errors 27 from flumotion.common import log, documentation 28 from flumotion.common import eventcalendar, tz 29 from flumotion.common.i18n import N_, gettexter 30 from flumotion.component.base import scheduler 31 from flumotion.component.bouncers.algorithms import base 32 33 __all__ = ['IcalBouncerAlgorithm'] 34 __version__ = "$Rev$" 35 T_ = gettexter() 36 3739 40 logCategory = 'icalbouncer' 41 events = [] 42 maxKeyCardDuration = timedelta(days=1) 43 466848 self.props = self.args['properties'] 49 self.iCalScheduler = None 50 self.subscriptionToken = None 51 self.check_properties(component) 52 self.setup(component)5355 56 def missingModule(moduleName): 57 m = messages.Error(T_(N_( 58 "To use the iCalendar bouncer you need to have " 59 "the '%s' module installed.\n"), moduleName), 60 mid='error-python-%s' % moduleName) 61 documentation.messageAddPythonInstall(m, moduleName) 62 component.addMessage(m)63 64 if not eventcalendar.HAS_ICALENDAR: 65 missingModule('icalendar') 66 if not eventcalendar.HAS_DATEUTIL: 67 missingModule('dateutil')70 self._icsfile = self.props['file'] 71 72 try: 73 handle = open(self._icsfile, 'r') 74 except IOError, e: 75 m = messages.Error(T_(N_( 76 "Failed to open iCalendar file '%s'. " 77 "Check permissions on that file."), self._icsfile), 78 mid='error-icalbouncer-file') 79 component.addMessage(m) 80 raise errors.ComponentSetupHandledError() 81 82 try: 83 self.iCalScheduler = scheduler.ICalScheduler(handle) 84 except (ValueError, IndexError, KeyError), e: 85 m = messages.Error(T_(N_( 86 "Error parsing ical file '%s'."), self._icsfile), 87 debug=log.getExceptionMessage(e), 88 mid="error-icalbouncer-file") 89 component.addMessage(m) 90 raise errors.ComponentSetupHandledError() 91 self.subscriptionToken = \ 92 self.iCalScheduler.subscribe(self._do_nothing, self._eventEnded)9395 self.debug('authenticating keycard') 96 97 # need to check if inside an event time 98 cal = self.iCalScheduler.getCalendar() 99 now = datetime.now(tz.UTC) 100 eventInstances = cal.getActiveEventInstances() 101 if not eventInstances: 102 keycard.state = keycards.REFUSED 103 self.info("failed in authentication, outside hours") 104 return None 105 last_end = now 106 while eventInstances: 107 # decorate-sort-undecorate to get the event ending last 108 instance = max([(ev.end, ev) for ev in eventInstances])[1] 109 duration = instance.end - now 110 111 if duration > self.maxKeyCardDuration: 112 duration = self.maxKeyCardDuration 113 break 114 if last_end == instance.end: 115 break 116 eventInstances = cal.getActiveEventInstances(instance.end) 117 last_end = instance.end 118 119 durationSecs = duration.days * 86400 + duration.seconds 120 keycard.duration = durationSecs 121 keycard.state = keycards.AUTHENTICATED 122 self.info("authenticated login, duration %d seconds", 123 durationSecs) 124 return keycard125127 # we might not have an iCalScheduler, if something went wrong 128 # during do_setup or do_check 129 if self.iCalScheduler: 130 self.iCalScheduler.cleanup() 131 if self.subscriptionToken: 132 self.iCalScheduler.unsubscribe(self.subscriptionToken) 133 self.subscriptionToken = None134136 self.debug("_eventEnded") 137 if not event.start < datetime.now(tz.UTC) < event.end: 138 return 139 cal = self.iCalScheduler.getCalendar() 140 eventInstances = cal.getActiveEventInstances() 141 if not eventInstances: 142 self.debug("We're now outside hours, revoking all keycards") 143 self._expire_all_keycards()144 147 150
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 on Tue Aug 13 06:17:34 2013 | http://epydoc.sourceforge.net |