def wrapper(context, request): qs = QueryString(request) type_filters = qs.get_type_filters() if len(type_filters) != 1: raise HTTPBadRequest( explanation='URL requires one type parameter.' ) if type_filters[0][1] not in types: raise HTTPBadRequest( explanation=f'{type_filters[0][1]} not a valid type for endpoint.' ) return func(context, request)
def popup_toggle(request): """ Toggle whether the user is configured to receive fedmsg popups in the web UI. Args: request (pyramid.util.Request): The current request. Returns: pyramid.httpexceptions.HTTPFound: A redirect to the "next" field of the request, or the home page if "next" is not defined. Raises: pyramid.exceptions.HTTPForbidden: If the user is not logged in. pyramid.httpexceptions.HTTPBadRequest: If the user is not found. It is unknown under which circumstances this could happen. """ # Get the user userid = request.authenticated_userid if userid is None: raise HTTPForbidden("You must be logged in.") user = request.db.query( models.User).filter_by(name=unicode(userid)).first() if user is None: raise HTTPBadRequest("For some reason, user does not exist.") # Toggle the value. user.show_popups = not user.show_popups # And send the user back return_to = request.params.get('next', request.route_url('home')) return HTTPFound(location=return_to)
def table_item_save(request): person_id = None if ('person_id' in request.POST) and request.POST['person_id'].isdigit(): person_id = int(request.POST['person_id']) user_login = request.POST[ 'user_login'] if 'user_login' in request.POST else None if not user_login: raise HTTPBadRequest('"user_login" is required parameter') if not person_id: users = DBSession.query(User).filter(User.login == user_login).all() if len(users) > 0: return { 'Result': 'Error', 'Message': u'Такой логин уже присутствует в системе' } with transaction.manager: if person_id: person = DBSession.query(Person) \ .options(joinedload('user')) \ .filter(Person.id == person_id) \ .all()[0] user = person.user else: person = Person() DBSession.add(person) user = User() DBSession.add(user) person.user = user for attr in request.POST: table_name, field = attr.split('_') if field == 'id': continue if table_name == 'person': setattr(person, field, request.POST[attr]) if table_name == 'user': setattr(user, field, request.POST[attr]) if 'user_active' in request.POST and request.POST['user_active']: user.active = True else: user.active = False if 'user_password' in request.POST and request.POST['user_password']: user.password = User.password_hash(request.POST['user_password']) DBSession.flush() DBSession.refresh(user) DBSession.refresh(person) person_json = person.as_json_dict('person_') user_json = user.as_json_dict('user_') item_json = person_json.copy() item_json.update(user_json) return {'Result': 'OK', 'Record': item_json}
def receive_events(request): json_body = request.json_body parsed_events_set = EventsSetSchema().loads(json_body) if len(parsed_events_set.errors.keys()) > 0: raise HTTPBadRequest() last_update_ts = int(parsed_events_set.data['stop']) events = [] if 'data' in parsed_events_set.data: events = parsed_events_set.data['data'] events_to_insert = [] for event in events: existed = DBSession.query(exists().where(Event.event_id==event.event_id)).scalar() exists_in_inserted_list = any(ev.event_id == event.event_id for ev in events_to_insert) if not existed and not exists_in_inserted_list: events_to_insert.append(event) with transaction.manager: Meta.filter_by(key=LAST_UPDATE_KEY).update({ 'value': last_update_ts }) for event in events_to_insert: DBSession.add(event) return response_ok(dict( count=len(events), start=parsed_events_set.data['start'], stop=parsed_events_set.data['stop'], lastUpdateTs=last_update_ts ))
def __init__(self, req: "CamcopsRequest") -> None: # Check the basics if req.method != RequestMethod.POST: raise HTTPBadRequest("Must use POST method") # ... this is for humans to view, so it has a pretty error # Read key things self.req = req self.operation = req.get_str_param(TabletParam.OPERATION) self.device_name = req.get_str_param(TabletParam.DEVICE) self.username = req.get_str_param(TabletParam.USER) self.password = req.get_str_param(TabletParam.PASSWORD) self.session_id = req.get_int_param(TabletParam.SESSION_ID) self.session_token = req.get_str_param(TabletParam.SESSION_TOKEN) self.tablet_version_str = req.get_str_param(TabletParam.CAMCOPS_VERSION) # noqa try: self.tablet_version_ver = make_version(self.tablet_version_str) except ValueError: fail_user_error("CamCOPS tablet version nonsensical: {!r}".format( self.tablet_version_str)) # Basic security check: no pretending to be the server if self.device_name == DEVICE_NAME_FOR_SERVER: fail_user_error("Tablets cannot use the device name {!r}".format( DEVICE_NAME_FOR_SERVER)) if self.username == USER_NAME_FOR_SYSTEM: fail_user_error("Tablets cannot use the username {!r}".format( USER_NAME_FOR_SYSTEM)) self._device_obj = None # type: Device # Ensure table version is OK if self.tablet_version_ver < MINIMUM_TABLET_VERSION: fail_user_error( "Tablet CamCOPS version too old: is {v}, need {r}".format( v=self.tablet_version_str, r=MINIMUM_TABLET_VERSION)) # Other version things are done via properties # Upload efficiency self._dirty_table_names = set() # type: Set[str] # Report log.info("Incoming client API connection from IP={i}, port={p}, " "device_name={dn!r}, " # "device_id={di}, " "camcops_version={v}, " "username={u}, operation={o}", i=req.remote_addr, p=req.remote_port, dn=self.device_name, # di=self.device_id, v=self.tablet_version_str, u=self.username, o=self.operation)
def view_manage(self): post = self.request.POST action = post.get('action') if action == 'move': _from = post.get('from') _to = post.get('to') if _from is None or _to is None: # return Response(body='"from" and "to" request params are missing', # content_type='text/plain', # status_int=400) return HTTPBadRequest('"from" and "to" request params are missing') from_path = get_abs_path(_from) to_path = get_abs_path(_to) if os.path.isdir(to_path): return HTTPBadRequest('The "to" path is directory. Full end path of file must be specified') if not os.path.isfile(from_path): return HTTPBadRequest('There no file at the path passed with "to" parameter') try: os.rename(from_path, to_path) except Exception: # TODO log exception? return HTTPBadRequest('error during file moving') rel_to_path = get_rel_path(to_path) return rel_to_path elif action == 'delete': _path = post.get('path') if _path is None: return HTTPBadRequest('"path" request param is missing') delete_path = get_abs_path(_path) if os.path.isdir(delete_path): return HTTPBadRequest('The "to" path is directory. Full end path of file must be specified') if not os.path.isfile(delete_path): return HTTPBadRequest('There no file at the path passed with "path" parameter') try: os.remove(delete_path) except Exception: return HTTPBadRequest('error during file deletion') rel_delete_path = get_rel_path(delete_path) return rel_delete_path else: # return Response(body='"action" request param is missing', # content_type='text/plain', # status_int=400) return HTTPBadRequest('"action" request param is missing')
def on_update_record(event): if getattr(event.request, '_attachment_auto_save', False): # Record attributes are being by the plugin itself. return # A user is changing the record, make sure attachment metadata is not # altered manually. for change in event.impacted_records: attachment_before = change['old'].get('attachment') attachment_after = change['new'].get('attachment') if attachment_before and attachment_after: if attachment_before != attachment_after: error_msg = "Attachment metadata cannot be modified." raise http_error(HTTPBadRequest(), message=error_msg)
def latest_builds_in_tag(request): """ Return a list of the latest builds for a given tag. Args: request (pyramid.request.Request): The current request. The request's "tag" parameter is used to pass the koji tagname being queried. Returns: dict: A dictionary of the release dist tag to the latest build. """ koji = request.koji tag = request.params.get('tag') if not tag: raise HTTPBadRequest("tag parameter is required") else: return koji.listTagged(tag, latest=True)
def popup_toggle(request): # Get the user from bodhi.models import User userid = authenticated_userid(request) if userid is None: raise HTTPForbidden("You must be logged in.") user = request.db.query(User).filter_by(name=unicode(userid)).first() if user is None: raise HTTPBadRequest("For some reason, user does not exist.") # Toggle the value. user.show_popups = not user.show_popups # And send the user back return_to = request.params.get('next', request.route_url('home')) return HTTPFound(location=return_to)
def put_some_bacon(request): raise HTTPBadRequest()
def render(data, system): """ Render the given data as an RSS view. If the request's content type is set to the default, this function will change it to application/rss+xml. Args: data (dict): A dictionary describing the information to be rendered. The information can be different types of objects, such as updates, users, comments, or overrides. system (pyramid.events.BeforeRender): Used to get the current request. Returns: str: An RSS document representing the given data. """ request = system.get('request') if request is not None: response = request.response ct = response.content_type if ct == response.default_content_type: response.content_type = 'application/rss+xml' if 'updates' in data: key = 'updates' feed_title = 'Released updates' elif 'users' in data: key = 'users' feed_title = 'Bodhi users' elif 'comments' in data: key = 'comments' feed_title = 'User comments' elif 'overrides' in data: key = 'overrides' feed_title = 'Update overrides' else: # This is a request we don't know how to render. Let's return BadRequest and log. log.debug('Unable to render RSS feed for data: %s', data) # See if we have a request so we can set a code without raising an Exception if request is not None: response.status = HTTPBadRequest.code return 'Invalid RSS feed request' else: raise HTTPBadRequest('Invalid RSS feed request') feed_description_list = [] for k in request.GET.keys(): feed_description_list.append('%s(%s)' % (k, request.GET[k])) if feed_description_list: feed_description = 'Filtered on: ' + ', '.join( feed_description_list) else: feed_description = "All %s" % (key) feed = FeedGenerator() feed.title(feed_title) feed.link(href=request.url, rel='self') feed.description(feed_description) feed.language('en') def linker(route, param, key): def link_dict(obj): return dict(href=request.route_url(route, **{param: obj[key]})) return link_dict def describe_update(alias, notes, builds): """ Wrap calls to operator.itemgetter to retrieve notes and builds list. Methods are used to fill feed entry values, so we must use a wrapper to get an HTML formatted description from the `notes` and the `builds` properties of the update. For example: getter = describe_update(operator.itemgetter('notes'),operator.itemgetter('builds')) description_value = getter(update_data) Args: alias (operator.itemgetter): A callable object which returns update alias as string. notes (operator.itemgetter): A callable object which returns update notes as string. builds (operator.itemgetter): A callable object which returns a list of builds associated to the update. Returns: function: A function which accepts a dict representing an update as parameter. """ def describe(*args, **kwargs): text = f'# {alias(*args, **kwargs)}\n' text += f'## Packages in this update:\n' for p in builds(*args, **kwargs): text += f'* {p.nvr}\n' text += f'## Update description:\n{notes(*args, **kwargs)}' return markup(None, text) return describe getters = { 'updates': { 'title': operator.itemgetter('title'), 'link': linker('update', 'id', 'alias'), 'description': describe_update(operator.itemgetter('alias'), operator.itemgetter('notes'), operator.itemgetter('builds')), 'pubDate': lambda obj: utc.localize(obj['date_submitted']), }, 'users': { 'title': operator.itemgetter('name'), 'link': linker('user', 'name', 'name'), 'description': operator.itemgetter('name'), }, 'comments': { 'title': operator.itemgetter('rss_title'), 'link': linker('comment', 'id', 'id'), 'description': operator.itemgetter('text'), 'pubDate': lambda obj: utc.localize(obj['timestamp']), }, 'overrides': { 'title': operator.itemgetter('nvr'), 'link': linker('override', 'nvr', 'nvr'), 'description': operator.itemgetter('notes'), 'pubDate': lambda obj: utc.localize(obj['submission_date']), }, } for value in reversed(data[key]): feed_item = feed.add_item() for name, getter in getters[key].items(): # Because we have to use methods to fill feed entry attributes, # it's done by getting methods by name and calling them # on the same line. getattr(feed_item, name)(getter(value)) return feed.rss_str()
def render(data, system): """ Render the given data as an RSS view. If the request's content type is set to the default, this function will change it to application/rss+xml. Args: data (dict): A dictionary describing the information to be rendered. The information can be different types of objects, such as updates, users, comments, or overrides. system (pyramid.events.BeforeRender): Used to get the current request. Returns: str: An RSS document representing the given data. """ request = system.get('request') if request is not None: response = request.response ct = response.content_type if ct == response.default_content_type: response.content_type = 'application/rss+xml' if 'updates' in data: key = 'updates' feed_title = 'Released updates' elif 'users' in data: key = 'users' feed_title = 'Bodhi users' elif 'comments' in data: key = 'comments' feed_title = 'User comments' elif 'overrides' in data: key = 'overrides' feed_title = 'Update overrides' else: # This is a request we don't know how to render. Let's return BadRequest and log. log.debug('Unable to render RSS feed for data: %s', data) # See if we have a request so we can set a code without raising an Exception if request is not None: response.status = HTTPBadRequest.code return 'Invalid RSS feed request' else: raise HTTPBadRequest('Invalid RSS feed request') feed_description_list = [] for k in request.GET.keys(): feed_description_list.append('%s(%s)' % (k, request.GET[k])) if feed_description_list: feed_description = 'Filtered on: ' + ', '.join( feed_description_list) else: feed_description = "All %s" % (key) feed = FeedGenerator() feed.title(feed_title) feed.link(href=request.url, rel='self') feed.description(feed_description) feed.language('en') def linker(route, param, key): def link_dict(obj): return dict(href=request.route_url(route, **{param: obj[key]})) return link_dict getters = { 'updates': { 'title': operator.itemgetter('alias'), 'link': linker('update', 'id', 'alias'), 'description': operator.itemgetter('notes'), 'pubdate': lambda obj: utc.localize(obj['date_submitted']), }, 'users': { 'title': operator.itemgetter('name'), 'link': linker('user', 'name', 'name'), 'description': operator.itemgetter('name'), }, 'comments': { 'title': operator.itemgetter('rss_title'), 'link': linker('comment', 'id', 'id'), 'description': operator.itemgetter('text'), 'pubdate': lambda obj: utc.localize(obj['timestamp']), }, 'overrides': { 'title': operator.itemgetter('nvr'), 'link': linker('override', 'nvr', 'nvr'), 'description': operator.itemgetter('notes'), 'pubdate': lambda obj: utc.localize(obj['submission_date']), }, } for value in data[key]: feed_item = feed.add_item() for name, getter in getters[key].items(): # Because we have to use methods to fill feed entry attributes, # it's done by getting methods by name and calling them # on the same line. getattr(feed_item, name)(getter(value)) return feed.rss_str()