예제 #1
0
def get_authn_url(api_gateway_endpoint, host, access_key, reauthorize=False):
    """
    Generates an authentication URL for an access key if no request or access
    tokens exist for it.
    """
    if access_key_has_access_token(access_key) and not reauthorize:
        logger.debug("Access key already has token: %s", access_key)
        return urllib.parse.urlunparse(
            ("https", host, f"{api_gateway_endpoint}/token", "", "", ""))
    if reauthorize:
        delete_existing_access_tokens(access_key)

    token_data = request_request_token()
    if token_data is None:
        logger.error("Unable to get token; see previous logs for why.")
        return None

    callback_url = urllib.parse.urlunparse(
        ("https", host, f"{api_gateway_endpoint}/callback", "", "", ""))
    auth_url = urllib.parse.urlunparse((
        "https",
        "www.tripit.com",
        "/oauth/authorize",
        "",
        f"oauth_token={token_data['token']}&oauth_callback={callback_url}",
        "",
    ))
    associate_request_token_with_access_key(token_data["token"], access_key,
                                            token_data["token_secret"])
    return auth_url
예제 #2
0
 def _run():
     session = TripitWebDriver()
     try:
         _sign_in(session)
         return _create_new_trip(session)
     # We want a broad exception here.
     # pylint: disable=broad-except
     except Exception as failure:
         logger.error("Failed to create a new test trip: %s", failure)
예제 #3
0
 def _run(token):
     try:
         item = TripitRequestToken.get(token)
         return {
             "access_key": item.access_key,
             "token": item.token,
             "token_secret": item.token_secret,
         }
     except TripitRequestToken.DoesNotExist:
         logger.error("Token not found during test: %s", token)
예제 #4
0
 def _run(trip_id):
     session = TripitWebDriver()
     try:
         _sign_in(session)
         _delete_current_trip(session, trip_id)
         session.close()
     # We want a broad exception here.
     # pylint: disable=broad-except
     except Exception as failure:
         logger.error("Failed to create a new test trip: %s", failure)
예제 #5
0
 def _run(access_key, token, secret):
     try:
         if not TripitRequestToken.exists():
             TripitRequestToken.create_table(wait=True)
         new_mapping = TripitRequestToken(token,
                                          access_key=access_key,
                                          token_secret=secret)
         new_mapping.save()
         new_mapping.refresh()
     except TransactWriteError:
         logger.error("Failed to mock a request token mapping for %s",
                      access_key)
예제 #6
0
def get_host(event):
    """
    Get the host associated with this API gateway from an event.
    """
    try:
        return event["headers"]["Host"]
    except (KeyError, TypeError):
        logger.error(
            "Failed to get host from headers, %s",
            json.dumps(event["Headers"]),
        )
        return None
예제 #7
0
 def insert(access_key, token, token_secret):
     """
     Inserts a new access token.
     """
     try:
         if not TripitAccessToken.exists():
             TripitAccessToken.create_table()
         new_mapping = TripitAccessToken(access_key, token=token, token_secret=token_secret)
         new_mapping.save()
         new_mapping.refresh()
     except TransactWriteError as failed_write_error:
         logger.error("Failed to write new data for ak %s: %s", access_key, failed_write_error)
예제 #8
0
def handle_callback(request_token):
    """
    Handles TripIt callbacks and persists access tokens with access keys for
    future use.
    """
    access_key = get_access_key_from_request_token(request_token)
    if access_key is None:
        logger.error("This token hasn't been mapped yet: %s", request_token)
        return False
    request_token_secret = get_token_secret_from_request_token(request_token)
    if request_token_secret is None:
        logger.error(
            "BUG: No token secret mapped to request token from step 1: %s",
            access_key)
        return False
    access_token_data = request_access_token(request_token,
                                             request_token_secret)
    if access_token_data is None:
        logger.error("Failed to obtain an access token from request token %s",
                     request_token)
        return False
    try:
        TripitAccessToken.insert(
            access_key=access_key,
            token=access_token_data["token"],
            token_secret=access_token_data["token_secret"],
        )
        return True
    except TransactWriteError:
        logger.error("Failed to write new token; see logs above")
        return False
