def on_post(self, req, resp): sid = req.cookie('session-id') if sid and r.get('reactivation_%s' % sid): resp.body = { 'message': 'error', 'info': 'Please wait 5 seconds...', 'not_active': False, 'wait': 5 } return if not sid: sid = getANewSessionId() # this session is temprary resp.set_header( 'set-cookie', 'session-id=%s; path=/; max-age=%s; HttpOnly' % (sid, 5)) r.incr('reactivation_' + sid, 1) r.expire('reactivation_' + sid, 60) ip = req.env.get('HTTP_X_FORWARDED_FOR') form = json.loads(req.stream.read()) target = req.session.query(User).filter( User.email == form.get('email')).first() if target: host = req.protocol + '://' + get_ip(req) reset_link = host + \ '/api/auth/changepasswordverify?token=' + target.token send_envelope.delay( form.get('email'), [], [], 'Account Password Reset', 'Hi <strong>{u}</strong>! <a href="{l}">reset</a> your account password.' .format(u=target.firstname, l=reset_link)) resp.body = {'message': 'reset key sent'}
def on_post(self, req, resp): sid = req.cookie('session-id') if sid and r.get('reactivation_%s' % sid): resp.body = { 'message': 'error', 'info': 'Please wait 5 seconds...', 'not_active': False, 'wait': 5 } return if not sid: sid = getANewSessionId() # this session is temprary resp.set_header( 'set-cookie', 'session-id=%s; path=/; max-age=%s; HttpOnly' % (sid, 5)) r.incr('reactivation_' + sid, 1) r.expire('reactivation_' + sid, 60) ip = req.env.get('HTTP_X_FORWARDED_FOR') form = json.loads(req.stream.read()) target = req.session.query(User).filter( User.email == form.get('email')).first() if target and target.active: resp.body = { 'message': 'error', 'info': 'account is already active', 'not_active': False } logger.warning( '{ip}|Tried to reactivate {u} which is already activated!'. format(ip=ip, u=target.email)) elif target and not target.active: host = req.protocol + '://' + req.headers.get('HOST') activation_link = host + '/api/auth/activate?token=' + target.token send_envelope.delay( form.get('email'), [], [], 'Account ReActivation', 'Hi <strong>{u}</strong>! Please <a href="{l}">ReActivate</a> your account.' .format(u=target.firstname, l=activation_link)) logger.info('{ip}|requested reactivation key for {u}'.format( ip=ip, u=target.email)) resp.body = { 'message': 'success', 'info': 'check your reactivation email' } #resp.status = falcon.HTTP_302 #m = encodestring('Check your email for activation key.') # resp.location = '/app/#auth/login?m=%s'%m # return else: resp.status = falcon.HTTP_202 logger.warning( '{ip}|requested reactivation key for not existed account'. format(ip=ip)) resp.body = {'message': 'error', 'info': 'email not available'}
def plan(self, do_plan=True, do_guntt=False, do_resource=False, do_msproject=False, do_profit=False, do_trace=True, do_traceSvg=False, report_width=1000): # lets select just one task #puid = getUUID() + '_' + self.uuid schedule_path = os.path.join(public_upload_folder, 'Fearless_project_%s.tjp' % self.uuid) plan_path = os.path.join(public_upload_folder, 'plan_%s.html' % (self.uuid)) overall_plan_path = os.path.join(public_upload_folder, 'plan.html') overall_gantt_path = os.path.join(public_upload_folder, 'gantt.html') overall_resource_path = os.path.join(public_upload_folder, 'resource.html') guntt_path = os.path.join(public_upload_folder, 'guntt_%s.html' % (self.uuid)) resource_path = os.path.join(public_upload_folder, 'resource_%s.html' % (self.uuid)) msproject_path = os.path.join(public_upload_folder, 'MS-project_%s.xml' % (self.uuid)) profit_path = os.path.join(public_upload_folder, 'ProfiAndLoss_%s.html' % (self.uuid)) csv_path = os.path.join(public_upload_folder, 'csv_%s.csv' % (self.uuid)) trace_path = os.path.join(public_upload_folder, 'TraceReport_%s.csv' % (self.uuid)) traceSvg_path = os.path.join(public_upload_folder, 'TraceReport_%s.html' % (self.uuid)) if not r.get('fearless_tj3_lock'): r.set('fearless_tj3_lock', 'OK') # just for highly requested projects r.expire('fearless_tj3_lock', 5) else: return if not self.tasks: self.reports = [] return templateFile = os.path.abspath( os.path.join(os.path.dirname(__file__), '../templates/masterProject.tjp')) t = Template(filename=templateFile) session = session_factory() projects = session.query(Project).order_by(asc(Project.id)).all() resources = session.query(User).all() subProjectTasks = [] reports = [] for p in projects: if p.tasks: planData = p.tjp_subproject(do_plan=do_plan, do_guntt=do_guntt, do_resource=do_resource, do_msproject=do_msproject, do_profit=do_profit, do_trace=do_trace, do_traceSvg=do_traceSvg, report_width=report_width) subProjectTasks.append(planData.get('subProjectTasks')) reports.append(planData.get('report')) finalplan = t.render(reports=reports, subProjectTasks=subProjectTasks, now=now(), subprojects=projects, resources=resources) session.close() if self.last_plan == hashlib.md5(finalplan.encode( 'utf-8', 'ignore')).hexdigest(): print 'Using cached plan' return else: for i in [ schedule_path, plan_path, guntt_path, resource_path, msproject_path, profit_path, csv_path, traceSvg_path ]: if os.path.isfile(i): os.remove(i) #plan_path = '/tmp/Fearless_project.tjp' tj3 = sh.Command('../../bin/ruby/bin/tj3') with open(schedule_path, 'wb') as f: f.write(finalplan.encode('utf-8')) try: print 'Start Calculating project %s' % self.id import time s = time.time() tj = tj3(schedule_path, '--silent', '--no-color', '--add-trace', o=public_upload_folder, c='4') print 'Finished in %s seconds' % round(time.time() - s, 3) except Exception, e: print e # print type(repr(e)) for i in xrange(3): _d = '<br/>'.join(repr(e).split('\\n')[17:]).replace( '\\x1b[31m', '<b>').replace('\\x1b[0m', '</b>').split('\\x1b[35m') if len(_d) > 1: self.reports.append(_d[1]) self.reports = [] return
def Authenticate(req, resp, params): ''' :param req: :param resp: :param params: :return: usage: using curl or httpie: http "http://127.0.0.1:5003/api/db/user" --auth [email protected]:password using requests: ... using urllib2: ... ''' # return ip = req.env.get('HTTP_X_FORWARDED_FOR') or req.env.get('REMOTE_ADDR') free_services = [ '/api/auth/signup', '/api/auth/login', '/api/ping', '/api/auth/activate', '/api/auth/reactivate', '/api/auth/reset', '/api/auth/logout', '/api/auth/getUserInfo', '/api/auth/changepasswordverify', '/api/auth/changepassword', '/api/test_upload' ] sid = req.cookie('session-id') if sid: sid_digest = hashlib.sha1(sid).hexdigest() ip_digest = hashlib.sha1(ip).hexdigest() ''' Now we need to check if session is available and it's sha1 is in redis''' #return if req.path in free_services or '/api/note' in req.path or ( sid and r.get(sid_digest)): ''' User can access 1000 api calls per minute (for now! NOTE)''' api_count_key = ip_digest + '_access_count' access_count = r.get(api_count_key) return if not access_count: '''probabaly acceess count expired, lets create one and let user in''' r.set(api_count_key, 1) r.expire(api_count_key, 60) # not more than 1000 requests per second! its fair elif int(access_count) <= 1000: r.incr(api_count_key, 1) elif not '/api/ping' in req.path and not '/api/asset/save' in req.path: message = 'Too many api access in short amount of time' raise falcon.HTTPUnauthorized('Authentication required', message) else: auth_header = req.headers.get('AUTHORIZATION') if auth_header: auth_header_parts = auth_header.split() if len(auth_header_parts) == 2: auth_mode, auth_64 = auth_header_parts # ok, we need to check it if auth_mode and auth_64 and auth_mode == 'Basic': username, password = decodestring(auth_64).split(':') user = req.session.query(User).filter( User.email == username).first() if user and user.password == password: logger.info( '{ip}|{u} accessed with Basic Auth for API use"'. format(u=user.email, ip=ip)) return # FREE PASS TO GO else: logger.info( 'User "{u}" provided wrong Basic Auth for API use"' .format(u=username)) message = 'Wrong Info' else: message = 'Incorrect Auth header. Must be Basic' else: message = 'Wrong Auth header formatting' else: message = 'You need to provide Basic Auth header to authenticate' sid = getANewSessionId() hashed_sid = hashlib.sha1(sid).hexdigest() # this session is not yet saved resp.append_header('Set-Cookie', 'session-id=%s;path=/;max-age=10; HttpOnly' % sid) #resp.status = falcon.HTTP_302 #next = encodestring(req.path) resp.location = '/app/#auth/login/%s' % next raise falcon.HTTPUnauthorized('Authentication required', message, href=req.protocol + '://' + req.headers.get('HOST') + '/app/#auth/login', scheme='Token; UUID')
def on_post(self, req, resp): '''Add a user to database''' ip = req.env.get('HTTP_X_FORWARDED_FOR') sid = req.cookie('session-id') if sid and r.get('fail_' + sid): resp.body = { 'message': 'error', 'info': 'Very Quick! Good, but you need to wait', 'wait': 5 } return form = json.loads(req.stream.read()) email = form.get('email') if email: email = email.lower() target = req.session.query(User).filter(User.email == email).first() if not sid: sid = getANewSessionId() hashed_sid = hashlib.sha1(sid).hexdigest() ''' Here is the smart line! If users tries to login again and again, then the same cookie will be used ''' resp.append_header('set-cookie', 'session-id=%s; path=/; max-age=5; HttpOnly' % sid) # this session is not yet saved # don't tell what's wrong! if not target or not target.password == form.get('password'): r.incr('fail_' + sid, 1) r.expire('fail_' + sid, 60) logger.warning('{ip}|Wrong information provided'.format(ip=ip)) resp.body = { 'message': 'error', 'info': 'login information is not correct', 'wait': 5 } else: if target.active: target.lastLogIn = now() rem_time = 3600 * 24 # this session is not yet saved groups = ','.join([i.name for i in target.grps]) resp.append_header( 'set-cookie', 'userid=%s; path=/; max-age=%s' % (str(target.id), rem_time)) resp.append_header( 'set-cookie', 'groups=%s; path=/; max-age=%s' % (str(groups), rem_time)) resp.append_header( 'set-cookie', 'username=%s; path=/; max-age=%s' % (str(target.firstname or target.alias), rem_time)) resp.append_header( 'set-cookie', 'session-id=%s; path=/; max-age=%s; HttpOnly' % (sid, rem_time)) target.latest_session_id = hashed_sid r.incr(hashed_sid, 1) # add it to redis r.expire(hashed_sid, rem_time) logger.info('{ip}|"{u}" loggin in from web"'.format( u=target.email, ip=ip)) resp.body = { 'message': 'success', 'firstname': target.firstname, 'id': target.id, 'avatar': target.avatar, 'groups': [i.name for i in target.grps] } else: logger.warning( '{ip}|{u} tried to login from web without activation"'. format(u=target.email, ip=ip)) resp.body = { 'message': 'warning', 'info': 'Please check your email and activate your account', 'not_active': True }
def on_get(self, req, resp): """Handles GET requests""" # resp.set_header('Set-Cookie','fig=newton; Max-Age=200') # print req.get_header('Cookie') wsock = req.env.get('wsgi.websocket') #client = req.env.get('HTTP_X_FORWARDED_FOR') if wsock: while True: try: '''AssetInfo should be something like this: {"id":5,"command":"hey()"} ''' showInfo = wsock.receive() if not showInfo: continue data = json.loads(showInfo) assetId = data.get('id') command = data.get('command') frame = data.get('frame') note = data.get('note') slide = data.get('slide') want_to_be_master = data.get('i_want_to_be_master') client = json.loads(showInfo).get('client') or req.env.get( 'HTTP_X_FORWARDED_FOR') if assetId: print assetId if not str(client) in r.lrange( 'show_%s_watchers' % assetId, 0, -1): r.rpush('show_%s_watchers' % assetId, client) r.expire('show_%s_watchers' % assetId, 1) master = r.get('show_%s_master' % assetId) if want_to_be_master: # Asset is unlocked # check if not other master if master and str(client) != master: pass else: r.set('show_%s_master' % assetId, str(client)) r.set('show_%s_command' % assetId, command) r.set('show_%s_frame' % assetId, frame) r.set('show_%s_note' % assetId, note) r.set('show_%s_slide' % assetId, slide) r.expire('show_%s_master' % assetId, 1) r.expire('show_%s_command' % assetId, 1) r.expire('show_%s_frame' % assetId, 1) r.expire('show_%s_note' % assetId, 1) r.expire('show_%s_slide' % assetId, 1) command = r.get('show_%s_command' % assetId) frame = r.get('show_%s_frame' % assetId) note = r.get('show_%s_note' % assetId) slide = r.get('show_%s_slide' % assetId) watchers = r.lrange('show_%s_watchers' % assetId, 0, -1) #note = json.loads(note) if r.getset( 'show_%s_%s_latest_command' % (assetId, client), command) == command: command = None if r.getset( 'show_%s_%s_latest_frame' % (assetId, client), frame) == frame: frame = 'KEEP' if r.getset( 'show_%s_%s_latest_note' % (assetId, client), note) == note: note = 'KEEP' # if master == str(client): ## dont send command to its issuer # command = None # frames = None wsock.send( dumps({ "master": r.get('show_%s_master' % assetId), "frame": frame, "command": command, "note": note, "slide": slide, 'watchers': watchers })) except (WebSocketError, KeyboardInterrupt): break