def lambda_handler(event, context): if 'httpMethod' not in event: return bad_request('Not an HTTP invokation') # if it is an HTTP invokation, validate the token email = get_cognito_email(event) print(email) user_id = get_user_id_by_email(email) print(user_id) if not user_id: return forbidden() # for get or patch method, queryString should be sent with the permission type query_string = event['queryStringParameters'] if event[ 'queryStringParameters'] else None if not query_string: return bad_request( {'message': 'The event does not contain queryStringParameters'}) if event['httpMethod'] == 'GET': return get_settings_from_event(query_string, user_id) elif event['httpMethod'] == 'PATCH': return patch_settings_from_event(event=event, query_string=query_string, user_id=user_id, email=email) return bad_request({'message': 'Bad request'})
def handler(event, context): try: email = validate_body(event.get("body")) except BadRequestException as e: return bad_request(str(e)) # check if email is in cognito user pool try: user = client.admin_get_user(UserPoolId=COGNITO_USER_POOL_ID, Username=email) except client.exceptions.UserNotFoundException: return bad_request("An account with this email was not found.") # check if email is verified email_verified = [ attr["Value"] for attr in user["UserAttributes"] if attr["Name"] == "email_verified" ][0] if email_verified == "true": return bad_request("The account's email is already verified.") try: client.resend_confirmation_code(ClientId=COGNITO_CLIENT_ID, Username=email) except client.exceptions.CodeDeliveryFailureException: return bad_request("This email does not exist.") return response( 200, {"message": "Please check your email for verification link."})
def create_user(): data = request.get_json() try: last_name = data['last_name'] first_name = data['first_name'] patronymic_name = data['patronymic_name'] email = data['email'] password = data['password'] except: create_message = 'User not created - Invalid names or number of columns.' app.logger.info(create_message) return bad_request(create_message) if last_name != '' and first_name != '' and email != '' and password != '': hashed_password = generate_password_hash(password, method='sha256') new_user = Users(last_name=last_name, first_name=first_name, patronymic_name=patronymic_name, password=hashed_password, email=email) db.session.add(new_user) db.session.commit() user = Users.query.filter_by(last_name=last_name, first_name=first_name, email=email)[-1] create_message = 'User created: {} {} {} | {} | id= {}'.format( last_name, first_name, patronymic_name, email, user.id) app.logger.info(create_message) return jsonify({'message': create_message}) else: create_message = 'User not created - columns should not be empty' app.logger.info(create_message) return bad_request(create_message)
def handler(event, context): """Update existed custom entity.""" entity = None params = event.get("pathParameters", dict()) or dict() uid = params.get("uid", None) try: entity = json.loads(event.get("body")) except json.decoder.JSONDecodeError as e: return bad_request("Invalid request body: {0}".format(str(e))) try: entity = EntitySchema().load(entity) except ValidationError as err: return response(400, err.messages) if entity and uid: try: entity, ok = db.create_or_update(item=entity, uid=uid) except BadRequestException as e: return bad_request(str(e)) if ok: # If entity updated successfully then return it in responce try: entity = EntitySchema().dump(entity) except ValidationError as err: return response(400, err.messages) entity.update({"success": True}) return response(200, entity) return response(404, {"status": "Not Found"})
def handler(event, context): try: username, password, groups = validate_body(event.get("body")) except BadRequestException as e: return bad_request(str(e)) try: client.sign_up(ClientId=CLIENT_ID, Username=username, Password=password) except client.exceptions.CodeDeliveryFailureException: return bad_request("This email does not exist.") except ClientError as error: return bad_request(error.response["Error"]["Message"]) except ParamValidationError as error: return bad_request(str(error.kwargs["report"])) for group in groups: client.admin_add_user_to_group(UserPoolId=USER_POOL_ID, Username=username, GroupName=group) db = UsersDatabaseManager(username) db.add_new_user() return response( 200, {"message": "Please check your email for verification link."})
def handler(event, context): res = {} try: refresh_token = event["headers"]["Authorization"].split()[1] res = client.initiate_auth( AuthFlow="REFRESH_TOKEN", ClientId=CLIENT_ID, AuthParameters={"REFRESH_TOKEN": refresh_token}) except client.exceptions.NotAuthorizedException: err_msg = "Invalid Refresh Token" logging.warning(f"!!! NotAuthorizedException: {err_msg}") return bad_request(err_msg) except client.exceptions.InvalidParameterException: err_msg = "Missing required parameter REFRESH_TOKEN" logging.warning(f"!!! InvalidParameterException: {err_msg}") return bad_request(err_msg) except Exception as e: logging.warning(f"!!! Other Exception: {e}") return bad_request(repr(e)) auth_result = res.get("AuthenticationResult", {}) res = { "AccessToken": auth_result.get("AccessToken", ""), "ExpiresIn": auth_result.get("ExpiresIn", ""), "TokenType": auth_result.get("TokenType", ""), } return response(200, res)
def lambda_handler(event, context): body = event["body"] if event["body"] else None if not body: return bad_request( {'message': 'Event request does not contain body object'}) if 'action' not in body: return bad_request({'message': 'Body does not contain \'action\' key'}) if body["action"] not in ALLOWED_ACTIONS: return bad_request({ 'message': 'Body does not contain a valid action. Valid actions are: ' + ','.join(ALLOWED_ACTIONS) }) if body["action"] == 'check-user-permissions': if ACL_MANAGEMENT_VALIDATOR.validate(body): # get the permission of the user user_permission = get_permissions_by_user_id(body["user_id"]) if body["permission"] in user_permission: return ok({'authorized': 'True'}) else: # else, return bad request return forbidden() else: return bad_request(ACL_MANAGEMENT_VALIDATOR.errors)
def handler(event, context) -> dict: del context # unused structlog.get_logger().log("Validating POST request", body=event['body']) values = urllib.parse.parse_qs(event['body'], strict_parsing=True) structlog.get_logger().log("Decoded body", body=values) try: csrf = values['CSRF'][0] csrf = jwt.decode( csrf, key=get_csrf_jwt_secret(), algorithms=['HS256'], verify=True, ) now = time.time() assert csrf['iat'] >= now - 300 raw_refresh_token = get_raw_refresh_token(event) assert csrf['sub'] == raw_refresh_token except KeyError: return bad_request('', 'CSRF token missing') except jwt.InvalidTokenError: return bad_request('', 'CSRF token decode failed') except AssertionError as e: return bad_request('CSRF token unacceptable, please try again', e) except NotLoggedIn: pass with open(os.path.join(os.path.dirname(__file__), 'logout.html')) as f: html = f.read() return { 'statusCode': 200, 'headers': { 'Content-Type': 'text/html', 'Set-Cookie': generate_cookie( get_config().cookie_name_refresh_token, "", max_age=-1, ), 'Referrer-Policy': 'no-referrer', # Prevent grant-token from leaking }, 'body': html, }
def shorten_url_get(shortcode): if not short_code_valid(shortcode): return bad_request('Shortcode invalide', 412) try: sc = Shortcodes.query.filter(Shortcodes.shortcode == shortcode).first() if not sc: return bad_request("Shortcode not found", 404) sc.redirect_count += 1 sc.last_redirect = datetime.now() db.session.commit() # better add detail exception except Exception: return jsonify({'error': 'Service is temporarily unavailable'}), 500 else: return redirect(sc.url)
def handler(event, context) -> dict: del context # unused try: raw_grant = event['queryStringParameters']['grant'] except (TypeError, KeyError): return bad_request('', 'missing required parameter') try: grant = jwt.decode( raw_grant, get_grant_jwt_secret(), algorithms=['HS256'], ) assert 'exp' in grant assert 'azp' in grant assert 'sub' in grant assert 'domains' in grant except (jwt.InvalidTokenError, AssertionError): return bad_request('', 'invalid grant token') refresh_token = grant # We need to re-sign this with the refresh_token key raw_refresh_token = jwt.encode(refresh_token, get_refresh_token_jwt_secret(), algorithm='HS256').decode('ascii') with open(os.path.join(os.path.dirname(__file__), 'use_grant.html')) as f: html = f.read() html = html.replace('{{{domains}}}', json.dumps(list(grant['domains'])))\ .replace('{{{authorize_url}}}', json.dumps(f"https://{os.environ['DOMAIN_NAME']}/authorize")) now = time.time() return { 'statusCode': 200, 'headers': { 'Content-Type': 'text/html', 'Set-Cookie': generate_cookie( get_config().cookie_name_refresh_token, raw_refresh_token, max_age=int(refresh_token['exp'] - now), ), 'Referrer-Policy': 'no-referrer', # Prevent grant-token from leaking }, 'body': html, }
def get_stats(shortcode): if not short_code_valid(shortcode): return bad_request('Shortcode invalide', 412) try: sc = Shortcodes.query.filter(Shortcodes.shortcode == shortcode).first() except Exception: return jsonify({'error': 'Service is temporarily unavailable'}), 500 else: if sc is None: return bad_request("Shortcode not found", 404) return jsonify({ "created": sc.created, "lastRedirect": sc.last_redirect, "redirectCount": sc.redirect_count }), 200
def healthcheck(): try: Shortcodes.query.first() except Exception: return bad_request('Oooo, shit, man!', 500) else: return jsonify({'response': 'OK'}), 200
def add_mod(): # adds a user to the list of moderators username = request.form["username"] user = User.query.filter( func.lower(User.username) == func.lower(username)).first() if not user: return bad_request("user not found") user.form_mod = True run = True while run: # issue key key = "".join( random.choices(string.ascii_letters + string.digits, k=32)) user.api_key = key try: db.session.add(user) db.session.commit() run = False except IntegrityError: # check for uniqueness continue db.session.add(user) db.session.commit() url = url_for('settings', _external=True) subj = f"invitation to moderate {g.settings.site_title}" body = f"**gadzooks!** u/{g.user.username} has added you as a moderator of {g.settings.site_title}" body += f"\n\nclick [here]({url}) to view the site. mod tools will be visible at the top of the page." send_message(username, subj, body) return jsonify(status="OK"), 200
def add_exemption(): # adds an exemption of restrictions for a user username = request.form["username"] if not username: return bad_request("username not provided") user = User.query.filter( func.lower(username) == func.lower(username)).first() if user: user.is_exempt = True if len(user.response) > 0: user.response = "" db.session.add(user) db.session.commit() return jsonify(status="OK"), 200 else: return bad_request("User does not exist yet")
def remove_mod(): # removes a user from the list of moderators username = request.form["username"] user = User.query.filter( func.lower(User.username) == func.lower(username)).first() if not user: return bad_request("user not found") user.form_mod = False db.session.add(user) db.session.commit() return jsonify(status="OK"), 200
def handler(event, context): try: entry = json.loads(event["body"])["entry"] except Exception: return bad_request("There is no 'entry' in request body!") # read rows = list() try: obj = s3.get_object(Bucket=WRITE_TO_BUCKET_NAME, Key=FILE_NAME) body = csv.DictReader(codecs.getreader("utf-8")(obj["Body"]), delimiter=delimiter) for i, row in enumerate(body): # add chunks in case of a big file? rows.append(dict(row)) except (s3.exceptions.NoSuchKey, KeyError): pass except s3.exceptions.NoSuchBucket: return bad_request("No bucket with name " + WRITE_TO_BUCKET_NAME + "!") # add new next_id = 1 + max([int(row["id"]) for row in rows] or [0]) date = datetime.now().strftime("%d.%m.%Y %H:%M") rows.append({"id": str(next_id), "created_at": date, "text": entry}) # write pipe = Pipe() writer = csv.DictWriter(pipe, ["id", "created_at", "text"], delimiter=delimiter) writer.writeheader() for row in rows: writer.writerow(row) s3.put_object(Body=str.encode(pipe.value), Bucket=WRITE_TO_BUCKET_NAME, Key=FILE_NAME) return response(200, { "message": "New entry was added", "last_records": rows[-10:] })
def handler(event, context): """Create new custom entity.""" new_entity = None try: new_entity = json.loads(event.get("body")) except json.decoder.JSONDecodeError as e: return bad_request("Invalid request body: {0}".format(str(e))) try: new_entity = EntitySchema().load(new_entity) except ValidationError as err: return response(400, err.messages) if new_entity: # Validate if records with current email already exist email = new_entity.get("email") items = db.find_by_email(email) if items: err_message = dict(email=[ f"Record with email '{email}' already exists", ], ) return response(400, err_message) entity, ok = db.create_or_update(item=new_entity) try: entity = EntitySchema().dump(entity) except ValidationError as err: return response(400, err.messages) # If new record created successfully if ok: entity.update({"success": True}) return response(201, entity) return bad_request("Something went wrong")
def handler(event, context) -> dict: del context # unused try: refresh_token = get_refresh_token(event) except NotLoggedIn: return { 'statusCode': 401, 'body': "Not logged in", } except BadRequest as e: return bad_request('', e) except InternalServerError as e: return internal_server_error('', e) if 'domains' in refresh_token: # delegated token with domain restrictions domains = refresh_token['domains'] else: domains = get_domains() access_tokens = {} try: for domain in domains: access_tokens[domain] = access_token_from_refresh_token( refresh_token, domain, ) except BadRequest as e: return bad_request('', e) return { 'statusCode': 200, 'headers': { 'Content-Type': 'application/json', }, 'body': json.dumps(access_tokens), }
def lambda_handler(event, context): body = event["body"] if event["body"] else None if not body: return bad_request( {'message': 'Event request does not contain body object'}) if 'action' not in body: return bad_request({'message': 'Body does not contain \'action\' key'}) if body["action"] not in ALLOWED_ACTIONS: return bad_request({ 'message': 'Body does not contain a valid action. Valid actions are: ' + ','.join(ALLOWED_ACTIONS) }) if body["action"] == 'run': if RUN_QUERY_VALIDATOR.validate(body): queries = body['queries'] response = execute_queries(queries) return response else: return bad_request(RUN_QUERY_VALIDATOR.errors)
def delete_user(user_id): user = Users.query.filter_by(id=user_id).first() if not user: return not_found('User not found!') data = request.get_json() if check_password_hash(user.password, data['password']): db.session.delete(user) db.session.commit() delete_message = 'User deleted: {} {} {} | {} | id={}'.format( user.last_name, user.first_name, user.patronymic_name, user.email, user.id) app.logger.info(delete_message) return jsonify({'message': delete_message}) else: return bad_request('Password is not valid!!')
def patch_site_settings_values(**kwargs): body = kwargs.get('body') email = kwargs.get('email') settings = { 'site_visibility': body.get('site_visibility', ''), 'title': body.get('title', ''), 'fontsize': body.get('fontsize', ''), 'coloraccent': body.get('coloraccent', ''), 'isdarkmode': body.get('isdarkmode', ''), 'description': body.get('description', ''), 'copyright': body.get('copyright', ''), 'websiteurl': body.get('websiteurl', ''), 'brandmail': body.get('brandmail', ''), 'brandlogourl': body.get('brandlogourl', ''), 'faviconurl': body.get('faviconurl', ''), 'appiconurl': body.get('appiconurl', '') } schema_validation = Validator(PATCH_ADMIN_SETTINGS_SCHEMA) remove_empty_values_of_dict(settings) resp = None if schema_validation.validate(settings): query = dynamic_update_query( settings, 'settings.site_settings', '', email) print(query) msg = { 'body': { 'action': 'run', 'queries': [query] } } method, result = db_handler(msg) print(result) if method == 'ok': resp = settings else: return bad_request(schema_validation.errors) return ok(resp)
def update_setting(): # generic method to update settings setting_name = request.form["setting"] data = request.form["data"] if data == "true": data = True elif data == "false": data = False if setting_name.lower() not in g.settings.__dict__.keys(): return bad_request(f"setting field {setting_name} does not exist") if setting_name == 'min_age' and data is not None: age = age_to_words(int(data)) setattr(g.settings, 'min_age_word', age) setattr(g.settings, setting_name, data) db.session.add(g.settings) db.session.commit() return jsonify(status="OK"), 200
def get_settings_from_event(query_string, user_id): if ADMIN_SETTINGS_URL_VALIDATOR.validate(query_string): # get the permission of the user user_permission = get_current_user_permission( user_id, query_string['permission']) print(user_permission) if user_permission['authorized'] == 'True': # if yes, then get data return get_site_settings_values() else: # else, return bad request return forbidden() else: return bad_request(ADMIN_SETTINGS_URL_VALIDATOR.errors)
def create_user_card(user_id): user = Users.query.filter_by(id=user_id).first() if not user: return not_found('User not found!') data = request.get_json() if check_password_hash(user.password, data['password']): number_new_card, cvv_new_card, pin_new_card = generate_new_card() hashed_cvv = generate_password_hash(cvv_new_card, method='sha256') hashed_pin = generate_password_hash(pin_new_card, method='sha256') val_date = datetime.now() + timedelta(days=365) new_card = Cards(number=number_new_card, cvv_code=hashed_cvv, pin_code=hashed_pin, user_id=user_id, validity_date=val_date) db.session.add(new_card) db.session.commit() create_message = 'Card for user id={} created: {}'.format( user_id, '*' * 9 + str(number_new_card[-4:])) app.logger.info(create_message) return jsonify({'message': create_message}) else: return bad_request('Password is not valid!')
def shorten_url(): if not request.json: return bad_request('Url must be provided in json format.', 400) if 'url' not in request.json: return bad_request('Url parameter not found.', 400) if request.method == 'POST': json = request.json url = json['url'] if not url_valid(url): return bad_request('Provided url is not valid.', 400) if 'shortcode' in json: try: sc = Shortcodes.query.filter( Shortcodes.shortcode == json['shortcode']).first() if sc: return bad_request('Shortcode already in used', 409) except Exception: return jsonify({'error': 'Service is temporarily unavailable'}), 500 else: shortcode = json['shortcode'] else: shortcode = shorten(url) if not short_code_valid(shortcode): return bad_request('Shortcode invalide', 412) sc = Shortcodes(url=url, shortcode=shortcode) try: db.session.add(sc) db.session.commit() except sqlalchemy.exc.IntegrityError: return bad_request('url already exists', 400) except Exception as err: return jsonify({'error': 'Service is temporarily unavailable'}), 500 else: return jsonify({'shortened_url': shortcode}), 201
def handler(event, context) -> dict: del context # unused try: cognito_code = event['queryStringParameters']['code'] state = event['queryStringParameters']['state'] except (TypeError, KeyError): return bad_request('', 'missing required parameter') try: state = jwt.decode( state, get_state_jwt_secret(), algorithms=['HS256'], ) except jwt.InvalidTokenError: return bad_request('', 'invalid state token') try: cognito_token = exchange_cognito_code(event, cognito_code) except BadRequest: return bad_request() except InternalServerError: return internal_server_error() # Issue a token valid for 180 days. This allows the user to issue delegate # tokens for up to this time. # But set the expiration of the Cookie itself to the validity of the # Cognito token. # Unless the user actively safeguards his cookie, he will have to # re-authenticate with Cognito. If this is malicious intend, the user # could delegate the same access to himself, and get the same result. now = int(time.time()) refresh_token = { 'iat': now, # Issued AT 'exp': now + 180 * 24 * 60 * 60, # EXPire: 180 days, maximum duration of delegated tokens 'azp': cognito_token['cognito:username'], # AuthoriZed Party } raw_refresh_token = jwt.encode( refresh_token, get_refresh_token_jwt_secret(), algorithm='HS256', ).decode('ascii') structlog.get_logger().msg( "Cognito Code exchanged succesfully, issuing refresh_token", refresh_token=refresh_token) # Don't log signed token, only payload try: if state['action'] == 'index': location = f"https://{os.environ['DOMAIN_NAME']}/" elif state['action'] == 'delegate': location = f"https://{os.environ['DOMAIN_NAME']}/delegate" elif state['action'] == 'authorize': location = f"https://{os.environ['DOMAIN_NAME']}/authorize?" + \ f"redirect_uri={urllib.parse.quote_plus(state['redirect_uri'])}" else: raise ValueError(f"Invalid action `{state['action']}`") except (KeyError, ValueError) as e: structlog.get_logger().msg("state is invalid", exception=e) return internal_server_error() return { 'statusCode': 302, 'headers': { 'Content-Type': 'text/plain', 'Location': location, 'Set-Cookie': generate_cookie(get_config().cookie_name_refresh_token, raw_refresh_token, max_age=int(cognito_token['exp'] - now)), }, 'body': 'Redirecting...', }
def GET(self): bad_request("error message")
def handler(event, context) -> dict: del context # unused try: redirect_uri = event['queryStringParameters']['redirect_uri'] except KeyError: return bad_request('', "No redirect_uri parameter found") redirect_uri_comp = urlsplit(redirect_uri) try: refresh_token = get_refresh_token(event) except NotLoggedIn: state = { 'action': 'authorize', 'redirect_uri': redirect_uri, } raw_state = jwt.encode( state, get_state_jwt_secret(), algorithm='HS256', ) return redirect_to_cognito(state=raw_state) except BadRequest as e: return bad_request('', e) except InternalServerError as e: return internal_server_error('', e) # Is this domain allowed? if not is_allowed_domain(redirect_uri_comp.netloc): return bad_request('', f"{redirect_uri} is not an allowed domain") if 'domains' in refresh_token: # delegated token with domain restrictions if redirect_uri_comp.netloc not in refresh_token['domains']: return bad_request( '', f"{redirect_uri} is not an allowed domain for this refresh token" ) try: access_token = access_token_from_refresh_token( refresh_token, redirect_uri_comp.netloc) except BadRequest as e: return bad_request('', e) return { 'statusCode': 302, 'headers': { 'Content-Type': 'text/plain', 'Location': urlunsplit(( 'https', redirect_uri_comp.netloc, get_config().set_cookie_path, urlencode({ # query 'access_token': access_token, # Key must match with λ@E's expectations 'redirect_uri': redirect_uri, # Key must match with λ@E's expectations }), '', # fragment )), }, 'body': 'Redirecting...', }
def POST(self): """ Expects POST body to be the query (a simple string) Returns: A JSON object containing: answerbox to "who is" questions, social of tweets and facebook status, articles of nyt and official website Sample Response: { whois: Object, corrected_query: String, "t": Twitter, "f": Facebook, "o": Official Site, "n": NYT, "wc": word cloud } """ try: content_type = web.ctx.env.get('CONTENT_TYPE') if content_type != 'application/json': bad_request('Content-Type should be application/json') #end if # check POST data user_input = web.data() if len(user_input) == 0: bad_request('Please enter your question.') #end if response = {} # who-is answer box whois_flag = False if re.search("(who('|'s|is| is|) | who)", user_input, re.IGNORECASE): raw_name = re.sub("(who('|'s|is| is|) | who)", "", user_input, flags=re.IGNORECASE) raw_name = raw_name.strip() if len(raw_name) > 0: whois_flag = True if whois_flag: name = normalized_name(raw_name) if len(name) > 0: whois_answer = get_whois_answer(name) if whois_answer is not None: response["whois"] = whois_answer # query spelling correction query = user_input query_tokens = query.split(" ") corrected_query_tokens = [get_correct_word(token) for token in query_tokens] original_query = " ".join(query_tokens) query = " ".join(corrected_query_tokens) if query != original_query: response["corrected_query"]=query # use elasticsearch to retrieve documents es = web.ctx['W2V4_ELASTICSEARCH'] twitter_hits = find_relavent_records(es, query, web.ctx['W2V4_TWITTER_INDEX'], get_doc_type(web.ctx['W2V4_TWITTER_INDEX'])) fb_hits = find_relavent_records(es, query, web.ctx['W2V4_FACEBOOK_INDEX'], get_doc_type(web.ctx['W2V4_FACEBOOK_INDEX'])) official_hits = find_relavent_records(es, query, web.ctx['W2V4_OFFICIAL_INDEX'], get_doc_type(web.ctx['W2V4_OFFICIAL_INDEX'])) nyt_hits = find_relavent_records(es, query, web.ctx['W2V4_NYT_INDEX'], get_doc_type(web.ctx['W2V4_NYT_INDEX'])) sent_weight = float(web.ctx['W2V4_SENTIMENT_WEIGHT']) # prepare for json pass to view twitter_result = twitter_hits['hits']['hits'] fb_result = fb_hits['hits']['hits'] official_result = official_hits['hits']['hits'] nyt_result = nyt_hits['hits']['hits'] if len(twitter_result)>0: response["t"] = twitter_result if len(fb_result)>0: response["f"] = fb_result if len(official_result)>0: response["o"] = official_result if len(nyt_result)>0: response["n"] = nyt_result # word cloud string_for_wc = [] for result in nyt_result[:3]: string_for_wc.append(result["_source"]["text"]) #end for if len(string_for_wc) >0: tmp = ' '.join(string_for_wc) f = os.path.join(os.path.dirname(__file__),'..','static','images','wordcloud.png') if os.path.exists(f): os.remove(f) #end if wc = my_wordcloud.generate_wc(tmp) if wc is not None: response["wc"] = wc + "?" + str(time.time()*1000) web.header('Content-Type', 'application/json') return json.dumps(response) except: (type, value, tb) = sys.exc_info() traceback.print_tb(tb) internal_error(str(type) + " " + str(value))
def POST(self): """ " Expects POST body to be for the form " { "issue": <issue>, "position": <position> } " " Returns: " A list of JSON objects for each candidate, including their " position on the issue entered by the user, and a similarity score. " " Sample Response: " { positions: [{ "candidate": "Jeb Bush", "position": "blah blah", "score": 0.91" }, ...]} """ # check Content-Type content_type = web.ctx.env.get('CONTENT_TYPE') if content_type != 'application/json': bad_request('Content-Type should be application/json') #end if # check POST data user_input = json.loads(web.data()) if 'issue' not in user_input or 'position' not in user_input: bad_request('Issue and position are required.') #end if if len(user_input['issue']) == 0 and len(user_input['position']) == 0: bad_request('Please enter an issue and your position.') #end if try: query = user_input['issue'] + " " + user_input['position'] es = web.ctx['W2V4_ELASTICSEARCH'] twitter_positions = find_relevant_positions(es, query, web.ctx['W2V4_TWITTER_INDEX'], get_doc_type(web.ctx['W2V4_TWITTER_INDEX'])) fb_positions = find_relevant_positions(es, query, web.ctx['W2V4_FACEBOOK_INDEX'], get_doc_type(web.ctx['W2V4_FACEBOOK_INDEX'])) official_positions = find_relevant_positions(es, query, web.ctx['W2V4_OFFICIAL_INDEX'], get_doc_type(web.ctx['W2V4_OFFICIAL_INDEX'])) nyt_positions = find_relevant_positions(es, query, web.ctx['W2V4_NYT_INDEX'], get_doc_type(web.ctx['W2V4_NYT_INDEX'])) sent_weight = float(web.ctx['W2V4_SENTIMENT_WEIGHT']) positions = [] for c in CANDIDATES: positions.append({ 'candidate': c, 'score': get_score(c,sent_weight,twitter_positions,fb_positions,official_positions,nyt_positions), 'position': get_position(c,twitter_positions,fb_positions,official_positions,nyt_positions) }) #end for sorted_positions = sorted(positions,key=(lambda x: x['score']),reverse=True) response = { 'positions': sorted_positions } web.header('Content-Type', 'application/json') return json.dumps(response) except: (type, value, tb) = sys.exc_info() traceback.print_tb(tb) internal_error(str(type) + " " + str(value))
def handler(event, context) -> dict: del context # unused try: refresh_token = get_refresh_token(event) except NotLoggedIn: state = { 'action': 'delegate', } raw_state = jwt.encode( state, get_state_jwt_secret(), algorithm='HS256', ) return redirect_to_cognito(state=raw_state) except BadRequest as e: return bad_request('', e) except InternalServerError as e: return internal_server_error('', e) if event['httpMethod'] == 'GET': structlog.get_logger().msg("Rendering index HTML") if 'domains' in refresh_token: # User wants to further narrow his access domains = refresh_token['domains'] groups = {} else: domains = get_domains() groups = {} scan_paginator = dynamodb_client.get_paginator('scan') response_iterator = scan_paginator.paginate( TableName=get_config().group_table, ) for page in response_iterator: for group_entry in page['Items']: try: groups[group_entry['group'] ['S']] = group_entry['domains']['SS'] except KeyError as e: structlog.get_logger().msg( "Invalid group in DynamoDB: " + repr(group_entry)) pass with open(os.path.join(os.path.dirname(__file__), 'delegate.html')) as f: html = f.read() html = html.replace('{{{domains}}}', json.dumps(domains)) \ .replace('{{{groups}}}', json.dumps(groups)) \ .replace('{{{use_grant_url}}}', json.dumps(f"https://{os.environ['DOMAIN_NAME']}/use_grant?grant=")) return { 'statusCode': 200, 'headers': { 'Content-Type': 'text/html', }, 'body': html, } elif event['httpMethod'] == 'POST': structlog.get_logger().log("Validating POST request", body=event['body']) values = urllib.parse.parse_qs(event['body'], strict_parsing=True) structlog.get_logger().log("Decoded body", body=values) try: exp = int(values['exp'][0]) del values['exp'] subject = values['subject'][0] assert len(subject) > 0 del values['subject'] except (KeyError, AssertionError): return bad_request('mandatory fields not present') if exp > refresh_token['exp']: return bad_request('expiration too long') domains = set(values.keys()) for domain in domains: if not re.match(r'^[a-zA-Z0-9.-]+$', domain): return bad_request( '', f"`{domain}` does not look like a domain name") if not is_allowed_domain(domain): return bad_request('', 'Unknown domain in request') if 'domains' in refresh_token: if not domains.issubset(refresh_token['domains']): return bad_request('', 'domain requested outside refresh_token') delegate_token = { 'iat': int(time.time()), 'exp': exp, 'domains': list(domains), 'azp': refresh_token['azp'], # Authorized Party 'sub': refresh_token.get('sub', []) + [subject], # subject } structlog.get_logger().log("Issuing JWT", jwt=delegate_token) raw_delegate_token = jwt.encode( delegate_token, get_grant_jwt_secret(), algorithm='HS256', ).decode('ascii') return { 'statusCode': 200, 'headers': { 'Content-Type': 'text/plain', }, 'body': raw_delegate_token, }