def unlock_user(request, username):
    try:
        api_client.get_connection(request).users(username).patch({"is_locked_out": False})

        admin_username = request.user.user_data.get("username", "Unknown")
        logger.info(
            "Admin %(admin_username)s removed lock-out for user %(username)s"
            % {"admin_username": admin_username, "username": username},
            extra={"elk_fields": {"@fields.username": admin_username}},
        )
        messages.success(
            request, gettext("Unlocked user ‘%(username)s’, they can now log in again") % {"username": username}
        )
    except HttpClientError as e:
        api_errors_to_messages(request, e, gettext("This user could not be enabled"))
    return redirect(reverse("list-users"))
    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request
        self.client = get_connection(request)

        for credit in self.credits:
            self.fields['comment_%s' % credit['id']] = forms.CharField(required=False)
def retrieve_last_balance(request, date):
    client = api_client.get_connection(request)
    response = client.balances.get(limit=1, date__lt=date.isoformat())
    if response.get('results'):
        return response['results'][0]
    else:
        return None
    def clean(self):
        if self.is_valid():
            data = {
                'first_name': self.cleaned_data['first_name'],
                'last_name': self.cleaned_data['last_name'],
                'email': self.cleaned_data['email'],
                'user_admin': self.cleaned_data['user_admin'],
            }
            try:
                admin_username = self.request.user.user_data.get('username', 'Unknown')

                if self.create:
                    data['username'] = self.cleaned_data['username']
                    api_client.get_connection(self.request).users().post(data)

                    logger.info('Admin %(admin_username)s created user %(username)s' % {
                        'admin_username': admin_username,
                        'username': data['username'],
                    }, extra={
                        'elk_fields': {
                            '@fields.username': admin_username,
                        }
                    })
                else:
                    username = self.initial['username']
                    api_client.get_connection(self.request).users(username).patch(data)

                    logger.info('Admin %(admin_username)s edited user %(username)s' % {
                        'admin_username': admin_username,
                        'username': username,
                    }, extra={
                        'elk_fields': {
                            '@fields.username': admin_username,
                        }
                    })
            except HttpClientError as e:
                try:
                    response_body = json.loads(e.content.decode('utf-8'))
                    for field, errors in response_body.items():
                        if isinstance(errors, list):
                            for error in errors:
                                self.add_error(field, error)
                        else:
                            self.add_error(field, errors)
                except (AttributeError, ValueError, KeyError):
                    raise forms.ValidationError(self.error_messages['generic'])
        return self.cleaned_data
 def get_initial(self):
     username = self.kwargs["username"]
     try:
         response = api_client.get_connection(self.request).users(username).get()
         return {
             "username": response.get("username", ""),
             "first_name": response.get("first_name", ""),
             "last_name": response.get("last_name", ""),
             "email": response.get("email", ""),
             "user_admin": response.get("user_admin", False),
         }
     except HttpNotFoundError:
         raise Http404
    def test_token_refreshed_automatically(self):
        """
        Test that if I call the /test/ endpoint with an
        expired access token, the module should automatically:

        - request a new access token
        - update request.user.token to the new token
        - finally request /test/ with the new valid token
        """

        def build_expires_at(dt):
            return (dt - datetime.datetime(1970, 1, 1)).total_seconds()

        # dates
        now = datetime.datetime.now()
        one_day_delta = datetime.timedelta(days=1)

        expired_yesterday = build_expires_at(now - one_day_delta)
        expires_tomorrow = build_expires_at(now + one_day_delta)

        # set access_token.expires_at to yesterday
        self.request.user.token["expires_at"] = expired_yesterday
        expired_token = self.request.user.token

        # mock the refresh token endpoint, return a new token
        new_token = generate_tokens(expires_at=expires_tomorrow)
        responses.add(
            responses.POST,
            api_client.REQUEST_TOKEN_URL,
            body=json.dumps(new_token),
            status=200,
            content_type="application/json",
        )

        # mock the /test/ endpoint, return valid body
        expected_response = {"success": True}
        responses.add(
            responses.GET,
            self.test_endpoint,
            body=json.dumps(expected_response),
            status=200,
            content_type="application/json",
        )

        # test
        conn = api_client.get_connection(self.request)
        result = conn.test.get()

        self.assertDictEqual(result, expected_response)
        self.assertDictEqual(self.request.user.token, new_token)
        self.assertNotEqual(expired_token["access_token"], new_token["access_token"])
def undelete_user(request, username):
    context = {"breadcrumbs": make_breadcrumbs(_("Enable user"))}
    if request.method == "POST":
        try:
            api_client.get_connection(request).users(username).patch({"is_active": True})

            admin_username = request.user.user_data.get("username", "Unknown")
            logger.info(
                "Admin %(admin_username)s enabled user %(username)s"
                % {"admin_username": admin_username, "username": username},
                extra={"elk_fields": {"@fields.username": admin_username}},
            )
            context["username"] = username
            return render(request, "mtp_common/user_admin/undeleted.html", context=context)
        except HttpClientError as e:
            api_errors_to_messages(request, e, gettext("This user could not be enabled"))
            return redirect(reverse("list-users"))

    try:
        user = api_client.get_connection(request).users(username).get()
        context["user"] = user
        return render(request, "mtp_common/user_admin/undelete.html", context=context)
    except HttpNotFoundError:
        raise Http404
    def get_context_data(self, **kwargs):
        context_data = super().get_context_data(**kwargs)

        # TODO: this note only applies to cashbook; we need a way to pass it in from client apps
        prison_count = api_client.get_connection(self.request).prisons.get().get("count", 0)
        if prison_count > 0:
            context_data["permissions_note"] = ngettext(
                "The new user will have access to the same prison as you do.",
                "The new user will have access to the same prisons as you do.",
                prison_count,
            ) % {"prison_count": prison_count}
        else:
            context_data["permissions_note"] = gettext("The new user will not have access to manage any prisons.")

        return context_data
    def test_with_valid_access_token(self):
        # mock the response, return valid body
        expected_response = {"success": True}

        responses.add(
            responses.GET,
            self.test_endpoint,
            body=json.dumps(expected_response),
            status=200,
            content_type="application/json",
        )

        # should return the same generated body
        conn = api_client.get_connection(self.request)
        result = conn.test.get()

        self.assertDictEqual(result, expected_response)
