Beispiel #1
0
    def get_object(self):
        token = self.request.data.get('token')
        try:
            decoded_token = jwt_decode_handler(token)
        except jwt.ExpiredSignature:
            msg = _('This invitation is expired.')
            raise BadRequest(msg)
        except jwt.DecodeError:
            msg = _('Error decoding signature.')
            raise BadRequest(msg)

        user_id = decoded_token.get('user_id')
        invitation_code = decoded_token.get('invitation_code')

        if User.objects.filter(used_invitation_code=invitation_code):
            msg = _('This invitation link has been already used')
            raise BadRequest(msg)

        try:
            user = User.objects.filter(
                invitation_mail_sent=True, ).get(id=user_id)
        except User.DoesNotExist:
            raise BadRequest(_('No user found'))

        self.request.user = user
        self.request.user.used_invitation_code = invitation_code
        return user
Beispiel #2
0
def verify_signer_or_bad_request(signer):
    try:
        signer.verify()
    except SignatureExpired:
        raise BadRequest('Signature expired')
    except BadSignature:
        raise BadRequest('Invalid signature')
Beispiel #3
0
    def get(self, request):
        user = request.user
        state_id = getattr(self, 'state_id', None)
        zipcode = getattr(self, 'zipcode', None)
        dosages = request.query_params.getlist('dosages[]', [])
        end_date = request.query_params.get('end_date')
        med_id = request.query_params.get('med_id')
        provider_categories = request.query_params.getlist(
            'provider_categories[]', [])
        provider_types = request.query_params.getlist('provider_types[]', [])
        start_date = request.query_params.get('start_date')

        # check permission
        state_id, zipcode = force_user_state_id_and_zipcode(
            user, state_id, zipcode)

        # ensure correct geography filters
        if zipcode:
            geography = zipcode
        elif state_id:
            try:
                geography = State.objects.get(id=state_id).state_name
            except State.DoesNotExist:
                raise BadRequest('No such state exists')
        else:
            geography = 'US'

        try:
            med_name = MedicationName.objects.get(id=med_id)
        except MedicationName.DoesNotExist:
            raise BadRequest('No such medication in database')

        filename = '{medication_name}_{geography}_{date_from}_{date_to}_{user_id}_{timestamp}.csv'.format(
            medication_name=med_name.name.replace(' ', '_').replace(
                '(', '').replace(')', ''),
            geography=geography,
            date_from=start_date.format('%Y-%m-%d'),
            date_to=end_date.format('%Y-%m-%d'),
            user_id=user.id,
            timestamp=str(time.time()),
        )

        if hasattr(settings, 'AWS_S3_BUCKET_NAME'):
            file_url = boto3.client('s3').generate_presigned_url(
                ClientMethod='get_object',
                Params={
                    'Bucket': settings.AWS_S3_BUCKET_NAME,
                    'Key': filename
                })
        else:
            file_url = 'local_csv_url'

        generate_csv_export.delay(filename, file_url, user.id, med_id, dosages,
                                  start_date, end_date, provider_types,
                                  provider_categories, state_id, zipcode)

        return Response({'file_url': file_url})
def login(request):
    '''
    Logs in the user via given login and password.
    '''
    serializer = LoginSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    data = serializer.data

    user_class = get_user_model()
    login_fields = (registration_settings.USER_LOGIN_FIELDS
                    or getattr(user_class, 'LOGIN_FIELDS', None)
                    or [user_class.USERNAME_FIELD])

    for field_name in login_fields:
        kwargs = {
            field_name: data['login'],
            'password': data['password'],
        }
        user = auth.authenticate(**kwargs)
        if user:
            break

    if not user:
        raise BadRequest('Login or password invalid.')

    if should_authenticate_session():
        auth.login(request, user)

    extra_data = {}

    if should_retrieve_token():
        token, _ = Token.objects.get_or_create(user=user)
        extra_data['token'] = token.key

    return get_ok_response('Login successful', extra_data=extra_data)
