def deco(request): try: user_id = get_user(request) issession = check_session(request) if user_id != None and issession == True: return f(request) except WrongRequestMethod: raise http_exc.HTTPBadRequest() # msg = request.get_error_msg('RequestError') # return send_error_response(msg) except NoResultFound: raise http_exc.HTTPNotFound() # msg = request.get_error_msg('NoResultFound') # return send_error_response(msg) except KeyError: raise http_exc.HTTPUnauthorized() # msg = request.get_error_msg('Unauthorised') # return send_error_response(msg) except AttributeError: raise http_exc.HTTPUnauthorized() # msg = request.get_error_msg('Unauthorised') # return send_error_response(msg) except jwt.exceptions.DecodeError: msg = request.get_error_msg('TokenError') return send_error_response(msg)
def generate_report(request): """Generates xlsx report """ try: user_id = request.user lang = rt.language(user_id) except KeyError: raise http_exc.HTTPUnauthorized() try: project = rt.get_state(user_id)._project_id # TODO remove test project if project is None: project = request.json_body['data']['project'] rt.update_state(user_id, tool_id='forecast', project_id=project) wb = rt.get_wb(user_id) session = request.dbsession permission_tree = build_permission_tree(session, project_name=project) scenarios = get_scenarios(session, user_id, None) for scenario in scenarios: scenario['details'] = get_scenario_details(session, user_id, scenario['id']) options = reporting.get_options_data(config=wb.data_config, scenarios=scenarios) data = reporting.collect_report_data(options=options, permission_tree=permission_tree, container=wb.default_container, config=wb.data_config, entities_ids=wb.selection, lang=lang) reporting.create_report(request.json_body['data']['file_name'], data) except Exception: raise http_exc.HTTPClientError() else: return Response(json_body=json.dumps('Success'), content_type='application/json')
def delete_user_identity(request): # Grab the identity id = request.matchdict['identity_id'] try: identity = DBSession.query(Identity) \ .filter(Identity.id==id) \ .first() except DBAPIError: raise httpexceptions.HTTPServiceUnavailable( connection_error_message, content_type='text/plain', ) if identity is None: raise httpexceptions.HTTPNotFound() elif len(identity.user.identities) <= 1: raise httpexceptions.HTTPForbidden("Cannot delete the only remaining " "identity connection.") # Check that this user has permission to remove an identity. permissible = security.has_permission('delete', identity, request) if not permissible: raise httpexceptions.HTTPUnauthorized() # Remove the identity DBSession.delete(identity) raise httpexceptions.HTTPNoContent()
def listener_add(self): log = logs.ice_log(__name__, self.request) # Try to find listener by the data from POST listener = self.findListenerByPost() if not listener: raise exc.HTTPUnauthorized() # If there is no access data connected to current listener, raise exception access = self.accessParams(listener) if not access: log.critical( 'There is no access data for listener with id {}'.format( listener.id, True)) raise exc.HTTPInternalServerError() # Check if user has active account if datetime.now().date() > access.expiration_date: raise exc.HTTPForbidden() # Check if user is not already connected if self.countActiveListeners(listener) >= access.max_listeners: raise exc.HTTPForbidden() # Add user to active_listeners table new_listener = models.ActiveListeners( listener_id=listener.id, listener_ip=self.request.remote_addr) self.request.dbsession.add(new_listener) log.info('Listener with id {} connected to icecast'.format( listener.id)) return Response(headerlist=[("listener_accepted", "1")], status_int=200)
def hawk_sessions(request): """Grab the Hawk Session from another Authentication backend.""" authn = AccountsAuthenticationPolicy() user = authn.authenticated_userid(request) if user is None: response = httpexceptions.HTTPUnauthorized() response.headers.update(authn.forget(request)) return response settings = request.registry.settings hmac_secret = settings['userid_hmac_secret'] algorithm = settings['hawk.algorithm'] token = os.urandom(32).hex() hawk_auth = HawkAuth(hawk_session=token, algorithm=algorithm) credentials = hawk_auth.credentials encoded_id = utils.hmac_digest(hmac_secret, credentials['id'].decode('utf-8')) cache_key = HAWK_SESSION_KEY.format(encoded_id) cache_ttl = int(settings['hawk.session_ttl_seconds']) session = utils.json.dumps({ "key": credentials["key"], "algorithm": credentials["algorithm"], "user_id": user }) request.registry.cache.set(cache_key, session, cache_ttl) headers = {'Hawk-Session-Token': token} return Response(headers=headers, status_code=201)
def delete_file(self): if self.admin_id is None: raise exc.HTTPUnauthorized('You are not authorized to delete file %s' % self.file_id) self.s3_fileshandler.delete_key(self.file_id) return { 'success': True }
def login(request): login = request.POST['username'] password = request.POST['password'] user = authenticate(request, login, password) if user: return {'result': 'ok', 'token': make_token(request, user)} else: raise exc.HTTPUnauthorized()
def findListenerByPost(self): # Get uuid from POST sent by icecast listener_uuid = self.uuidFromPost() # Try to find listener with given uuid listener = self.findListener(listener_uuid) if not listener: raise exc.HTTPUnauthorized() return listener
def unsubscribe(self): request = self.request subscription_id = request.GET['subscription_id'] subscription = Subscriptions.get_by_id(subscription_id) if subscription: if request.authenticated_userid != subscription.uri: raise httpexceptions.HTTPUnauthorized() subscription.active = False return {} return {}
def _extract_posted_body_id(request): try: # Anonymous creation with POST. return request.json["data"]["id"] except (ValueError, KeyError): # Bad POST data. if request.method.lower() == "post": error_details = {"name": "data.id", "description": "data.id in body: Required"} raise_invalid(request, **error_details) # Anonymous GET error_msg = "Cannot read accounts." raise http_error(httpexceptions.HTTPUnauthorized(), error=error_msg)
def edit_profile(self): """Handle POST payload from profile update form.""" if self.request.method != 'POST': return httpexceptions.HTTPMethodNotAllowed() # Nothing to do here for non logged-in users if self.request.authenticated_userid is None: return httpexceptions.HTTPUnauthorized() err, appstruct = validate_form(self.form, self.request.POST.items()) if err is not None: return err user = User.get_by_userid(self.request.domain, self.request.authenticated_userid) response = {'model': {'email': user.email}} # We allow updating subscriptions without validating a password subscriptions = appstruct.get('subscriptions') if subscriptions: data = json.loads(subscriptions) err = _update_subscription_data(self.request, data) if err is not None: return err return response # Any updates to fields below this point require password validation. # # `pwd` is the current password # `password` (used below) is optional, and is the new password # if not User.validate_user(user, appstruct.get('pwd')): return {'errors': {'pwd': _('Invalid password')}, 'code': 401} email = appstruct.get('email') if email: email_user = User.get_by_email(email) if email_user: if email_user.id != user.id: return { 'errors': { 'pwd': _('That email is already used') }, } response['model']['email'] = user.email = email password = appstruct.get('password') if password: user.password = password return response
def test_get_report_options_exception_401(web_app): """Test for view get_report_options exception 401 :param web_app: :type web_app: :return: :rtype: """ with pytest.raises(Exception) as exc_info: web_app.post_json("/forecast/get_report_options") actual = exc_info.value.args[0] expected = httpexc.HTTPUnauthorized().status assert expected in actual
def chpass(request): data = request.POST if request.authenticated_userid: pw = data['password'] if pw != data['confirm']: raise exc.HTTPForbidden() user = request.user with transaction.manager: user.password = encrypt_password(data['password']) request.dbsession.add(user) return dict(result='ok', token=make_token(request, request.user)) raise exc.HTTPUnauthorized()
def response_error(context, request): """Catch response error from Sync and trace them.""" message = '%s %s: %s' % (context.response.status_code, context.response.reason, context.response.text) # XXX: Make sure these HTTPError exception are coming from SyncClient. statsd_count(request, "syncclient.status_code.%s" % context.response.status_code) if context.response.status_code in (400, 401, 403, 404): # For this code we also want to log the info about the error. logger.info(context, exc_info=True) # For this specific code we do not want to log the error. if context.response.status_code == 304: response = httpexceptions.HTTPNotModified() elif context.response.status_code == 400: response = http_error(httpexceptions.HTTPBadRequest(), errno=ERRORS.INVALID_PARAMETERS, message=message) elif context.response.status_code == 401: response = http_error(httpexceptions.HTTPUnauthorized(), errno=ERRORS.INVALID_AUTH_TOKEN, message=message) # Forget the current user credentials. response.headers.extend(forget(request)) elif context.response.status_code == 403: response = http_error(httpexceptions.HTTPForbidden(), errno=ERRORS.FORBIDDEN, message=message) elif context.response.status_code == 404: response = http_error(httpexceptions.HTTPNotFound(), errno=ERRORS.INVALID_RESOURCE_ID, message=message) elif context.response.status_code == 412: message = 'Resource was modified meanwhile' response = http_error(httpexceptions.HTTPPreconditionFailed(), errno=ERRORS.MODIFIED_MEANWHILE, message=message) else: # For this code we also want to log the error. logger.error(context, exc_info=True) response = service_unavailable( httpexceptions.HTTPServiceUnavailable(), request) request.response = response export_headers(context.response, request) return reapply_cors(request, response)
def annotator_token(request): """ Return a JWT access token for the given request. The token can be used in the Authorization header in subsequent requests to the API to authenticate the user identified by the request.authenticated_userid of the _current_ request. """ try: session.check_csrf_token(request, token='assertion') except exceptions.BadCSRFToken: raise httpexceptions.HTTPUnauthorized() return generate_jwt(request, 3600)
def reset_password(self): """Request user password reset email""" reset_secret = self.request.json['reset_secret'] new_pass = self.request.json['password'] user = self.request.dbsession.query(User).filter_by(reset_secret=reset_secret).first() if user is not None and user.reset_expire > datetime.datetime.utcnow(): try: user.hash_password(new_pass) except ValueError: return exc.HTTPBadRequest() user.clear_secret() transaction.commit() return {'status': 'OK'} return exc.HTTPUnauthorized()
def _extract_posted_body_id(request): try: # Anonymous creation with POST. return request.json['data']['id'] except (ValueError, KeyError): # Bad POST data. if request.method.lower() == 'post': error_details = { 'name': 'data.id', 'description': 'data.id in body: Required' } raise_invalid(request, **error_details) # Anonymous GET error_msg = 'Cannot read accounts.' raise http_error(httpexceptions.HTTPUnauthorized(), error=error_msg)
def authorization_required(request): """Distinguish authentication required (``401 Unauthorized``) from not allowed (``403 Forbidden``). """ if Authenticated not in request.effective_principals: error_msg = "Please authenticate yourself to use this endpoint." response = http_error(httpexceptions.HTTPUnauthorized(), errno=ERRORS.MISSING_AUTH_TOKEN, message=error_msg) response.headers.extend(forget(request)) return response error_msg = "This user cannot access this resource." response = http_error(httpexceptions.HTTPForbidden(), errno=ERRORS.FORBIDDEN, message=error_msg) return response
def disable_user(self): """Disable the user by setting a random password.""" if self.request.authenticated_userid is None: return httpexceptions.HTTPUnauthorized() err, appstruct = validate_form(self.form, self.request.POST.items()) if err is not None: return err user = User.get_by_userid(self.request.domain, self.request.authenticated_userid) if User.validate_user(user, appstruct['pwd']): # Password check. # TODO: maybe have an explicit disabled flag in the status user.password = User.generate_random_password() self.request.session.flash(_('Account disabled.'), 'success') return {} else: return dict(errors={'pwd': _('Invalid password')}, code=401)
def get_report_options(request): """Returns options for report """ try: user_id = request.user except KeyError: raise http_exc.HTTPUnauthorized() try: # project = rt.get_state(user_id)._project_id wb = rt.get_wb(user_id) session = request.dbsession # permission_tree = build_permission_tree(session, project_name=project) # filters = {'authors': ['default_user'], 'period': [], 'criteria': []} scenarios = get_scenarios(session, user_id, None) for scenario in scenarios: scenario['details'] = get_scenario_details(session, user_id, scenario['id']) data = reporting.get_options_data(config=wb.data_config, scenarios=scenarios) except Exception: raise http_exc.HTTPClientError() else: return Response(json_body=json.dumps(data), content_type='application/json')
def unauthenticated_userid(self, request): """ Find the owner of the :http:header:`X-Weasyl-API-Key`. If there was no :http:header:`X-Weasyl-API-Key` header set, this will return :py:data:`None`. If the API key provided was invalid (i.e. doesn't map to a user), an :py:class:`~pyramid.httpexceptions.HTTPUnauthorized` exception will be raised. Otherwise, the API key's owner's userid is returned. :param request: The current pyramid :py:class:`~pyramid.request.Request`. """ api_token = request.headers.get('X-Weasyl-API-Key') if api_token is None: return None token_object = APIToken.query.filter_by(token=api_token).first() if token_object is None: raise httpexceptions.HTTPUnauthorized( headers={ 'WWW-Authenticate': 'Weasyl-API-Key realm="Weasyl"', }) return token_object.userid
def get_parent_id(self, request): # The whole challenge here is that we want to isolate what # authenticated users can list, but give access to everything to # administrators. # Plus when anonymous create accounts, we have to set their parent id # to the same value they would obtain when authenticated. if self.context.is_administrator: if self.context.on_collection: # Admin see all accounts. return '*' else: # No pattern matching for admin on single record. return request.matchdict['id'] if not self.context.is_anonymous: # Authenticated users see their own account only. return request.selected_userid # Anonymous creation with PUT. if 'id' in request.matchdict: return request.matchdict['id'] try: # Anonymous creation with POST. return request.json['data']['id'] except (ValueError, KeyError): # Bad POST data. if request.method.lower() == 'post': error_details = { 'name': 'data.id', 'description': 'data.id in body: Required' } raise_invalid(request, **error_details) # Anonymous GET error_msg = 'Cannot read accounts.' raise http_error(httpexceptions.HTTPUnauthorized(), error=error_msg)
def listener_remove(self): log = logs.ice_log(__name__, self.request) # Try to find listener by the data from POST listener = self.findListenerByPost() if not listener: raise exc.HTTPUnauthorized() if self.countActiveListeners(listener) <= 0: log.critical( 'Number of active listeners is <= 0 during listener_remove. | Listener id: {}' .format(listener.id), True) raise exc.HTTPInternalServerError() # Try to find active listener with given id and ip query = self.request.dbsession.query(models.ActiveListeners) listener_to_remove = query.filter( models.ActiveListeners.listener_id == listener.id).filter( models.ActiveListeners.listener_ip == self.request.remote_addr).first() # If there is no active listener that match to given ip, remove first with given id if not listener_to_remove: listener_to_remove = query.filter( models.ActiveListeners.listener_id == listener.id).first() # Check if we finally find him if not listener_to_remove: log.critical( 'Can not find listener with given id during listener_remove. | Listener id: {}' .format(listener.id), True) raise exc.HTTPInternalServerError() self.request.dbsession.delete(listener_to_remove) log.info('Listener with id {} disconnected from icecast'.format( listener.id)) return Response(status_int=200)
def unauthenticated_userid(self, request): """ Find the owner of the OAuth2 bearer token. If there was no :http:header:`Authorization` header set, this will return :py:data:`None`. If the bearer token provided was invalid (because e.g. the bearer token was invalid), an :py:class:`~pyramid.httpexceptions.HTTPUnauthorized` exception will be raised. Otherwise, the bearer token's owner's userid is returned. :param request: The current pyramid :py:class:`~pyramid.request.Request`. """ authorization = request.headers.get('Authorization') if authorization is None: return None token_object = find_token_for_authorization(authorization) if token_object is None: raise httpexceptions.HTTPUnauthorized( headers={ 'WWW-Authenticate': 'Bearer realm="Weasyl" error="invalid_token"', }) return token_object.userid
def refresh(request): if request.authenticated_userid: return dict(result='ok', token=make_token(request, request.user)) else: raise exc.HTTPUnauthorized()
def __call__(self, *args, **kw): for arg in args: if isinstance(arg, Request) or isinstance(arg, DummyRequest): if self.login(arg): return self.fn(*args, **kw) raise http.HTTPUnauthorized(headers={"Refresh": "url=/"})
def login(self): user_id = self.authenticate() if not user_id: return exc.HTTPUnauthorized() headers = remember(self.request, user_id) return Response(headers=headers)
def wrapper(request, *args, **kwargs): if not request.authenticated_userid: raise httpexceptions.HTTPUnauthorized() return function(request, *args, **kwargs)
def basic_challenge(request): response = httpexceptions.HTTPUnauthorized() response.headers.update(security.forget(request)) return response
def __call__(self, request): """ Handler that mimics what CubicWebPublisher.main_handle_request and CubicWebPublisher.core_handle do """ req = request.cw_request vreg = request.registry['cubicweb.registry'] try: content = None try: with cw_to_pyramid(request): ctrlid, rset = self.appli.url_resolver.process( req, req.path) try: controller = vreg['controllers'].select( ctrlid, req, appli=self.appli) log.info( "REQUEST [%s] '%s' selected controller %s at %s:%s", ctrlid, req.path, controller, inspect.getsourcefile(controller.__class__), inspect.getsourcelines(controller.__class__)[1]) emit_to_debug_channel("vreg", { "vreg": vreg, }) emit_to_debug_channel( "controller", { "kind": ctrlid, "request": req, "path": req.path, "controller": controller, "config": self.appli.repo.config, }) except cubicweb.NoSelectableObject: log.warn("WARNING '%s' unauthorized request", req.path) raise httpexceptions.HTTPUnauthorized( req._('not authorized')) req.update_search_state() content = controller.publish(rset=rset) # XXX this auto-commit should be handled by the cw_request # cleanup or the pyramid transaction manager. # It is kept here to have the ValidationError handling bw # compatible if req.cnx: txuuid = req.cnx.commit() # commited = True if txuuid is not None: req.data['last_undoable_transaction'] = txuuid except cubicweb.web.ValidationError as ex: # XXX The validation_error_handler implementation is light, we # should redo it better in cw_to_pyramid, so it can be properly # handled when raised from a cubicweb view. # BUT the real handling of validation errors should be done # earlier in the controllers, not here. In the end, the # ValidationError should never by handled here. content = self.appli.validation_error_handler(req, ex) except cubicweb.web.RemoteCallFailed: # XXX The default pyramid error handler (or one that we provide # for this exception) should be enough # content = self.appli.ajax_error_handler(req, ex) raise if content is not None: request.response.body = content except LogOut as ex: # The actual 'logging out' logic should be in separated function # that is accessible by the pyramid views headers = security.forget(request) raise HTTPSeeOther(ex.url, headers=headers) except cubicweb.AuthenticationError: # Will occur upon access to req.cnx which is a # cubicweb.dbapi._NeedAuthAccessMock. if not content: content = vreg['views'].main_template(req, 'login') request.response.status_code = 403 request.response.body = content except cubicweb.web.NotFound as ex: view = vreg['views'].select('404', req) content = vreg['views'].main_template(req, view=view) request.response.status_code = ex.status request.response.body = content finally: # XXX CubicWebPyramidRequest.headers_out should # access directly the pyramid response headers. request.response.headers.clear() for k, v in req.headers_out.getAllRawHeaders(): for item in v: request.response.headers.add(k, item) return request.response