def list_users(request):
    page_size = 20
    try:
        page = int(request.GET["page"])
        if page < 1:
            raise ValueError
    except (KeyError, ValueError):
        page = 1
    response = api_client.get_connection(request).users.get(limit=page_size, offset=(page - 1) * page_size)
    users = response.get("results", [])
    context = {
        "can_delete": request.user.has_perm("auth.delete_user"),
        "locked_users_exist": any(user["is_locked_out"] for user in users),
        "users": users,
        "page": page,
        "page_count": int(math.ceil(response.get("count", 0) / page_size)),
    }
    return render(request, "mtp_common/user_admin/list.html", context=context)
    def test_refresh_token_failing_raises_unauthorized(self):
        def build_expires_at(dt):
            return (dt - datetime.datetime(1970, 1, 1)).total_seconds()

        # dates
        now = datetime.datetime.now()
        one_day_delta = datetime.timedelta(days=1)

        expired_yesterday = build_expires_at(now - one_day_delta)

        # set access_token.expires_at to yesterday
        self.request.user.token["expires_at"] = expired_yesterday

        # mock the refresh token endpoint, return 401
        responses.add(responses.POST, api_client.REQUEST_TOKEN_URL, status=401, content_type="application/json")

        # test
        conn = api_client.get_connection(self.request)
        self.assertRaises(Unauthorized, conn.test.get)
def reconcile_for_date(request, receipt_date):
    checker = WorkdayChecker()
    start_date = set_worldpay_cutoff(receipt_date)
    end_date = set_worldpay_cutoff(checker.get_next_workday(receipt_date))

    if start_date.date() >= now().date() or end_date.date() > now().date():
        raise EarlyReconciliationError

    reconciliation_date = start_date
    while reconciliation_date < end_date:
        end_of_day = reconciliation_date + timedelta(days=1)
        client = api_client.get_connection(request)
        client.transactions.reconcile.post({
            'received_at__gte': reconciliation_date.isoformat(),
            'received_at__lt': end_of_day.isoformat(),
        })
        reconciliation_date = end_of_day

    return start_date, end_date
    def get_credits_view(self, request):
        client = get_connection(request)
        filters = request.GET.dict()
        try:
            page = int(filters.pop('page', 1))
            if page < 1:
                raise ValueError
        except (KeyError, ValueError):
            page = 1

        query_string = QueryDict(mutable=True)
        for key, value in filters.items():
            if value:
                query_string[key] = value
        ajax = query_string.get('ajax', False)
        query_string = query_string.urlencode()

        filters.pop('prisoner_name', None)  # this should not be used to identify prisoners
        filters.pop('return_to', None)  # this is for navigation not filtering
        filters.update(self.form_class.extra_filters)

        # convert empty filters into 'isblank' filters for special keys
        for blank_key in self.blank_keys:
            if filters.get(blank_key, None) == '':
                del filters[blank_key]
                filters['%s__isblank' % blank_key] = True

        offset = (page - 1) * self.page_size
        data = client.credits.get(offset=offset, limit=self.page_size, **filters)
        count = data['count']
        page_count = int(ceil(count / self.page_size))
        context = {
            'view': self,
            'page': page,
            'page_count': page_count,
            'query_string': query_string,
            'credits': data.get('results', []),
        }
        template_name = self.credits_ajax_template_name if ajax else self.credits_template_name
        return render(request, template_name, context)
 def _test_failure(self):
     conn = api_client.get_connection(self.request)
     self.assertRaises(
         Unauthorized, conn.test.get
     )
def retrieve_prisons(request):
    endpoint = api_client.get_connection(request).prisons.get
    return {prison['nomis_id']: prison for prison in retrieve_all_pages(endpoint)}
def retrieve_all_valid_credits(request, **kwargs):
    endpoint = api_client.get_connection(request).credits.get
    return retrieve_all_pages(endpoint, valid=True, **kwargs)
def retrieve_all_transactions(request, **kwargs):
    endpoint = api_client.get_connection(request).transactions.get
    return retrieve_all_pages(endpoint, **kwargs)
 def __init__(self, request, **kwargs):
     super().__init__(**kwargs)
     self.request = request
     self.client = get_connection(request)
     self.page_count = 0
    def test_invalid_access_token_raises_unauthorized(self):
        # mock the response, return 401
        responses.add(responses.GET, self.test_endpoint, status=401, content_type="application/json")

        conn = api_client.get_connection(self.request)
        self.assertRaises(Unauthorized, conn.test.get)
 def _test_success(self):
     conn = api_client.get_connection(self.request)
     return conn.test.get()