def process_verify_email_data(input_data, serializer_context=None):
    if serializer_context is None:
        serializer_context = {}
    if not registration_settings.REGISTER_EMAIL_VERIFICATION_ENABLED:
        raise Http404()
    serializer = VerifyEmailSerializer(
        data=input_data,
        context=serializer_context,
    )
    serializer.is_valid(raise_exception=True)

    data = serializer.validated_data
    signer = RegisterEmailSigner(data)
    verify_signer_or_bad_request(signer)
    request = serializer_context.get('request')
    new_email = data['email']

    if is_user_email_field_unique() and user_with_email_exists(new_email):
        raise BadRequest(_("This email is already registered."))

    email_field_name = get_user_email_field_name()
    user = get_user_by_verification_id(data['user_id'])
    old_email = getattr(user, email_field_name)
    setattr(user, email_field_name, new_email)
    user.save()

    signals.user_changed_email.send(
        sender=None,
        user=user,
        new_email=new_email,
        old_email=old_email,
        request=request,
    )
def send_reset_password_link(request):
    '''
    Send email with reset password link.
    ---
    serializer: SendResetPasswordLinkSerializer
    '''
    serializer = SendResetPasswordLinkSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    login = serializer.data['login']
    user_class = get_user_model_class()
    user_queryset = user_class.objects.all()

    user = None
    for login_field in get_login_fields():
        try:
            user = get_object_or_404(user_queryset, **{login_field: login})
            break
        except Http404:
            pass

    if not user:
        raise BadRequest('User not found')

    signer = ResetPasswordSigner({
        'user_id': user.pk,
    }, request=request)

    template_config = (
        registration_settings.RESET_PASSWORD_VERIFICATION_EMAIL_TEMPLATES)
    send_verification(user, signer, template_config)

    return get_ok_response('Reset link sent')
Beispiel #7
0
def validate_dates(query_params):
    start_date = query_params.get('start_date')
    end_date = query_params.get('end_date')

    if not (start_date and end_date):
        raise BadRequest(_('start_date and end_date required'))
    try:
        start_date = datetime.strptime(start_date, '%Y-%m-%d').astimezone()
        end_date = datetime.strptime(end_date, '%Y-%m-%d').astimezone()
    except ValueError as e:
        raise BadRequest(_('Incorrect date: {}').format(e))

    if end_date <= start_date:
        raise BadRequest(_('start_date must precede end_date.'))

    return start_date, end_date
Beispiel #8
0
def register(request):
    '''
    Register new user.
    '''
    serializer_class = registration_settings.REGISTER_SERIALIZER_CLASS
    serializer = serializer_class(data=request.data)
    serializer.is_valid(raise_exception=True)

    kwargs = {}

    if registration_settings.REGISTER_VERIFICATION_ENABLED:
        verification_flag_field = get_user_setting('VERIFICATION_FLAG_FIELD')
        kwargs[verification_flag_field] = False
        email_field = get_user_setting('EMAIL_FIELD')
        if (email_field not in serializer.validated_data
                or not serializer.validated_data[email_field]):
            raise BadRequest("User without email cannot be verified")

    user = serializer.save(**kwargs)

    signals.user_registered.send(sender=None, user=user, request=request)
    output_serializer_class = registration_settings.REGISTER_OUTPUT_SERIALIZER_CLASS  # noqa: E501
    output_serializer = output_serializer_class(instance=user)
    user_data = output_serializer.data

    if registration_settings.REGISTER_VERIFICATION_ENABLED:
        signer = RegisterSigner({
            'user_id': get_user_verification_id(user),
        },
                                request=request)
        template_config = (
            registration_settings.REGISTER_VERIFICATION_EMAIL_TEMPLATES)
        send_verification_notification(user, signer, template_config)

    return Response(user_data, status=status.HTTP_201_CREATED)