예제 #9
0
 def delete_tokens_by_access_key(access_key):
     """
     Deletes a token associated with an access key.
     """
     try:
         existing_request_token_mapping = TripitAccessToken.get(access_key)
         existing_request_token_mapping.delete()
         existing_request_token_mapping.save()
         existing_request_token_mapping.refresh()
         return None
     except TransactWriteError as failed_write_error:
         logger.error("Failed to write new data for ak %s: %s", access_key, failed_write_error)
         return None
     except TableDoesNotExist:
         logger.warning("Access token not created yet for key %s", access_key)
         return None
예제 #10
0
def resolve_trip(trip_reference, token, token_secret, human_times):
    """
    Generates a summarized version of a trip with expanded flight
    information.

    This involves a nested API call and might be time-expensive!
    """
    logger.debug("Fetching trip %s", trip_reference["id"])
    trip_info = get_from_tripit_v1(
        endpoint="".join(["/get/trip/id/", trip_reference["id"]]),
        token=token,
        token_secret=token_secret,
    )
    if trip_info.status_code != 200:
        logger.error("Unable to fetch trip %s, error %d", trip_reference["id"],
                     trip_info.status_code)
    trip_object = trip_info.json()["Trip"]

    if trip_is_empty(trip_object):
        logger.warn("Trip %s is empty", trip_object["id"])
        return {}

    flight_objects = trip_info.json().get("AirObject") or []
    note_objects = trip_info.json().get("NoteObject") or []
    flights = resolve_flights(flight_objects, human_times)
    trip_start_time = resolve_start_time(trip_object, flights, human_times)
    trip_end_time = resolve_end_time(trip_object, flights, human_times)
    primary_location = resolve_primary_location(trip_object)

    summarized_trip = {
        "id": int(trip_object["id"]),
        "name": trip_object["display_name"],
        "city": trip_object["primary_location"],
        "ends_on": trip_end_time,
        "ended": determine_if_trip_ended(trip_end_time, note_objects),
        "link": "https://www.tripit.com" + trip_object["relative_url"],
        "starts_on": trip_start_time,
        "flights": flights,
    }
    if human_times:
        for key in ["starts_on", "ends_on"]:
            summarized_trip[key] = convert_to_human_dt(summarized_trip[key])
    return summarized_trip
예제 #11
0
 def insert(token, access_key, token_secret):
     """
     Inserts a new access token.
     """
     try:
         if not TripitRequestToken.exists():
             TripitRequestToken.create_table()
         try:
             TripitRequestToken.get(token)
             logger.info("Access key already has token: %s", access_key)
             return None
         except TripitRequestToken.DoesNotExist:
             new_mapping = TripitRequestToken(
                 token, access_key=access_key, token_secret=token_secret
             )
             new_mapping.save()
             new_mapping.refresh()
     except TransactWriteError as failed_write_error:
         logger.error("Failed to write new data for token %s: %s", token, failed_write_error)
예제 #12
0
 def _run(authz_url):
     session = TripitWebDriver()
     try:
         session.visit(authz_url)
         session.fill_in("email_address",
                         os.environ.get("TRIPIT_SANDBOX_ACCOUNT_EMAIL"))
         session.fill_in("password",
                         os.environ.get("TRIPIT_SANDBOX_ACCOUNT_PASSWORD"))
         session.click_button("Sign In", element_type="button")
         junk_prefix = '<html><head></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">'
         junk_postfix = "</pre></body></html>"
         result = session.page().replace(junk_prefix,
                                         "").replace(junk_postfix, "")
         session.close()
         return json.loads(result)
     # We want a broad exception here.
     # pylint: disable=broad-except
     except Exception as failure:
         logger.error("Failed to authorize: %s", failure)
         return None
예제 #13
0
def get_all_trips(token, token_secret, human_times=False):
    """
    Retrieves all trips from TripIt and parses it in a way that's friendly to
    this API.

    We only care about flights and notes. Every other TripIt object is stripped out.
    """
    trip_data = get_from_tripit_v1(endpoint="/list/trip",
                                   token=token,
                                   token_secret=token_secret)
    logger.debug("Response: %d, Text: %s", trip_data.status_code,
                 trip_data.text)
    if trip_data.status_code != 200:
        logger.error("Failed to get trips: %s", trip_data.status_code)
        return None
    trips_json = trip_data.json()
    if "Trip" not in trips_json:
        logger.info("No trips found.")
        return []
    return join_trips(normalize_trip_objects(trips_json["Trip"]), token,
                      token_secret, human_times)