Ejemplo n.º 1
0
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."})
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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"})
Ejemplo n.º 5
0
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."})
Ejemplo n.º 6
0
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)
Ejemplo n.º 8
0
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,
        }
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
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,
        }
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
def healthcheck():
    try:
        Shortcodes.query.first()
    except Exception:
        return bad_request('Oooo, shit, man!', 500)
    else:
        return jsonify({'response': 'OK'}), 200
Ejemplo n.º 13
0
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
Ejemplo n.º 14
0
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")
Ejemplo n.º 15
0
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:]
    })
Ejemplo n.º 17
0
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),
    }
Ejemplo n.º 19
0
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)
Ejemplo n.º 20
0
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)
Ejemplo n.º 22
0
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)
Ejemplo n.º 24
0
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!')
Ejemplo n.º 25
0
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
Ejemplo n.º 26
0
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...',
    }
Ejemplo n.º 27
0
 def GET(self):
     bad_request("error message")
Ejemplo n.º 28
0
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...',
    }
Ejemplo n.º 29
0
    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))
Ejemplo n.º 30
0
    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))
Ejemplo n.º 31
0
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,
        }