コード例 #1
0
def cancel_participation():
  """Cancel the current user's participation to the study."""

  user_id = session.get('rr_user_id')
  if user_id == None:
      response = make_response(json.dumps('Current user not connected.'), 401)
      response.headers['Content-Type'] = 'application/json'
      return response

  client_log_table_insert(get_max_devices_table_id_from_users_table_id(user_id), user_id, "CANCEL-PARTICIPATION", "")

  # Send email to the maintainers about the cancellation
  try:
      import yagmail
      yag = yagmail.SMTP(app.config['GMAIL_FROM'], app.config['GMAIL_PWD'])
      msgBody = ['User id: ' + str(user_id)]
      print('Sending participation cancellation email with message body: ' + msgBody[0])
      yag.send(app.config['EMAIL_TO'], 'CANCEL request from user', msgBody)
      response = make_response(json.dumps('TrafficSense project informed of participation cancellation.'), 200)
      response.headers['Content-Type'] = 'application/json'
      return response
  except Exception as e:
      print('Exception' + e.message)
      response = make_response(json.dumps('Error in informing the TrafficSense project: ' + e.message), 500)
      response.headers['Content-Type'] = 'application/json'
      return response
コード例 #2
0
def authenticate_post():
    json = request.json
    user_id = json['userId']
    device_id = json['deviceId']
    installation_id = json['installationId']
    # Get optionally - old clients do not send this
    client_version = json.get('clientVersion')
    messaging_token = json.get('messagingToken', '')

    # 1. check that user exists or abort
    users_table_id = verify_user_id(user_id)

    devices_table_id = get_device_table_id(
        users_table_id, device_id, installation_id)
    session_token = get_session_token_for_device(devices_table_id)
    if session_token is None:
        print('User is not registered. userId=' + user_id)
        abort(403)

    # 2. Update messaging token, if included
    if len(messaging_token) > 1:
        update_messaging_token(devices_table_id, messaging_token)
    update_last_activity(devices_table_id, client_version)

    # 3. Update log
    client_log_table_insert(
        devices_table_id,
        get_user_id_from_device_id(devices_table_id),
        "MOBILE-AUTHENTICATE",
        "ClientVersion:" + (client_version or ""))

    return jsonify({
        'sessionToken': session_token
    })
コード例 #3
0
def authenticate_post():
    json = request.json
    user_id = json['userId']
    device_id = json['deviceId']
    installation_id = json['installationId']
    # Get optionally - old clients do not send this
    client_version = json.get('clientVersion')
    messaging_token = json.get('messagingToken', '')

    # 1. check that user exists or abort
    users_table_id = verify_user_id(user_id)

    devices_table_id = get_device_table_id(
        users_table_id, device_id, installation_id)
    session_token = get_session_token_for_device(devices_table_id)
    if session_token is None:
        print 'User is not registered. userId=' + user_id
        abort(403)

    # 2. Update messaging token, if included
    if len(messaging_token) > 1:
        update_messaging_token(devices_table_id, messaging_token)
    update_last_activity(devices_table_id, client_version)

    # 3. Update log
    client_log_table_insert(
        devices_table_id,
        get_user_id_from_device_id(devices_table_id),
        "MOBILE-AUTHENTICATE",
        "ClientVersion:" + (client_version or ""))

    return jsonify({
        'sessionToken': session_token
    })
コード例 #4
0
def path(session_token):
    devices_table_id = get_device_table_id_for_session(session_token)
    client_log_table_insert(
        devices_table_id,
        get_user_id_from_device_id(devices_table_id),
        "MOBILE-PATH",
        request.args.get("date"))
    devices = db.metadata.tables["devices"]
    where = devices.c.token == session_token
    return common_path(request, db, where)
コード例 #5
0
def path(session_token):
    devices_table_id = get_device_table_id_for_session(session_token)
    client_log_table_insert(
        devices_table_id,
        get_user_id_from_device_id(devices_table_id),
        "MOBILE-PATH",
        request.args.get("date"))
    devices = db.metadata.tables["devices"]
    where = devices.c.token == session_token
    return common_path(request, db, where)
