async def auth_via_next(user, password, env):
    """Authorization via NEXT stored credentials to access NEXT"""
    auth_info = await get_auth_by_next_id(user["next_id"])

    # check if a password is set on the account.
    if auth_info["hashed_password"] is None:
        raise ApiUnauthorized("No password is set on this account.")

    salt = auth_info.get("salt")
    hashed_password = auth_info.get("hashed_password")

    # compare the hashes.
    check_password = compare_hash(
        hashed_password,
        hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt, 100000).hex(),
    )

    if not check_password:
        raise ApiUnauthorized("Incorrect username or password.")

    token = generate_api_key(env("SECRET_KEY"), user["next_id"])
    return utils.create_authorization_response(
        token,
        {"message": "Authorization successful", "next_id": auth_info.get("next_id")},
    )
Beispiel #2
0
async def authorize(request):
    """ User login (authorization)
    """
    required_fields = ["id", "password"]
    utils.validate_fields(required_fields, request.json)
    password = request.json.get("password")
    hashed_pwd = hashlib.sha256(password.encode("utf-8")).hexdigest()
    auth_info = await auth_query.fetch_info_by_username(request)
    email = auth_info.get("email")
    if auth_info.get("hashed_password") is None:
        if request.app.config.DEMO_MODE:
            token = generate_api_key(
                request.app.config.SECRET_KEY, auth_info.get("user_id")
            )
            return utils.create_authorization_response(
                token,
                {
                    "message": "Authorization (demo mode) successful",
                    "user_id": auth_info.get("user_id"),
                },
            )
        if not email:
            raise ApiUnauthorized(
                "Unauthorized: No password nor email is set on this account"
            )
        # TODO: send email confirmation with password set link
        raise ApiUnauthorized("Unauthorized: No password is set")
    if auth_info.get("hashed_password") != hashed_pwd:
        # TODO: rate limit password attempts
        raise ApiUnauthorized("Unauthorized: Incorrect password")
    token = generate_api_key(request.app.config.SECRET_KEY, auth_info.get("user_id"))
    return utils.create_authorization_response(
        token,
        {"message": "Authorization successful", "user_id": auth_info.get("user_id")},
    )
Beispiel #3
0
 async def decorated_function(request, *args, **kwargs):
     if request.token is None:
         raise ApiUnauthorized("Unauthorized: No bearer token provided")
     try:
         id_dict = deserialize_apikey(request.app.config.SECRET_KEY,
                                      request.token)
         await auth_query.fetch_info_by_user_id(
             request.app.config.DB_CONN, id_dict.get("id"))
     except (ApiNotFound, BadSignature):
         raise ApiUnauthorized("Unauthorized: Invalid bearer token")
     response = await func(request, *args, **kwargs)
     return response
Beispiel #4
0
async def auth_via_next(user, password, env):
    """Authorization via NEXT stored credentials to access NEXT"""
    hashed_pwd = hashlib.sha256(password.encode("utf-8")).hexdigest()
    auth_info = await get_auth_by_next_id(user["next_id"])
    if auth_info["hashed_password"] is None:
        raise ApiUnauthorized("No password is set on this account.")
    if auth_info["hashed_password"] != hashed_pwd:
        raise ApiUnauthorized("The password you entered is incorrect.")

    token = generate_api_key(env("SECRET_KEY"), user["next_id"])
    return utils.create_authorization_response(
        token,
        {"message": "Authorization successful", "next_id": auth_info.get("next_id")},
    )
def extract_request_token(request):
    """Given a request was initiated by the chatbot engine, retrieve
    the auth token directly from the slot field, otherwise construct
    the token by concatenating the the supplied credentials (cookies)"""
    try:
        return request.json["tracker"]["slots"]["token"]
    except (KeyError, TypeError):
        pass
    if request.cookies.get(SIGNATURE_KEY) is None:
        raise ApiUnauthorized("Unauthorized: No token signature provided")
    if request.cookies.get(PAYLOAD_KEY) is None:
        raise ApiUnauthorized("Unauthorized: No token payload provided")
    return ".".join(
        [request.cookies.get(SIGNATURE_KEY),
         request.cookies.get(PAYLOAD_KEY)])
