def forbidden_view(context, request): msg = context.message result = context.result message = msg + "\n" + str(result) resp = HTTPForbidden() resp.body = bytes_(message) return resp
def forbidden_view(context, request): msg = context.message result = context.result message = msg + '\n' + str(result) resp = HTTPForbidden() resp.body = message return resp
def closure(request, *args, **kwargs): api_key = request.GET.get('key', None) raven_client = request.registry.raven_client stats_client = request.registry.stats_client if api_key is None: stats_client.incr('%s.no_api_key' % func_name) if error_on_invalidkey: return invalid_api_key_response() session = request.db_ro_session try: result = session.execute(API_CHECK.bindparams(api_key=api_key)) found_key = result.fetchone() except Exception: # pragma: no cover # if we cannot connect to backend DB, skip api key check raven_client.captureException() stats_client.incr('%s.dbfailure_skip_api_key' % func_name) return func(request, *args, **kwargs) if found_key is not None: maxreq, api_key_log, shortname = found_key if not shortname: # pragma: no cover shortname = api_key # remember api key and shortname on the request request.api_key_log = bool(api_key_log) request.api_key_name = shortname stats_client.incr('%s.api_key.%s' % (func_name, shortname)) should_limit = rate_limit(request.registry.redis_client, api_key, maxreq=maxreq) if should_limit: result = HTTPForbidden() result.content_type = 'application/json' result.body = DAILY_LIMIT return result elif should_limit is None: # pragma: no cover # We couldn't connect to Redis stats_client.incr('%s.redisfailure_skip_limit' % func_name) else: stats_client.incr('%s.unknown_api_key' % func_name) if error_on_invalidkey: return invalid_api_key_response() # provide the same api log/name attributes request.api_key_log = False request.api_key_name = None return func(request, *args, **kwargs)
def closure(request, *args, **kwargs): api_key = request.GET.get('key', None) heka_client = get_heka_client() stats_client = request.registry.stats_client if api_key is None: stats_client.incr('%s.no_api_key' % func_name) if error_on_invalidkey: return invalid_api_key_response() session = request.db_slave_session try: result = session.execute(API_CHECK.bindparams(api_key=api_key)) found_key = result.fetchone() except Exception: # if we cannot connect to backend DB, skip api key check heka_client.raven(RAVEN_ERROR) stats_client.incr('%s.dbfailure_skip_api_key' % func_name) return func(request, *args, **kwargs) if found_key is not None: maxreq, shortname = found_key if not shortname: shortname = api_key stats_client.incr('%s.api_key.%s' % (func_name, shortname)) should_limit = rate_limit(request.registry.redis_client, api_key, maxreq=maxreq) if should_limit: result = HTTPForbidden() result.content_type = 'application/json' result.body = DAILY_LIMIT return result elif should_limit is None: # We couldn't connect to Redis stats_client.incr('%s.redisfailure_skip_limit' % func_name) else: stats_client.incr('%s.unknown_api_key' % func_name) if error_on_invalidkey: return invalid_api_key_response() return func(request, *args, **kwargs)
def get_target_user_table(self, target: str) -> Optional[UserTable]: if not target or "@" not in target: return None if target == self.request.user.email: target_user = self.request.user else: target_user = DBSession.query(User).filter( User.email == target).one() if (target_user not in self.context.lecture_resource.dossier_resource. dossier.team.users): raise HTTPForbidden("Transfert non autorisé") return target_user.table_for(self.lecture)
def security_cb(r, o): geom_attr = getattr(o, _get_geom_col_info(layer)[0]) allowed = DBSession.query( RestrictionArea.area.collect.gcontains(geom_attr)) allowed = allowed.join(RestrictionArea.roles) allowed = allowed.join(RestrictionArea.layers) allowed = allowed.filter(RestrictionArea.area.area > 0) allowed = allowed.filter(RestrictionArea.readwrite == True) allowed = allowed.filter(Role.id == request.user.role.id) allowed = allowed.filter(Layer.id == layer.id).scalar() if not allowed: raise HTTPForbidden()
def proxy(self): if self.user is None: raise HTTPUnauthorized( "Authentication required", headers=[("WWW-Authenticate", 'Basic realm="TinyOWS"')] ) operation = self.lower_params.get("request") typenames = \ set([normalize_typename(self.lower_params.get("typename"))]) \ if "typename" in self.lower_params \ else set() method = self.request.method if method == "POST": try: (operation, typenames_post) = \ self._parse_body(self.request.body) except Exception as e: log.error("Error while parsing POST request body") log.exception(e) raise HTTPBadRequest( "Error parsing the request (see logs for more details)") typenames = typenames.union(typenames_post) if operation is None or operation == "": operation = "getcapabilities" if operation == "describefeaturetype": # for DescribeFeatureType we require that exactly one type-name # is given, otherwise we would have to filter the result if len(typenames) != 1: raise HTTPBadRequest( "Exactly one type-name must be given for " "DescribeFeatureType requests" ) if not self._is_allowed(typenames): raise HTTPForbidden( "No access rights for at least one of the given type-names" ) # we want clients to cache GetCapabilities and DescribeFeatureType req. use_cache = method == "GET" and operation in ("getcapabilities", "describefeaturetype") cache_control = PRIVATE_CACHE if use_cache else NO_CACHE response = self._proxy_callback( operation, self.role_id, cache_control, url=self._get_wfs_url(), params=dict(self.request.params), cache=use_cache, headers=self._get_headers(), body=self.request.body, ) return response
def get_and_check_subscription(request, company, guid): """Get and check permission to access a subscription """ model = SubscriptionModel(request.session) subscription = model.get(guid) if subscription is None: raise HTTPNotFound('No such subscription {}'.format(guid)) if subscription.customer.company_guid != company.guid: raise HTTPForbidden('You have no permission to access subscription {}' .format(guid)) return subscription
def import_file(request, oid, data, properties): """Import document from outer ZFiles database through RPC""" container = get_utility(IDocumentContainer) if not request.has_permission(CREATE_DOCUMENT_WITH_OWNER_PERMISSION, context=container): raise HTTPForbidden() if isinstance(data, Binary): data = data.data else: data = base64.b64decode(data) document = container.import_document(oid, data, properties, request) return document.oid
def __init__(self, context, request): if request.authenticated_userid is None: token = getattr(context, 'pw_token', None) rtoken = request.GET.get('t', object()) if token == rtoken and token.valid: super(UserChangePasswordForm, self).__init__(context, request) return else: if request.has_permission(security.PERM_EDIT): super(UserChangePasswordForm, self).__init__(context, request) return raise HTTPForbidden(_("Not allowed"))
def package_versions(context, request): """ Render the links for all versions of a package """ normalized_name = request.db.normalize_name(context.name) pkgs = request.db.all(normalized_name) if request.registry.use_fallback and not pkgs: redirect_url = "%s/%s/" % (request.registry.fallback_url.rstrip('/'), context.name) return HTTPFound(location=redirect_url) if not request.access.has_permission(normalized_name, 'read'): raise HTTPForbidden() return {'pkgs': pkgs}
def __init__(self, context, request): buttons = [] if request.has_permission(EDIT_COMMENT, context): buttons.append(self.button_save) if request.has_permission(DELETE_COMMENT, context): buttons.append(self.button_delete) if not buttons: raise HTTPForbidden( _("You're not allowed to edit or delete this comment")) buttons.append(self.button_cancel) self.buttons = buttons super(EditCommentForm, self).__init__(context, request)
def tinfo(self): tname = self.request.params.get('tname', None) if not tname: raise HTTPNotFound() tinfo = ptah.resolve('type:%s' % tname) if not tinfo: raise HTTPNotFound() if not tinfo in self.context.__type__.list_types(self.context): raise HTTPForbidden() return tinfo
def forbid_local_only(container): # type: (AnySettingsContainer) -> Any """ Raises an HTTP exception forbidding to resume the operation if invalid configuration is detected. """ config = get_weaver_configuration(container) if config not in WEAVER_CONFIGURATIONS_REMOTE: raise HTTPForbidden(json={ "description": "Invalid provider operation on [{}] instance. " "Processes requires unsupported remote execution.".format(config), })
def csrf_check(context, request): """ Checks for csrf validation explicitly from POSTed data. """ if request.method == "POST": token = request.POST.get("_csrf", None) # if we don't have it in normal POST, and this is ajax, # check in json encoded body. if not token and request.is_xhr: token = request.json_body.get("_csrf", None) if not token or token != request.session.get_csrf_token(): raise HTTPForbidden("CSRF token is missing or invalid")
def ticket_claim(self): """ After login or registration, redirect back here, where information about the ticket will be displayed, and a confirmation that you want to use the ticket for the current user. While we use a regular deform form, it's not ment to be displayed or handle any validation. """ if not self.request.authenticated_userid: raise HTTPForbidden( "Direct access to this view for unauthorized users not allowed." ) email = self.request.GET.get('email', '') ticket = self.context.invite_tickets.get(email, None) if ticket and ticket.closed != None: msg = _("This ticket has already been used.") self.flash_messages.add(msg, type='danger', auto_destruct=True, require_commit=False) return HTTPFound(location=self.request.resource_url(self.context)) schema = get_content_schemas( self.request.registry)['Meeting']['claim_ticket']() schema = schema.bind(context=self.context, request=self.request, view=self) form = deform.Form(schema, buttons=( button_add, button_cancel, )) if self.request.GET.get('claim'): controls = self.request.params.items() try: appstruct = form.validate(controls) except deform.ValidationFailure, e: msg = _( "ticket_validation_fail", default="Ticket validation failed. Either the " "ticket doesn't exist, was already used or the url used improperly. " "If you need help, please contact the moderator that invited you to this meeting." ) self.flash_messages.add(msg, type='danger', auto_destruct=False, require_commit=False) url = self.request.resource_url(self.root) return HTTPFound(location=url) #Everything in order, claim ticket ticket = self.context.invite_tickets[appstruct['email']] claim_ticket(ticket, self.request, self.request.authenticated_userid) self.flash_messages.add( _(u"You've been granted access to the meeting. Welcome!")) url = self.request.resource_url(self.context) return HTTPFound(location=url)
def delete_feed(request): user_name = request.matchdict['user'] logged_in = authenticated_userid(request) if user_name != logged_in: return HTTPForbidden() user = User.get_by_screen_name(user_name) feed = Feed.get_by_userid_and_name(user.id, request.matchdict['feedname']) if feed is not None: DBSession.delete(feed) return Response()
def forbidden_view(request): """Called when a user has been denied access to a resource or view. Setup:: >>> from mock import Mock >>> from pyramid_simpleauth import view >>> _unauthenticated_userid = view.unauthenticated_userid >>> view.unauthenticated_userid = Mock() >>> mock_request = Mock() >>> mock_request.path = '/forbidden/page' >>> mock_request.route_url.return_value = 'http://foo.com/login' If the user is already logged in, it means they don't have the requisit permission, so we raise a 403 Forbidden error:: >>> view.unauthenticated_userid.return_value = 1234 >>> response = forbidden_view(mock_request) >>> response.status '403 Forbidden' Otherwise we redirect to the login page:: >>> view.unauthenticated_userid.return_value = None >>> response = forbidden_view(mock_request) >>> kwargs = { ... '_query': [('next', '/forbidden/page'),], ... 'traverse': ('login',) ... } >>> mock_request.route_url.assert_called_with('simpleauth', **kwargs) >>> response.location 'http://foo.com/login' >>> response.status '302 Found' Teardown:: >>> view.unauthenticated_userid = _unauthenticated_userid """ if unauthenticated_userid(request): return HTTPForbidden() query = {'next': request.path} username_param = validate_username_param(request) if username_param: query['username'] = username_param url = request.route_url('simpleauth', traverse=('login', ), _query=query.items()) return HTTPFound(location=url)
def manage_main(self): request = self.request view_data = self.sdi_mgmt_views(self.context, request) if not view_data: request.session['came_from'] = request.url raise HTTPForbidden( location=request.sdiapi.mgmt_path(request.root, '@@login') ) view_name = '@@%s' % (view_data[0]['view_name'],) return HTTPFound( location=request.sdiapi.mgmt_path(request.context, view_name) )
def upload_file(request, data, properties): """Create new document through RPC""" container = get_utility(IDocumentContainer) if not request.has_permission(CREATE_DOCUMENT_PERMISSION, context=container): raise HTTPForbidden() if isinstance(data, Binary): data = data.data else: data = base64.b64decode(data) document = container.add_document(data, properties, request) return document.oid
def cached_view_audit_self(context, request): source = context.model.source allowed = set(source['principals_allowed']['audit']) if allowed.isdisjoint(request.effective_principals): raise HTTPForbidden() path = source['object']['@id'] return { '@id': path, 'audit': [a for a in chain(*source['audit'].values()) if a['path'] == path], }
def check(request, remote_addr): try: query = request.dbsession.query( banlist) # Checks if the ip is in banlist records = query.filter(banlist.ip == remote_addr).all() except DBAPIError: return Response(db_err_msg, content_type='text/plain', status=500) if remote_addr in records: return (HTTPForbidden())
def put(self): if not self.request.has_permission('moderator'): # moderators can change the profile of every user if self.request.authenticated_userid != \ self.request.validated['id']: # but a normal user can only change its own profile raise HTTPForbidden( 'No permission to change this user profile') self._reset_title() return self._put(UserProfile, schema_internal_user_profile)
def post_upload(context, request): properties = context.upgrade_properties() if properties['status'] not in ('uploading', 'upload failed'): raise HTTPForbidden( 'status must be "uploading" to issue new credentials') accession_or_external = properties.get( 'accession') or properties['external_accession'] external = context.propsheets.get('external', None) if external is None: # Handle objects initially posted as another state. bucket = request.registry.settings['file_upload_bucket'] uuid = context.uuid mapping = context.schema['file_format_file_extension'] file_extension = mapping[properties['file_format']] date = properties['date_created'].split('T')[0].replace('-', '/') key = '{date}/{uuid}/{accession_or_external}{file_extension}'.format( accession_or_external=accession_or_external, date=date, file_extension=file_extension, uuid=uuid, **properties) elif external.get('service') == 's3': bucket = external['bucket'] key = external['key'] else: raise ValueError(external.get('service')) name = 'up{time:.6f}-{accession_or_external}'.format( accession_or_external=accession_or_external, time=time.time(), **properties)[:32] # max 32 chars profile_name = request.registry.settings.get('file_upload_profile_name') creds = external_creds(bucket, key, name, profile_name) new_properties = None if properties['status'] == 'upload failed': new_properties = properties.copy() new_properties['status'] = 'uploading' registry = request.registry registry.notify(BeforeModified(context, request)) context.update(new_properties, {'external': creds}) registry.notify(AfterModified(context, request)) rendered = request.embed('/%s/@@object' % context.uuid, as_user=True) result = { 'status': 'success', '@type': ['result'], '@graph': [rendered], } return result
def create_view(request): if not request.user: return HTTPForbidden() entry = Entry() form = EntryCreateForm(request.POST) if request.method == 'POST' and form.validate(): form.populate_obj(entry) entry.author = request.user DBSession.add(entry) return HTTPFound(location=request.route_url('home')) return {'form': form, 'cancel': request.route_url('home')}
def add_entry(request): if request.authenticated_userid: if request.method == 'POST': try: Entry.from_request(request) except psycopg2.Error: # this will catch any errors generated by the database return HTTPInternalServerError() entry = Entry.desc_new() return entry.json_detail() else: return HTTPForbidden()
def forbidden_view(request): """Called when a user has been denied access to a resource or view. If the user is already logged in, it means they don't have the requisit permission, so we raise a 403 Forbidden error. Otherwise we redirect to the login page. """ if authenticated_userid(request): return HTTPForbidden() url = request.route_url('login', _query=(('next', request.path), )) return HTTPFound(location=url)
def validate_credentials(email, password): """ Validates email and password against database returning a token dictionary. Parameters: email (str): email to log in with password (str): Password to log in with Response: token (dict): Dictionary token (JWT) """ try: query = """ SELECT u.id , json_build_object( 'id', u.id, 'username', u.username, 'first', u.first_name, 'last', u.last_name, 'email', u.email, 'photo', u.photo, 'guest', u.guest ) as user from pp.users u where u.email = %s and u.guest = false and u.date_deleted is null and u.temp is null and encode(digest(%s||u.salt, 'sha256'), 'hex')=u.password; """ result = execute_query(datasource="db/pillpool", query=query, db_params=[email, password]) if result: return result[0] else: raise HTTPForbidden("Invalid Username or Password.") except: raise HTTPForbidden("Invalid Username or Password.")
def _proto_read(self, layer: "main.Layer") -> FeatureCollection: """ Read features for the layer based on the self.request. """ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel Layer, RestrictionArea, Role, ) proto = self._get_protocol_for_layer(layer) if layer.public: return proto.read(self.request) user = self.request.user if user is None: raise HTTPForbidden() cls = proto.mapped_class geom_attr = proto.geom_attr ras = models.DBSession.query(RestrictionArea.area, RestrictionArea.area.ST_SRID()) ras = ras.join(RestrictionArea.roles) ras = ras.join(RestrictionArea.layers) ras = ras.filter(Role.id.in_(get_roles_id(self.request))) ras = ras.filter(Layer.id == layer.id) collect_ra = [] use_srid = -1 for ra, srid in ras.all(): if ra is None: return proto.read(self.request) use_srid = srid collect_ra.append(to_shape(ra)) if not collect_ra: raise HTTPForbidden() filter1_ = create_filter(self.request, cls, geom_attr) ra = cascaded_union(collect_ra) filter2_ = ga_func.ST_Contains(from_shape(ra, use_srid), getattr(cls, geom_attr)) filter_ = filter2_ if filter1_ is None else and_(filter1_, filter2_) feature = proto.read(self.request, filter=filter_) if isinstance(feature, HTTPException): raise feature # pylint: disable=raising-non-exception return feature
def closure(request, *args, **kwargs): raven_client = request.registry.raven_client stats_client = request.registry.stats_client api_key = None api_key_text = request.GET.get('key', None) if api_key_text is None: stats_client.incr('%s.no_api_key' % func_name) if error_on_invalidkey: return invalid_api_key_response() try: api_key = ApiKey.getkey(request.db_ro_session, api_key_text) except Exception: # pragma: no cover # if we cannot connect to backend DB, skip api key check raven_client.captureException() stats_client.incr('%s.dbfailure_skip_api_key' % func_name) if api_key is not None: stats_client.incr('%s.api_key.%s' % (func_name, api_key.name)) should_limit = rate_limit(request.registry.redis_client, api_key_text, maxreq=api_key.maxreq) if should_limit: response = HTTPForbidden() response.content_type = 'application/json' response.body = DAILY_LIMIT return response elif should_limit is None: # pragma: no cover # We couldn't connect to Redis stats_client.incr('%s.redisfailure_skip_limit' % func_name) else: stats_client.incr('%s.unknown_api_key' % func_name) if error_on_invalidkey: return invalid_api_key_response() # If we failed to look up an ApiKey, create an empty one # rather than passing None through api_key = api_key or ApiKey() return func(request, api_key, *args, **kwargs)
def create(self): set_common_headers(self.request, "layers", NO_CACHE) if self.request.user is None: raise HTTPForbidden() self.request.response.cache_control.no_cache = True layer = self._get_layer_for_request() def check_geometry(_, feature, obj): del obj # unused geom = feature.geometry if geom and not isinstance(geom, geojson.geometry.Default): shape = asShape(geom) srid = self._get_geom_col_info(layer)[1] spatial_elt = from_shape(shape, srid=srid) allowed = models.DBSession.query(func.count( RestrictionArea.id)) allowed = allowed.join(RestrictionArea.roles) allowed = allowed.join(RestrictionArea.layers) allowed = allowed.filter(RestrictionArea.readwrite.is_(True)) allowed = allowed.filter( Role.id.in_([r.id for r in self.request.user.roles])) allowed = allowed.filter(Layer.id == layer.id) allowed = allowed.filter( or_(RestrictionArea.area.is_(None), RestrictionArea.area.ST_Contains(spatial_elt))) if allowed.scalar() == 0: raise HTTPForbidden() # check if geometry is valid if self._get_validation_setting(layer): self._validate_geometry(spatial_elt) protocol = self._get_protocol_for_layer(layer, before_create=check_geometry) try: features = protocol.create(self.request) for feature in features.features: self._log_last_update(layer, feature) return features except TopologicalError as e: self.request.response.status_int = 400 return {"error_type": "validation_error", "message": str(e)} except exc.IntegrityError as e: log.error(str(e)) self.request.response.status_int = 400 return { "error_type": "integrity_error", "message": str(e.orig.diag.message_primary) }
def get_changes(self): # this method is called from all replica servers # and either returns changelog entry content for {serial} or, # if it points to the "next" serial, will block and wait # until that serial is committed. However, after # MAX_REPLICA_BLOCK_TIME, we return 202 Accepted to indicate # the replica should try again. The latter has two benefits: # - nginx' timeout would otherwise return 504 (Gateway Timeout) # - if the replica is not waiting anymore we would otherwise # never time out here, leading to more and more threads # if no commits happen. if not self.xom.is_master(): raise HTTPForbidden("Replication protocol disabled") expected_uuid = self.request.headers.get(H_EXPECTED_MASTER_ID, None) master_uuid = self.xom.config.get_master_uuid() # we require the header but it is allowed to be empty # (during initialization) if expected_uuid is None: msg = "replica sent no %s header" % H_EXPECTED_MASTER_ID threadlog.error(msg) raise HTTPBadRequest(msg) if expected_uuid and expected_uuid != master_uuid: threadlog.error("expected %r as master_uuid, replica sent %r", master_uuid, expected_uuid) raise HTTPBadRequest( "expected %s as master_uuid, replica sent %s" % (master_uuid, expected_uuid)) serial = self.request.matchdict["serial"] with self.update_replica_status(serial): keyfs = self.xom.keyfs if serial.lower() == "nop": raw_entry = b"" else: try: serial = int(serial) except ValueError: raise HTTPNotFound("serial needs to be int") raw_entry = self._wait_for_entry(serial) devpi_serial = keyfs.get_current_serial() r = Response(body=raw_entry, status=200, headers={ str("Content-Type"): str("application/octet-stream"), str("X-DEVPI-SERIAL"): str(devpi_serial), }) return r
def add_form(self): content_type = self.request.params.get('content_type') tag = self.request.GET.get('tag', None) #Permission check add_permission = self.api.content_types_add_perm(content_type) if not has_permission(add_permission, self.context, self.request): raise HTTPForbidden( "You're not allowed to add '%s' in this context." % content_type) factory = self.api.get_content_factory(content_type) schema_name = self.api.get_schema_name(content_type, 'add') schema = createSchema(schema_name).bind(context=self.context, request=self.request, api=self.api) form = Form(schema, buttons=(button_add, button_cancel)) self.api.register_form_resources(form) if content_type == 'AgendaItem': self.response['tabs'] = self.api.render_single_view_component( self.context, self.request, 'tabs', 'manage_agenda') post = self.request.POST if 'add' in post: controls = post.items() try: #appstruct is deforms convention. It will be the submitted data in a dict. appstruct = form.validate(controls) except ValidationFailure, e: self.response['form'] = e.render() return self.response kwargs = {} kwargs.update(appstruct) if self.api.userid: kwargs['creators'] = [self.api.userid] obj = createContent(content_type, **kwargs) name = self.generate_slug(obj.title) self.context[name] = obj self.api.flash_messages.add(_(u"Successfully added")) #Success, redirect url = self.request.resource_url(obj) #Polls might have a special redirect action if the poll plugin has a settings schema: if content_type == 'Poll': if obj.get_poll_plugin().get_settings_schema() is not None: url += 'poll_config' else: url = self.request.resource_url(obj.__parent__, anchor=obj.uid) msg = _( u"private_poll_info", default= u"The poll is created in private state, to show it the participants you have to change the state to upcoming." ) self.api.flash_messages.add(msg) return HTTPFound(location=url)
def client_issue_list(ctx, req): cfg = req.registry.settings if not asbool(cfg.get('netprofile.client.ticket.enabled', True)): raise HTTPForbidden(detail=_('Issues view is disabled')) sess = DBSession() ent = req.user.parent q = sess.query(Ticket)\ .filter(Ticket.entity == ent, Ticket.show_client == True)\ .order_by(Ticket.creation_time.desc()) tpldef = {'sess': DBSession(), 'tickets': q.all()} req.run_hook('access.cl.tpldef', tpldef, req) req.run_hook('access.cl.tpldef.issue.list', tpldef, req) return tpldef
def traversal_security(event): """ Check traversal was permitted at each step """ request = event.request traversed = reversed(list(lineage(request.context))) # Required to view the root page as anonymous user # XXX Needs test once login based browser tests work. next(traversed) # Skip root object for resource in traversed: result = has_permission('traverse', resource, request) if not result: msg = 'Unauthorized: traversal failed permission check' raise HTTPForbidden(msg, result=result)
def make_403_error(message, realm='CIOC RPC'): error = HTTPForbidden() error.content_type = "text/plain" error.text = message return error
def __init__(self): HTTPForbidden.__init__(self, "CSRF attempt suspected.")
def forbidden(self): response = HTTPForbidden() response.content_type = 'application/json' response.body = DAILY_LIMIT return response