def user_node(self, request): """Returns the storage node root for the user""" # warning: # the client expects a string body not a json body # except when the node is 'null' # If we're not using a node assignment backend then return fallback. if self.nodes is None: return self.return_fallback() # Look up the user and see if they already have a node assigned. self.auth.get_user_info(request.user, ['syncNode']) if not request.user.get('userid'): return HTTPNotFound() if request.user.get('syncNode'): syncnode = 'https://%s/' % request.user.get('syncNode') return text_response(syncnode) # Assign a new node using the backend. # This assumes it will remember the assignment, and optimally that # it will cache it in the user's syncNode property for our reference. try: new_node = self.nodes.get_best_node('sync', user=request.user) except NodeAlreadyWrittenError, e: new_node = e.node
def delete_user(self, request): """Deletes the user.""" if not hasattr(request, 'user_password'): raise HTTPBadRequest() res = self.auth.delete_user(request.user, request.user_password) return text_response(int(res))
def _heartbeat(self, request): """Performs a health check on the server. Returns a 200 on success, a 503 on failure. Application based on SyncServerApp can implement _check_server to add their own tests. It is enabled by default at __heartbeat__ but does not perform any test on the infra unless _check_server is overriden. """ # calls the check if any - this will raise a 503 if anything's wrong self._check_server(request) return text_response('')
def change_password(self, request): """Changes the user's password Takes a classical authentication or a reset code """ # the body is in plain text utf8 string new_password = request.body.decode('utf8') if not valid_password(request.user.get('username'), new_password): raise HTTPBadRequest('Password should be at least 8 ' 'characters and not the same as your ' 'username') key = request.headers.get('X-Weave-Password-Reset') if key is not None: user_id = self.auth.get_user_id(request.user) if user_id is None: raise HTTPNotFound() if not self.reset.verify_reset_code(request.user, key): log_cef('Invalid Reset Code submitted', 5, request.environ, self.app.config, request.user['username'], 'InvalidResetCode', submitedtoken=key) raise HTTPJsonBadRequest(ERROR_INVALID_RESET_CODE) if not self.auth.admin_update_password(request.user, new_password, key): raise HTTPInternalServerError('Password change failed ' 'unexpectedly.') else: # classical auth self.app.auth.authenticate_user(request, self.app.config, request.user['username']) if request.user['userid'] is None: log_cef('User Authentication Failed', 5, request.environ, self.app.config, request.user['username'], AUTH_FAILURE) raise HTTPUnauthorized() if not self.auth.update_password( request.user, request.user_password, new_password): raise HTTPInternalServerError('Password change failed ' 'unexpectedly.') return text_response('success')
def delete_password_reset(self, request, **data): """Forces a password reset clear""" if self.reset is None: logger.debug('reset attempted, but no resetcode library installed') raise HTTPServiceUnavailable() self._check_captcha(request, data) self.auth.get_user_id(request.user) self.reset.clear_reset_code(request.user) log_cef("User requested password reset clear", 9, request.environ, self.app.config, request.user.get('username'), PASSWD_RESET_CLR) return text_response('success')
def change_password(self, request): """Changes the user's password Takes a classical authentication or a reset code """ # the body is in plain text utf8 string new_password = request.body.decode('utf8') if not valid_password(request.user.get('username'), new_password): raise HTTPBadRequest('Password should be at least 8 ' 'characters and not the same as your ' 'username') key = request.headers.get('X-Weave-Password-Reset') if key is not None: user_id = self.auth.get_user_id(request.user) if user_id is None: raise HTTPNotFound() if not self.reset.verify_reset_code(request.user, key): log_cef('Invalid Reset Code submitted', 5, request.environ, self.app.config, request.user['username'], 'InvalidResetCode', submitedtoken=key) raise HTTPJsonBadRequest(ERROR_INVALID_RESET_CODE) if not self.auth.admin_update_password(request.user, new_password, key): raise HTTPInternalServerError('Password change failed ' 'unexpectedly.') else: # classical auth self.app.auth.authenticate_user(request, self.app.config, request.user['username']) if request.user['userid'] is None: log_cef('User Authentication Failed', 5, request.environ, self.app.config, request.user['username'], AUTH_FAILURE) raise HTTPUnauthorized() if not self.auth.update_password(request.user, request.user_password, new_password): raise HTTPInternalServerError('Password change failed ' 'unexpectedly.') return text_response('success')
def password_reset(self, request, **data): """Sends an e-mail for a password reset request.""" if self.reset is None: self.logger.debug('reset attempted, but no resetcode library ' 'installed') raise HTTPServiceUnavailable() request.response.headers.add('X-Frame-Options', 'DENY') user_id = self.auth.get_user_id(request.user) if user_id is None: # user not found raise HTTPJsonBadRequest(ERROR_INVALID_USER) self.auth.get_user_info(request.user, ['mail']) if request.user.get('mail') is None: raise HTTPJsonBadRequest(ERROR_NO_EMAIL_ADDRESS) self._check_captcha(request, data) try: # the request looks fine, let's generate the reset code code = self.reset.generate_reset_code(request.user) urlgen = URLGenerator(self.app.mapper, request.environ) data = {'user_name': request.user['username'], 'code': code, 'host': request.host_url, 'url': urlgen(controller="user", action="password_reset_form")} body = render_mako('password_reset_mail.mako', **data) sender = request.config['smtp.sender'] host = request.config['smtp.host'] port = int(request.config['smtp.port']) user = request.config.get('smtp.user') password = request.config.get('smtp.password') subject = 'Resetting your Services password' res, msg = send_email(sender, request.user['mail'], subject, body, host, port, user, password) if not res: raise HTTPServiceUnavailable(msg) except AlreadySentError: #backend handled the reset code email. Keep going pass return text_response('success')
def change_email(self, request): """Changes the user e-mail""" # the body is in plain text email = request.body if not valid_email(email): raise HTTPJsonBadRequest(ERROR_NO_EMAIL_ADDRESS) if not hasattr(request, 'user_password'): raise HTTPBadRequest() if not self.auth.update_field(request.user, request.user_password, 'mail', email): raise HTTPInternalServerError('User update failed.') return text_response(email)
def password_reset(self, request, **data): """Sends an e-mail for a password reset request.""" if self.reset is None: logger.debug('reset attempted, but no resetcode library installed') raise HTTPServiceUnavailable() user_id = self.auth.get_user_id(request.user) if user_id is None: # user not found raise HTTPJsonBadRequest(ERROR_INVALID_USER) self.auth.get_user_info(request.user, ['mail']) if request.user.get('mail') is None: raise HTTPJsonBadRequest(ERROR_NO_EMAIL_ADDRESS) self._check_captcha(request, data) try: # the request looks fine, let's generate the reset code code = self.reset.generate_reset_code(request.user) data = { 'host': request.host_url, 'user_name': request.user['username'], 'code': code } body = render_mako('password_reset_mail.mako', **data) sender = request.config['smtp.sender'] host = request.config['smtp.host'] port = int(request.config['smtp.port']) user = request.config.get('smtp.user') password = request.config.get('smtp.password') subject = 'Resetting your Services password' res, msg = send_email(sender, request.user['mail'], subject, body, host, port, user, password) if not res: raise HTTPServiceUnavailable(msg) except AlreadySentError: #backend handled the reset code email. Keep going pass return text_response('success')
def test_response_conversions(self): data = {'some': 'data'} resp = text_response(data) self.assertEquals(resp.body, "{'some': 'data'}") self.assertEquals(resp.content_type, 'text/plain') data = "abc" resp = whoisi_response(data) self.assertEquals( resp.body, '\x00\x00\x00\x03"a"\x00\x00\x00\x03"b"\x00\x00\x00\x03"c"') self.assertEquals(resp.content_type, 'application/whoisi') request = Request({}) request.accept = 'application/whoisi' resp = convert_response(request, data) self.assertEquals( resp.body, '\x00\x00\x00\x03"a"\x00\x00\x00\x03"b"\x00\x00\x00\x03"c"') self.assertEquals(resp.content_type, 'application/whoisi') resp = newlines_response(data) self.assertEquals(resp.body, '"a"\n"b"\n"c"\n') self.assertEquals(resp.content_type, 'application/newlines') request = Request({}) request.accept = 'application/newlines' resp = convert_response(request, data) self.assertEquals(resp.body, '"a"\n"b"\n"c"\n') self.assertEquals(resp.content_type, 'application/newlines') data = {'some': 'data'} resp = json_response(data) self.assertEquals(resp.body, '{"some": "data"}') self.assertEquals(resp.content_type, 'application/json') request = Request({}) resp = convert_response(request, data) self.assertEquals(resp.body, '{"some": "data"}') self.assertEquals(resp.content_type, 'application/json')
def test_response_conversions(self): data = {'some': 'data'} resp = text_response(data) self.assertEquals(resp.body, "{'some': 'data'}") self.assertEquals(resp.content_type, 'text/plain') data = "abc" resp = whoisi_response(data) self.assertEquals(resp.body, '\x00\x00\x00\x03"a"\x00\x00\x00\x03"b"\x00\x00\x00\x03"c"') self.assertEquals(resp.content_type, 'application/whoisi') request = Request({}) request.accept = 'application/whoisi' resp = convert_response(request, data) self.assertEquals(resp.body, '\x00\x00\x00\x03"a"\x00\x00\x00\x03"b"\x00\x00\x00\x03"c"') self.assertEquals(resp.content_type, 'application/whoisi') resp = newlines_response(data) self.assertEquals(resp.body, '"a"\n"b"\n"c"\n') self.assertEquals(resp.content_type, 'application/newlines') request = Request({}) request.accept = 'application/newlines' resp = convert_response(request, data) self.assertEquals(resp.body, '"a"\n"b"\n"c"\n') self.assertEquals(resp.content_type, 'application/newlines') data = {'some': 'data'} resp = json_response(data) self.assertEquals(resp.body, '{"some": "data"}') self.assertEquals(resp.content_type, 'application/json') request = Request({}) resp = convert_response(request, data) self.assertEquals(resp.body, '{"some": "data"}') self.assertEquals(resp.content_type, 'application/json')
def return_fallback(self): if self.fallback_node is None: msg = "No fallback node has been configured. "\ "Please set nodes.fallback_node in your config file." raise BackendError(msg) return text_response(self.fallback_node)
def user_exists(self, request): if request.user.get('username') is None: raise HTTPNotFound() uid = self.auth.get_user_id(request.user) return text_response(int(uid is not None))
def index(self, request, **kw): """Show a simple "It Works!" page at the root.""" return text_response("It Works!")
new_node = e.node except Exception: self.logger.error(traceback.format_exc()) self.logger.error("Node assignment failed") return json_response(None) if new_node is None: return json_response(None) if new_node != "null": if not new_node.startswith('http'): new_node = 'https://' + new_node if not new_node.endswith('/'): new_node = new_node + '/' return text_response(new_node) def password_reset(self, request, **data): """Sends an e-mail for a password reset request.""" if self.reset is None: self.logger.debug('reset attempted, but no resetcode library ' 'installed') raise HTTPServiceUnavailable() request.response.headers.add('X-Frame-Options', 'DENY') user_id = self.auth.get_user_id(request.user) if user_id is None: # user not found raise HTTPJsonBadRequest(ERROR_INVALID_USER) self.auth.get_user_info(request.user, ['mail'])