async def deny_user_scope_roles(request): """Request: POST /deny_scope_roles Body : - user_token - service_token (json) - scope - user - roles Response HTTP 200 in JWT token: success Response HTTP 400 in JWT token: entryAlreadyExists """ # Verifiquem que la petició tingui tots els parametres request_data = await get_validate_request(request) scope = request_data.get('scope') username = request_data.get('username') # Verifiquem que l'usuari que vol realitzar l'acció és manager await check_manager(username, scope, request) # !!important # Obtenim les dades del nou usuari que volem eliminar els rols params = await request.post() user = params.get('user', None) if user is None: raise HTTPBadRequest(reason='user is missing') if not validate_email(user): raise HTTPBadRequest(reason="user isn't a valid email address") roles = params.get('roles', None) if roles is None: raise HTTPBadRequest(reason='roles is missing') if not isinstance(roles, list): roles = ast.literal_eval(roles) user_manager = request.app['settings']['user_manager'] # Remove the role to the user for role in roles: result_role = await user_manager.delScopeRole(scope, user, role) if result_role == 'success': # Deshabilitem la cache redis per aquest camp db_token = request.app['settings']['db_token'] user_scope = '{0}::{1}'.format(user, scope) with (await db_token) as redis: result_cache = await redis.delete(user_scope) status = 200 elif result_role == 'noSuchAttribute': status = 400 else: raise HTTPBadRequest(reason='role deny') token = jwt_response(request, result_role) return Response(status=status, body=token, content_type='text/plain')
async def get(self, request: Request) -> Response: """Handle oauth token request.""" hass = request.app["hass"] def check_get(param): if param not in request.query: _LOGGER.error("State missing in request.") raise HTTPBadRequest( text="Parameter {} not found".format(param)) return request.query[param] state = check_get("state") code = check_get("code") if state not in self._flows: _LOGGER.error("State unexpected %s", state) raise HTTPBadRequest(text="State can not be translated into flow") flow_id = self._flows[state] _LOGGER.debug("Received auth request for flow %s", flow_id) try: await hass.config_entries.flow.async_configure( flow_id, {"code": code}) return Response( headers={"content-type": "text/html"}, text="<script>window.close()</script>", ) except data_entry_flow.UnknownFlow: raise HTTPBadRequest(text="Unkown flow")
async def get_queue_limit(request): query = request.rel_url.query if 'uid' not in query: raise HTTPBadRequest(reason=VALIDATION_ERROR) uid = query['uid'].isdigit() and int(query['uid']) if uid < 1: raise HTTPBadRequest(reason=VALIDATION_ERROR) user = await User.query.where(User.id == uid).gino.one_or_none() if user is None: raise HTTPNotFound(reason=USER_NOT_FOUND) redis = request.app['redis'] lim_key = f'lim_send:{uid}' ttl = -1 value = await redis.get(lim_key) value = int(value) if value is not None else 0 if value > 0: ttl = await redis.ttl(lim_key) # This case is real and tested # TODO: LUA script to fetch the value and it's ttl atomically if ttl == 0: value = 0 ttl = -1 return { 'value': value, 'ttl': ttl, 'daily': daily_limit[user.role], }
async def processImage(self, data): #print('data', data) imgdir = '/var/www/' try: image = data["url"] if image.strip() == "": return HTTPBadRequest(text="url can not be empty") elif isUrl(image): image = await fetch(session, image) else: image = image if ( image.startswith('/')) else os.path.abspath(imgdir + image) if not isReadableFile(image): raise HTTPNotFound(text="url`s image not exist") nsfw_prob = classify(image) text = nsfw_prob.astype(str) del (data, imgdir, image, nsfw_prob) return web.Response(text=text) except KeyError: return HTTPBadRequest(text="Missing `url` parameter") except OSError as e: if "cannot identify" in str(e): raise HTTPUnsupportedMediaType(text="url is invalid image") else: raise e
def serve_bytes(self, request: Request, bytes: bytearray, include_length: bool = True) -> Any: if "Range" in request.headers: # Do range request if not rangePattern.match(request.headers['Range']): raise HTTPBadRequest() numbers = intPattern.findall(request.headers['Range']) start = int(numbers[0]) end = int(numbers[1]) if start < 0: raise HTTPBadRequest() if start > end: raise HTTPBadRequest() if end > len(bytes) - 1: raise HTTPBadRequest() resp = Response(body=bytes[start:end + 1], status=206) resp.headers['Content-Range'] = "bytes {0}-{1}/{2}".format( start, end, len(bytes)) if include_length: resp.headers["Content-length"] = str(len(bytes)) return resp else: resp = Response(body=io.BytesIO(bytes)) resp.headers["Content-length"] = str(len(bytes)) return resp
async def error_handler_middleware(request: Request, handler: RequestHandler) -> StreamResponse: try: return await handler(request) except HTTPRedirection as e: # redirects are implemented as exceptions in aiohttp for whatever reason... raise e except NotFoundError as e: kind = type(e).__name__ message = f"Error: {kind}\nMessage: {str(e)}" log.info(f"Request {request} has failed with exception: {message}", exc_info=exc_info(e)) raise HTTPNotFound(text=message) from e except (ClientError, AttributeError) as e: kind = type(e).__name__ ex_str = str(e) message = f"Error: {kind}\nMessage: {ex_str}" log.info(f"Request {request} has failed with exception: {message}", exc_info=exc_info(e)) await event_sender.core_event( CoreEvent.ClientError, {"version": version(), "kind": kind, "message": ex_str} ) raise HTTPBadRequest(text=message) from e except Exception as e: kind = type(e).__name__ ex_str = str(e) message = f"Error: {kind}\nMessage: {ex_str}" log.warning(f"Request {request} has failed with exception: {message}", exc_info=exc_info(e)) await event_sender.core_event( CoreEvent.ServerError, {"version": version(), "kind": kind, "message": ex_str} ) raise HTTPBadRequest(text=message) from e
async def parse_paging(self): """ Retrieve from query params limit, offset, last and validate them :return: limit, offset, last """ try: limit = int(self.request.query.get('limit', self.default_limit)) assert 0 < limit <= self.max_limit except (ValueError, AssertionError): raise HTTPBadRequest( reason=f'Invalid limit 0 < limit <= {self.max_limit}') try: offset = int(self.request.query.get('offset', 0)) assert offset >= 0 except (ValueError, AssertionError): raise HTTPBadRequest(reason='Invalid offset: offset >= 0') try: last = self.request.query.get('last') if last is not None: assert ObjectId.is_valid(last) last = ObjectId(last) except (ValueError, AssertionError): raise HTTPBadRequest(reason='Invalid last') return limit, offset, last
async def statistic_receiver(request: Request): auth = request.headers.get('Authorization') if not auth: raise HTTPUnauthorized() secret = auth.replace("Bearer ", '') if secret != SECRET: raise HTTPForbidden() payload = msgpack.unpackb(await request.read(), encoding='utf-8') if not isinstance(payload, list): raise HTTPBadRequest() for metric in payload: try: name, ts_value = metric ts, value = ts_value ts = float(ts) assert isinstance(value, (int, float, type(None))) except: log.exception("Invalid data in %r", metric) raise HTTPBadRequest() QUEUE.append((name, value, ts)) return Response(content_type='text/plain', status=HTTPStatus.ACCEPTED)
async def post(self) -> Response: """ update package build status JSON body must be supplied, the following model is used: { "status": "unknown", # package build status string, must be valid `BuildStatusEnum` "package": {} # package body (use `dataclasses.asdict` to generate one), optional. # Must be supplied in case if package base is unknown } :return: 204 on success """ base = self.request.match_info["package"] data = await self.request.json() try: package = Package.from_json( data["package"]) if "package" in data else None status = BuildStatusEnum(data["status"]) except Exception as e: raise HTTPBadRequest(text=str(e)) try: self.service.update(base, status, package) except UnknownPackage: raise HTTPBadRequest( text=f"Package {base} is unknown, but no package body set") return HTTPNoContent()
def validate(self, *args, **kwargs): super(RegexpValidator, self).validate(*args, **kwargs) self._value_to_str() if self.reg: if not isinstance(self.reg, str): raise HTTPBadRequest(text="") if not Regexp(self.reg)(self.value): raise HTTPBadRequest(text="%s字段不符合格式要求!" % self.key)
async def get_history_key(request): query = request.rel_url.query if 'sender_id' not in query: raise HTTPBadRequest(reason=VALIDATION_ERROR) sender_id = query['sender_id'] sender_id = sender_id.isdigit() and int(sender_id) if sender_id < 1: raise HTTPBadRequest(reason=VALIDATION_ERROR) return f'history:{sender_id}:{time_ns()}'
async def valid_token(request): """ Validate token! Request: POST /valid_token Body : - service_code - token Response HTTP 200 in JWT token: { 'user': '******' } """ params = await request.post() service_token = params.get('code', None) if service_token is None: raise HTTPBadRequest(reason='code is missing') db_tauths = request.app['settings']['db_tauths'] with (await db_tauths) as redis: client_id = await redis.get(service_token) if client_id is None: raise HTTPBadRequest(reason='Invalid Service Token') token = params.get('token', None) if token is None: raise HTTPBadRequest(reason='token is missing') db_token = request.app['settings']['db_token'] with (await db_token) as redis: user = await redis.get(token) if user is None: raise HTTPBadRequest(reason='user invalid') secret = request.app['settings']['jwtsecret'] # if its ok redirect to get_access_token token = jwt.encode( { 'iat': datetime.utcnow(), 'exp': datetime.utcnow() + timedelta(seconds=60), 'user': user.decode('utf-8') }, secret, algorithm='HS256') return Response(body=token, content_type='text/plain')
async def view(request): code = request.query.get('code') dl = request.query.get('dl', None) == '1' try: ecode = EcodeDecoder().decode(code) except Exception as e: print(e) return HTTPBadRequest() # Locale locales_config = ContextHolder.context.config.locales_config locale = ecode.locale.code if locale not in locales_config.locales: return HTTPBadRequest() # Fonts fonts_config = ContextHolder.context.config.fonts_config fonts = fonts_config.by_locale(locale) font = next(filter(lambda f: f['id'] == ecode.font_id, fonts), None) if font is None: return HTTPBadRequest() font_path = str(fonts_config.fonts_path.joinpath(font['path'])) try: img_data = emojilib.generate( text=ecode.text, width=ecode.size.width, height=ecode.size.height, color='{:08X}'.format(ecode.foreground_color), background_color='{:08X}'.format(ecode.background_color), size_fixed=EcodeFlag.SIZE_FIXED in ecode.flags, disable_stretch=EcodeFlag.STRETCH not in ecode.flags, align=ecode.align.code, typeface_file=font_path, format=ecode.fmt.code ) except Exception as e: print(e) return HTTPBadRequest() headers = {} headers['Cache-Control'] = 'public, max-age={}'.format(60 * 60 * 24) # 1 day if dl: filename = '{}.{}'.format(re.sub(r'\s','_', ecode.text), ecode.fmt.code) desposition = 'attachment; filename=\"{}\"'.format(filename) headers['Content-Disposition'] = desposition return Response( body=img_data, headers=headers, content_type='image/{}'.format(ecode.fmt.code) )
async def get_events_from_pg(request): num_events = request.query.get("num_events") try: if int(num_events) < 0: return HTTPBadRequest() except ValueError: return HTTPBadRequest() async with request.app.pool.acquire() as conn: resp = await get_last_events(conn, num_events) return json_response(status=200, data={"events": resp})
async def upload(request): """Load multipart data and store it as a file.""" if not request.headers['content-type'].startswith('multipart/form-data'): raise HTTPBadRequest() reader = await request.multipart() data = await reader.next() if data.name != 'file': raise HTTPBadRequest() with open(f"/tmp/{uuid4().hex}", 'wb') as target: target.write(await data.read()) return Response(text=target.name, content_type="text/plain")
async def post(self): try: req = await self.request.json() logger.debug(f"{req}") except Exception as e: logger.warning(e) raise HTTPBadRequest() res = await order_handler.push(req) if "error" in res.keys(): if res["error"]: return json_response({"validation_error": {"orders": res["error"]}}, status=400) else: raise HTTPBadRequest() return json_response(res, status=201)
async def get_validate_request(request): """Return data from `request`: - scope - username Validate: - service_token - scope - user_token :return: dict [scope, username] """ params = await request.post() service_token = params.get('service_token', None) if service_token is None: raise HTTPBadRequest(reason='service_token is missing') db_tauths = request.app['settings']['db_tauths'] with (await db_tauths) as redis: client_id = await redis.get(service_token) if client_id is None: raise HTTPBadRequest(reason='Invalid service_token') scope = params.get('scope', None) if scope is None: raise HTTPBadRequest(reason='scope is missing') user_token = params.get('user_token', None) if user_token is None: raise HTTPBadRequest(reason='user_token is missing') # We need the user info so we are going to get it from UserManager db_token = request.app['settings']['db_token'] with (await db_token) as redis: username = await redis.get(user_token) if username is None: raise HTTPBadRequest(reason='bad token') username = username.decode("utf-8") return { 'scope': scope, 'username': username, }
async def _upload(self, request: Request): logger.info("Drive start upload request") await self._checkDriveHeaders(request) if request.query.get('uploadType') != 'resumable': raise HTTPBadRequest() mimeType = request.headers.get('X-Upload-Content-Type', None) if mimeType is None: raise HTTPBadRequest() size = int(request.headers.get('X-Upload-Content-Length', -1)) if size < 0: raise HTTPBadRequest() total_size = 0 for item in self.items.values(): total_size += item.get('size', 0) total_size += size if total_size > self.space_available: return json_response( {"error": { "errors": [{ "reason": "storageQuotaExceeded" }] }}, status=400) metadata = await request.json() id = self.generateId() # Validate parents if 'parents' in metadata: for parent in metadata['parents']: if parent not in self.items: raise HTTPNotFound() if parent in self.lostPermission: return Response( status=403, content_type="application/json", text='{"error": {"errors": [{"reason": "forbidden"}]}}' ) self._upload_info['size'] = size self._upload_info['mime'] = mimeType self._upload_info['item'] = self.formatItem(metadata, id) self._upload_info['id'] = id self._upload_info['next_start'] = 0 metadata['bytes'] = bytearray() metadata['size'] = size resp = Response() resp.headers['Location'] = "http://localhost:" + \ str(self._port) + "/upload/drive/v3/files/progress/" + id return resp
async def confirm(request): token = request.match_info["token"] try: token_data = get_token_data( token, request.app["config"]["application"]["secret_key"]) id_ = token_data["id"] except Exception: flash(request, ("danger", _("Le lien est invalide ou a expiré"))) raise HTTPBadRequest() async with request.app["db-pool"].acquire() as conn: q = "UPDATE client SET confirmed = true WHERE id = $1 RETURNING id" try: updated = await conn.fetchval(q, id_) if updated is None: raise except Exception: flash(request, ("danger", _("Vous ne pouvez pas être enregistré."))) return HTTPFound(request.app.router["register"].url_for()) else: flash(request, ( "info", _("Votre enregistrement est confirmé, vous pouvez vous connecter." ))) return HTTPFound(request.app.router["login"].url_for())
async def get_auth_token(data: bytes, session: ClientSession) -> str: async with session.post(AUTH_URL, data=data) as response: response_data = await response.json() if 'access_token' in response_data: return response_data['access_token'] else: raise HTTPBadRequest()
async def verify_contact_method(request, ctx: AppConfig, session: AuthnSession): try: user_profile_id = UUID(request.match_info['user_profile_id']) contact_method_id = UUID(request.match_info['contact_method_id']) except ValueError: raise HTTPNotFound() challenge_response = AuthnChallengeResponseRequest.unmarshal_request( await request.json()) if user_profile_id != session.user_profile_id: raise HTTPForbidden() if challenge_response.challenge_id != session.pending_challenge.challenge_id: raise HTTPBadRequest() session.pending_challenge.attempts += 1 session.changed() if session.pending_challenge.attempts > security.MaxVerificationChallengeAttempts: session.invalidate() raise HTTPForbidden(body="Too many invalid attempts") if challenge_response.passcode != session.pending_challenge.secret: raise HTTPUnauthorized(body="Incorrect passcode") async with op.session(ctx) as ss: await op.user_profile.\ mark_contact_method_verified(contact_method_id, user_profile_id=user_profile_id).\ execute(ss) session.clear_pending_challenge() return HTTPOk()
async def confirm(request): token = request.match_info["token"] try: token_data = get_token_data( token, request.app["config"]["application"]["secret_key"]) id_ = token_data["id"] email_address = token_data["email_address"] except Exception: flash(request, ("danger", _("Le lien est invalide ou a expiré"))) raise HTTPBadRequest() async with request.app["db-pool"].acquire() as conn: q = "UPDATE client SET email_address = $1 WHERE id = $2" try: await conn.execute(q, email_address, id_) except Exception: flash( request, ("danger", _("Votre adresse email ne peut pas être modifiée"))) else: flash(request, ("info", _("Votre adresse email a été modifiée"))) login = await authorized_userid(request) if login: return HTTPFound(request.app.router["home"].url_for()) else: return HTTPFound(request.app.router["login"].url_for())
async def manualauth(self, request: Request) -> None: client_id = request.query.get("client_id", "") code = request.query.get("code", "") client_secret = request.query.get("client_secret", "") if client_id != "" and client_secret != "": try: # Redirect to the webpage that takes you to the google auth page. self.manual_exchanger = self.exchanger_builder.build( client_id=client_id.strip(), client_secret=client_secret.strip(), redirect=MANUAL_CODE_REDIRECT_URI) return web.json_response({ 'auth_url': await self.manual_exchanger.getAuthorizationUrl() }) except Exception as e: return web.json_response({ 'error': "Couldn't create authorization URL, Google said:" + str(e) }) elif code != "": try: self._coord.saveCreds(await self.manual_exchanger.exchange(code)) self._global_info.setIngoreErrorsForNow(True) return web.json_response({'auth_url': "index?fresh=true"}) except KnownError as e: return web.json_response({'error': e.message()}) except Exception as e: return web.json_response({ 'error': "Couldn't authorize with Google Drive, Google said:" + str(e) }) raise HTTPBadRequest()
def _value_to_str(self): if isinstance(self.value, bytes): self.value = self.value.decode('utf-8') try: self.value = str(self.value) except: raise HTTPBadRequest(text="")
def edit(self, courier_id, raw_data): session = self.make_session() courier_query = session.query(Courier).filter_by(id=courier_id) courier = courier_query.first() if courier is None: raise HTTPBadRequest orders_query = session.query(Order).filter_by(courier_id=courier_id) orders = list(orders_query.all()) regions_query = session.query(Region).filter_by(courier_id=courier_id) regions = list(regions_query.all()) hours_query = session.query(CourierHours).filter_by( courier_id=courier_id) hours = list(hours_query.all()) self.logger.debug(f"{courier} {orders} {regions} {hours}") for i in raw_data.keys(): if i == "courier_type": if raw_data["courier_type"] in ["foot", "bike", "car"]: pass session.delete(courier) courier.transport = raw_data[i] session.add(courier) orders_query.delete() for j in orders: if j.weight > weight_dict[raw_data[i]]: j.courier_id = None session.add(j) else: session.rollback() raise HTTPBadRequest elif i == "regions": regions = self.make_region_records(courier_id, raw_data[i]) if regions: regions_query.delete() for j in regions: session.add(j) else: session.rollback() raise HTTPBadRequest elif i == "working_hours": hours = self.make_time_records(courier_id, raw_data[i]) if hours: hours_query.delete() for j in hours: session.add(j) else: session.rollback() raise HTTPBadRequest else: self.logger.warning("wrong keys for courier editing") session.rollback() raise HTTPBadRequest() session.commit() res = { "courier_id": courier_id, "courier_type": courier.transport, "regions": [i.import_id for i in regions], "working_hours": [str(i) for i in hours] } self.logger.debug(f"edit res: {res}") return res
async def users_put(request: Request) -> Response: session_maker = request.app['db_session_manager'] if not request.headers['X-Login'] == request.match_info['login']: return HTTPForbidden() session: Session = session_maker() try: data = await request.json() if data: user = session.query(Users).filter_by( login=request.match_info['login']).first() if not user: return HTTPNotFound() user_put = UsersSchema().load(data, session=session, partial=True) user.first_name = user_put.first_name user.last_name = user_put.last_name user.email = user_put.email user.phone = user_put.phone session.commit() return HTTPNoContent(headers={'Location': f"/users/{user.login}"}) else: session.close() return HTTPBadRequest() except Exception: session.rollback() raise finally: session.close()
async def users_post(request: Request) -> Response: session_maker = request.app['db_session_manager'] session: Session = session_maker() try: data = await request.json() if data: user = session.query(Users).filter_by(login=data['login']).first() if user: return HTTPConflict() user = UsersSchema().load(data, session=session) session.add(user) session.commit() return HTTPCreated(headers={ 'Location': f"/users/{user.login}", 'Content-Type': 'application/json' }, body=json.dumps({'id': user.id})) else: return HTTPBadRequest() except Exception: session.rollback() raise finally: session.close()
async def check_manager(username, scope, request): """Check user is superuser or manager in scope""" # Check superuser if plone.oauth.is_superuser(username): return True # Or check manager in scope ttl = request.app['settings']['ttl_user_info'] db_token = request.app['settings']['db_token'] user_scope = '{0}::{1}'.format(username, scope) # Search Redis with (await db_token) as redis: result = await redis.get(user_scope) if result is not None: result = ujson.loads(result) else: # Search LDAP user_manager = request.app['settings']['user_manager'] result = await user_manager.getUserInfo(username, scope) # Cache in redis with (await db_token) as redis: await redis.set(user_scope, ujson.dumps(result)) await redis.expire(user_scope, ttl) roles = result.get('roles', {}) # XXX: TODO not hardcoded if 'manager' in roles or 'site administrator' in roles: return True # Is not a manager raise HTTPBadRequest(reason='NOT VALID token: must be manager')
async def _authenticate(self, request: Request): await self._verifyHeader(request) input_json = await request.json() if input_json.get("username") != self._username or input_json.get( "password") != self._password: raise HTTPBadRequest() return self._formatDataResponse({})
def _value_to_int(self): if isinstance(self.value, bytes): self.value = self.value.decode('utf-8') try: self.value = int(self.value) except: raise HTTPBadRequest(text="%s不是int!" % self.key)