def observer_changes(message): sys.stderr.write('observerChanges\n') if 'observer' not in session: socketio.emit('terminate', {}, namespace='/observer', room=request.sid) return sid = rr.get('da:interviewsession:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid'])) if sid is None: key = 'da:session:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) sys.stderr.write('observerChanges: sid is none.\n') if rr.get(key) is None: sys.stderr.write('observerChanges: session has gone away for good. Sending stopcontrolling.\n') socketio.emit('stopcontrolling', {'key': key}, namespace='/observer', room=request.sid) else: socketio.emit('noconnection', {'key': key}, namespace='/observer', room=request.sid) else: sid = sid.decode() sys.stderr.write('observerChanges: sid exists at ' + time.strftime("%Y-%m-%d %H:%M:%S") + '\n') rr.publish(sid, json.dumps(dict(messagetype='controllerchanges', sid=request.sid, clicked=message.get('clicked', None), parameters=message['parameters']))) # sid=request.sid, yaml_filename=str(message['i']), uid=str(message['uid']), user_id=str(message['userid']) self_key = 'da:control:sid:' + str(request.sid) key = 'da:control:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) #sys.stderr.write('Controlling ' + key + '\n') pipe = rr.pipeline() pipe.set(self_key, key) pipe.expire(key, 12) pipe.set(key, request.sid) pipe.expire(key, 12) pipe.execute()
def start_control(message): if 'observer' not in session: socketio.emit('terminate', {}, namespace='/observer', room=request.sid) return self_key = 'da:control:sid:' + str(request.sid) key = 'da:control:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) existing_sid = rr.get(key) if existing_sid is None or existing_sid.decode() == request.sid: #sys.stderr.write('Controlling ' + key + '\n') pipe = rr.pipeline() pipe.set(self_key, key) pipe.expire(self_key, 12) pipe.set(key, request.sid) pipe.expire(key, 12) pipe.execute() int_key = 'da:interviewsession:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) int_sid = rr.get(int_key) if int_sid is not None: int_sid = int_sid.decode() rr.publish(int_sid, json.dumps(dict(messagetype='controllerstart'))) else: sys.stderr.write('That key ' + key + ' is already taken\n') key = 'da:session:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) #rr.publish('da:monitor', json.dumps(dict(messagetype='abortcontroller', key=key))) socketio.emit('abortcontrolling', {'key': key}, namespace='/observer', room=request.sid)
def validate(self): from docassemble.webapp.daredis import r from docassemble.base.logger import logmessage from flask import request, abort result = True key = 'da:failedlogin:ip:' + str(request.remote_addr) failed_attempts = r.get(key) if failed_attempts is not None and int(failed_attempts) > daconfig['attempt limit']: abort(404) verification_key = 'da:phonelogin:'******':code' verification_code = r.get(verification_key) #r.delete(verification_key) supplied_verification_code = re.sub(r'[^0-9]', '', self.verification_code.data) logmessage("Supplied code is " + str(supplied_verification_code)) if verification_code is None: logmessage("Verification code with " + str(verification_key) + " is None") result = False elif verification_code.decode() != supplied_verification_code: logmessage("Verification code with " + str(verification_key) + " which is " + str(verification_code.decode()) + " does not match supplied code, which is " + str(self.verification_code.data)) result = False else: logmessage("Code matched") if result is False: logmessage("Problem with form") r.incr(key) r.expire(key, 86400) elif failed_attempts is not None: r.delete(key) return result
def validate(self): #import redis #import docassemble.base.util from docassemble.webapp.daredis import r from docassemble.base.logger import logmessage from flask import request, abort result = True #r = redis.StrictRedis(host=docassemble.base.util.redis_server, db=0) key = 'da:failedlogin:ip:' + str(request.remote_addr) failed_attempts = r.get(key) if failed_attempts is not None and int(failed_attempts) > daconfig['attempt limit']: abort(404) verification_key = 'da:phonelogin:'******':code' verification_code = r.get(verification_key) #r.delete(verification_key) supplied_verification_code = re.sub(r'[^0-9]', '', self.verification_code.data) logmessage("Supplied code is " + str(supplied_verification_code)) if verification_code is None: logmessage("Verification code with " + str(verification_key) + " is None") result = False elif verification_code != supplied_verification_code: logmessage("Verification code with " + str(verification_key) + " which is " + str(verification_code) + " does not match supplied code, which is " + str(self.verification_code.data)) result = False else: logmessage("Code matched") if result is False: logmessage("Problem with form") r.incr(key) r.expire(key, 86400) elif failed_attempts is not None: r.delete(key) return result
def validate(self): result = True key = 'da:failedlogin:ip:' + str(get_requester_ip(request)) failed_attempts = r.get(key) if failed_attempts is not None and int( failed_attempts) > daconfig['attempt limit']: abort(404) verification_key = 'da:phonelogin:'******':code' verification_code = r.get(verification_key) #r.delete(verification_key) supplied_verification_code = re.sub(r'[^0-9]', '', self.verification_code.data) logmessage("Supplied code is " + str(supplied_verification_code)) if verification_code is None: logmessage("Verification code with " + str(verification_key) + " is None") result = False elif verification_code.decode() != supplied_verification_code: logmessage("Verification code with " + str(verification_key) + " which is " + str(verification_code.decode()) + " does not match supplied code, which is " + str(self.verification_code.data)) result = False else: logmessage("Code matched") if result is False: logmessage("Problem with form") r.incr(key) r.expire(key, 86400) elif failed_attempts is not None: r.delete(key) return result
def observer_changes(message): sys.stderr.write('observerChanges\n') if 'observer' not in session: socketio.emit('terminate', {}, namespace='/observer', room=request.sid) return sid = rr.get('da:interviewsession:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid'])) if sid is None: key = 'da:session:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) sys.stderr.write('observerChanges: sid is none.\n') if rr.get(key) is None: sys.stderr.write('observerChanges: session has gone away for good. Sending stopcontrolling.\n') socketio.emit('stopcontrolling', {'key': key}, namespace='/observer', room=request.sid) else: socketio.emit('noconnection', {'key': key}, namespace='/observer', room=request.sid) else: sys.stderr.write('observerChanges: sid exists at ' + time.strftime("%Y-%m-%d %H:%M:%S") + '\n') rr.publish(sid, json.dumps(dict(messagetype='controllerchanges', sid=request.sid, clicked=message.get('clicked', None), parameters=message['parameters']))) # sid=request.sid, yaml_filename=str(message['i']), uid=str(message['uid']), user_id=str(message['userid']) self_key = 'da:control:sid:' + str(request.sid) key = 'da:control:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) #sys.stderr.write('Controlling ' + key + '\n') pipe = rr.pipeline() pipe.set(self_key, key) pipe.expire(key, 12) pipe.set(key, request.sid) pipe.expire(key, 12) pipe.execute()
def on_observer_disconnect(): sys.stderr.write('Client disconnected from observer\n') self_key = 'da:control:sid:' + str(request.sid) int_key = rr.get(self_key) if int_key is not None: rr.delete(int_key) other_sid = rr.get(re.sub(r'^da:control:uid:', 'da:interviewsession:uid:', int_key)) else: other_sid = None rr.delete(self_key) if other_sid is not None: sys.stderr.write("Calling controllerexit 2"); rr.publish(other_sid, json.dumps(dict(messagetype='controllerexit', sid=request.sid))) rr.publish(request.sid, json.dumps(dict(message='KILL', sid=request.sid)))
def on_observer_disconnect(): sys.stderr.write('Client disconnected from observer\n') self_key = 'da:control:sid:' + str(request.sid) int_key = rr.get(self_key) if int_key is not None: int_key = int_key.decode() rr.delete(int_key) other_sid = rr.get(re.sub(r'^da:control:uid:', 'da:interviewsession:uid:', int_key)) else: other_sid = None rr.delete(self_key) if other_sid is not None: other_sid = other_sid.decode() sys.stderr.write("Calling controllerexit 2"); rr.publish(other_sid, json.dumps(dict(messagetype='controllerexit', sid=request.sid))) rr.publish(request.sid, json.dumps(dict(message='KILL', sid=request.sid)))
def monitor_chat_message(data): if 'monitor' not in session: socketio.emit('terminate', {}, namespace='/monitor', room=request.sid) return key = data.get('key', None) #sys.stderr.write("Key is " + str(key) + "\n") if key is None: sys.stderr.write("No key provided\n") return m = re.match(r'da:session:uid:(.*):i:(.*):userid:(.*)', key) if not m: sys.stderr.write("Invalid key provided\n") return session_id = m.group(1) yaml_filename = m.group(2) chat_user_id = m.group(3) key = 'da:interviewsession:uid:' + str(session_id) + ':i:' + str(yaml_filename) + ':userid:' + str(chat_user_id) sid = rr.get(key) if sid is None: sys.stderr.write("No sid for monitor chat message with key " + str(key) + "\n") return sid = sid.decode() secret = secrets.get(sid, None) if secret is not None: secret = str(secret) #obtain_lock(session_id, yaml_filename) try: steps, user_dict, encrypted = fetch_user_dict(session_id, yaml_filename, secret=secret) except Exception as err: #release_lock(session_id, yaml_filename) sys.stderr.write("monitor_chat_message: could not get dictionary: " + text_type(err) + "\n") return #release_lock(session_id, yaml_filename) nowtime = datetime.datetime.utcnow() if encrypted: message = encrypt_phrase(data['data'], secret) else: message = pack_phrase(data['data']) user_id = session.get('user_id', None) if user_id is not None: user_id = int(user_id) person = UserModel.query.filter_by(id=user_id).first() chat_mode = user_dict['_internal']['livehelp']['mode'] m = re.match('t([0-9]+)', chat_user_id) if m: temp_owner_id = m.group(1) owner_id = None else: temp_owner_id = None owner_id = chat_user_id if chat_mode in ['peer', 'peerhelp']: open_to_peer = True else: open_to_peer = False record = ChatLog(filename=yaml_filename, key=session_id, message=message, encrypted=encrypted, modtime=nowtime, user_id=user_id, temp_owner_id=temp_owner_id, owner_id=owner_id, open_to_peer=open_to_peer) db.session.add(record) db.session.commit() modtime = nice_utc_date(nowtime) rr.publish(sid, json.dumps(dict(origin='client', messagetype='chat', sid=request.sid, yaml_filename=yaml_filename, uid=session_id, user_id=chat_user_id, message=dict(id=record.id, user_id=record.user_id, first_name=person.first_name, last_name=person.last_name, email=person.email, modtime=modtime, message=data['data'], roles=[role.name for role in person.roles], mode=chat_mode))))
def monitor_chat_message(data): if 'monitor' not in session: socketio.emit('terminate', {}, namespace='/monitor', room=request.sid) return key = data.get('key', None) #sys.stderr.write("Key is " + str(key) + "\n") if key is None: sys.stderr.write("No key provided\n") return m = re.match(r'da:session:uid:(.*):i:(.*):userid:(.*)', key) if not m: sys.stderr.write("Invalid key provided\n") return session_id = m.group(1) yaml_filename = m.group(2) chat_user_id = m.group(3) key = 'da:interviewsession:uid:' + str(session_id) + ':i:' + str(yaml_filename) + ':userid:' + str(chat_user_id) sid = rr.get(key) if sid is None: sys.stderr.write("No sid for monitor chat message with key " + str(key) + "\n") return secret = secrets.get(sid, None) if secret is not None: secret = str(secret) #obtain_lock(session_id, yaml_filename) try: steps, user_dict, encrypted = fetch_user_dict(session_id, yaml_filename, secret=secret) except Exception as err: #release_lock(session_id, yaml_filename) sys.stderr.write("monitor_chat_message: could not get dictionary: " + unicode(err) + "\n") return #release_lock(session_id, yaml_filename) nowtime = datetime.datetime.utcnow() if encrypted: message = encrypt_phrase(data['data'], secret) else: message = pack_phrase(data['data']) user_id = session.get('user_id', None) if user_id is not None: user_id = int(user_id) person = UserModel.query.filter_by(id=user_id).first() chat_mode = user_dict['_internal']['livehelp']['mode'] m = re.match('t([0-9]+)', chat_user_id) if m: temp_owner_id = m.group(1) owner_id = None else: temp_owner_id = None owner_id = chat_user_id if chat_mode in ['peer', 'peerhelp']: open_to_peer = True else: open_to_peer = False record = ChatLog(filename=yaml_filename, key=session_id, message=message, encrypted=encrypted, modtime=nowtime, user_id=user_id, temp_owner_id=temp_owner_id, owner_id=owner_id, open_to_peer=open_to_peer) db.session.add(record) db.session.commit() modtime = nice_utc_date(nowtime) rr.publish(sid, json.dumps(dict(origin='client', messagetype='chat', sid=request.sid, yaml_filename=yaml_filename, uid=session_id, user_id=chat_user_id, message=dict(id=record.id, user_id=record.user_id, first_name=person.first_name, last_name=person.last_name, email=person.email, modtime=modtime, message=data['data'], roles=[role.name for role in person.roles], mode=chat_mode))))
def stop_control(message): if 'observer' not in session: socketio.emit('terminate', {}, namespace='/observer', room=request.sid) return self_key = 'da:control:sid:' + str(request.sid) key = 'da:control:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) sys.stderr.write('Stop controlling ' + key + '\n') existing_sid = rr.get(key) pipe = rr.pipeline() pipe.delete(self_key) if existing_sid is not None and existing_sid == request.sid: pipe.delete(key) pipe.execute() sid = rr.get('da:interviewsession:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid'])) if sid is not None: sys.stderr.write("Calling controllerexit 1"); rr.publish(sid, json.dumps(dict(messagetype='controllerexit', sid=request.sid))) else: pipe.execute()
def validate(self): #import redis from docassemble.webapp.daredis import r #import docassemble.base.util from flask import request, abort #r = redis.StrictRedis(host=docassemble.base.util.redis_server, db=0) key = 'da:failedlogin:ip:' + str(request.remote_addr) failed_attempts = r.get(key) if failed_attempts is not None and int( failed_attempts) > daconfig['attempt limit']: abort(404) if daconfig['ldap login'].get('enable', False): ldap_server = daconfig['ldap login'].get('server', 'localhost').strip() username = self.email.data password = self.password.data connect = ldap.open(ldap_server) try: connect.simple_bind_s(username, password) connect.unbind_s() from flask import current_app user_manager = current_app.user_manager user, user_email = user_manager.find_user_by_email( self.email.data) if not user: from docassemble.base.generate_key import random_alphanumeric from docassemble.webapp.db_object import db from docassemble.webapp.users.models import UserModel, Role while True: new_social = 'ldap$' + random_alphanumeric(32) existing_user = UserModel.query.filter_by( social_id=new_social).first() if existing_user: continue break user = UserModel(social_id=new_social, email=self.email.data, nickname='', active=True) user_role = Role.query.filter_by(name='user').first() user.roles.append(user_role) db.session.add(user) db.session.commit() result = True except ldap.LDAPError: connect.unbind_s() result = super(MySignInForm, self).validate() else: result = super(MySignInForm, self).validate() if result is False: r.incr(key) r.expire(key, daconfig['ban period']) elif failed_attempts is not None: r.delete(key) return result
def stop_control(message): if 'observer' not in session: socketio.emit('terminate', {}, namespace='/observer', room=request.sid) return self_key = 'da:control:sid:' + str(request.sid) key = 'da:control:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) sys.stderr.write('Stop controlling ' + key + '\n') existing_sid = rr.get(key) pipe = rr.pipeline() pipe.delete(self_key) if existing_sid is not None and existing_sid.decode() == request.sid: pipe.delete(key) pipe.execute() sid = rr.get('da:interviewsession:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid'])) if sid is not None: sid = sid.decode() sys.stderr.write("Calling controllerexit 1"); rr.publish(sid, json.dumps(dict(messagetype='controllerexit', sid=request.sid))) else: pipe.execute()
def monitor_unblock(data): if 'monitor' not in session: socketio.emit('terminate', {}, namespace='/monitor', room=request.sid) return key = data.get('key', None) if key is None: sys.stderr.write("No key provided\n") return sys.stderr.write("Unblocking\n") rr.delete(re.sub(r'^da:session:', 'da:block:', key)) sid = rr.get(re.sub(r'^da:session:', 'da:interviewsession:', key)) if sid is not None: rr.publish(sid, json.dumps(dict(messagetype='chatpartner', sid=request.sid))) socketio.emit('unblock', {'key': key}, namespace='/monitor', room=request.sid)
def on_monitor_disconnect(): user_id = session.get('user_id', None) sys.stderr.write('Client disconnected from monitor\n') rr.delete('da:monitor:' + str(request.sid)) rr.expire('da:monitor:available:' + str(user_id), 5) for key in rr.keys('da:monitor:role:*:userid:' + str(user_id)): rr.expire(key, 5) for key in rr.keys('da:phonecode:monitor:' + str(user_id) + ':uid:*'): the_code = rr.get(key) if the_code is not None: rr.expire('da:callforward:' + str(the_code), 5) rr.expire(key, 5) rr.expire('da:monitor:chatpartners:' + str(user_id), 5) rr.publish(request.sid, json.dumps(dict(message='KILL', sid=request.sid)))
def monitor_chat_log(data): if 'monitor' not in session: socketio.emit('terminate', {}, namespace='/monitor', room=request.sid) return key = data.get('key', None) #sys.stderr.write("Key is " + str(key) + "\n") if key is None: sys.stderr.write("No key provided\n") return m = re.match(r'da:session:uid:(.*):i:(.*):userid:(.*)', key) if not m: sys.stderr.write("Invalid key provided\n") return session_id = m.group(1) yaml_filename = m.group(2) chat_user_id = m.group(3) key = 'da:interviewsession:uid:' + str(session_id) + ':i:' + str(yaml_filename) + ':userid:' + str(chat_user_id) sid = rr.get(key) if sid is None: sys.stderr.write("No sid for monitor chat message with key " + str(key) + "\n") return sid = sid.decode() secret = secrets.get(sid, None) if secret is not None: secret = str(secret) #obtain_lock(session_id, yaml_filename) try: steps, user_dict, encrypted = fetch_user_dict(session_id, yaml_filename, secret=secret) except Exception as err: #release_lock(session_id, yaml_filename) sys.stderr.write("monitor_chat_log: could not get dictionary: " + text_type(err) + "\n") return #release_lock(session_id, yaml_filename) chat_mode = user_dict['_internal']['livehelp']['mode'] m = re.match('t([0-9]+)', chat_user_id) if m: temp_user_id = m.group(1) user_id = None else: temp_user_id = None user_id = chat_user_id self_user_id = session.get('user_id', None) if user_id is not None: user_id = int(user_id) if temp_user_id is not None: temp_user_id = int(temp_user_id) if self_user_id is not None: self_user_id = int(self_user_id) messages = get_chat_log(chat_mode, yaml_filename, session_id, user_id, temp_user_id, secret, self_user_id, None) socketio.emit('chat_log', {'uid': session_id, 'i': yaml_filename, 'userid': chat_user_id, 'mode': chat_mode, 'data': messages}, namespace='/monitor', room=request.sid)
def monitor_chat_log(data): if 'monitor' not in session: socketio.emit('terminate', {}, namespace='/monitor', room=request.sid) return key = data.get('key', None) #sys.stderr.write("Key is " + str(key) + "\n") if key is None: sys.stderr.write("No key provided\n") return m = re.match(r'da:session:uid:(.*):i:(.*):userid:(.*)', key) if not m: sys.stderr.write("Invalid key provided\n") return session_id = m.group(1) yaml_filename = m.group(2) chat_user_id = m.group(3) key = 'da:interviewsession:uid:' + str(session_id) + ':i:' + str(yaml_filename) + ':userid:' + str(chat_user_id) sid = rr.get(key) if sid is None: sys.stderr.write("No sid for monitor chat message with key " + str(key) + "\n") return secret = secrets.get(sid, None) if secret is not None: secret = str(secret) #obtain_lock(session_id, yaml_filename) try: steps, user_dict, encrypted = fetch_user_dict(session_id, yaml_filename, secret=secret) except Exception as err: #release_lock(session_id, yaml_filename) sys.stderr.write("monitor_chat_log: could not get dictionary: " + unicode(err) + "\n") return #release_lock(session_id, yaml_filename) chat_mode = user_dict['_internal']['livehelp']['mode'] m = re.match('t([0-9]+)', chat_user_id) if m: temp_user_id = m.group(1) user_id = None else: temp_user_id = None user_id = chat_user_id self_user_id = session.get('user_id', None) if user_id is not None: user_id = int(user_id) if temp_user_id is not None: temp_user_id = int(temp_user_id) if self_user_id is not None: self_user_id = int(self_user_id) messages = get_chat_log(chat_mode, yaml_filename, session_id, user_id, temp_user_id, secret, self_user_id, None) socketio.emit('chat_log', {'uid': session_id, 'i': yaml_filename, 'userid': chat_user_id, 'mode': chat_mode, 'data': messages}, namespace='/monitor', room=request.sid)
def start_control(message): if 'observer' not in session: socketio.emit('terminate', {}, namespace='/observer', room=request.sid) return self_key = 'da:control:sid:' + str(request.sid) key = 'da:control:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) existing_sid = rr.get(key) if existing_sid is None or existing_sid == request.sid: #sys.stderr.write('Controlling ' + key + '\n') pipe = rr.pipeline() pipe.set(self_key, key) pipe.expire(self_key, 12) pipe.set(key, request.sid) pipe.expire(key, 12) pipe.execute() int_key = 'da:interviewsession:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) int_sid = rr.get(int_key) if int_sid is not None: rr.publish(int_sid, json.dumps(dict(messagetype='controllerstart'))) else: sys.stderr.write('That key ' + key + ' is already taken\n') key = 'da:session:uid:' + str(message['uid']) + ':i:' + str(message['i']) + ':userid:' + str(message['userid']) #rr.publish('da:monitor', json.dumps(dict(messagetype='abortcontroller', key=key))) socketio.emit('abortcontrolling', {'key': key}, namespace='/observer', room=request.sid)
def monitor_unblock(data): if 'monitor' not in session: socketio.emit('terminate', {}, namespace='/monitor', room=request.sid) return key = data.get('key', None) if key is None: sys.stderr.write("No key provided\n") return sys.stderr.write("Unblocking\n") rr.delete(re.sub(r'^da:session:', 'da:block:', key)) sid = rr.get(re.sub(r'^da:session:', 'da:interviewsession:', key)) if sid is not None: sid = sid.decode() rr.publish(sid, json.dumps(dict(messagetype='chatpartner', sid=request.sid))) socketio.emit('unblock', {'key': key}, namespace='/monitor', room=request.sid)
def monitor_block(data): if 'monitor' not in session: socketio.emit('terminate', {}, namespace='/monitor', room=request.sid) return key = data.get('key', None) if key is None: sys.stderr.write("No key provided\n") return rr.set(re.sub(r'^da:session:', 'da:block:', key), 1) sid = rr.get(re.sub(r'^da:session:', 'da:interviewsession:', key)) if sid is not None: rr.publish(sid, json.dumps(dict(messagetype='block', sid=request.sid))) sys.stderr.write("Blocking\n") else: sys.stderr.write("Could not block because could not get sid\n") socketio.emit('block', {'key': key}, namespace='/monitor', room=request.sid)
def on_monitor_disconnect(): user_id = session.get('user_id', None) sys.stderr.write('Client disconnected from monitor\n') rr.delete('da:monitor:' + str(request.sid)) rr.expire('da:monitor:available:' + str(user_id), 5) for key in rr.keys('da:monitor:role:*:userid:' + str(user_id)): key = key.decode() rr.expire(key, 5) for key in rr.keys('da:phonecode:monitor:' + str(user_id) + ':uid:*'): key = key.decode() the_code = rr.get(key) if the_code is not None: the_code = the_code.decode() rr.expire('da:callforward:' + the_code, 5) rr.expire(key, 5) rr.expire('da:monitor:chatpartners:' + str(user_id), 5) rr.publish(request.sid, json.dumps(dict(message='KILL', sid=request.sid)))
def monitor_block(data): if 'monitor' not in session: socketio.emit('terminate', {}, namespace='/monitor', room=request.sid) return key = data.get('key', None) if key is None: sys.stderr.write("No key provided\n") return rr.set(re.sub(r'^da:session:', 'da:block:', key), 1) sid = rr.get(re.sub(r'^da:session:', 'da:interviewsession:', key)) if sid is not None: sid = sid.decode() rr.publish(sid, json.dumps(dict(messagetype='block', sid=request.sid))) sys.stderr.write("Blocking\n") else: sys.stderr.write("Could not block because could not get sid\n") socketio.emit('block', {'key': key}, namespace='/monitor', room=request.sid)
def add_specific_api_key(name, api_key, user_id, secret_key): info = dict(name=name, method='none', constraints=[]) if not (isinstance(api_key, str) and len(api_key) == 32): return False info['last_four'] = api_key[-4:] new_api_key = encrypt_api_key(api_key, secret_key) if len(r.keys('da:apikey:userid:*:key:' + new_api_key + ':info')) > 0: return False for rkey in r.keys('da:apikey:userid:' + str(user_id) + ':key:*:info'): rkey = rkey.decode() try: info = json.loads(r.get(rkey).decode()) assert isinstance(info, dict) except: continue if info['name'] == name: return False r.set('da:apikey:userid:' + str(user_id) + ':key:' + new_api_key + ':info', json.dumps(info)) return True
def obtain_lock(user_code, filename): key = 'da:lock:' + user_code + ':' + filename found = False count = 4 while count > 0: record = rr.get(key) if record: sys.stderr.write("obtain_lock: waiting for " + key + "\n") time.sleep(1.0) else: found = False break found = True count -= 1 if found: sys.stderr.write("Request for " + key + " deadlocked\n") release_lock(user_code, filename) pipe = rr.pipeline() pipe.set(key, 1) pipe.expire(key, 4) pipe.execute()
def validate(self): from docassemble.webapp.daredis import r from flask import request, abort key = 'da:failedlogin:ip:' + str(request.remote_addr) failed_attempts = r.get(key) if failed_attempts is not None and int(failed_attempts) > daconfig['attempt limit']: abort(404) if daconfig['ldap login'].get('enable', False): ldap_server = daconfig['ldap login'].get('server', 'localhost').strip() username = self.email.data password = self.password.data connect = ldap.open(ldap_server) try: connect.simple_bind_s(username, password) connect.unbind_s() from flask import current_app user_manager = current_app.user_manager user, user_email = user_manager.find_user_by_email(self.email.data) if not user: from docassemble.base.generate_key import random_alphanumeric from docassemble.webapp.db_object import db from docassemble.webapp.users.models import UserModel, Role while True: new_social = 'ldap$' + random_alphanumeric(32) existing_user = UserModel.query.filter_by(social_id=new_social).first() if existing_user: continue break user = UserModel(social_id=new_social, email=self.email.data, nickname='', active=True) user_role = Role.query.filter_by(name='user').first() user.roles.append(user_role) db.session.add(user) db.session.commit() result = True except ldap.LDAPError: connect.unbind_s() result = super(MySignInForm, self).validate() else: from flask import current_app user_manager = current_app.user_manager user, user_email = user_manager.find_user_by_email(self.email.data) if user is None: return False if user and (user.password is None or (user.social_id is not None and not user.social_id.startswith('local$'))): self.email.errors = list(self.email.errors) if user.social_id.startswith('google$'): self.email.errors.append(word("You need to log in with Google.")) elif user.social_id.startswith('azure$'): self.email.errors.append(word("You need to log in with Azure.")) elif user.social_id.startswith('auth0$'): self.email.errors.append(word("You need to log in with Auth0.")) elif user.social_id.startswith('twitter$'): self.email.errors.append(word("You need to log in with Twitter.")) elif user.social_id.startswith('facebook$'): self.email.errors.append(word("You need to log in with Facebook.")) else: self.email.errors.append(word("You cannot log in this way.")) return False #sys.stderr.write("Trying super validate\n") result = super(MySignInForm, self).validate() #sys.stderr.write("Super validate response was " + repr(result) + "\n") if result is False: r.incr(key) r.expire(key, daconfig['ban period']) elif failed_attempts is not None: r.delete(key) return result
def validate(self): from docassemble.webapp.daredis import r from flask import request, abort key = 'da:failedlogin:ip:' + str(request.remote_addr) failed_attempts = r.get(key) if failed_attempts is not None and int( failed_attempts) > daconfig['attempt limit']: abort(404) if daconfig['ldap login'].get('enable', False): ldap_server = daconfig['ldap login'].get('server', 'localhost').strip() username = self.email.data password = self.password.data connect = ldap.open(ldap_server) try: connect.simple_bind_s(username, password) connect.unbind_s() from flask import current_app user_manager = current_app.user_manager user, user_email = user_manager.find_user_by_email( self.email.data) if not user: from docassemble.base.generate_key import random_alphanumeric from docassemble.webapp.db_object import db from docassemble.webapp.users.models import UserModel, Role while True: new_social = 'ldap$' + random_alphanumeric(32) existing_user = UserModel.query.filter_by( social_id=new_social).first() if existing_user: continue break user = UserModel(social_id=new_social, email=self.email.data, nickname='', active=True) user_role = Role.query.filter_by(name='user').first() user.roles.append(user_role) db.session.add(user) db.session.commit() result = True except ldap.LDAPError: connect.unbind_s() result = super(MySignInForm, self).validate() else: from flask import current_app user_manager = current_app.user_manager user, user_email = user_manager.find_user_by_email(self.email.data) if user is None: return False if user and (user.password is None or (user.social_id is not None and not user.social_id.startswith('local$'))): self.email.errors = list(self.email.errors) if user.social_id.startswith('google$'): self.email.errors.append( word("You need to log in with Google.")) elif user.social_id.startswith('azure$'): self.email.errors.append( word("You need to log in with Azure.")) elif user.social_id.startswith('auth0$'): self.email.errors.append( word("You need to log in with Auth0.")) elif user.social_id.startswith('twitter$'): self.email.errors.append( word("You need to log in with Twitter.")) elif user.social_id.startswith('facebook$'): self.email.errors.append( word("You need to log in with Facebook.")) else: self.email.errors.append( word("You cannot log in this way.")) return False #sys.stderr.write("Trying super validate\n") result = super(MySignInForm, self).validate() #sys.stderr.write("Super validate response was " + repr(result) + "\n") if result is False: r.incr(key) r.expire(key, daconfig['ban period']) elif failed_attempts is not None: r.delete(key) return result
def interview_connect(): session_id = session.get('uid', None) if session_id is not None: user_dict, is_encrypted = get_dict_encrypt() if is_encrypted: secret = request.cookies.get('secret', None) else: secret = None if secret is not None: secret = str(secret) if user_dict is None: sys.stderr.write("user_dict did not exist.\n") socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) return chat_info = user_dict['_internal']['livehelp'] if chat_info['availability'] == 'unavailable': sys.stderr.write("Socket started but chat is unavailable.\n") socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) return #sys.stderr.write('chat info is ' + str(chat_info) + "\n") if user_dict['_internal']['livehelp']['mode'] in ['peer', 'peerhelp']: peer_ok = True else: peer_ok = False yaml_filename = session.get('i', None) the_user_id = session.get('user_id', 't' + str(session.get('tempuser', None))) if request.sid not in threads: #sys.stderr.write('Starting thread for sid ' + str(request.sid) + "\n") threads[request.sid] = socketio.start_background_task(target=background_thread, sid=request.sid, user_id=session.get('user_id', None), temp_user_id=session.get('tempuser', None)) channel_up = wait_for_channel(rr, request.sid) if not channel_up: sys.stderr.write("Channel did not come up.\n") socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) return lkey = 'da:ready:uid:' + str(session_id) + ':i:' + str(yaml_filename) + ':userid:' + str(the_user_id) #sys.stderr.write("Searching: " + lkey + "\n") if rr.exists(lkey): lkey_exists = True else: lkey_exists = False if lkey_exists is False and peer_ok is False: sys.stderr.write("Key does not exist: " + lkey + ".\n") #socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) #return failed_to_find_partner = True found_help = False if lkey_exists: partner_keys = rr.lrange(lkey, 0, -1) #sys.stderr.write("partner_keys is: " + str(type(partner_keys)) + " " + str(partner_keys) + "\n") if partner_keys is None and not peer_ok: sys.stderr.write("No partner keys: " + lkey + ".\n") socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) return rr.delete(lkey) for pkey in partner_keys: pkey = pkey.decode() #sys.stderr.write("Considering: " + pkey + "\n") partner_sid = rr.get(pkey) if partner_sid is not None: partner_sid = partner_sid.decode() if re.match(r'^da:monitor:available:.*', pkey): is_help = True else: is_help = False if is_help and found_help: continue #sys.stderr.write("Trying to pub to " + str(partner_sid) + " from " + str(pkey) + "\n") listeners = rr.publish(partner_sid, json.dumps(dict(messagetype='chatready', uid=session_id, i=yaml_filename, userid=the_user_id, secret=secret, sid=request.sid))) #sys.stderr.write("Listeners: " + str(listeners) + "\n") if re.match(r'^da:interviewsession.*', pkey): rr.publish(request.sid, json.dumps(dict(messagetype='chatready', sid=partner_sid))) else: rr.publish(request.sid, json.dumps(dict(messagetype='chatpartner', sid=partner_sid))) if listeners > 0: if is_help: found_help = True failed_to_find_partner = False if failed_to_find_partner and peer_ok is False: sys.stderr.write("Unable to reach any potential chat partners.\n") #socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) #return key = 'da:interviewsession:uid:' + str(session_id) + ':i:' + str(yaml_filename) + ':userid:' + str(the_user_id) rr.set(key, request.sid)
def validate(self): key = 'da:failedlogin:ip:' + str(get_requester_ip(request)) failed_attempts = r.get(key) if failed_attempts is not None and int( failed_attempts) > daconfig['attempt limit']: abort(404) if daconfig['ldap login'].get('enable', False): ldap_server = daconfig['ldap login'].get('server', 'localhost').strip() username = self.email.data password = self.password.data connect = ldap.initialize('ldap://' + ldap_server) connect.set_option(ldap.OPT_REFERRALS, 0) try: connect.simple_bind_s(username, password) if connect.whoami_s() is not None: connect.unbind_s() user_manager = current_app.user_manager user, user_email = user_manager.find_user_by_email( self.email.data) if not user: while True: new_social = 'ldap$' + random_alphanumeric(32) existing_user = db.session.execute( select(UserModel).filter_by( social_id=new_social)).scalar() if existing_user: continue break user = UserModel(social_id=new_social, email=self.email.data, nickname='', active=True) user_role = db.session.execute( select(Role).filter_by(name='user')).scalar_one() user.roles.append(user_role) db.session.add(user) db.session.commit() result = True else: connect.unbind_s() result = super().validate() except (ldap.LDAPError, ldap.INVALID_CREDENTIALS): connect.unbind_s() result = super().validate() else: user_manager = current_app.user_manager user, user_email = user_manager.find_user_by_email(self.email.data) if user is None: if daconfig.get('confirm registration', False): self.email.errors = [] self.email.errors.append( word("Incorrect Email and/or Password")) self.password.errors = [] self.password.errors.append( word("Incorrect Email and/or Password")) else: self.email.errors = list(self.email.errors) self.email.errors.append(word("Account did not exist.")) return False if user and (user.password is None or (user.social_id is not None and not user.social_id.startswith('local$'))): self.email.errors = list(self.email.errors) if user.social_id.startswith('google$'): self.email.errors.append( word("You need to log in with Google.")) elif user.social_id.startswith('azure$'): self.email.errors.append( word("You need to log in with Azure.")) elif user.social_id.startswith('auth0$'): self.email.errors.append( word("You need to log in with Auth0.")) elif user.social_id.startswith('twitter$'): self.email.errors.append( word("You need to log in with Twitter.")) elif user.social_id.startswith('facebook$'): self.email.errors.append( word("You need to log in with Facebook.")) else: self.email.errors.append( word("You cannot log in this way.")) return False #sys.stderr.write("Trying super validate\n") result = super().validate() #sys.stderr.write("Super validate response was " + repr(result) + "\n") if result is False: r.incr(key) r.expire(key, daconfig['ban period']) elif failed_attempts is not None: r.delete(key) return result
def install_package(package): sys.stderr.write("install_package: " + package.name + "\n") if package.type == 'zip' and package.upload is None: return 0, '' sys.stderr.write('install_package: ' + package.name + "\n") from docassemble.base.config import daconfig PACKAGE_DIRECTORY = daconfig.get('packages', '/usr/share/docassemble/local') logfilecontents = '' #pip.utils.logging._log_state = threading.local() #pip.utils.logging._log_state.indentation = 0 pip_log = tempfile.NamedTemporaryFile() temp_dir = tempfile.mkdtemp() use_pip_cache = r.get('da:updatepackage:use_pip_cache') if use_pip_cache is None: disable_pip_cache = False elif int(use_pip_cache): disable_pip_cache = False else: disable_pip_cache = True if package.type == 'zip' and package.upload is not None: saved_file = SavedFile(package.upload, extension='zip', fix=True) # with zipfile.ZipFile(saved_file.path + '.zip', mode='r') as zf: # for zinfo in zf.infolist(): # parts = splitall(zinfo.filename) # if parts[-1] == 'setup.py': commands = ['pip', 'install'] if disable_pip_cache: commands.append('--no-cache-dir') commands.extend([ '--quiet', '--prefix=' + PACKAGE_DIRECTORY, '--src=' + temp_dir, '--log-file=' + pip_log.name, '--upgrade', saved_file.path + '.zip' ]) elif package.type == 'git' and package.giturl is not None: if package.gitbranch is not None: branchpart = '@' + str(package.gitbranch) else: branchpart = '' if package.gitsubdir is not None: commands = ['pip', 'install'] if disable_pip_cache: commands.append('--no-cache-dir') commands.extend([ '--quiet', '--prefix=' + PACKAGE_DIRECTORY, '--src=' + temp_dir, '--upgrade', '--log-file=' + pip_log.name, 'git+' + str(package.giturl) + '.git' + branchpart + '#egg=' + package.name + '&subdirectory=' + str(package.gitsubdir) ]) else: commands = ['pip', 'install'] if disable_pip_cache: commands.append('--no-cache-dir') commands.extend([ '--quiet', '--prefix=' + PACKAGE_DIRECTORY, '--src=' + temp_dir, '--upgrade', '--log-file=' + pip_log.name, 'git+' + str(package.giturl) + '.git' + branchpart + '#egg=' + package.name ]) elif package.type == 'pip': if package.limitation is None: limit = "" else: limit = str(package.limitation) commands = ['pip', 'install'] if disable_pip_cache: commands.append('--no-cache-dir') commands.extend([ '--quiet', '--prefix=' + PACKAGE_DIRECTORY, '--src=' + temp_dir, '--upgrade', '--log-file=' + pip_log.name, package.name + limit ]) else: sys.stderr.write("Wrong package type\n") return 1, 'Unable to recognize package type: ' + package.name sys.stderr.write("install_package: running " + " ".join(commands) + "\n") logfilecontents += " ".join(commands) + "\n" returnval = 1 try: subprocess.call(commands) returnval = 0 except subprocess.CalledProcessError as err: returnval = err.returncode sys.stderr.flush() sys.stdout.flush() time.sleep(4) with open(pip_log.name, 'rU') as x: logfilecontents += x.read().decode('utf8') pip_log.close() try: sys.stderr.write(logfilecontents + "\n") except: pass sys.stderr.flush() sys.stdout.flush() time.sleep(4) sys.stderr.write('returnval is: ' + str(returnval) + "\n") sys.stderr.write('install_package: done' + "\n") shutil.rmtree(temp_dir) return returnval, logfilecontents
def install_package(package): sys.stderr.write("install_package: " + package.name + "\n") if package.type == 'zip' and package.upload is None: return 0, '' sys.stderr.write('install_package: ' + package.name + "\n") from docassemble.base.config import daconfig PACKAGE_DIRECTORY = daconfig.get('packages', '/usr/share/docassemble/local') logfilecontents = '' #pip.utils.logging._log_state = threading.local() #pip.utils.logging._log_state.indentation = 0 pip_log = tempfile.NamedTemporaryFile() temp_dir = tempfile.mkdtemp() use_pip_cache = r.get('da:updatepackage:use_pip_cache') if use_pip_cache is None: disable_pip_cache = False elif int(use_pip_cache): disable_pip_cache = False else: disable_pip_cache = True if package.type == 'zip' and package.upload is not None: saved_file = SavedFile(package.upload, extension='zip', fix=True) # with zipfile.ZipFile(saved_file.path + '.zip', mode='r') as zf: # for zinfo in zf.infolist(): # parts = splitall(zinfo.filename) # if parts[-1] == 'setup.py': commands = ['pip', 'install'] if disable_pip_cache: commands.append('--no-cache-dir') commands.extend(['--quiet', '--prefix=' + PACKAGE_DIRECTORY, '--src=' + temp_dir, '--log-file=' + pip_log.name, '--upgrade', saved_file.path + '.zip']) elif package.type == 'git' and package.giturl is not None: if package.gitbranch is not None: branchpart = '@' + str(package.gitbranch) else: branchpart = '' if package.gitsubdir is not None: commands = ['pip', 'install'] if disable_pip_cache: commands.append('--no-cache-dir') commands.extend(['--quiet', '--prefix=' + PACKAGE_DIRECTORY, '--src=' + temp_dir, '--upgrade', '--log-file=' + pip_log.name, 'git+' + str(package.giturl) + '.git' + branchpart + '#egg=' + package.name + '&subdirectory=' + str(package.gitsubdir)]) else: commands = ['pip', 'install'] if disable_pip_cache: commands.append('--no-cache-dir') commands.extend(['--quiet', '--prefix=' + PACKAGE_DIRECTORY, '--src=' + temp_dir, '--upgrade', '--log-file=' + pip_log.name, 'git+' + str(package.giturl) + '.git' + branchpart + '#egg=' + package.name]) elif package.type == 'pip': if package.limitation is None: limit = "" else: limit = str(package.limitation) commands = ['pip', 'install'] if disable_pip_cache: commands.append('--no-cache-dir') commands.extend(['--quiet', '--prefix=' + PACKAGE_DIRECTORY, '--src=' + temp_dir, '--upgrade', '--log-file=' + pip_log.name, package.name + limit]) else: sys.stderr.write("Wrong package type\n") return 1, 'Unable to recognize package type: ' + package.name sys.stderr.write("install_package: running " + " ".join(commands) + "\n") logfilecontents += " ".join(commands) + "\n" returnval = 1 try: subprocess.call(commands) returnval = 0 except subprocess.CalledProcessError as err: returnval = err.returncode sys.stderr.flush() sys.stdout.flush() time.sleep(4) with open(pip_log.name, 'rU') as x: logfilecontents += x.read().decode('utf8') pip_log.close() try: sys.stderr.write(logfilecontents + "\n") except: pass sys.stderr.flush() sys.stdout.flush() time.sleep(4) sys.stderr.write('returnval is: ' + str(returnval) + "\n") sys.stderr.write('install_package: done' + "\n") shutil.rmtree(temp_dir) return returnval, logfilecontents
def update_monitor(message): if 'monitor' not in session: socketio.emit('terminate', {}, namespace='/monitor', room=request.sid) return #sys.stderr.write('received message from ' + str(request.sid) + "\n") available_for_chat = message['available_for_chat'] new_subscribed_roles = message['subscribed_roles'] new_phone_partners = message['phone_partners_to_add'] term_phone_partners = message['phone_partners_to_terminate'] phone_number = message['phone_number'] phone_number_key = 'da:monitor:phonenumber:' + str(session['user_id']) if phone_number is None or phone_number == '': rr.delete(phone_number_key) else: pipe = rr.pipeline() pipe.set(phone_number_key, phone_number) pipe.expire(phone_number_key, 2592000) pipe.execute() phone_partners = dict() prefix = 'da:phonecode:monitor:' + str(session['user_id']) + ':uid:' for key in term_phone_partners: the_code = rr.get(key) if the_code is not None: rr.delete(re.sub(r'da:session:uid:', prefix, key)) rr.delete('da:callforward:' + str(the_code)) if phone_number is None or phone_number == '': for key in rr.keys(prefix + '*'): the_code = rr.get(key) if the_code is not None: rr.delete(key) rr.delete('da:callforward:' + str(the_code)) else: codes_in_use = set() for key in rr.keys('da:callforward:*'): code = re.sub(r'^da:callforward:', '', key) codes_in_use.add(code) for key in rr.keys(prefix + '*'): phone_partners[re.sub(r'^da:phonecode:monitor:[0-9]*:uid:', 'da:session:uid:', key)] = 1 for key in new_phone_partners: if key in phone_partners: continue times = 0 ok = False while times < 1000: times += 1 code = "%04d" % random.randint(1000, 9999) if code in codes_in_use: continue ok = True the_code = code new_key = re.sub(r'^da:session:uid:', prefix, key) code_key = 'da:callforward:' + str(code) pipe = rr.pipeline() pipe.set(new_key, code) pipe.set(code_key, phone_number) pipe.expire(new_key, 300) pipe.expire(code_key, 300) pipe.execute() phone_partners[key] = 1 break if times >= 1000: logmessage("update_monitor: could not get a random integer") #sys.stderr.write('subscribed roles are type ' + str(type(new_subscribed_roles)) + " which is " + str(new_subscribed_roles) + "\n") monitor_key = 'da:monitor:' + str(request.sid) pipe = rr.pipeline() pipe.set(monitor_key, 1) pipe.expire(monitor_key, 60) pipe.execute() key = 'da:monitor:available:' + str(session['user_id']) key_exists = rr.exists(key) chat_partners = dict() for cp_key in rr.hgetall('da:monitor:chatpartners:' + str(session['user_id'])): if rr.get(cp_key) is None: rr.hdel('da:monitor:chatpartners:' + str(session['user_id']), cp_key) else: chat_partners[re.sub('^da:interviewsession:uid:', r'da:session:uid:', cp_key)] = 1 #sys.stderr.write('daAvailableForChat is ' + str(available_for_chat) + " for key " + key + "\n") if available_for_chat: pipe = rr.pipeline() pipe.set(key, request.sid) pipe.expire(key, 60) pipe.execute() elif key_exists: #sys.stderr.write("Deleting shit\n") pipe = rr.pipeline() pipe.delete(key) for avail_key in rr.keys('da:monitor:role:*:userid:' + str(session['user_id'])): pipe.delete(avail_key) pipe.execute() avail_roles = list() for key in rr.keys('da:chat:roletype:*'): avail_roles.append(re.sub(r'^da:chat:roletype:', r'', key)) sub_role_key = 'da:monitor:userrole:' + str(session['user_id']) if rr.exists(sub_role_key): subscribed_roles = rr.hgetall(sub_role_key) else: subscribed_roles = dict() del_mon_role_keys = list() for role_key in new_subscribed_roles.keys(): if role_key not in avail_roles: #sys.stderr.write("role_key is " + str(role_key) + " which is " + str(type(role_key)) + "\n") del new_subscribed_roles[role_key] for role_key in subscribed_roles.keys(): if role_key not in avail_roles: rr.hdel(sub_role_key, role_key) del_mon_role_keys.append('da:monitor:role:' + role_key + ':userid:' + str(session['user_id'])) for role_key in new_subscribed_roles.keys(): if role_key not in subscribed_roles: rr.hset(sub_role_key, role_key, 1) subscribed_roles[role_key] = 1 for role_key in subscribed_roles.keys(): if role_key not in new_subscribed_roles: rr.hdel(sub_role_key, role_key) del_mon_role_keys.append('da:monitor:role:' + role_key + ':userid:' + str(session['user_id'])) del subscribed_roles[role_key] if len(del_mon_role_keys): pipe = rr.pipeline() for key in del_mon_role_keys: pipe.delete(key) pipe.execute() if available_for_chat and len(subscribed_roles): pipe = rr.pipeline() for role_key in subscribed_roles.keys(): key = 'da:monitor:role:' + role_key + ':userid:' + str(session['user_id']) pipe.set(key, 1) pipe.expire(key, 60) pipe.execute() keylist = list() for key in rr.keys('da:session:*'): keylist.append(key) sessions = dict() for key in keylist: try: sessobj = pickle.loads(rr.get(key)) except: sys.stderr.write('error parsing value of ' + str(key) + " which was " + str(rr.get(key)) + "\n") continue if sessobj.get('chatstatus', None) != 'off': html = rr.get(re.sub(r'^da:session:', 'da:html:', key)) if html is not None: obj = json.loads(html) sessobj['browser_title'] = obj.get('browser_title', 'not available') if rr.exists(re.sub(r'^da:session:', 'da:block:', key)): sessobj['blocked'] = True else: sessobj['blocked'] = False sessions[key] = sessobj socketio.emit('updatemonitor', {'available_for_chat': available_for_chat, 'subscribedRoles': subscribed_roles, 'sessions': sessions, 'availRoles': sorted(avail_roles), 'chatPartners': chat_partners, 'phonePartners': phone_partners}, namespace='/monitor', room=request.sid)
def interview_connect(): session_id = session.get('uid', None) if session_id is not None: user_dict, is_encrypted = get_dict_encrypt() if is_encrypted: secret = request.cookies.get('secret', None) else: secret = None if secret is not None: secret = str(secret) if user_dict is None: sys.stderr.write("user_dict did not exist.\n") socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) return chat_info = user_dict['_internal']['livehelp'] if chat_info['availability'] == 'unavailable': sys.stderr.write("Socket started but chat is unavailable.\n") socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) return #sys.stderr.write('chat info is ' + str(chat_info) + "\n") if user_dict['_internal']['livehelp']['mode'] in ['peer', 'peerhelp']: peer_ok = True else: peer_ok = False yaml_filename = session.get('i', None) the_user_id = session.get('user_id', 't' + str(session.get('tempuser', None))) if request.sid not in threads: #sys.stderr.write('Starting thread for sid ' + str(request.sid) + "\n") threads[request.sid] = socketio.start_background_task(target=background_thread, sid=request.sid, user_id=session.get('user_id', None), temp_user_id=session.get('tempuser', None)) channel_up = wait_for_channel(rr, request.sid) if not channel_up: sys.stderr.write("Channel did not come up.\n") socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) return lkey = 'da:ready:uid:' + str(session_id) + ':i:' + str(yaml_filename) + ':userid:' + str(the_user_id) #sys.stderr.write("Searching: " + lkey + "\n") if rr.exists(lkey): lkey_exists = True else: lkey_exists = False if lkey_exists is False and peer_ok is False: sys.stderr.write("Key does not exist: " + lkey + ".\n") #socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) #return failed_to_find_partner = True found_help = False if lkey_exists: partner_keys = rr.lrange(lkey, 0, -1) #sys.stderr.write("partner_keys is: " + str(type(partner_keys)) + " " + str(partner_keys) + "\n") if partner_keys is None and not peer_ok: sys.stderr.write("No partner keys: " + lkey + ".\n") socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) return rr.delete(lkey) for pkey in partner_keys: #sys.stderr.write("Considering: " + pkey + "\n") partner_sid = rr.get(pkey) if partner_sid is not None: if re.match(r'^da:monitor:available:.*', pkey): is_help = True else: is_help = False if is_help and found_help: continue #sys.stderr.write("Trying to pub to " + str(partner_sid) + " from " + str(pkey) + "\n") listeners = rr.publish(partner_sid, json.dumps(dict(messagetype='chatready', uid=session_id, i=yaml_filename, userid=the_user_id, secret=secret, sid=request.sid))) #sys.stderr.write("Listeners: " + str(listeners) + "\n") if re.match(r'^da:interviewsession.*', pkey): rr.publish(request.sid, json.dumps(dict(messagetype='chatready', sid=partner_sid))) else: rr.publish(request.sid, json.dumps(dict(messagetype='chatpartner', sid=partner_sid))) if listeners > 0: if is_help: found_help = True failed_to_find_partner = False if failed_to_find_partner and peer_ok is False: sys.stderr.write("Unable to reach any potential chat partners.\n") #socketio.emit('terminate', {}, namespace='/wsinterview', room=request.sid) #return key = 'da:interviewsession:uid:' + str(session_id) + ':i:' + str(yaml_filename) + ':userid:' + str(the_user_id) rr.set(key, request.sid)
def update_monitor(message): if 'monitor' not in session: socketio.emit('terminate', {}, namespace='/monitor', room=request.sid) return #sys.stderr.write('received message from ' + str(request.sid) + "\n") available_for_chat = message['available_for_chat'] new_subscribed_roles = message['subscribed_roles'] new_phone_partners = message['phone_partners_to_add'] term_phone_partners = message['phone_partners_to_terminate'] phone_number = message['phone_number'] phone_number_key = 'da:monitor:phonenumber:' + str(session['user_id']) if phone_number is None or phone_number == '': rr.delete(phone_number_key) else: pipe = rr.pipeline() pipe.set(phone_number_key, phone_number) pipe.expire(phone_number_key, 2592000) pipe.execute() phone_partners = dict() prefix = 'da:phonecode:monitor:' + str(session['user_id']) + ':uid:' for key in term_phone_partners: the_code = rr.get(key) if the_code is not None: the_code = the_code.decode() rr.delete(re.sub(r'da:session:uid:', prefix, key)) rr.delete('da:callforward:' + the_code) if phone_number is None or phone_number == '': for key in rr.keys(prefix + '*'): key = key.decode() the_code = rr.get(key) if the_code is not None: the_code = the_code.decode() rr.delete(key) rr.delete('da:callforward:' + the_code) else: codes_in_use = set() for key in rr.keys('da:callforward:*'): key = key.decode() code = re.sub(r'^da:callforward:', '', key) codes_in_use.add(code) for key in rr.keys(prefix + '*'): key = key.decode() phone_partners[re.sub(r'^da:phonecode:monitor:[0-9]*:uid:', 'da:session:uid:', key)] = 1 for key in new_phone_partners: if key in phone_partners: continue times = 0 ok = False while times < 1000: times += 1 code = "%04d" % random.randint(1000, 9999) if code in codes_in_use: continue ok = True the_code = code new_key = re.sub(r'^da:session:uid:', prefix, key) code_key = 'da:callforward:' + str(code) pipe = rr.pipeline() pipe.set(new_key, code) pipe.set(code_key, phone_number) pipe.expire(new_key, 300) pipe.expire(code_key, 300) pipe.execute() phone_partners[key] = 1 break if times >= 1000: logmessage("update_monitor: could not get a random integer") #sys.stderr.write('subscribed roles are type ' + str(type(new_subscribed_roles)) + " which is " + str(new_subscribed_roles) + "\n") monitor_key = 'da:monitor:' + str(request.sid) pipe = rr.pipeline() pipe.set(monitor_key, 1) pipe.expire(monitor_key, 60) pipe.execute() key = 'da:monitor:available:' + str(session['user_id']) key_exists = rr.exists(key) chat_partners = dict() for cp_key in rr.hgetall('da:monitor:chatpartners:' + str(session['user_id'])): cp_key = cp_key.decode() if rr.get(cp_key) is None: rr.hdel('da:monitor:chatpartners:' + str(session['user_id']), cp_key) else: chat_partners[re.sub('^da:interviewsession:uid:', r'da:session:uid:', cp_key)] = 1 #sys.stderr.write('daAvailableForChat is ' + str(available_for_chat) + " for key " + key + "\n") if available_for_chat: pipe = rr.pipeline() pipe.set(key, request.sid) pipe.expire(key, 60) pipe.execute() elif key_exists: #sys.stderr.write("Deleting shit\n") pipe = rr.pipeline() pipe.delete(key) for avail_key in rr.keys('da:monitor:role:*:userid:' + str(session['user_id'])): pipe.delete(avail_key.decode()) pipe.execute() avail_roles = list() for key in rr.keys('da:chat:roletype:*'): avail_roles.append(re.sub(r'^da:chat:roletype:', r'', key.decode())) sub_role_key = 'da:monitor:userrole:' + str(session['user_id']) if rr.exists(sub_role_key): subscribed_roles = decode_dict(rr.hgetall(sub_role_key)) else: subscribed_roles = dict() del_mon_role_keys = list() for role_key in [k for k in new_subscribed_roles.keys()]: if role_key not in avail_roles: #sys.stderr.write("role_key is " + str(role_key) + " which is " + str(type(role_key)) + "\n") del new_subscribed_roles[role_key] for role_key in [k for k in subscribed_roles.keys()]: if role_key not in avail_roles: rr.hdel(sub_role_key, role_key) del_mon_role_keys.append('da:monitor:role:' + role_key + ':userid:' + str(session['user_id'])) for role_key in [k for k in new_subscribed_roles.keys()]: if role_key not in subscribed_roles: rr.hset(sub_role_key, role_key, 1) subscribed_roles[role_key] = 1 for role_key in [k for k in subscribed_roles.keys()]: if role_key not in new_subscribed_roles: rr.hdel(sub_role_key, role_key) del_mon_role_keys.append('da:monitor:role:' + role_key + ':userid:' + str(session['user_id'])) del subscribed_roles[role_key] if len(del_mon_role_keys): pipe = rr.pipeline() for key in del_mon_role_keys: pipe.delete(key) pipe.execute() if available_for_chat and len(subscribed_roles): pipe = rr.pipeline() for role_key in [k for k in subscribed_roles.keys()]: key = 'da:monitor:role:' + role_key + ':userid:' + str(session['user_id']) pipe.set(key, 1) pipe.expire(key, 60) pipe.execute() keylist = list() for key in rr.keys('da:session:*'): keylist.append(key.decode()) sessions = dict() for key in keylist: try: sessobj = fix_pickle_obj(rr.get(key)) except: sys.stderr.write('error parsing value of ' + str(key) + " which was " + repr(rr.get(key)) + "\n") continue if sessobj.get('chatstatus', None) != 'off': html = rr.get(re.sub(r'^da:session:', 'da:html:', key)) if html is not None: html = html.decode() obj = json.loads(html) sessobj['browser_title'] = obj.get('browser_title', 'not available') if rr.exists(re.sub(r'^da:session:', 'da:block:', key)): sessobj['blocked'] = True else: sessobj['blocked'] = False sessions[key] = sessobj socketio.emit('updatemonitor', {'available_for_chat': available_for_chat, 'subscribedRoles': subscribed_roles, 'sessions': sessions, 'availRoles': sorted(avail_roles), 'chatPartners': chat_partners, 'phonePartners': phone_partners}, namespace='/monitor', room=request.sid)