コード例 #6
0
def energymap():
    """Draw the energy consumption map of the user."""
    user_id = session.get('rr_user_id')
    if user_id == None:
        # Not authenticated -> throw back to front page
        return index()
    client_log_table_insert(get_max_devices_table_id_from_users_table_id(user_id), user_id, "WEB-PATH", "")
    return render_template('energymap.html',
                           APPLICATION_NAME=APPLICATION_NAME,
                           RR_URL_PREFIX=app.config['RR_URL_PREFIX'],
                           api_key=app.config['MAPS_API_KEY'])
コード例 #7
0
def download_dump():
    user_id = session.get('rr_user_id')
    if user_id == None:
        response = make_response(json.dumps(
            'No user data in current session.'), 401)
        response.headers['Content-Type'] = 'application/json'
        return response
    client_log_table_insert(
        get_max_devices_table_id_from_users_table_id(user_id),
        user_id, "WEB-DOWNLOAD-DATA", "")
    return common_download_zip(user_id)
コード例 #8
0
def logtest():
    user_id = 1
    device_id = 1
    # Dummy entries for setting up the tables
    # from pyfiles.database_interface import (
    #     users_table_insert, devices_table_insert)
    # users_table_insert("user", "foobar", "barfoo")
    # devices_table_insert(1, "foobar", "a5b8ef8f-73b1-4197-ade9-29141c0ed6e9", "model", "a5b8ef8f-73b1-4197-ade9-29141c0ed6e9")
    print('get_user_id_from_device_id: ' + str(get_user_id_from_device_id(device_id)))
    print('get_max_devices_table_id_from_users_table_id: ' + str(get_max_devices_table_id_from_users_table_id(user_id)))
    client_log_table_insert(device_id, get_user_id_from_device_id(device_id), "WEB-PATH", "Kukkuluuruu")
    response = make_response(json.dumps('Logtest successfully executed.'), 200)
    response.headers['Content-Type'] = 'application/json'
    return response
コード例 #9
0
def fbrefresh(session_token):
    device_id = get_device_table_id_for_session(session_token)
    if device_id < 0:
        return ""
    # get the token
    messaging_token = request.args.get("messaging_token")
    if len(messaging_token) > 1:
        update_messaging_token(device_id, messaging_token)

    user_id = get_user_id_from_device_id(device_id)
    if user_id < 0:
        return ""
    client_log_table_insert(device_id, user_id, "MOBILE-FCM-TOKEN", "")
    return make_response(json.dumps('Ack'), 200)
コード例 #10
0
def fbrefresh(session_token):
    device_id = get_device_table_id_for_session(session_token)
    if device_id < 0:
        return ""
    # get the token
    messaging_token = request.args.get("messaging_token")
    if len(messaging_token) > 1:
        update_messaging_token(device_id, messaging_token)

    user_id = get_user_id_from_device_id(device_id)
    if user_id < 0:
        return ""
    client_log_table_insert(device_id, user_id, "MOBILE-FCM-TOKEN", "")
    return make_response(json.dumps('Ack'), 200)
コード例 #11
0
def trips_json():
    user_id = session.get('rr_user_id')
    if user_id == None:
        response = make_response(json.dumps(
            'No user data in current session.'), 401)
        response.headers['Content-Type'] = 'application/json'
        return response

    client_log_table_insert(
        get_max_devices_table_id_from_users_table_id(user_id),
        user_id,
        "WEB-TRIPS-LIST", "/".join([
            request.args.get("firstday", ""),
            request.args.get("lastday", "")]))

    return common_trips_json(request, db, user_id)
