Lines 299-304
class UMCP_Dispatcher(object):
|
Link Here
|
---|
|
299 |
except KeyError: |
299 |
except KeyError: |
300 |
CORE.info('Session %r not found' % (sessionid,)) |
300 |
CORE.info('Session %r not found' % (sessionid,)) |
301 |
|
301 |
|
|
|
302 |
@classmethod |
303 |
def clean_sessions(cls): |
304 |
now = time.time() |
305 |
for sessionid, user in list(Ressource.sessions.items()): |
306 |
session = UMCP_Dispatcher.sessions.get(sessionid) |
307 |
if (not session or not session._requestid2response_queue) and user.timed_out(now): |
308 |
CORE.info('session %r timed out' % (sessionid,)) |
309 |
Ressource.sessions.pop(user.sessionid, None) |
310 |
return True # execute again! |
311 |
|
302 |
|
312 |
|
303 |
class UploadManager(dict): |
313 |
class UploadManager(dict): |
304 |
|
314 |
|
|
357 |
self.username = username |
367 |
self.username = username |
358 |
self.password = password |
368 |
self.password = password |
359 |
self.saml = saml |
369 |
self.saml = saml |
360 |
self._time_remaining = _session_timeout |
|
|
361 |
self.reset_timeout() |
370 |
self.reset_timeout() |
362 |
self.data = data or {} |
371 |
self.data = data or {} |
363 |
|
372 |
|
364 |
def reset_timeout(self): |
373 |
def reset_timeout(self): |
365 |
self._time_remaining = self.session_validity |
374 |
self._timeout = time.time() + _session_timeout |
366 |
|
375 |
|
367 |
@property |
376 |
def timed_out(self, now): |
368 |
def session_validity(self): |
377 |
return self.session_end_time < now |
369 |
if self.saml is not None: |
|
|
370 |
return self.time_remaining |
371 |
return _session_timeout |
372 |
|
378 |
|
373 |
@property |
379 |
@property |
374 |
def time_remaining(self): |
380 |
def session_end_time(self): |
375 |
remaining = [] |
381 |
if self.is_saml_user() and self.saml.response.not_on_or_after: |
376 |
if self.saml is not None: |
382 |
return self.saml.response.not_on_or_after |
377 |
remaining.append(self.saml.time_remaining) |
383 |
return self._timeout |
378 |
remaining.append(self._time_remaining) |
|
|
379 |
try: |
380 |
return min(remaining) |
381 |
except ValueError: # no SAML, no client |
382 |
return 0 |
383 |
|
384 |
|
384 |
def is_saml_user(self): |
385 |
def is_saml_user(self): |
385 |
# self.saml indicates that it was originally a |
386 |
# self.saml indicates that it was originally a |
|
400 |
else: |
401 |
else: |
401 |
return None |
402 |
return None |
402 |
|
403 |
|
403 |
def timed_out(self): |
|
|
404 |
return self.saml.timed_out() |
405 |
|
406 |
def __repr__(self): |
404 |
def __repr__(self): |
407 |
return '<User(%s, %s, %s)>' % (self.username, self.sessionid, self.saml is not None) |
405 |
return '<User(%s, %s, %s)>' % (self.username, self.sessionid, self.saml is not None) |
408 |
|
406 |
|
Lines 415-431
class SAMLUser(object):
|
Link Here
|
---|
|
415 |
self.data = response.ava |
413 |
self.data = response.ava |
416 |
self.username = u''.join(self.data['uid']) |
414 |
self.username = u''.join(self.data['uid']) |
417 |
|
415 |
|
418 |
@property |
|
|
419 |
def time_remaining(self): |
420 |
if self.response.not_on_or_after == 0: |
421 |
return 0 |
422 |
return int(self.response.not_on_or_after - time.time()) |
423 |
|
424 |
def timed_out(self): |
425 |
if self.response.not_on_or_after == 0: |
426 |
return False |
427 |
return self.time_remaining < 0 |
428 |
|
429 |
|
416 |
|
430 |
traceback_pattern = re.compile(r'(Traceback.*most recent call|File.*line.*in.*\d)') |
417 |
traceback_pattern = re.compile(r'(Traceback.*most recent call|File.*line.*in.*\d)') |
431 |
|
418 |
|
Lines 654-660
class Ressource(object):
|
Link Here
|
---|
|
654 |
|
641 |
|
655 |
def check_saml_session_validity(self): |
642 |
def check_saml_session_validity(self): |
656 |
user = self.get_user() |
643 |
user = self.get_user() |
657 |
if user and user.saml is not None and user.time_remaining < 1: |
644 |
if user and user.saml is not None and user.timed_out(time.time()): |
658 |
raise UMC_HTTPError(UNAUTHORIZED) |
645 |
raise UMC_HTTPError(UNAUTHORIZED) |
659 |
|
646 |
|
660 |
def set_cookies(self, *cookies, **kwargs): |
647 |
def set_cookies(self, *cookies, **kwargs): |
Lines 681-688
class Ressource(object):
|
Link Here
|
---|
|
681 |
olduser = self.get_user() |
668 |
olduser = self.get_user() |
682 |
|
669 |
|
683 |
user = User(sessionid, username, password, saml or olduser and olduser.saml, kwargs) |
670 |
user = User(sessionid, username, password, saml or olduser and olduser.saml, kwargs) |
684 |
self._session_timeout_timer(user) |
|
|
685 |
|
686 |
self.sessions[sessionid] = user |
671 |
self.sessions[sessionid] = user |
687 |
self.set_cookies(('UMCSessionId', sessionid), ('UMCUsername', username)) |
672 |
self.set_cookies(('UMCSessionId', sessionid), ('UMCUsername', username)) |
688 |
return user |
673 |
return user |
Lines 699-726
class Ressource(object):
|
Link Here
|
---|
|
699 |
if not value or value not in self.sessions: |
684 |
if not value or value not in self.sessions: |
700 |
return |
685 |
return |
701 |
user = self.sessions[value] |
686 |
user = self.sessions[value] |
702 |
if user.time_remaining <= 0: |
687 |
if user.timed_out(time.time()): |
703 |
return |
688 |
return |
704 |
return user |
689 |
return user |
705 |
|
690 |
|
706 |
def _session_timeout_timer(self, user): |
|
|
707 |
"""In order to avoid problems when the system time is changed (e.g., |
708 |
via rdate), we register a timer event that counts down the session |
709 |
timeout second-wise.""" |
710 |
|
711 |
# count down the remaining time |
712 |
user._time_remaining -= 1 |
713 |
|
714 |
session = UMCP_Dispatcher.sessions.get(user.sessionid) |
715 |
if user._time_remaining <= 0 and (not session or not session._requestid2response_queue): |
716 |
self._log('info', 'session timed out') |
717 |
self.sessions.pop(user.sessionid, None) |
718 |
return |
719 |
|
720 |
# count down the timer second-wise (in order to avoid problems when |
721 |
# changing the system time, e.g. via rdate) |
722 |
notifier.timer_add(1000, lambda: self._session_timeout_timer(user)) |
723 |
|
724 |
|
691 |
|
725 |
class CPgeneric(Ressource): |
692 |
class CPgeneric(Ressource): |
726 |
|
693 |
|
Lines 884-891
class CPGet(CPgeneric):
|
Link Here
|
---|
|
884 |
raise UMC_HTTPError(UNAUTHORIZED) |
851 |
raise UMC_HTTPError(UNAUTHORIZED) |
885 |
info['username'] = user.username |
852 |
info['username'] = user.username |
886 |
info['auth_type'] = user.saml and 'SAML' |
853 |
info['auth_type'] = user.saml and 'SAML' |
887 |
info['remaining'] = user.time_remaining |
854 |
info['remaining'] = user.session_end_time - time.time() |
888 |
info['validity'] = user.session_validity |
|
|
889 |
return json.dumps({"status": 200, "result": info, "message": ""}).encode('ASCII') |
855 |
return json.dumps({"status": 200, "result": info, "message": ""}).encode('ASCII') |
890 |
|
856 |
|
891 |
@cherrypy.expose |
857 |
@cherrypy.expose |
Lines 1017-1023
class CPAuth(CPgeneric):
|
Link Here
|
---|
|
1017 |
CORE.info('CPAuth/auth/sso: got new auth request (%s:%s <=> %s)' % (get_ip_address(), remote.port, remote.name)) |
983 |
CORE.info('CPAuth/auth/sso: got new auth request (%s:%s <=> %s)' % (get_ip_address(), remote.port, remote.name)) |
1018 |
|
984 |
|
1019 |
user = self.get_user() |
985 |
user = self.get_user() |
1020 |
if not user or not user.saml or user.timed_out(): |
986 |
if not user or not user.saml or user.timed_out(time.time()): |
1021 |
# redirect user to login page in case he's not authenticated or his session timed out |
987 |
# redirect user to login page in case he's not authenticated or his session timed out |
1022 |
raise HTTPRedirect('/univention/saml/') |
988 |
raise HTTPRedirect('/univention/saml/') |
1023 |
|
989 |
|
Lines 1619-1624
class UMC_HTTP_Daemon(DaemonRunner):
|
Link Here
|
---|
|
1619 |
notifier.init(notifier.GENERIC) |
1585 |
notifier.init(notifier.GENERIC) |
1620 |
notifier.dispatch.MIN_TIMER = get_int('umc/http/dispatch-interval', notifier.dispatch.MIN_TIMER) |
1586 |
notifier.dispatch.MIN_TIMER = get_int('umc/http/dispatch-interval', notifier.dispatch.MIN_TIMER) |
1621 |
notifier.dispatcher_add(UMCP_Dispatcher.check_queue) |
1587 |
notifier.dispatcher_add(UMCP_Dispatcher.check_queue) |
|
|
1588 |
notifier.timer_add(1000, UMCP_Dispatcher.clean_sessions) |
1622 |
notifier.loop() |
1589 |
notifier.loop() |
1623 |
except (SystemExit, KeyboardInterrupt) as exc: |
1590 |
except (SystemExit, KeyboardInterrupt) as exc: |
1624 |
# stop the web server |
1591 |
# stop the web server |