Beispiel #6
0
async def update_proposal(request, proposal_id):
    """Update proposal."""
    log_request(request)
    LOGGER.debug("update proposal %s\n%s", proposal_id, request.json)
    required_fields = ["reason", "status"]
    validate_fields(required_fields, request.json)
    if request.json["status"] not in ("REJECTED", "APPROVED"):
        raise ApiBadRequest(
            "Bad Request: status must be either 'REJECTED' or 'APPROVED'"
        )
    txn_key, txn_user_id = await get_transactor_key(request=request)

    conn = await create_connection()
    proposal_resource = await proposals_query.fetch_proposal_resource(
        conn, proposal_id=proposal_id
    )
    approvers_list = await compile_proposal_resource(conn, proposal_resource)
    conn.close()
    if txn_user_id not in approvers_list["approvers"]:
        raise ApiUnauthorized(
            "Bad Request: You don't have the authorization to APPROVE or REJECT the proposal"
        )
    batch_list = PROPOSAL_TRANSACTION[proposal_resource.get("type")][
        request.json["status"]
    ].batch_list(
        signer_keypair=txn_key,
        signer_user_id=txn_user_id,
        proposal_id=proposal_id,
        object_id=proposal_resource.get("object"),
        related_id=proposal_resource.get("target"),
        reason=request.json.get("reason"),
    )
    await send(request.app.config.VAL_CONN, batch_list, request.app.config.TIMEOUT)
    await send_notification(proposal_resource.get("target"), proposal_id)
    return json({"proposal_id": proposal_id})
Beispiel #7
0
def auth_via_ldap(user_map, password, env):
    """Authorize via LDAP credentials to access NEXT."""
    ldap_server = env("LDAP_SERVER")
    if ldap_server:
        server = Server(ldap_server)
        conn = Connection(
            server, user=user_map["remote_id"], password=password, read_only=True
        )
        if not conn.bind():
            ldap_login_msg = re.search(
                "data ([0-9a-fA-F]*), v[0-9a-fA-F]*", conn.result["message"]
            )
            if ldap_login_msg and ldap_login_msg.group(1):
                ldap_err_code = ldap_login_msg.group(1)
                login_error = LDAP_ERR_MESSAGES.get(
                    ldap_err_code, LDAP_ERR_MESSAGES["default"]
                )
            else:
                login_error = LDAP_ERR_MESSAGES["default"]

            raise ApiUnauthorized(login_error)
        conn.unbind()

        token = generate_api_key(env("SECRET_KEY"), user_map["next_id"])
        return utils.create_authorization_response(
            token,
            {"message": "Authorization successful", "next_id": user_map["next_id"]},
        )
    raise ApiBadRequest("Missing LDAP_SERVER env variable.")
 async def decorated_function(request, *args, **kwargs):
     try:
         id_dict = deserialize_api_key(
             request.app.config.SECRET_KEY, utils.extract_request_token(request)
         )
         await get_auth_by_next_id(id_dict.get("id"))
     except (ApiNotFound, BadSignature):
         raise ApiUnauthorized("Unauthorized: Invalid bearer token")
     response = await func(request, *args, **kwargs)
     return response
Beispiel #9
0
def extract_request_token(request):
    """If a request was initiated by the chatbot engine, retrieve
    the auth token directly from the tracker slot. Otherwise return
    the 'Authorization' header token."""

    if request.token is not None:
        return request.token
    try:
        return request.json["tracker"]["slots"]["token"]
    except (KeyError, TypeError):
        pass

    raise ApiUnauthorized("Unauthorized: No authentication token provided")
Beispiel #10
0
async def authorize(request):
    required_fields = ["id", "password"]
    utils.validate_fields(required_fields, request.json)

    password = request.json.get("password")
    hashed_pwd = hashlib.sha256(password.encode("utf-8")).hexdigest()
    auth_info = await auth_query.fetch_info_by_user_name(
        request.app.config.DB_CONN, request.json.get("id")
    )
    if auth_info is None or auth_info.get("hashed_password") != hashed_pwd:
        raise ApiUnauthorized("Unauthorized: Incorrect user id or password")
    token = generate_api_key(request.app.config.SECRET_KEY, auth_info.get("user_id"))
    return json({"data": {"authorization": token, "user_id": auth_info.get("user_id")}})