コード例 #12
0
def logtest():
    user_id = 1
    device_id = 1
    # Dummy entries for setting up the tables
    # from pyfiles.database_interface import (
    #     users_table_insert, devices_table_insert)
    # users_table_insert("user", "foobar", "barfoo")
    # devices_table_insert(1, "foobar", "a5b8ef8f-73b1-4197-ade9-29141c0ed6e9", "model", "a5b8ef8f-73b1-4197-ade9-29141c0ed6e9")
    print 'get_user_id_from_device_id: ' + str(
        get_user_id_from_device_id(device_id))
    print 'get_max_devices_table_id_from_users_table_id: ' + str(
        get_max_devices_table_id_from_users_table_id(user_id))
    client_log_table_insert(device_id, get_user_id_from_device_id(device_id),
                            "WEB-PATH", "Kukkuluuruu")
    response = make_response(json.dumps('Logtest successfully executed.'), 200)
    response.headers['Content-Type'] = 'application/json'
    return response
コード例 #13
0
def setlegmode_post():
    """Allow user to correct detected transit modes and line names."""

    user_id = session.get('rr_user_id')
    if user_id == None:
        # Not authenticated -> throw back to front page
        return index()

    device, legid, legact, legline = common_setlegmode(request, db, user_id)

    client_log_table_insert(
        device,
        user_id,
        "WEB-PATH-EDIT",
        "%s %s %s" % (legid, legact, legline))

    return jsonify({})
コード例 #14
0
def setlegmode_post():
    """Allow user to correct detected transit modes and line names."""

    devices = db.metadata.tables["devices"]
    user = select(
        [devices.c.user_id],
        devices.c.token == request.json["sessionToken"]
        ).scalar()

    device, legid, legact, legline = common_setlegmode(request, db, user)

    client_log_table_insert(
        device,
        user,
        "MOBILE-PATH-EDIT",
        "%s %s %s" % (legid, legact, legline))

    return jsonify({})
コード例 #15
0
def setlegmode_post():
    """Allow user to correct detected transit modes and line names."""

    devices = db.metadata.tables["devices"]
    user = select(
        [devices.c.user_id],
        devices.c.token == request.json["sessionToken"]
        ).scalar()

    device, legid, legact, legline = common_setlegmode(request, db, user)

    client_log_table_insert(
        device,
        user,
        "MOBILE-PATH-EDIT",
        "%s %s %s" % (legid, legact, legline))

    return jsonify({})
コード例 #16
0
def energycertificate_svg():
    user_id = session.get('rr_user_id')
    if user_id == None:
        # Not authenticated -> throw back to front page
        return index()

    firstlastday = [
        d in request.args and datetime.datetime.strptime(
            request.args[d], '%Y-%m-%d') or None
        for d in ["firstday", "lastday"]]

    client_log_table_insert(
        get_max_devices_table_id_from_users_table_id(user_id),
        user_id,
        "WEB-CERTIFICATE",
        "/".join(str(x)[:10] for x in firstlastday))

    return Response(get_svg(user_id, *firstlastday), mimetype="image/svg+xml")
コード例 #17
0
def svg(session_token):
    device_id = get_device_table_id_for_session(session_token)
    if device_id < 0:
        return ""
    user_id = get_user_id_from_device_id(device_id)
    if user_id < 0:
        return ""

    firstlastday = [
        d in request.args and datetime.datetime.strptime(
            request.args[d], '%Y-%m-%d') or None
        for d in ["firstday", "lastday"]]

    client_log_table_insert(
        device_id,
        user_id,
        "MOBILE-CERTIFICATE",
        "/".join(str(x)[:10] for x in firstlastday))

    return get_svg(user_id, *firstlastday)
コード例 #18
0
def svg(session_token):
    device_id = get_device_table_id_for_session(session_token)
    if device_id < 0:
        return ""
    user_id = get_user_id_from_device_id(device_id)
    if user_id < 0:
        return ""

    firstlastday = [
        d in request.args and datetime.datetime.strptime(
            request.args[d], '%Y-%m-%d') or None
        for d in ["firstday", "lastday"]]

    client_log_table_insert(
        device_id,
        user_id,
        "MOBILE-CERTIFICATE",
        "/".join(str(x)[:10] for x in firstlastday))

    return get_svg(user_id, *firstlastday)