def register(request):
    '''
    Register new user.
    '''
    serializer_class = registration_settings.REGISTER_SERIALIZER_CLASS
    serializer = serializer_class(data=request.data)
    serializer.is_valid(raise_exception=True)

    kwargs = {}

    if registration_settings.REGISTER_VERIFICATION_ENABLED:
        verification_flag_field = get_user_setting('VERIFICATION_FLAG_FIELD')
        kwargs[verification_flag_field] = False
        email_field = get_user_setting('EMAIL_FIELD')
        if (email_field in serializer.validated_data
                and not serializer.validated_data[email_field]):
            raise BadRequest("User without email cannot be verified")

    user = serializer.save(**kwargs)

    profile_serializer_class = registration_settings.PROFILE_SERIALIZER_CLASS
    profile_serializer = profile_serializer_class(instance=user)
    user_data = profile_serializer.data

    if registration_settings.REGISTER_VERIFICATION_ENABLED:
        signer = RegisterSigner({
            'user_id': user.pk,
        }, request=request)
        template_config = (
            registration_settings.REGISTER_VERIFICATION_EMAIL_TEMPLATES)
        send_verification(user, signer, template_config)

    return Response(user_data, status=status.HTTP_201_CREATED)
def register(request):
    '''
    Register new user.
    '''
    serializer_class = registration_settings.REGISTER_SERIALIZER_CLASS
    serializer = serializer_class(data=request.data,
                                  context={'request': request})
    serializer.is_valid(raise_exception=True)

    kwargs = {}

    if registration_settings.REGISTER_VERIFICATION_ENABLED:
        verification_flag_field = get_user_setting('VERIFICATION_FLAG_FIELD')
        kwargs[verification_flag_field] = False
        email_field_name = get_user_email_field_name()
        if (email_field_name not in serializer.validated_data
                or not serializer.validated_data[email_field_name]):
            raise BadRequest(_("User without email cannot be verified"))

    with transaction.atomic():
        user = serializer.save(**kwargs)
        if registration_settings.REGISTER_VERIFICATION_ENABLED:
            send_register_verification_email_notification(request, user)

    signals.user_registered.send(sender=None, user=user, request=request)
    output_serializer_class = registration_settings.REGISTER_OUTPUT_SERIALIZER_CLASS
    output_serializer = output_serializer_class(
        instance=user,
        context={'request': request},
    )
    user_data = output_serializer.data
    return Response(user_data, status=status.HTTP_201_CREATED)
Beispiel #11
0
def register(request):
    '''
    Register new user.
    '''

    # Check reCaptcha

    serializer_class = registration_settings.REGISTER_SERIALIZER_CLASS
    serializer = serializer_class(data=request.data)
    serializer.is_valid(raise_exception=True)

    kwargs = {}

    if registration_settings.REGISTER_VERIFICATION_ENABLED:
        verification_flag_field = get_user_setting('VERIFICATION_FLAG_FIELD')
        kwargs[verification_flag_field] = False
        email_field = get_user_setting('EMAIL_FIELD')
        if (email_field not in serializer.validated_data
                or not serializer.validated_data[email_field]):
            raise BadRequest("User without email cannot be verified")

    # Check if reCaptcha is enabled
    if registration_settings.RECAPTCHA_ENABLED:
        recaptcha_key = get_user_setting('RECAPTCHA_KEY')
        recaptcha_token = request.data.get('recaptcha_token', None)
        if recaptcha_key is None:
            raise BadRequest("reCaptcha enabled, missing key")
        if recaptcha_token is None:
            raise BadRequest("reCaptcha enabled, missing token")
        if not check_recaptcha_token:
            raise BadRequest("Error with reCaptcha token")

    user = serializer.save(**kwargs)

    output_serializer_class = registration_settings.REGISTER_OUTPUT_SERIALIZER_CLASS  # noqa: E501
    output_serializer = output_serializer_class(instance=user)
    user_data = output_serializer.data

    if registration_settings.REGISTER_VERIFICATION_ENABLED:
        signer = RegisterSigner({
            'user_id': user.pk,
        }, request=request)
        template_config = (
            registration_settings.REGISTER_VERIFICATION_EMAIL_TEMPLATES)
        send_verification_notification(user, signer, template_config)

    return Response(user_data, status=status.HTTP_201_CREATED)
def logout(request):
    '''
    Logs out the user. returns an error if the user is not
    authenticated.
    '''
    if not request.user.is_authenticated:
        raise BadRequest('Not logged in')

    auth.logout(request)

    return get_ok_response('Logout successful')
