def login(self, login, password, db=None): if db and db != request.db: raise Exception("Could not select database '%s'" % db) uid = request.session.authenticate(request.db, login, password) if not uid: return Response(response="Wrong login/password", status=401) self.check_user(uid) return Response(headers={ 'X-CSRF-TOKEN': request.csrf_token(), })
class Root_new(openerp.http.Root): def get_response(self, httprequest, result, explicit_session): if isinstance(result, Response) and result.is_qweb: try: result.flatten() except (Exception), e: if request.db: result = request.registry['ir.http']._handle_exception(e) else: raise if isinstance(result, basestring): response = Response(result, mimetype='text/html') else: response = result if httprequest.session.should_save: self.session_store.save(httprequest.session) # We must not set the cookie if the session id was specified using a http header or a GET parameter. # There are two reasons to this: # - When using one of those two means we consider that we are overriding the cookie, which means creating a new # session on top of an already existing session and we don't want to create a mess with the 'normal' session # (the one using the cookie). That is a special feature of the Session Javascript class. # - It could allow session fixation attacks. if not explicit_session and hasattr(response, 'set_cookie'): response.set_cookie('session_id', httprequest.session.sid, max_age=2 * 60) return response
def response_wrap(*args, **kw): response = f(*args, **kw) if isinstance(response, Response) or f.routing_type == 'json': return response if isinstance(response, basestring): return Response(response) if isinstance(response, werkzeug.exceptions.HTTPException): response = response.get_response(request.httprequest.environ) if isinstance(response, werkzeug.wrappers.BaseResponse): response = Response.force_type(response) response.set_default() return response _logger.warn("<function %s.%s> returns an invalid response type for an http request" % ( f.__module__, f.__name__)) return response
def test_mfa_login_post_firefox_response_returned( self, val_mock, gen_mock, redirect_mock, request_mock ): '''Should behave well if redirect returns Response (Firefox case)''' request_mock.env = self.env request_mock.db = self.registry.db_name redirect_mock.return_value = Response('Test Response') test_token = self.test_user.mfa_login_token request_mock.params = {'mfa_login_token': test_token} val_mock.return_value = True test_result = self.test_controller.mfa_login_post() self.assertIn('Test Response', test_result.response)
def _json_response(self, result=None, error=None): response = {} if error is not None: response['error'] = error if result is not None: response['result'] = result mime = 'application/json' body = simplejson.dumps(response) return Response(body, headers=[('Content-Type', mime), ('Content-Length', len(body))])
def _json_response(self, result=None, error=None): if not result: response = {} else: response = { 'pagination': result.pagination, 'msg': result.msg } if error is not None: response['error'] = error if result is not None: response['payload'] = result.payload if self.jsonp: # If we use jsonp, that's mean we are called from another host # Some browser (IE and Safari) do no allow third party cookies # We need then to manage http sessions manually. response['session_id'] = self.session_id mime = 'application/javascript' body = "%s(%s);" % (self.jsonp, json.dumps(response),) else: mime = 'application/json' body = json.dumps(response) resp = Response(body, headers=[('Content-Type', mime), ('Content-Length', len(body))]) if result.status_code == 401: resp.status = "401 Unauthorized" if result.status_code == 400: resp.status = "400 Bad Request" if result.status_code == 500: resp.status = "500 Internal Server Error" return resp
def _json_response(self, result=None, error=None): response = {} if error is not None: response["error"] = error mime = "application/json" # openerp 11+ version: # body = json.dumps(response, default=date_utils.json_default) # openerp 10 only: status = error and error.pop("code") or result.status_code body = response and json.dumps(response) or result.data return Response( body, status=status, headers=[("Content-Type", mime), ("Content-Length", len(body))], )
class Root_tkobr(openerp.http.Root): @lazy_property def session_store(self): # Setup http sessions path = openerp.tools.config.session_dir _logger.debug('HTTP sessions stored in: %s', path) return werkzeug.contrib.sessions.FilesystemSessionStore(path, session_class=OpenERPSession) def get_response(self, httprequest, result, explicit_session): if isinstance(result, Response) and result.is_qweb: try: result.flatten() except(Exception), e: if request.db: result = request.registry['ir.http']._handle_exception(e) else: raise if isinstance(result, basestring): response = Response(result, mimetype='text/html') else: response = result if httprequest.session.should_save: self.session_store.save(httprequest.session) # We must not set the cookie if the session id was specified using a http header or a GET parameter. # There are two reasons to this: # - When using one of those two means we consider that we are overriding the cookie, which means creating a new # session on top of an already existing session and we don't want to create a mess with the 'normal' session # (the one using the cookie). That is a special feature of the Session Javascript class. # - It could allow session fixation attacks. if not explicit_session and hasattr(response, 'set_cookie'): if not request.uid: request.uid = openerp.SUPERUSER_ID seconds = 90 * 24 * 60 * 60 if httprequest.session.uid: user_obj = request.registry.get('res.users') # expiring_date, seconds = user_obj.get_expiring_date(request.cr, # request.uid, httprequest.session.uid, request.context) response.set_cookie('session_id', httprequest.session.sid, max_age=90*24*60*60) #seconds) return response
def _json_response(self, result=None, error=None): """ Format the answer and add required headers. """ response = {} status = 200 if error is not None: status = error.get('ErrorCode') response = error if result is not None: status = result.pop('code') response = result mime = 'application/json' body = simplejson.dumps(response) headers = [ ('Content-Type', mime), ('Content-Length', len(body)), ('x-cim-RequestId', self.uuid), ] http_response = Response(body, headers=headers, status=status) ONRAMP_LOGGER.info('[SEND] %s %s "%s"', status, headers, response) return http_response
def get_document(self, oid=-1): """Render a http response for a document""" document_mgr = request.env['easy_my_coop.document'] doc = document_mgr.sudo().browse(oid) ir_http_mgr = request.env['ir.http'] status, headers, content = ir_http_mgr.sudo().binary_content( model=doc._name, id=oid, field='document', filename_field='filename', download=True ) if status == 304: return Response(status, headers) elif status == 301: # TODO: test this case not sure if this render the same # return werkzeug.utils.redirect(content, code=301) return request.redirect(content, code=301) elif status != 200: return request.not_found() content_base64 = base64.b64decode(content) headers.append(('Content-Length', len(content_base64))) return request.make_response(content_base64, headers)
def _json_response(self, result=None, error=None): response = {} if error is not None: response['error'] = error if result is not None: response = result if self.jsonp: # If we use jsonp, that's mean we are called from another host # Some browser (IE and Safari) do no allow third party cookies # We need then to manage http sessions manually. response['session_id'] = self.session_id mime = 'application/javascript' body = "%s(%s);" % ( self.jsonp, simplejson.dumps(response), ) else: mime = 'application/json' body = simplejson.dumps(response) return Response(body, headers=[('Content-Type', mime), ('Content-Length', len(body))])
def mfa_login_post(self, *args, **kwargs): """Process MFA login attempt Overview: * Try to find a user based on the MFA login token. If this doesn't work, redirect to the password login page with an error message * Validate the confirmation code provided by the user. If it's not valid, redirect to the previous login step with an error message * Generate a long-term MFA login token for the user and log the user in using the token * Build a trusted device cookie and add it to the response if the trusted device option was checked * Redirect to the provided URL or to '/web' if one was not given """ # sudo() is required because there is no request.env.uid (likely since # there is no user logged in at the start of the request) user_model_sudo = request.env['res.users'].sudo() device_model_sudo = user_model_sudo.env['res.users.device'] config_model_sudo = user_model_sudo.env['ir.config_parameter'] token = request.params.get('mfa_login_token') try: user = user_model_sudo.user_from_mfa_login_token(token) except (MfaTokenInvalidError, MfaTokenExpiredError) as exception: return http.local_redirect( '/web/login', query={ 'redirect': request.params.get('redirect'), 'error': exception.message, }, keep_hash=True, ) confirmation_code = request.params.get('confirmation_code') if not user.validate_mfa_confirmation_code(confirmation_code): return http.local_redirect( '/auth_totp/login', query={ 'redirect': request.params.get('redirect'), 'error': _('Your confirmation code is not correct. Please try' ' again.'), 'mfa_login_token': token, }, keep_hash=True, ) # These context managers trigger a safe commit, which persists the # changes right away and is needed for the auth call with Environment.manage(): with registry(request.db).cursor() as temp_cr: temp_env = Environment(temp_cr, SUPERUSER_ID, request.context) temp_user = temp_env['res.users'].browse(user.id) temp_user.generate_mfa_login_token(60 * 24 * 30) token = temp_user.mfa_login_token request.session.authenticate(request.db, user.login, token, user.id) redirect = request.params.get('redirect') if not redirect: redirect = '/web' response = Response(http.redirect_with_hash(redirect)) if request.params.get('remember_device'): device = device_model_sudo.create({'user_id': user.id}) secret = config_model_sudo.get_param('database.secret') device_cookie = JsonSecureCookie({'device_id': device.id}, secret) cookie_lifetime = timedelta(days=30) cookie_exp = datetime.utcnow() + cookie_lifetime device_cookie = device_cookie.serialize(cookie_exp) cookie_key = 'trusted_devices_%d' % user.id sec_config = config_model_sudo.get_param('auth_totp.secure_cookie') security_flag = sec_config != '0' response.set_cookie( cookie_key, device_cookie, max_age=cookie_lifetime.total_seconds(), expires=cookie_exp, httponly=True, secure=security_flag, ) return response
def send_file(filepath_or_fp, mimetype=None, as_attachment=False, filename=None, mtime=None, add_etags=True, cache_timeout=http.STATIC_CACHE, conditional=True): """This is a modified version of Flask's send_file() Sends the contents of a file to the client. This will use the most efficient method available and configured. By default it will try to use the WSGI server's file_wrapper support. By default it will try to guess the mimetype for you, but you can also explicitly provide one. For extra security you probably want to send certain files as attachment (HTML for instance). The mimetype guessing requires a `filename` or an `attachment_filename` to be provided. Please never pass filenames to this function from user sources without checking them first. :param filepath_or_fp: the filename of the file to send. Alternatively a file object might be provided in which case `X-Sendfile` might not work and fall back to the traditional method. Make sure that the file pointer is positioned at the start of data to send before calling :func:`send_file`. :param mimetype: the mimetype of the file if provided, otherwise auto detection happens. :param as_attachment: set to `True` if you want to send this file with a ``Content-Disposition: attachment`` header. :param filename: the filename for the attachment if it differs from the file's filename or if using file object without 'name' attribute (eg: E-tags with StringIO). :param mtime: last modification time to use for contitional response. :param add_etags: set to `False` to disable attaching of etags. :param conditional: set to `False` to disable conditional responses. :param cache_timeout: the timeout in seconds for the headers. """ if isinstance(filepath_or_fp, (str, unicode)): if not filename: filename = os.path.basename(filepath_or_fp) file = open(filepath_or_fp, 'rb') if not mtime: mtime = os.path.getmtime(filepath_or_fp) else: file = filepath_or_fp if not filename: filename = getattr(file, 'name', None) file.seek(0, 2) size = file.tell() file.seek(0) if mimetype is None and filename: mimetype = mimetypes.guess_type(filename)[0] if mimetype is None: mimetype = 'application/octet-stream' headers = werkzeug.datastructures.Headers() if as_attachment: if filename is None: raise TypeError('filename unavailable, required for sending as attachment') headers.add('Content-Disposition', 'attachment', filename=filename) headers['Content-Length'] = size data = wrap_file(request.httprequest.environ, file) rv = Response(data, mimetype=mimetype, headers=headers, direct_passthrough=True) if isinstance(mtime, str): try: server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT mtime = datetime.datetime.strptime(mtime.split('.')[0], server_format) except Exception: mtime = None if mtime is not None: rv.last_modified = mtime rv.cache_control.public = True if cache_timeout: rv.cache_control.max_age = cache_timeout rv.expires = int(time.time() + cache_timeout) if add_etags and filename and mtime: etag_str = 'odoo-%s-%s-%s' % ( mtime, size, adler32( filename.encode('utf-8') if isinstance(filename, unicode) else filename ) & 0xffffffff ) # hide odoo string from etags rv.set_etag(hashlib.md5(etag_str).hexdigest()) if conditional: rv = rv.make_conditional(request.httprequest) # make sure we don't send x-sendfile for servers that # ignore the 304 status code for x-sendfile. if rv.status_code == 304: rv.headers.pop('x-sendfile', None) return rv
def wrap(*args, **kw): try: return f(*args, **kw) except Exception, e: return Response(response=str(e), status=500)
def wunderlist_step_1(self): headers = { 'X-Client-ID': self.client_id, 'X-Access-Token': request.env.user.wunderlist_access_token } """ --- Not sure if folder is a good idea! --- # Sync folders wu_folders = requests.get('https://a.wunderlist.com/api/v1/folders', headers=headers).json() wu_folders_keys = {} for f in wu_folders: wu_folders_keys[f['id']] = f areas = request.env['gtd.area'].search([]) for area in areas: lists = {'Next': None, 'Today': None, 'Tomorrow': None, 'Waiting': None} if not area.wu_id: # Create a folder if it does not exist for l in lists: r = requests.post('http://a.wunderlist.com/api/v1/lists', headers=headers, json={ 'title': l }).json() lists[l] = r['id'] # Create folder r = requests.post('https://a.wunderlist.com/api/v1/folders', headers=headers, json={ 'title': area.name, 'list_ids': lists.values() }).json() area.write({'wu_id': r['id']}) else: print 2 raise """ # Get Lists and crate if required lists = { 'Next': None, 'Today': None, 'Tomorrow': None, 'Waiting': None } lists_url = 'http://a.wunderlist.com/api/v1/lists' r = requests.get(lists_url, headers=headers) for rec in r.json(): if rec['title'] in lists: lists[rec['title']] = rec['id'] # Create missing for k, v in lists.items(): if not v: payload = {'title': k} print 'Creating list %s.' % k r = requests.post(lists_url, headers=headers, json=payload) lists[k] = r.json()['id'] # Clear & fill for k, v in lists.items(): # Clear lists wu_tasks = requests.get('http://a.wunderlist.com/api/v1/tasks', headers=headers, params={ 'list_id': v }).json() for task in wu_tasks: r = requests.delete('http://a.wunderlist.com/api/v1/tasks/%s' % task['id'], params={'revision': task['revision']}, headers=headers) # Fill with projects & tasks new_projects = request.env['gtd.project'].search([('state', '=', 'Active')]) for proj in new_projects: # Check that project has tasks in required state has_state = False for task in proj.tasks: if task.state == k: has_state = True break if not has_state: continue # Go on note = '' wu_task = requests.post('http://a.wunderlist.com/api/v1/tasks', headers=headers, json={ 'list_id': v, 'title': '%s' % proj.name, }).json() note += html2text(proj.note) # Create subtasks for task in [t for t in proj.tasks if t.state == k]: subtask = requests.post( 'http://a.wunderlist.com/api/v1/subtasks', headers=headers, json={ 'task_id': wu_task['id'], 'title': task.name, }).json() if task.note: note += html2text(task.note) if note: wu_note = requests.post( 'http://a.wunderlist.com/api/v1/notes', headers=headers, json={ 'task_id': wu_task['id'], 'content': note }) return Response('Wunderlist sync is complete. Close this window.')
def update_state(self, **kw): # results=http.request.env['product.product'].sudo().search_read([],fields=['name','website_url','product_tmpl_id']) headers = {'Content-Type': 'application/json'} body={'results':{'code':200,'message':{'name':'test'}}} return Response(json.dumps(body),status=200,headers=headers)
def send_file(filepath_or_fp, mimetype=None, as_attachment=False, filename=None, mtime=None, add_etags=True, cache_timeout=http.STATIC_CACHE, conditional=True): """This is a modified version of Flask's send_file() Sends the contents of a file to the client. This will use the most efficient method available and configured. By default it will try to use the WSGI server's file_wrapper support. By default it will try to guess the mimetype for you, but you can also explicitly provide one. For extra security you probably want to send certain files as attachment (HTML for instance). The mimetype guessing requires a `filename` or an `attachment_filename` to be provided. Please never pass filenames to this function from user sources without checking them first. :param filepath_or_fp: the filename of the file to send. Alternatively a file object might be provided in which case `X-Sendfile` might not work and fall back to the traditional method. Make sure that the file pointer is positioned at the start of data to send before calling :func:`send_file`. :param mimetype: the mimetype of the file if provided, otherwise auto detection happens. :param as_attachment: set to `True` if you want to send this file with a ``Content-Disposition: attachment`` header. :param filename: the filename for the attachment if it differs from the file's filename or if using file object without 'name' attribute (eg: E-tags with StringIO). :param mtime: last modification time to use for contitional response. :param add_etags: set to `False` to disable attaching of etags. :param conditional: set to `False` to disable conditional responses. :param cache_timeout: the timeout in seconds for the headers. """ if isinstance(filepath_or_fp, (str, unicode)): if not filename: filename = os.path.basename(filepath_or_fp) file = open(filepath_or_fp, 'rb') if not mtime: mtime = os.path.getmtime(filepath_or_fp) else: file = filepath_or_fp if not filename: filename = getattr(file, 'name', None) file.seek(0, 2) size = file.tell() file.seek(0) if mimetype is None and filename: mimetype = mimetypes.guess_type(filename)[0] if mimetype is None: mimetype = 'application/octet-stream' headers = werkzeug.datastructures.Headers() if as_attachment: if filename is None: raise TypeError( 'filename unavailable, required for sending as attachment') headers.add('Content-Disposition', 'attachment', filename=filename) headers['Content-Length'] = size data = wrap_file(request.httprequest.environ, file) rv = Response(data, mimetype=mimetype, headers=headers, direct_passthrough=True) if isinstance(mtime, str): try: server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT mtime = datetime.datetime.strptime( mtime.split('.')[0], server_format) except Exception: mtime = None if mtime is not None: rv.last_modified = mtime rv.cache_control.public = True if cache_timeout: rv.cache_control.max_age = cache_timeout rv.expires = int(time.time() + cache_timeout) if add_etags and filename and mtime: etag_str = 'odoo-%s-%s-%s' % ( mtime, size, adler32( filename.encode('utf-8') if isinstance(filename, unicode) else filename) & 0xffffffff) # hide odoo string from etags rv.set_etag(hashlib.md5(etag_str).hexdigest()) if conditional: rv = rv.make_conditional(request.httprequest) # make sure we don't send x-sendfile for servers that # ignore the 304 status code for x-sendfile. if rv.status_code == 304: rv.headers.pop('x-sendfile', None) return rv