Esempio n. 1
0
def handle_login(request):
    try:
        serializer = LoginRequestSerializer(data=request.data)
    except ParseError:
        raise CredoAPIException(
            "Could not parse request body as a valid JSON object")

    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data

    if vd.get("username"):
        user = authenticate(username=vd["username"], password=vd["password"])
    elif request.data.get("email"):
        user = authenticate(email=vd["email"], password=vd["password"])
    else:
        raise LoginException("Missing credentials.")
    if not user:
        raise LoginException(
            "Invalid username/email and password combination or unverified email."
        )
    if not user.is_active:
        raise LoginException("Email not verified.")

    data = {
        "username": user.username,
        "display_name": user.display_name,
        "email": user.email,
        "team": user.team.name,
        "language": user.language,
        "token": user.key,
    }
    logger.info("Logging in user {}".format(user))
    return data
Esempio n. 2
0
def handle_mapping_export(request):
    try:
        serializer = MappingExportRequestSerializer(data=request.data)
    except ParseError:
        raise CredoAPIException(
            "Could not parse request body as a valid JSON object")

    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data

    job_id = generate_token()[:16]

    s3 = boto3.resource(
        "s3",
        aws_access_key_id=settings.S3_ACCESS_KEY_ID,
        aws_secret_access_key=settings.S3_SECRET_KEY,
        endpoint_url=settings.S3_ENDPOINT_URL,
    )

    url = s3.meta.client.generate_presigned_url(
        ClientMethod="get_object",
        ExpiresIn=settings.S3_EXPIRES_IN,
        Params={
            "Bucket": settings.S3_BUCKET,
            "Key": "mapping_export_{}.json".format(job_id),
        },
    )

    mapping_export.delay(job_id, vd["mapping_type"])

    logger.info("Exporting mapping by request from {}, type {}, id {}".format(
        request.user, vd["mapping_type"], job_id))

    return {"url": url}
Esempio n. 3
0
def handle_update_info(request):
    serializer = InfoRequestSerializer(data=request.data)
    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data

    user = request.user
    update_fields = []

    if vd.get('display_name'):
        user.display_name = vd['display_name']
        update_fields.append('display_name')

    if vd.get('team') is not None:
        user.team = Team.objects.get_or_create(name=vd['team'])[0]
        update_fields.append('team')

    if vd.get('language'):
        user.language = vd['language']
        update_fields.append('language')

    try:
        user.save(update_fields=update_fields)
        logger.info('Updated info for user {}'.format(user))
    except IntegrityError:
        raise CredoAPIException('Invalid parameters')

    data = {
        'username': user.username,
        'display_name': user.display_name,
        'email': user.email,
        'team': user.team.name,
        'language': user.language,
    }
    return data
Esempio n. 4
0
def handle_ping(request):
    try:
        serializer = PingRequestSerializer(data=request.data)
    except ParseError:
        raise CredoAPIException(
            "Could not parse request body as a valid JSON object")

    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))

    vd = serializer.validated_data
    Ping.objects.create(
        timestamp=vd["timestamp"],
        delta_time=vd["delta_time"],
        on_time=vd["on_time"],
        metadata=vd["metadata"],
        device=Device.objects.get_or_create(
            device_id=vd["device_id"],
            device_type=vd["device_type"],
            device_model=vd["device_model"],
            system_version=vd["system_version"],
            user=request.user,
        )[0],
        user=request.user,
    )

    if vd["on_time"]:
        recalculate_user_stats.delay(request.user.id)

    logger.info("Stored ping for user {}".format(request.user))
Esempio n. 5
0
def handle_registration(request):
    try:
        serializer = RegisterRequestSerializer(data=request.data)
    except ParseError:
        raise CredoAPIException(
            "Could not parse request body as a valid JSON object")

    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data

    register_user(vd["email"], vd["password"], vd["username"],
                  vd["display_name"], vd["team"])
Esempio n. 6
0
def handle_login(request):
    serializer = LoginRequestSerializer(data=request.data)
    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data

    if vd.get('username'):
        user = authenticate(username=vd['username'], password=vd['password'])
    elif request.data.get('email'):
        user = authenticate(email=vd['email'], password=vd['password'])
    else:
        raise LoginException('Missing credentials.')
    if not user:
        raise LoginException(
            'Invalid username/email and password combination or unverified email.'
        )
    if not user.is_active:
        raise LoginException('Email not verified.')

    data = {
        'username': user.username,
        'display_name': user.display_name,
        'email': user.email,
        'team': user.team.name,
        'language': user.language,
        'token': user.key
    }
    logger.info('Logging in user {}'.format(user))
    return data