コード例 #19
0
def connect():
  """Exchange the one-time authorization code for a token and
  store the token in the session."""
  # Ensure that the request is not a forgery and that the user sending
  # this connect request is the expected user.
  # print 'Session state returns: ' + session.get('state')
  if request.args.get('state', '') != session.get('state'):
    response = make_response(json.dumps('Invalid state parameter.'), 401)
    response.headers['Content-Type'] = 'application/json'
    print('401 due to invalid state parameter.')
    return response
  # Delete the one-time token - page refresh required to re-connect
  del session['state']
  # If this request does not have `X-Requested-With` header, this could be a CSRF
  if not request.headers.get('X-Requested-With'):
    response = make_response(json.dumps('Invalid header.'), 403)
    response.headers['Content-Type'] = 'application/json'
    print('403 due to missing X-Requested-With header.')
    return response

  code = request.data

  try:
    # Upgrade the authorization code into a credentials object
    oauth_flow = flow_from_clientsecrets(CLIENT_SECRET_FILE,
                                         scope='profile',
                                         redirect_uri='postmessage')
    credentials = oauth_flow.step2_exchange(code)
  except FlowExchangeError as err:
    # invalid token
    print('Invalid token: ' + code + ". error: " + err.message)
    response = make_response(
        json.dumps('Failed to upgrade the authorization code.'), 401)
    response.headers['Content-Type'] = 'application/json'
    return response

  # An ID Token is a cryptographically-signed JSON object encoded in base 64.
  # Normally, it is critical that you validate an ID Token before you use it,
  # but since you are communicating directly with Google over an
  # intermediary-free HTTPS channel and using your Client Secret to
  # authenticate yourself to Google, you can be confident that the token you
  # receive really comes from Google and is valid. If your server passes the
  # ID Token to other components of your app, it is extremely important that
  # the other components validate the token before using it.
  google_id = verify_and_get_account_id(CLIENT_ID, credentials)['google_id']

  stored_credentials = session.get('credentials')
  stored_google_id = session.get('google_id')
  if stored_credentials is not None and google_id == stored_google_id:
    response = make_response(json.dumps('Current user is already connected.'),
                             200)
    response.headers['Content-Type'] = 'application/json'
    return response
  # Store the access token in the session for later use.
  session['credentials'] = credentials
  session['google_id'] = google_id
  # Find and store the RegularRoutes user id
  user_hash_id = user_hash(google_id)
  user_id = get_users_table_id(user_hash_id)
  if user_id < 0:
      # No data for the user -> show the nodata -page
      print('No data found for the current user.')
      response = make_response(json.dumps('Nodata.'), 200)
      response.headers['Content-Type'] = 'application/json'
      return response
  client_log_table_insert(get_max_devices_table_id_from_users_table_id(user_id), user_id, "WEB-CONNECT", "")
  session['rr_user_id'] = user_id
  response = make_response(json.dumps('Successfully connected user.'), 200)
  response.headers['Content-Type'] = 'application/json'
  return response
コード例 #20
0
def destinations(session_token):

    dd = db.metadata.tables["device_data"]
    devices = db.metadata.tables["devices"]
    users = db.metadata.tables["users"]
    legs = db.metadata.tables["legs"]

    # Limit number of destinations on output, all if blank given
    limit = request.args.get("limit", DESTINATIONS_LIMIT)
    limit = None if limit == "" else int(limit)

    # Exclude nearby and faraway destinations from point if given, or last
    # device location is not given. All included if blank given in either.
    lat = request.args.get("lat")
    lng = request.args.get("lng")

    exclude = True
    if "" not in (lat, lng):
        if None not in (lat, lng):
            excoord = "POINT(%s %s)" % (lng, lat)
        else:
            excoord = db.engine.execute(select(
                [func.ST_AsText(dd.c.coordinate)],
                devices.c.token == session_token,
                order_by=dd.c.time.desc(),
                limit=1)).scalar()
        if excoord is not None:
            rmin, rmax = INCLUDE_DESTINATIONS_BETWEEN
            exclude = and_(
                not_(func.st_dwithin(legs.c.coordinate_start, excoord, rmin)),
                func.st_dwithin(legs.c.coordinate_start, excoord, rmax))

    start = datetime.datetime.now() - datetime.timedelta(days=30)

    query = select(
        [   func.ST_AsGeoJSON(legs.c.coordinate_start).label("geojson"),
            legs.c.time_start,
            legs.c.time_end],
        and_(
            devices.c.token == session_token,
            legs.c.time_end >= start,
            legs.c.activity == "STILL",
            exclude),
        devices.join(users).join(legs))

    stops = list(dict(x) for x in db.engine.execute(query))
    for x in stops:
        x["coordinates"] = json.loads(x["geojson"])["coordinates"]

    dests = sorted(
        stop_clusters(stops, DEST_RADIUS_MAX * 2),
        key=lambda x: x["visits_rank"])

    geojson = {
        "type": "FeatureCollection",
        "features": [
            {   "type": "Feature",
                "geometry": {
                    "type": "Point",
                    "coordinates": d["coordinates"]},
                "properties": d}
            for d in dests[:limit]]}

    for f in geojson["features"]:
        del f["properties"]["coordinates"] # included in geometry
        f["properties"]["visits"] = len(f["properties"]["visits"])

    devices_table_id = get_device_table_id_for_session(session_token)
    client_log_table_insert(devices_table_id, get_user_id_from_device_id(devices_table_id), "MOBILE-DESTINATIONS", "")

    return jsonify(geojson)