Beispiel #13
0
def force_user_state_id_and_zipcode(user, state_id, zipcode):
    from medications.models import ZipCode

    if user.permission_level == user.STATE_LEVEL:
        if not user.state_id or (zipcode and ZipCode.objects.filter(
                zipcode=zipcode, state_id=user.state_id).count() == 0):
            msg = _(
                'Permission denied - Please check with system administrator')
            raise BadRequest(msg)
        return user.state_id, zipcode
    return state_id, zipcode
def register_email(request):
    '''
    Register new email.
    '''
    user = request.user

    serializer_class = registration_settings.REGISTER_EMAIL_SERIALIZER_CLASS
    serializer = serializer_class(
        data=request.data,
        context={'request': request},
    )
    serializer.is_valid(raise_exception=True)

    email = serializer.get_email()
    email_already_used = is_user_email_field_unique(
    ) and user_with_email_exists(email)  # noqa: E501

    if registration_settings.REGISTER_EMAIL_VERIFICATION_ENABLED:
        signer = RegisterEmailSigner(
            {
                'user_id': get_user_verification_id(user),
                'email': email,
            },
            request=request)
        notification_data = {
            'params_signer': signer,
            'email_already_used': email_already_used,
        }
        template_config_data = registration_settings.REGISTER_EMAIL_VERIFICATION_EMAIL_TEMPLATES  # noqa: E501
        send_verification_notification(
            NotificationType.REGISTER_EMAIL_VERIFICATION,
            user,
            notification_data,
            template_config_data,
            custom_user_address=email)
    else:
        if email_already_used:
            raise BadRequest(_("This email is already registered."))

        email_field_name = get_user_email_field_name()
        old_email = getattr(user, email_field_name)
        setattr(user, email_field_name, email)
        user.save()
        signals.user_changed_email.send(
            sender=None,
            user=user,
            new_email=email,
            old_email=old_email,
            request=request,
        )

    return get_ok_response(_("Register email link email sent"))
Beispiel #15
0
def login(request):
    '''
    Logs in the user via given login and password.
    '''
    serializer_class = registration_settings.LOGIN_SERIALIZER_CLASS
    serializer = serializer_class(data=request.data)
    serializer.is_valid(raise_exception=True)
    user = serializer.get_authenticated_user()

    if not user:
        raise BadRequest('Login or password invalid.')

    extra_data = perform_login(request, user)

    return get_ok_response('Login successful', extra_data=extra_data)
def register(request):
    '''
    Register new user.
    '''
    serializer_class = registration_settings.REGISTER_SERIALIZER_CLASS
    serializer = serializer_class(
        data=request.data,
        context={'request': request},
    )
    serializer.is_valid(raise_exception=True)

    kwargs = {}

    if registration_settings.REGISTER_VERIFICATION_ENABLED:
        verification_flag_field = get_user_setting('VERIFICATION_FLAG_FIELD')
        kwargs[verification_flag_field] = False
        email_field_name = get_user_email_field_name()
        if (email_field_name not in serializer.validated_data
                or not serializer.validated_data[email_field_name]):
            raise BadRequest("User without email cannot be verified")

    with transaction.atomic():
        user = serializer.save(**kwargs)
        if registration_settings.REGISTER_VERIFICATION_ENABLED:
            signer = RegisterSigner({
                'user_id': get_user_verification_id(user),
            }, request=request)
            template_config_data = registration_settings.REGISTER_VERIFICATION_EMAIL_TEMPLATES  # noqa: E501
            notification_data = {
                'params_signer': signer,
            }
            send_verification_notification(
                NotificationType.REGISTER_VERIFICATION, user,
                notification_data, template_config_data)

    signals.user_registered.send(sender=None, user=user, request=request)
    output_serializer_class = registration_settings.REGISTER_OUTPUT_SERIALIZER_CLASS  # noqa: E501
    output_serializer = output_serializer_class(
        instance=user,
        context={'request': request},
    )
    user_data = output_serializer.data
    return Response(user_data, status=status.HTTP_201_CREATED)
Beispiel #17
0
def logout(request):
    '''
    Logs out the user. returns an error if the user is not
    authenticated.
    '''
    user = request.user
    serializer = LogoutSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    data = serializer.validated_data

    if should_authenticate_session():
        auth.logout(request)
    if should_retrieve_token() and data['revoke_token']:
        try:
            user.auth_token.delete()
        except Token.DoesNotExist:
            raise BadRequest('Cannot remove non-existent token')

    return get_ok_response('Logout successful')