Esempio n. 7
0
def handle_data_export(request):
    serializer = DataExportRequestSerializer(data=request.data)
    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data

    job_id = generate_token()[:16]

    s3 = boto3.resource('s3',
                        aws_access_key_id=settings.S3_ACCESS_KEY_ID,
                        aws_secret_access_key=settings.S3_SECRET_KEY,
                        endpoint_url=settings.S3_ENDPOINT_URL)

    url = s3.meta.client.generate_presigned_url(
        ClientMethod='get_object',
        ExpiresIn=86400,  # 24h
        Params={
            'Bucket': 'credo_test',
            'Key': 'export_{}.json'.format(job_id)
        })

    os.system(
        'python manage.py s3_data_export --id {} --since {} --until {} --limit {} --type {}&'
        .format(job_id, vd['since'], vd['until'], vd['limit'],
                vd['data_type']))

    logger.info(
        'Exporting data by request from {}, type {}, since {}, until {}, limit {}, id {}'
        .format(request.user, vd['data_type'], vd['since'], vd['until'],
                vd['limit'], job_id))
    return {'url': url}
Esempio n. 8
0
def handle_oauth_login(request):
    try:
        serializer = OAuthLoginRequestSerializer(data=request.data)
    except ParseError:
        raise CredoAPIException(
            "Could not parse request body as a valid JSON object")

    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data

    try:
        oat, _ = get_token(vd["authorization_code"], vd["provider"])
    except requests.exceptions.RequestException as e:
        raise CredoAPIException(str(e))

    try:
        email, username, display_name = get_userinfo(oat, vd["provider"])
    except requests.exceptions.RequestException as e:
        raise CredoAPIException(str(e))

    new_account = False

    try:
        user = User.objects.get(email=email)
        if not user.is_active:
            logger.info("Enabling user account because of valid OAuth login")
            user.is_active = True
            user.save()
    except User.DoesNotExist:
        user = register_oauth_user(email, username, display_name,
                                   vd["provider"])
        new_account = True

    data = {
        "new_account": new_account,
        "token": user.key,
    }

    logger.info("OAuth login for user {}".format(user))
    return data
Esempio n. 9
0
def handle_registration(request):
    serializer = RegisterRequestSerializer(data=request.data)
    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data

    user = None

    try:
        u = User.objects.get(email=vd['email'])
        if not u.is_active:
            user = u
            user.team = Team.objects.get_or_create(name=vd['team'])[0]
            user.display_name = vd['display_name']
            user.key = generate_token()
            user.username = vd['username']
            user.email_confirmation_token = generate_token()
            user.set_password(vd['password'])
            user.save()
            logger.info(
                'Updating user info and resending activation email to user {}'.
                format(user))
    except User.DoesNotExist:
        logger.info('Creating new user {} {}'.format(vd['username'],
                                                     vd['display_name']))

    if not user:
        try:
            user = User.objects.create_user(
                team=Team.objects.get_or_create(name=vd['team'])[0],
                display_name=vd['display_name'],
                key=generate_token(),
                password=vd['password'],
                username=vd['username'],
                email=vd['email'],
                is_active=False,
                email_confirmation_token=generate_token(),
            )
        except IntegrityError:
            logger.warning('User registration failed, IntegrityError', vd)
            raise RegistrationException(
                "User with given username or email already exists.")

    if user:
        logger.info('Sending registration email to {}'.format(user.email))
        try:
            send_registration_email(user.email, user.email_confirmation_token,
                                    user.username, user.display_name)
        except Exception as e:
            logger.exception(e)
            logger.error(
                'Failed to send confirmation email for user {} ({})'.format(
                    user, user.email))