コード例 #21
0
def register_post():
    """
        Server should receive valid one-time token that can be used to authenticate user via Google+ API
        See: https://developers.google.com/+/web/signin/server-side-flow#step_6_send_the_authorization_code_to_the_server

    """
    data = request.json
    google_one_time_token = data['oneTimeToken']
    device_id = data['deviceId']
    installation_id = data['installationId']
    device_model = data['deviceModel']
    # print 'deviceModel=' + str(device_model)
    # Get optionally - old clients do not send this
    client_version = data.get('clientVersion')

    # 1. authenticate with Google
    validation_data = authenticate_with_google_oauth(app.config['AUTH_REDIRECT_URI'], CLIENT_SECRET_FILE, CLIENT_ID, google_one_time_token)
    if validation_data is None:
        abort(403)  # auth failed

    account_google_id = validation_data['google_id']

    # The following hash value is also generated in client and used in authentication
    user_id = user_hash(account_google_id)

    users_table_id = None

    # 2. Check if user has registered previously
    ext_users_table_id = get_users_table_id(user_id)
    if ext_users_table_id >= 0:
        users_table_id = ext_users_table_id

    # 3. Check if same device has registered with same user
    devices_table_id = get_device_table_id(
        users_table_id, device_id, installation_id)

    # 4. create/update user to db
    if users_table_id is None:
        users_table_id = users_table_insert(str(user_id), str(validation_data['refresh_token']), str(validation_data['access_token']))
    else:
        print 're-registration for same user detected -> using existing user account'
        users_table_update(str(users_table_id), str(validation_data['refresh_token']), str(validation_data['access_token']))

    # 5. Create/update device to db
    if devices_table_id is None:
        session_token = uuid4().hex
        devices_table_id = devices_table_insert(
            users_table_id,
            device_id,
            installation_id,
            device_model,
            session_token,
            client_version)
    else:
        print 'device re-registration detected -> using same device'
        update_last_activity(devices_table_id, client_version)
        session_token = get_session_token_for_device(devices_table_id)

    # 6. Log the registration
    client_log_table_insert(
        devices_table_id,
        users_table_id,
        "MOBILE-REGISTER",
        "ClientVersion:" + (client_version or ""))

    resp = jsonify({'sessionToken': session_token})
    return resp