Beispiel #18
0
def login(request):
    '''
    Logs in the user via given login and password.
    '''
    serializer_class = registration_settings.LOGIN_SERIALIZER_CLASS
    serializer = serializer_class(data=request.data)
    serializer.is_valid(raise_exception=True)
    user = serializer.get_authenticated_user()

    if not user:
        raise BadRequest('Login or password invalid.')

    if should_authenticate_session():
        auth.login(request, user)

    extra_data = {}

    if should_retrieve_token():
        token, _ = Token.objects.get_or_create(user=user)
        extra_data['token'] = token.key

    return get_ok_response('Login successful', extra_data=extra_data)
Beispiel #19
0
    def get_queryset(self):
        '''
        query_params:
            - med_ids: list of MedicaitonName ids
            - dosages: list of Dosage ids
            - localization: list of 2 coordinates (must be int or float)
            - distance: int, in miles
        '''
        med_ids = self.request.query_params.getlist('med_ids[]', None)
        dosages = self.request.query_params.getlist('dosages[]', None)
        location = self.request.query_params.get('localization')
        distance = self.request.query_params.get('distance')

        # 1 - validate location
        try:
            location = list(map(float, location.split(',')))
            location_point = Point(
                location[0],
                location[1],
                srid=4326,
            )
        except (IndexError, ValueError, AttributeError):
            raise BadRequest(
                'Location should be provided and be a list of 2 coordinates')

        # 2 - fetch ndc codes from filters: med id and dosage + support for all
        if len(med_ids) == 1 and med_ids[0] == 'all':
            med_ndc_qs = MedicationMedicationNameMedicationDosageThrough.objects.all(
            )
        else:
            med_ndc_qs = MedicationMedicationNameMedicationDosageThrough.objects.filter(
                medication_name_id__in=med_ids,
                medication_dosage_id__in=dosages)
        med_ndc_ids = med_ndc_qs.select_related(
            'medication__ndc_codes', ).distinct().values_list(
                'medication__ndc_codes', flat=True)

        # 2 - fetch provider medication entries (supply levels) for the ndc ndc_codes
        # and filter by distance
        provider_medication_ids = ProviderMedicationNdcThrough.objects.filter(
            latest=True,
            medication_ndc_id__in=med_ndc_ids,
            provider__geo_localization__distance_lte=(
                location_point,
                D(mi=distance),
            ),
        ).values_list(
            'id',
            flat=True,
        )

        # SPECIAL INSTRUCTION
        # Exclude providers from vaccine finder organization ID 4504 (4383 in medfinder)
        # vaccine finder type needs to be 4 (pharamacy), exclude all other
        # More info at https://www.pivotaltracker.com/story/show/162711148

        provider_qs = Provider.objects.filter(
            Q(organization_id=4383) | Q(vaccine_finder_type=4)
        ).filter(geo_localization__distance_lte=(
            location_point,
            D(mi=distance),
        ), ).annotate(
            distance=Distance(
                'geo_localization',
                location_point,
            ),
            total_supply=Coalesce(
                Sum(
                    'provider_medication__level',
                    filter=Q(
                        provider_medication__id__in=provider_medication_ids,
                        provider_medication__latest=True,
                        active=True,
                    ),
                ),
                0,
            ),
            amount_medications=Count(
                'provider_medication',
                filter=Q(
                    provider_medication__id__in=provider_medication_ids,
                    provider_medication__latest=True,
                    active=True,
                ),
            )).prefetch_related(
                Prefetch(
                    'provider_medication',
                    queryset=ProviderMedicationNdcThrough.objects.filter(
                        latest=True,
                        id__in=provider_medication_ids,
                    ).select_related(
                        'medication_ndc__medication',
                        'medication_ndc__medication__medication_name',
                    ).order_by(
                        '-level',
                        '-medication_ndc__medication__drug_type'))).order_by(
                            '-total_supply', '-active', '-amount_medications',
                            'distance')

        return provider_qs