Esempio n. 10
0
def handle_update_info(request):
    try:
        serializer = InfoRequestSerializer(data=request.data)
    except ParseError:
        raise CredoAPIException(
            "Could not parse request body as a valid JSON object")

    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data

    user = request.user
    update_fields = []

    if vd.get("display_name"):
        user.display_name = vd["display_name"]
        update_fields.append("display_name")

    if vd.get("team") is not None:
        user.team = Team.objects.get_or_create(name=vd["team"])[0]
        update_fields.append("team")

    if vd.get("language"):
        user.language = vd["language"]
        update_fields.append("language")

    try:
        user.save(update_fields=update_fields)
        logger.info("Updated info for user {}".format(user))
    except IntegrityError:
        raise CredoAPIException("Invalid parameters")

    data = {
        "username": user.username,
        "display_name": user.display_name,
        "email": user.email,
        "team": user.team.name,
        "language": user.language,
    }
    return data
Esempio n. 11
0
def handle_ping(request):
    serializer = PingRequestSerializer(data=request.data)
    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data
    Ping.objects.create(timestamp=vd['timestamp'],
                        delta_time=vd['delta_time'],
                        on_time=vd['on_time'],
                        device=Device.objects.get_or_create(
                            device_id=vd['device_id'],
                            device_type=vd['device_type'],
                            device_model=vd['device_model'],
                            system_version=vd['system_version'],
                            user=request.user)[0],
                        user=request.user)
    logger.info('Stored ping for user {}'.format(request.user))
Esempio n. 12
0
def handle_detection(request):
    serializer = DetectionRequestSerializer(data=request.data)
    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data
    detections = []
    for d in vd['detections']:

        frame_content = base64.b64decode(d['frame_content'])
        visible = True
        if (not frame_content) or validate_image(frame_content):
            visible = False

        detections.append(
            Detection.objects.create(accuracy=d['accuracy'],
                                     altitude=d['altitude'],
                                     frame_content=frame_content,
                                     height=d['height'],
                                     width=d['height'],
                                     d_id=d['id'],
                                     latitude=d['latitude'],
                                     longitude=d['longitude'],
                                     provider=d['provider'],
                                     timestamp=d['timestamp'],
                                     source='api_v2',
                                     device=Device.objects.get_or_create(
                                         device_id=vd['device_id'],
                                         device_type=vd['device_type'],
                                         device_model=vd['device_model'],
                                         system_version=vd['system_version'],
                                         user=request.user)[0],
                                     user=request.user,
                                     team=request.user.team,
                                     visible=visible))
    data = {
        'detections': [
            {
                'id': d.id  # TODO: Should we send more data?
            } for d in detections
        ]
    }
    logger.info('Stored {} detections for user {}'.format(
        len(detections), request.user))
    return data
Esempio n. 13
0
def handle_detection(request):
    try:
        serializer = DetectionRequestSerializer(data=request.data)
    except ParseError:
        raise CredoAPIException(
            "Could not parse request body as a valid JSON object")

    if not serializer.is_valid():
        raise CredoAPIException(str(serializer.errors))
    vd = serializer.validated_data

    detections = []
    r = None
    for d in vd["detections"]:

        frame_content = base64.b64decode(d["frame_content"])
        visible = True
        if (not frame_content) or (not validate_image(frame_content)):
            visible = False

        if visible:
            if not r:
                r = get_redis_connection(write=False)
            start_time = r.zscore(cache.make_key("start_time"),
                                  request.user.id)
            if start_time:
                visible = d["timestamp"] > start_time
            else:
                visible = False

        if visible and d["x"] is not None:
            r = get_redis_connection()
            if not r.sadd(
                    cache.make_key("pixels_{}".format(request.user.id)),
                    "{} {}".format(d["x"], d["y"]),
            ):
                visible = False

        detections.append(
            Detection.objects.create(
                accuracy=d["accuracy"],
                altitude=d["altitude"],
                frame_content=frame_content,
                height=d["height"],
                width=d["width"],
                x=d["x"],
                y=d["y"],
                latitude=d["latitude"],
                longitude=d["longitude"],
                provider=d["provider"],
                timestamp=d["timestamp"],
                metadata=d["metadata"],
                source="api_v2",
                device=Device.objects.get_or_create(
                    device_id=vd["device_id"],
                    device_type=vd["device_type"],
                    device_model=vd["device_model"],
                    system_version=vd["system_version"],
                    user=request.user,
                )[0],
                user=request.user,
                team=request.user.team,
                visible=visible,
            ))
    data = {"detections": [{"id": d.id} for d in detections]}
    recalculate_user_stats.delay(request.user.id)
    recalculate_team_stats.delay(request.user.team.id)
    logger.info("Stored {} detections for user {}".format(
        len(detections), request.user))
    return data