Beispiel #11
0
async def next_admin_creation(request):
    """Creating the admin user.  Used exclusively for the creation of the NEXT admin

    Args:
        request:
            obj: a request object
    """
    try:
        txn_key, txn_user_id = await get_transactor_key(request)
        is_admin = await check_admin_status(txn_user_id)
        if not is_admin:
            raise ApiUnauthorized(
                "You do not have the authorization to create an account.")
    except ApiUnauthorized:
        txn_key = Key()
        txn_user_id = str(uuid4())
    key_pair = txn_key
    next_id = txn_user_id
    return txn_key, txn_user_id, next_id, key_pair
        async def decorated_function(request, *args, **kwargs):
            try:
                id_dict = deserialize_api_key(
                    request.app.config.SECRET_KEY, utils.extract_request_token(request)
                )

                conn = await db_utils.create_connection(
                    request.app.config.DB_HOST,
                    request.app.config.DB_PORT,
                    request.app.config.DB_NAME,
                )

                await auth_query.fetch_info_by_user_id(conn, id_dict.get("id"))

                conn.close()

            except (ApiNotFound, BadSignature):
                raise ApiUnauthorized("Unauthorized: Invalid bearer token")
            response = await func(request, *args, **kwargs)
            return response
Beispiel #13
0
def extract_request_token(request):
    """If a request was initiated by the chatbot engine, retrieve
    the auth token directly from the slot field, otherwise return
    the Authorization header value or cookie token values."""

    if "Authorization" in request.headers:
        return request.headers["Authorization"]

    token_signature = request.cookies.get(SIGNATURE_KEY)
    token_payload = request.cookies.get(PAYLOAD_KEY)

    if token_signature and token_payload:
        return ".".join([token_signature, token_payload])

    try:
        return request.json["tracker"]["slots"]["token"]
    except (KeyError, TypeError):
        pass

    raise ApiUnauthorized("Unauthorized: No authentication token provided")
async def authorize(request):
    """ API Endpoint to authenticate and login to the NEXT platform. """
    required_fields = ["id", "password", "auth_source"]
    utils.validate_fields(required_fields, request.json)
    username = request.json.get("id")
    password = request.json.get("password")
    auth_source = request.json.get("auth_source")

    if auth_source == "next":
        hashed_pwd = hashlib.sha256(password.encode("utf-8")).hexdigest()
        auth_info = await auth_query.fetch_info_by_username(request)
        email = auth_info.get("email")
        if auth_info.get("hashed_password") is None:
            if request.app.config.DEMO_MODE:
                token = generate_api_key(
                    request.app.config.SECRET_KEY, auth_info.get("user_id")
                )
                return utils.create_authorization_response(
                    token,
                    {
                        "message": "Authorization (demo mode) successful",
                        "user_id": auth_info.get("user_id"),
                    },
                )
            if not email:
                raise ApiUnauthorized("No password or email is set on this account.")
            # TODO: send email confirmation with password set link
            raise ApiUnauthorized("No password is set on this account.")
        if auth_info.get("hashed_password") != hashed_pwd:
            # TODO: rate limit password attempts
            raise ApiUnauthorized("The password you entered is incorrect.")

        token = generate_api_key(
            request.app.config.SECRET_KEY, auth_info.get("user_id")
        )
        return utils.create_authorization_response(
            token,
            {
                "message": "Authorization successful",
                "user_id": auth_info.get("user_id"),
            },
        )

    if auth_source == "ldap":
        if LDAP_SERVER:
            if username != "" and password != "":
                ldap_user_dn = await auth_query.fetch_dn_by_username(request)
                server = Server(LDAP_SERVER)
                conn = Connection(
                    server, user=ldap_user_dn, password=password, read_only=True
                )

                if not conn.bind():
                    ldap_login_msg = re.search(
                        "data ([0-9a-fA-F]*), v[0-9a-fA-F]*", conn.result["message"]
                    )
                    if ldap_login_msg and ldap_login_msg.group(1):
                        ldap_err_code = ldap_login_msg.group(1)
                        login_error = LDAP_ERR_MESSAGES.get(
                            ldap_err_code, LDAP_ERR_MESSAGES["default"]
                        )
                    else:
                        login_error = LDAP_ERR_MESSAGES["default"]

                    raise ApiUnauthorized(login_error)

                auth_info = await auth_query.fetch_info_by_username(request)
                conn.unbind()

                token = generate_api_key(
                    request.app.config.SECRET_KEY, auth_info.get("user_id")
                )
                return utils.create_authorization_response(
                    token,
                    {
                        "message": "Authorization successful",
                        "user_id": auth_info.get("user_id"),
                    },
                )
            raise ApiBadRequest(LDAP_ERR_MESSAGES["default"])
        raise ApiBadRequest("Missing LDAP_SERVER env variable.")
    raise ApiBadRequest("Invalid authentication source.")