コード例 #22
0
def destinations(session_token):

    dd = db.metadata.tables["device_data"]
    devices = db.metadata.tables["devices"]
    users = db.metadata.tables["users"]
    legs = db.metadata.tables["legs"]

    # Limit number of destinations on output, all if blank given
    limit = request.args.get("limit", DESTINATIONS_LIMIT)
    limit = None if limit == "" else int(limit)

    # Exclude nearby and faraway destinations from point if given, or last
    # device location is not given. All included if blank given in either.
    lat = request.args.get("lat")
    lng = request.args.get("lng")

    exclude = True
    if "" not in (lat, lng):
        if None not in (lat, lng):
            excoord = "POINT(%s %s)" % (lng, lat)
        else:
            excoord = db.engine.execute(select(
                [func.ST_AsText(dd.c.coordinate)],
                devices.c.token == session_token,
                order_by=dd.c.time.desc(),
                limit=1)).scalar()
        if excoord is not None:
            rmin, rmax = INCLUDE_DESTINATIONS_BETWEEN
            exclude = and_(
                not_(func.st_dwithin(legs.c.coordinate_start, excoord, rmin)),
                func.st_dwithin(legs.c.coordinate_start, excoord, rmax))

    start = datetime.datetime.now() - datetime.timedelta(days=30)

    query = select(
        [   func.ST_AsGeoJSON(legs.c.coordinate_start).label("geojson"),
            legs.c.time_start,
            legs.c.time_end],
        and_(
            devices.c.token == session_token,
            legs.c.time_end >= start,
            legs.c.activity == "STILL",
            exclude),
        devices.join(users).join(legs))

    stops = list(dict(x) for x in db.engine.execute(query))
    for x in stops:
        x["coordinates"] = json.loads(x["geojson"])["coordinates"]

    dests = sorted(
        stop_clusters(stops, DEST_RADIUS_MAX * 2),
        key=lambda x: x["visits_rank"])

    geojson = {
        "type": "FeatureCollection",
        "features": [
            {   "type": "Feature",
                "geometry": {
                    "type": "Point",
                    "coordinates": d["coordinates"]},
                "properties": d}
            for d in dests[:limit]]}

    for f in geojson["features"]:
        del f["properties"]["coordinates"] # included in geometry
        f["properties"]["visits"] = len(f["properties"]["visits"])

    devices_table_id = get_device_table_id_for_session(session_token)
    client_log_table_insert(devices_table_id, get_user_id_from_device_id(devices_table_id), "MOBILE-DESTINATIONS", "")

    return jsonify(geojson)
コード例 #23
0
def register_post():
    """
        Server should receive valid one-time token that can be used to authenticate user via Google+ API
    """
    data = request.json
    google_one_time_token = data['oneTimeToken']
    device_id = data['deviceId']
    installation_id = data['installationId']
    device_model = data['deviceModel']
    # print 'deviceModel=' + str(device_model)
    # Get optionally - old clients do not send this
    client_version = data.get('clientVersion')

    # 1. authenticate with Google
    validation_data, response = authenticate_with_google_oauth(app.config['AUTH_REDIRECT_URI'], CLIENT_SECRET_FILE, CLIENT_ID, google_one_time_token)
    if response:
        return response

    account_google_id = validation_data['google_id']

    # The following hash value is also generated in client and used in authentication
    user_id = user_hash(account_google_id)

    users_table_id = None

    # 2. Check if user has registered previously
    ext_users_table_id = get_users_table_id(user_id)
    if ext_users_table_id >= 0:
        users_table_id = ext_users_table_id

    # 3. Check if same device has registered with same user
    devices_table_id = get_device_table_id(
        users_table_id, device_id, installation_id)

    # 4. create/update user to db
    if users_table_id is None:
        users_table_id = users_table_insert(str(user_id), str(validation_data['refresh_token']), str(validation_data['access_token']))
    else:
        print('re-registration for same user detected -> using existing user account')
        users_table_update(str(users_table_id), str(validation_data['refresh_token']), str(validation_data['access_token']))

    # 5. Create/update device to db
    if devices_table_id is None:
        session_token = uuid4().hex
        devices_table_id = devices_table_insert(
            users_table_id,
            device_id,
            installation_id,
            device_model,
            session_token,
            client_version)
    else:
        print('device re-registration detected -> using same device')
        update_last_activity(devices_table_id, client_version)
        session_token = get_session_token_for_device(devices_table_id)

    # 6. Log the registration
    client_log_table_insert(
        devices_table_id,
        users_table_id,
        "MOBILE-REGISTER",
        "ClientVersion:" + (client_version or ""))

    resp = jsonify({'sessionToken': session_token})
    return resp